|
1 /* |
|
2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: A class for TrackLog functionality |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "ctracklog.h" |
|
19 #include "locationmanagerdebug.h" |
|
20 #include "locationtraildefs.h" |
|
21 #include "rtracklog.h" |
|
22 #include <f32file.h> |
|
23 #include <s32file.h> |
|
24 #include <PathInfo.h> |
|
25 #include <centralrepository.h> |
|
26 #include <locationeventdef.h> |
|
27 #include "cgpxconverterao.h" |
|
28 |
|
29 EXPORT_C CTrackLog* CTrackLog::NewL() |
|
30 { |
|
31 CTrackLog* self = new (ELeave) CTrackLog(); |
|
32 CleanupStack::PushL( self ); |
|
33 self->ConstructL(); |
|
34 CleanupStack::Pop( self ); |
|
35 return self; |
|
36 } |
|
37 |
|
38 void CTrackLog::ConstructL() |
|
39 { |
|
40 LOG("CTrackLog::ConstructL start"); |
|
41 |
|
42 iGpxConverter = CGpxConverterAO::NewL(); |
|
43 |
|
44 TInt bufSize( 0 ); |
|
45 TRAPD( err, ReadCenRepValueL( KTrackLogSizeKey, bufSize )); |
|
46 LOG1("CLocationManagerServer::ConstructL, cenrep bufsize value:%d", bufSize); |
|
47 |
|
48 if ( err != KErrNone ) |
|
49 { |
|
50 LOG1("CTrackLog::ConstructL, cenrep err:%d", err); |
|
51 iMaxBufferSize = KTrackLogBufSize; |
|
52 } |
|
53 else |
|
54 { |
|
55 iMaxBufferSize = bufSize; |
|
56 } |
|
57 User::LeaveIfError( iFs.Connect() ); |
|
58 |
|
59 LOG("CTrackLog::ConstructL end"); |
|
60 } |
|
61 |
|
62 CTrackLog::CTrackLog() : |
|
63 iMaxBufferSize( KTrackLogBufSize ), |
|
64 iRecording( EFalse ) |
|
65 { |
|
66 } |
|
67 |
|
68 CTrackLog::~CTrackLog() |
|
69 { |
|
70 delete iGpxConverter; |
|
71 iFs.Close(); |
|
72 } |
|
73 |
|
74 EXPORT_C void CTrackLog::StartRecordingL(TItemId aId) |
|
75 { |
|
76 LOG("CTrackLog::StartRecording start"); |
|
77 _LIT( KExtTmp, ".tmp" ); |
|
78 _LIT( KExtGpx, ".gpx" ); |
|
79 |
|
80 iTagId = aId; |
|
81 iFs.PrivatePath( iTmpFileName ); |
|
82 TInt err; |
|
83 err = iFs.MkDirAll( iTmpFileName ); |
|
84 if ( err != KErrAlreadyExists && err != KErrNone ) |
|
85 { |
|
86 User::Leave( err ); |
|
87 } |
|
88 |
|
89 TTime now( 0 ); |
|
90 now.HomeTime(); |
|
91 TDateTime datetime = now.DateTime(); |
|
92 |
|
93 _LIT( KGpxFileName, "tracklog%d%02d%02d%02d%02d%02d" ); |
|
94 HBufC* fileName = HBufC::NewL( KMaxFileName ); |
|
95 CleanupStack::PushL( fileName ); |
|
96 TPtr namePtr = fileName->Des(); |
|
97 |
|
98 namePtr.Format(KGpxFileName, datetime.Year(), datetime.Month() + 1, datetime.Day() + 1, |
|
99 datetime.Hour(), datetime.Minute(), datetime.Second() ); |
|
100 |
|
101 iTrackLogItemArray.Reset(); |
|
102 iRecording = ETrue; |
|
103 iGpxFileName.Copy( namePtr ); |
|
104 iTmpFileName.Append( iGpxFileName ); |
|
105 |
|
106 iGpxFileName.Append( KExtGpx ); |
|
107 iTmpFileName.Append( KExtTmp ); |
|
108 |
|
109 WriteBufferToFileL(); |
|
110 |
|
111 CleanupStack::PopAndDestroy( fileName ); |
|
112 LOG("CTrackLog::StartRecording end"); |
|
113 } |
|
114 |
|
115 EXPORT_C void CTrackLog::StopRecordingL() |
|
116 { |
|
117 LOG("CTrackLog::StopRecording start"); |
|
118 |
|
119 // "flush" buffer |
|
120 WriteBufferToFileL(); |
|
121 iTrackLogItemArray.Reset(); |
|
122 // gpx converter will clean up boundaries |
|
123 iGpxConverter->AddToQueueL( iTmpFileName, iBoundaries ); |
|
124 |
|
125 iBoundaries = NULL; |
|
126 iRecording = EFalse; |
|
127 LOG("CTrackLog::StopRecording end"); |
|
128 } |
|
129 |
|
130 EXPORT_C void CTrackLog::CancelRecording() |
|
131 { |
|
132 LOG("CTrackLog::CancelRecording start"); |
|
133 iRecording = EFalse; |
|
134 iTrackLogItemArray.Reset(); |
|
135 iFs.Delete( iTmpFileName ); |
|
136 LOG("CTrackLog::CancelRecording end"); |
|
137 } |
|
138 |
|
139 void CTrackLog::LocationAdded( const TLocationTrailItem& aTrailItem, |
|
140 const TPositionSatelliteInfo& aSatellites ) |
|
141 { |
|
142 LOG("CTrackLog::LocationAdded start"); |
|
143 |
|
144 const TInt KMaxLat = 90; |
|
145 const TInt KMinLat = -90; |
|
146 const TInt KMaxLon = 180; |
|
147 const TInt KMinLon = -180; |
|
148 if ( !iBoundaries ) |
|
149 { |
|
150 iBoundaries = new TBoundaries; |
|
151 iBoundaries->minLatitude = KMaxLat; |
|
152 iBoundaries->maxLatitude = KMinLat; |
|
153 iBoundaries->minLongitude = KMaxLon; |
|
154 iBoundaries->maxLongitude = KMinLon; |
|
155 iBoundaries->distance = 0; |
|
156 } |
|
157 |
|
158 if ( IsRecording() ) |
|
159 { |
|
160 TTrackLogItem newItem; |
|
161 newItem.iTimeStamp = aTrailItem.iTimeStamp; |
|
162 newItem.iLatitude = aTrailItem.iLocationData.iPosition.Latitude(); |
|
163 newItem.iLongitude = aTrailItem.iLocationData.iPosition.Longitude(); |
|
164 newItem.iAltitude = aTrailItem.iLocationData.iPosition.Altitude(); |
|
165 newItem.iHdop = aSatellites.HorizontalDoP(); |
|
166 newItem.iVdop = aSatellites.VerticalDoP(); |
|
167 newItem.iCourse = aTrailItem.iLocationData.iCourse.Course(); |
|
168 newItem.iQuality = aTrailItem.iLocationData.iQuality; |
|
169 newItem.iNumSatellites = aTrailItem.iLocationData.iSatellites; |
|
170 |
|
171 iTrackLogItemArray.Append(newItem); |
|
172 |
|
173 // Keep the latest satellite information safe. |
|
174 iSatelliteInfo = aSatellites; |
|
175 |
|
176 // Check if the GPS fix is lost or buffer is full. |
|
177 // If true, then write buffer to a file. |
|
178 if ( Math::IsNaN(newItem.iLatitude) || Math::IsNaN(newItem.iLongitude) || |
|
179 iTrackLogItemArray.Count() > iMaxBufferSize ) |
|
180 { |
|
181 LOG("CTrackLog::LocationAdded - buffer full, writing to file"); |
|
182 TRAPD( err, WriteBufferToFileL() ); |
|
183 if( err != KErrNone ) |
|
184 { |
|
185 LOG1("WriteBufferToFileL leave error: %d", err); |
|
186 } |
|
187 iTrackLogItemArray.Reset(); |
|
188 } |
|
189 if( !Math::IsNaN( newItem.iLatitude ) && !Math::IsNaN( newItem.iLongitude ) ) |
|
190 { |
|
191 TReal32 distance; |
|
192 if ( !lastCoords ) |
|
193 { |
|
194 lastCoords = new TCoordinate( aTrailItem.iLocationData.iPosition ); |
|
195 } |
|
196 else |
|
197 { |
|
198 TLocality newCoords(aTrailItem.iLocationData.iPosition, |
|
199 aTrailItem.iLocationData.iPosition.HorizontalAccuracy() ); |
|
200 TInt err = newCoords.Distance(*lastCoords, distance); |
|
201 if ( err == KErrNone ) |
|
202 { |
|
203 delete lastCoords; |
|
204 lastCoords = new TCoordinate( aTrailItem.iLocationData.iPosition ); |
|
205 iBoundaries->distance += distance; |
|
206 } |
|
207 } |
|
208 iBoundaries->maxLatitude = Max( iBoundaries->maxLatitude, newItem.iLatitude ); |
|
209 iBoundaries->minLatitude = Min( iBoundaries->minLatitude, newItem.iLatitude ); |
|
210 iBoundaries->maxLongitude = Max( iBoundaries->maxLongitude, newItem.iLongitude ); |
|
211 iBoundaries->minLongitude = Min( iBoundaries->minLongitude, newItem.iLongitude ); |
|
212 } |
|
213 } |
|
214 LOG("CTrackLog::LocationAdded end"); |
|
215 } |
|
216 |
|
217 void CTrackLog::WriteBufferToFileL() |
|
218 { |
|
219 LOG("CTrackLog::WriteBufferToFileL start"); |
|
220 |
|
221 RFile64 file; |
|
222 RFileWriteStream writer; |
|
223 |
|
224 TInt err; |
|
225 err = file.Open( iFs, iTmpFileName, EFileRead ); |
|
226 if ( err != KErrNone ) |
|
227 { |
|
228 err = writer.Create( iFs, iTmpFileName, EFileWrite ); |
|
229 if( err != KErrNone ) |
|
230 { |
|
231 User::Leave( err ); |
|
232 } |
|
233 writer << I64LOW( iTagId ); |
|
234 writer << I64HIGH( iTagId ); |
|
235 } |
|
236 else |
|
237 { |
|
238 CleanupClosePushL( file ); |
|
239 TInt64 endpos( 0 ); |
|
240 file.Seek( ESeekEnd, endpos ); |
|
241 CleanupStack::PopAndDestroy( &file ); |
|
242 err = writer.Open( iFs, iTmpFileName, EFileWrite ); |
|
243 if( err != KErrNone ) |
|
244 { |
|
245 User::Leave( err ); |
|
246 } |
|
247 writer.Sink()->SeekL( MStreamBuf::EWrite, TStreamPos( endpos )); |
|
248 } |
|
249 |
|
250 CleanupClosePushL( writer ); |
|
251 |
|
252 TInt count = iTrackLogItemArray.Count(); |
|
253 |
|
254 for( TInt i = 0; i < count; i++ ) |
|
255 { |
|
256 writer << iTrackLogItemArray[i]; |
|
257 } |
|
258 |
|
259 writer.CommitL(); |
|
260 |
|
261 CleanupStack::PopAndDestroy( &writer ); |
|
262 LOG("CTrackLog::WriteBufferToFileL end"); |
|
263 } |
|
264 |
|
265 EXPORT_C TInt CTrackLog::GetStatus( TBool& aRecording, TPositionSatelliteInfo& aFixQuality ) |
|
266 { |
|
267 aFixQuality = iSatelliteInfo; |
|
268 aRecording = IsRecording(); |
|
269 |
|
270 return KErrNone; |
|
271 } |
|
272 |
|
273 EXPORT_C TBool CTrackLog::IsRecording() |
|
274 { |
|
275 return iRecording; |
|
276 } |
|
277 |
|
278 EXPORT_C void CTrackLog::GetTrackLogName(TFileName& aFileName) |
|
279 { |
|
280 aFileName = iGpxFileName; |
|
281 } |
|
282 |
|
283 EXPORT_C void CTrackLog::AddGpxObserver( MGpxConversionObserver* aObserver ) |
|
284 { |
|
285 iGpxConverter->AddObserver( aObserver ); |
|
286 } |
|
287 |
|
288 EXPORT_C void CTrackLog::StartRecoveryL() |
|
289 { |
|
290 _LIT( KWildTmp, "*.tmp" ); |
|
291 |
|
292 TInt err; |
|
293 CDir* files; |
|
294 TFileName *filename = new (ELeave) TFileName(); |
|
295 TFindFile finder( iFs ); |
|
296 iFs.PrivatePath( iTmpFileName ); |
|
297 err = finder.FindWildByDir( KWildTmp, iTmpFileName, files); |
|
298 if ( err == KErrNone ) |
|
299 { |
|
300 TInt count = files->Count(); |
|
301 for( TInt i = 0; i < count; i++ ) |
|
302 { |
|
303 filename->Copy(iTmpFileName); |
|
304 filename->Append((*files)[i].iName); |
|
305 TRAP_IGNORE( iGpxConverter->AddToQueueL( *filename, NULL )); |
|
306 } |
|
307 } |
|
308 delete filename; |
|
309 delete files; |
|
310 } |
|
311 |
|
312 void CTrackLog::ReadCenRepValueL(TInt aKey, TInt& aValue) |
|
313 { |
|
314 LOG( "LocationManagerServer::ReadCenRepValueL(), begin" ); |
|
315 CRepository* repository; |
|
316 repository = CRepository::NewLC( KRepositoryUid ); |
|
317 User::LeaveIfError(repository->Get( aKey, aValue)); |
|
318 CleanupStack::PopAndDestroy(repository); |
|
319 LOG( "LocationManagerServer::ReadCenRepValueL(), end" ); |
|
320 } |
|
321 |
|
322 |
|
323 void TTrackLogItem::ExternalizeL( RWriteStream& aStream ) const |
|
324 { |
|
325 aStream.WriteReal64L( iLatitude ); |
|
326 aStream.WriteReal64L( iLongitude ); |
|
327 aStream.WriteReal32L( iAltitude ); |
|
328 aStream.WriteReal32L( iCourse ); |
|
329 aStream.WriteReal32L( iQuality ); |
|
330 aStream.WriteUint32L( iNumSatellites ); |
|
331 aStream.WriteReal32L( iHdop ); |
|
332 aStream.WriteReal32L( iVdop ); |
|
333 aStream.WriteUint32L( I64LOW( iTimeStamp.Int64() )); |
|
334 aStream.WriteUint32L( I64HIGH( iTimeStamp.Int64() )); |
|
335 } |
|
336 |
|
337 void TTrackLogItem::InternalizeL( RReadStream& aStream ) |
|
338 { |
|
339 iLatitude = aStream.ReadReal64L(); |
|
340 iLongitude = aStream.ReadReal64L(); |
|
341 iAltitude = aStream.ReadReal32L(); |
|
342 TReal32 realVal; |
|
343 realVal = aStream.ReadReal32L(); |
|
344 iCourse = realVal; |
|
345 realVal = aStream.ReadReal32L(); |
|
346 iQuality = realVal; |
|
347 TUint32 satellites; |
|
348 satellites = aStream.ReadUint32L(); |
|
349 iNumSatellites = satellites; |
|
350 realVal = aStream.ReadReal32L(); |
|
351 iHdop = realVal; |
|
352 realVal = aStream.ReadReal32L(); |
|
353 iVdop = realVal; |
|
354 TUint32 low( 0 ); |
|
355 TUint32 high( 0 ); |
|
356 low = aStream.ReadUint32L(); |
|
357 high = aStream.ReadUint32L(); |
|
358 TInt64 timestamp( 0 ); |
|
359 timestamp = MAKE_TINT64( high, low ); |
|
360 iTimeStamp = timestamp; |
|
361 } |