locationmanager/locationtrail/src/ctracklog.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationmanager/locationtrail/src/ctracklog.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,361 @@
+/*
+* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  A class for TrackLog functionality
+*
+*/
+
+#include "ctracklog.h"
+#include "locationmanagerdebug.h"
+#include "locationtraildefs.h"
+#include "rtracklog.h"
+#include <f32file.h>
+#include <s32file.h>
+#include <PathInfo.h>
+#include <centralrepository.h>
+#include <locationeventdef.h>
+#include "cgpxconverterao.h"
+
+EXPORT_C CTrackLog* CTrackLog::NewL()
+	{
+    CTrackLog* self = new (ELeave) CTrackLog();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+	}
+
+void CTrackLog::ConstructL()
+	{
+	LOG("CTrackLog::ConstructL start");
+	
+	iGpxConverter = CGpxConverterAO::NewL();
+	
+    TInt bufSize( 0 );
+    TRAPD( err, ReadCenRepValueL( KTrackLogSizeKey, bufSize ));
+    LOG1("CLocationManagerServer::ConstructL, cenrep bufsize value:%d", bufSize);
+    
+    if ( err != KErrNone )
+    	{
+        LOG1("CTrackLog::ConstructL, cenrep err:%d", err);
+        iMaxBufferSize = KTrackLogBufSize;
+    	}
+    else
+    	{
+    	iMaxBufferSize = bufSize;
+    	}
+	User::LeaveIfError( iFs.Connect() );
+	
+	LOG("CTrackLog::ConstructL end");
+	}
+
+CTrackLog::CTrackLog() :
+	iMaxBufferSize( KTrackLogBufSize ),
+	iRecording( EFalse )
+	{
+	}
+
+CTrackLog::~CTrackLog()
+	{
+	delete iGpxConverter;
+	iFs.Close();
+	}
+
+EXPORT_C void CTrackLog::StartRecordingL(TItemId aId)
+	{
+	LOG("CTrackLog::StartRecording start");
+	_LIT( KExtTmp, ".tmp" );
+	_LIT( KExtGpx, ".gpx" );
+	
+	iTagId = aId;
+	iFs.PrivatePath( iTmpFileName );
+	TInt err;
+	err = iFs.MkDirAll( iTmpFileName );
+	if ( err != KErrAlreadyExists && err != KErrNone )
+		{
+		User::Leave( err );
+		}
+
+	TTime now( 0 );
+	now.HomeTime();
+	TDateTime datetime = now.DateTime();
+	
+	_LIT( KGpxFileName, "tracklog%d%02d%02d%02d%02d%02d" );
+	HBufC* fileName = HBufC::NewL( KMaxFileName );
+	CleanupStack::PushL( fileName );
+	TPtr namePtr = fileName->Des();
+	
+	namePtr.Format(KGpxFileName, datetime.Year(), datetime.Month() + 1, datetime.Day() + 1,
+			datetime.Hour(), datetime.Minute(), datetime.Second() );
+
+	iTrackLogItemArray.Reset();
+	iRecording = ETrue;
+	iGpxFileName.Copy( namePtr );
+	iTmpFileName.Append( iGpxFileName );
+
+	iGpxFileName.Append( KExtGpx );
+	iTmpFileName.Append( KExtTmp );	
+	
+	WriteBufferToFileL();
+	
+	CleanupStack::PopAndDestroy( fileName );
+	LOG("CTrackLog::StartRecording end");
+	}
+
+EXPORT_C void CTrackLog::StopRecordingL()
+	{
+	LOG("CTrackLog::StopRecording start");
+	
+	// "flush" buffer
+	WriteBufferToFileL();
+	iTrackLogItemArray.Reset();
+	// gpx converter will clean up boundaries
+	iGpxConverter->AddToQueueL( iTmpFileName, iBoundaries );
+	
+	iBoundaries = NULL;
+	iRecording = EFalse;
+	LOG("CTrackLog::StopRecording end");
+	}
+
+EXPORT_C void CTrackLog::CancelRecording()
+	{
+	LOG("CTrackLog::CancelRecording start");
+	iRecording = EFalse;
+	iTrackLogItemArray.Reset();
+	iFs.Delete( iTmpFileName );
+	LOG("CTrackLog::CancelRecording end");
+	}
+
+void CTrackLog::LocationAdded( const TLocationTrailItem& aTrailItem, 
+							   const TPositionSatelliteInfo& aSatellites )
+	{
+	LOG("CTrackLog::LocationAdded start");
+
+	const TInt KMaxLat = 90;
+	const TInt KMinLat = -90;
+	const TInt KMaxLon = 180;
+	const TInt KMinLon = -180;
+	if ( !iBoundaries )
+		{
+		iBoundaries = new TBoundaries;	
+		iBoundaries->minLatitude = KMaxLat;
+		iBoundaries->maxLatitude = KMinLat;
+		iBoundaries->minLongitude = KMaxLon;
+		iBoundaries->maxLongitude = KMinLon;
+		iBoundaries->distance = 0;
+		}
+	
+	if ( IsRecording() )
+		{
+		TTrackLogItem newItem;
+		newItem.iTimeStamp = aTrailItem.iTimeStamp;
+		newItem.iLatitude = aTrailItem.iLocationData.iPosition.Latitude();
+		newItem.iLongitude = aTrailItem.iLocationData.iPosition.Longitude();
+		newItem.iAltitude = aTrailItem.iLocationData.iPosition.Altitude();
+		newItem.iHdop = aSatellites.HorizontalDoP();
+		newItem.iVdop = aSatellites.VerticalDoP();
+		newItem.iCourse = aTrailItem.iLocationData.iCourse.Course();
+		newItem.iQuality = aTrailItem.iLocationData.iQuality;
+		newItem.iNumSatellites = aTrailItem.iLocationData.iSatellites;
+
+		iTrackLogItemArray.Append(newItem);
+		
+		// Keep the latest satellite information safe.
+		iSatelliteInfo = aSatellites;
+		
+		// Check if the GPS fix is lost or buffer is full.
+		// If true, then write buffer to a file.
+		if ( Math::IsNaN(newItem.iLatitude) || Math::IsNaN(newItem.iLongitude) ||
+				iTrackLogItemArray.Count() > iMaxBufferSize )
+			{
+			LOG("CTrackLog::LocationAdded - buffer full, writing to file");
+			TRAPD( err, WriteBufferToFileL() );
+			if( err != KErrNone )
+				{
+				LOG1("WriteBufferToFileL leave error: %d", err);
+				}
+			iTrackLogItemArray.Reset();
+			}
+		if( !Math::IsNaN( newItem.iLatitude ) && !Math::IsNaN( newItem.iLongitude ) )
+			{
+			TReal32 distance;
+			if ( !lastCoords )
+				{
+				lastCoords = new TCoordinate( aTrailItem.iLocationData.iPosition );
+				}
+			else
+				{
+				TLocality newCoords(aTrailItem.iLocationData.iPosition,
+						aTrailItem.iLocationData.iPosition.HorizontalAccuracy()	);
+				TInt err = newCoords.Distance(*lastCoords, distance);
+				if ( err == KErrNone )
+					{
+					delete lastCoords;
+					lastCoords = new TCoordinate( aTrailItem.iLocationData.iPosition );
+					iBoundaries->distance += distance;
+					}
+				}
+			iBoundaries->maxLatitude = Max( iBoundaries->maxLatitude, newItem.iLatitude );
+			iBoundaries->minLatitude = Min( iBoundaries->minLatitude, newItem.iLatitude );
+			iBoundaries->maxLongitude = Max( iBoundaries->maxLongitude, newItem.iLongitude );
+			iBoundaries->minLongitude = Min( iBoundaries->minLongitude, newItem.iLongitude );
+			}
+		}
+	LOG("CTrackLog::LocationAdded end");	
+	}
+
+void CTrackLog::WriteBufferToFileL()
+	{
+	LOG("CTrackLog::WriteBufferToFileL start");
+
+	RFile64 file;
+	RFileWriteStream writer;
+	
+	TInt err;
+	err = file.Open( iFs, iTmpFileName, EFileRead );
+	if ( err != KErrNone )
+		{
+		err = writer.Create( iFs, iTmpFileName, EFileWrite );
+		if( err != KErrNone )
+			{
+			User::Leave( err );
+			}
+		writer << I64LOW( iTagId );
+		writer << I64HIGH( iTagId );
+		}
+	else 
+		{
+		CleanupClosePushL( file );
+		TInt64 endpos( 0 );
+		file.Seek( ESeekEnd, endpos );
+		CleanupStack::PopAndDestroy( &file );
+		err = writer.Open( iFs, iTmpFileName, EFileWrite );
+		if( err != KErrNone )
+			{
+			User::Leave( err );
+			}
+		writer.Sink()->SeekL( MStreamBuf::EWrite, TStreamPos( endpos ));
+		}
+	
+	CleanupClosePushL( writer );
+	
+	TInt count = iTrackLogItemArray.Count();
+	
+	for( TInt i = 0; i < count; i++ )
+		{
+		writer << iTrackLogItemArray[i];
+		}
+	
+	writer.CommitL();
+	
+	CleanupStack::PopAndDestroy( &writer );
+	LOG("CTrackLog::WriteBufferToFileL end");
+	}
+
+EXPORT_C TInt CTrackLog::GetStatus( TBool& aRecording, TPositionSatelliteInfo& aFixQuality )
+	{
+	aFixQuality = iSatelliteInfo;
+	aRecording = IsRecording();
+	
+	return KErrNone;
+	}
+
+EXPORT_C TBool CTrackLog::IsRecording()
+	{
+	return iRecording;
+	}
+
+EXPORT_C void CTrackLog::GetTrackLogName(TFileName& aFileName)
+	{
+	aFileName = iGpxFileName;
+	}
+
+EXPORT_C void CTrackLog::AddGpxObserver( MGpxConversionObserver* aObserver )
+	{
+	iGpxConverter->AddObserver( aObserver );
+	}
+
+EXPORT_C void CTrackLog::StartRecoveryL()
+	{
+	_LIT( KWildTmp, "*.tmp" );
+
+	TInt err;
+	CDir* files;
+	TFileName *filename = new (ELeave) TFileName();
+	TFindFile finder( iFs );
+	iFs.PrivatePath( iTmpFileName );
+	err = finder.FindWildByDir( KWildTmp, iTmpFileName, files);
+	if ( err == KErrNone )
+		{
+		TInt count = files->Count();
+		for( TInt i = 0; i < count; i++ )
+			{
+			filename->Copy(iTmpFileName);
+			filename->Append((*files)[i].iName);
+			TRAP_IGNORE( iGpxConverter->AddToQueueL( *filename, NULL ));
+			}
+		}
+	delete filename;
+	delete files;
+	}
+
+void CTrackLog::ReadCenRepValueL(TInt aKey, TInt& aValue)
+	{
+	LOG( "LocationManagerServer::ReadCenRepValueL(), begin" );
+	CRepository* repository;
+	repository = CRepository::NewLC( KRepositoryUid );
+	User::LeaveIfError(repository->Get( aKey, aValue));
+	CleanupStack::PopAndDestroy(repository);
+    LOG( "LocationManagerServer::ReadCenRepValueL(), end" );   
+	}
+
+
+void TTrackLogItem::ExternalizeL( RWriteStream& aStream ) const
+	{
+	aStream.WriteReal64L( iLatitude );
+	aStream.WriteReal64L( iLongitude );
+	aStream.WriteReal32L( iAltitude );
+	aStream.WriteReal32L( iCourse );	
+	aStream.WriteReal32L( iQuality );	
+	aStream.WriteUint32L( iNumSatellites );
+	aStream.WriteReal32L( iHdop );
+	aStream.WriteReal32L( iVdop );
+	aStream.WriteUint32L( I64LOW( iTimeStamp.Int64() ));
+	aStream.WriteUint32L( I64HIGH( iTimeStamp.Int64() ));
+	}
+
+void TTrackLogItem::InternalizeL( RReadStream& aStream )
+	{
+	iLatitude = aStream.ReadReal64L();
+	iLongitude = aStream.ReadReal64L();
+	iAltitude = aStream.ReadReal32L();
+	TReal32 realVal;
+	realVal = aStream.ReadReal32L();
+	iCourse = realVal;
+	realVal = aStream.ReadReal32L();
+	iQuality = realVal;
+	TUint32 satellites;
+	satellites = aStream.ReadUint32L();
+	iNumSatellites = satellites;
+	realVal = aStream.ReadReal32L();
+	iHdop = realVal;
+	realVal = aStream.ReadReal32L();
+	iVdop = realVal;
+	TUint32 low( 0 );
+	TUint32 high( 0 );
+	low = aStream.ReadUint32L();
+	high = aStream.ReadUint32L();
+	TInt64 timestamp( 0 );
+	timestamp = MAKE_TINT64( high, low );
+	iTimeStamp = timestamp;
+	}