|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 |
|
17 |
|
18 // INCLUDE FILES |
|
19 #include <ecom/ecom.h> |
|
20 |
|
21 #include <lbscommon.h> |
|
22 #include <lbspositioninfo.h> |
|
23 #include <lbs/epos_cposmodules.h> |
|
24 #include <lbs/epos_cposmoduleidlist.h> |
|
25 #include <lbs/epos_cpositioner.h> |
|
26 #include <lbssatellite.h> |
|
27 #include "epos_mposmodulestatusmanager.h" |
|
28 |
|
29 #include "EPos_CPosRequestController.h" |
|
30 #include "epos_cposrequestor.h" |
|
31 #include "epos_defaultproxycommon.h" |
|
32 #include "epos_cpospsylisthandler.h" |
|
33 #include "epos_cpospsyfixstatemanager.h" |
|
34 #include "epos_cposconstmanager.h" |
|
35 #include "epos_cposexternalgpsmonitor.h" |
|
36 #include "epos_posgenericinfouser.h" |
|
37 |
|
38 |
|
39 // ================= LOCAL FUNCTIONS ======================= |
|
40 |
|
41 // ================= MEMBER FUNCTIONS ======================= |
|
42 |
|
43 // C++ default constructor can NOT contain any code, that |
|
44 // might leave. |
|
45 // |
|
46 CPosRequestController::CPosRequestController( |
|
47 CPosDefaultPositioner& aDefaultPositioner, |
|
48 MPosModuleStatusManager& aModuleStatusManager) |
|
49 : |
|
50 iDefaultPositioner( aDefaultPositioner ), |
|
51 iModuleStatusManager( aModuleStatusManager ), |
|
52 iCurrentPsy( KErrNotFound ) |
|
53 { |
|
54 } |
|
55 |
|
56 // EPOC default constructor can leave. |
|
57 void CPosRequestController::ConstructL( |
|
58 MPosModuleSettingsManager& aSettingsManager ) |
|
59 { |
|
60 TRACESTRING( "CPosRequestController::ConstructL start... " ) |
|
61 |
|
62 iPsyListHandler = CPosPsyListHandler::GetInstanceL(); |
|
63 iPsyListHandler->SetModuleSettingsManagerL( |
|
64 aSettingsManager ); |
|
65 iPsyListHandler->AddListenerL( this ); |
|
66 |
|
67 |
|
68 iPsyFixStateManager = CPosPsyFixStateManager::GetInstanceL(); |
|
69 iPsyFixStateManager->AddListenerL( this ); |
|
70 iConstManager = CPosConstManager::GetInstanceL(); |
|
71 |
|
72 iExtGpsPsyMonitor = CPosExternalGpsMonitor::GetInstanceL( |
|
73 iDefaultPositioner, |
|
74 iModuleStatusManager ); |
|
75 |
|
76 //Construct cleanup timer |
|
77 iCleanupTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
78 |
|
79 TRACESTRING( "CPosRequestController::ConstructL end " ) |
|
80 |
|
81 } |
|
82 |
|
83 // Two-phased constructor. |
|
84 CPosRequestController* CPosRequestController::NewL( |
|
85 CPosDefaultPositioner& aDefaultPositioner, |
|
86 MPosModuleSettingsManager& aSettingsManager, |
|
87 MPosModuleStatusManager& aModuleStatusManager ) |
|
88 { |
|
89 CPosRequestController* self = new (ELeave) |
|
90 CPosRequestController( |
|
91 aDefaultPositioner, |
|
92 aModuleStatusManager ); |
|
93 |
|
94 CleanupStack::PushL(self); |
|
95 self->ConstructL( |
|
96 aSettingsManager ); |
|
97 CleanupStack::Pop(self); |
|
98 return self; |
|
99 } |
|
100 |
|
101 // Destructor |
|
102 CPosRequestController::~CPosRequestController() |
|
103 { |
|
104 TRACESTRING( "CPosRequestController::destructor start... " ) |
|
105 |
|
106 if ( iPsyFixStateManager ) |
|
107 { |
|
108 iPsyFixStateManager->RemoveListener( this ); |
|
109 iPsyFixStateManager->ReleaseInstance(); |
|
110 } |
|
111 |
|
112 if ( iPsyListHandler ) |
|
113 { |
|
114 iPsyListHandler->RemoveListener( this ); |
|
115 iPsyListHandler->ReleaseInstance(); |
|
116 } |
|
117 |
|
118 if ( iConstManager ) |
|
119 { |
|
120 iConstManager->ReleaseInstance(); |
|
121 } |
|
122 |
|
123 if ( iExtGpsPsyMonitor ) |
|
124 { |
|
125 iExtGpsPsyMonitor->ReleaseInstance( |
|
126 iDefaultPositioner ); |
|
127 } |
|
128 |
|
129 // Close all requestors |
|
130 iRequestorArray.ResetAndDestroy(); |
|
131 iRequestorArray.Close(); |
|
132 |
|
133 //Close PSY List |
|
134 iPsyList.Close(); |
|
135 |
|
136 // Cleanup timer |
|
137 delete iCleanupTimer; |
|
138 |
|
139 TRACESTRING( "CPosRequestController::destructor end... " ) |
|
140 |
|
141 } |
|
142 |
|
143 // --------------------------------------------------------- |
|
144 // CPosRequestController::NotifyPositionUpdate |
|
145 // --------------------------------------------------------- |
|
146 // |
|
147 void CPosRequestController::NotifyPositionUpdate( |
|
148 TPositionInfoBase& aPosInfo, |
|
149 TRequestStatus& aStatus) |
|
150 { |
|
151 TRACESTRING( "CPosRequestController::NotifyPositionUpdate start... " ) |
|
152 |
|
153 //Default Proxy can't handle simultaneous location request. |
|
154 __ASSERT_DEBUG( |
|
155 iPosRequestStatus == NULL, |
|
156 DefaultProxyPanic( EDefaultProxyPanic_SimualtaneousLR ) ); |
|
157 |
|
158 aStatus = KRequestPending; |
|
159 iPosRequestStatus = &aStatus; |
|
160 iPosInfo = &aPosInfo; |
|
161 |
|
162 //When location request received, clear cleanup timer |
|
163 iCleanupTimer->Cancel(); |
|
164 |
|
165 TRAPD( err, StartPositionUpdateL() ); |
|
166 if( err != KErrNone ) |
|
167 { |
|
168 CompleteRequest(err); |
|
169 } |
|
170 |
|
171 TRACESTRING( "CPosRequestController::NotifyPositionUpdate end " ) |
|
172 } |
|
173 |
|
174 // --------------------------------------------------------- |
|
175 // CPosRequestController::CancelNotifyPositionUpdate |
|
176 // --------------------------------------------------------- |
|
177 // |
|
178 void CPosRequestController::CancelNotifyPositionUpdate(TInt aCancelReason) |
|
179 { |
|
180 TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate(TInt) start... " ) |
|
181 |
|
182 //Cancel location request with error to all loaded requestor |
|
183 TInt loadedRequestorCount = iRequestorArray.Count(); |
|
184 for ( TInt i = 0; i < loadedRequestorCount; i++ ) |
|
185 { |
|
186 CancelRequest( i, aCancelReason ); |
|
187 } |
|
188 |
|
189 CompleteRequest(KErrCancel); |
|
190 |
|
191 TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate(TInt) end " ) |
|
192 } |
|
193 |
|
194 // --------------------------------------------------------- |
|
195 // CPosRequestController::CancelNotifyPositionUpdate |
|
196 // --------------------------------------------------------- |
|
197 // |
|
198 void CPosRequestController::CancelNotifyPositionUpdate() |
|
199 { |
|
200 TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate start... " ) |
|
201 |
|
202 // This is a real user cancel |
|
203 CancelNotifyPositionUpdate(KErrCancel); |
|
204 |
|
205 TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate end " ) |
|
206 } |
|
207 |
|
208 // --------------------------------------------------------- |
|
209 // CPosRequestController::CancelRequest |
|
210 // --------------------------------------------------------- |
|
211 // |
|
212 void CPosRequestController::CancelRequest( TInt aIndex, TInt aCancelReason ) |
|
213 { |
|
214 TInt count = iRequestorArray.Count(); |
|
215 if ( aIndex < count ) |
|
216 { |
|
217 CPosRequestor* requestor = iRequestorArray[aIndex]; |
|
218 if ( requestor->IsActive() ) |
|
219 { |
|
220 //Notify external GPS PSY monitor that this PSY is not used. |
|
221 iExtGpsPsyMonitor->PsyNotUsed( requestor->ModuleId() ); |
|
222 requestor->CancelWithReason(aCancelReason); |
|
223 } |
|
224 } |
|
225 } |
|
226 |
|
227 // --------------------------------------------------------- |
|
228 // CPosRequestController::CancelRequest |
|
229 // --------------------------------------------------------- |
|
230 // |
|
231 void CPosRequestController::CancelRequest( TPositionModuleId aPsyId ) |
|
232 { |
|
233 TInt count = iRequestorArray.Count(); |
|
234 for ( TInt i = 0; i < count; i++ ) |
|
235 { |
|
236 CPosRequestor* requestor = iRequestorArray[i]; |
|
237 if ( requestor->ModuleId() == aPsyId && |
|
238 requestor->IsActive() ) |
|
239 { |
|
240 //Notify external GPS PSY monitor that this PSY is not used. |
|
241 iExtGpsPsyMonitor->PsyNotUsed( requestor->ModuleId() ); |
|
242 requestor->Cancel(); |
|
243 } |
|
244 } |
|
245 } |
|
246 |
|
247 // --------------------------------------------------------- |
|
248 // CPosRequestController::StartTrackingL |
|
249 // --------------------------------------------------------- |
|
250 // |
|
251 void CPosRequestController::StartTracking( |
|
252 const TTimeIntervalMicroSeconds& /*aInterval*/) |
|
253 { |
|
254 //This function does nothing. Tracking will be started |
|
255 //to any specific PSY only if this PSY will be used by |
|
256 //Default Proxy. |
|
257 |
|
258 TRACESTRING( "CPosRequestController::StartTracking" ) |
|
259 |
|
260 } |
|
261 |
|
262 // --------------------------------------------------------- |
|
263 // CPosRequestController::StopTracking |
|
264 // --------------------------------------------------------- |
|
265 // |
|
266 void CPosRequestController::StopTracking() |
|
267 { |
|
268 TRACESTRING( "CPosRequestController::StopTracking start..." ) |
|
269 |
|
270 //Stop tracking to all loaded PSYs |
|
271 TInt loadedRequestorCount = iRequestorArray.Count(); |
|
272 for ( TInt i = 0; i < loadedRequestorCount; i++ ) |
|
273 { |
|
274 iRequestorArray[i]->StopTracking(); |
|
275 } |
|
276 |
|
277 TRACESTRING( "CPosRequestController::StopTracking end" ) |
|
278 |
|
279 } |
|
280 |
|
281 // --------------------------------------------------------- |
|
282 // CPosRequestController::StartPositionUpdateL |
|
283 // --------------------------------------------------------- |
|
284 // |
|
285 void CPosRequestController::StartPositionUpdateL() |
|
286 { |
|
287 TRACESTRING( "CPosRequestController::StartPositionUpdateL start..." ) |
|
288 |
|
289 //Rebuid PSY list if neccessary |
|
290 if ( !iPsyListValid ) |
|
291 { |
|
292 iPsyListHandler->GetPsyListL( iPsyList ); |
|
293 iPsyListValid = ETrue; |
|
294 } |
|
295 |
|
296 iFirstResult = KErrNotFound; // as if no enabled psys found |
|
297 iCurrentPsy = KErrNotFound; // start from first module |
|
298 TryNextPositioner(); |
|
299 |
|
300 if ( !IsLocationRequestOnGoing() ) |
|
301 { |
|
302 CompleteRequest( iFirstResult ); |
|
303 } |
|
304 |
|
305 TRACESTRING( "CPosRequestController::StartPositionUpdateL end" ) |
|
306 |
|
307 } |
|
308 |
|
309 |
|
310 // --------------------------------------------------------- |
|
311 // CPosRequestController::TryNextPositioner |
|
312 // --------------------------------------------------------- |
|
313 // |
|
314 void CPosRequestController::TryNextPositioner() |
|
315 { |
|
316 TRACESTRING( "CPosRequestController::TryNextPositioner start..." ) |
|
317 |
|
318 // Find next enabled plugin we should try with |
|
319 TInt count = iPsyList.Count(); |
|
320 while ( ++iCurrentPsy < count ) |
|
321 { |
|
322 TPositionModuleId currentPsyId = iPsyList[iCurrentPsy]; |
|
323 |
|
324 TRACESTRING2( "PSY: %x", currentPsyId ) |
|
325 |
|
326 TUint32 classType = iPosInfo->PositionClassType(); |
|
327 if ( !iPsyListHandler->IsClassSupported( |
|
328 classType, |
|
329 currentPsyId ) ) |
|
330 { |
|
331 //if the requested class is not supported, then we try next PSY |
|
332 //in the PSY list |
|
333 |
|
334 if ( iCurrentPsy == 0 ) |
|
335 { |
|
336 //Error code fromt the first PSY |
|
337 iFirstResult = KErrArgument; |
|
338 } |
|
339 |
|
340 continue; |
|
341 } |
|
342 |
|
343 TRAPD( err, TryPositionerL( currentPsyId ) ); |
|
344 |
|
345 TRACESTRING2( "Try PSY completion code = %d", err ) |
|
346 |
|
347 if( err == KErrNone ) |
|
348 { |
|
349 //Location request is made to currentPsy. Check the fix state of |
|
350 //current PSY, if current PSY can't give a fix, we load next PSY |
|
351 if ( iPsyFixStateManager->GetPsyFixState( currentPsyId ) |
|
352 != CPosPsyFixStateManager::EPsyFixStateNo ) |
|
353 { |
|
354 //break from here. Othsewise, try next PSY |
|
355 break; |
|
356 } |
|
357 } |
|
358 else |
|
359 { |
|
360 //In error case, we store the error code if needed and try next PSY |
|
361 if ( iCurrentPsy == 0 ) |
|
362 { |
|
363 //Error code fromt the first PSY |
|
364 iFirstResult = err; |
|
365 } |
|
366 } |
|
367 } |
|
368 |
|
369 TRACESTRING( "CPosRequestController::TryNextPositioner end" ) |
|
370 |
|
371 } |
|
372 |
|
373 // --------------------------------------------------------- |
|
374 // CPosRequestController::TryPositionerL |
|
375 // --------------------------------------------------------- |
|
376 // |
|
377 void CPosRequestController::TryPositionerL( TPositionModuleId aPsyId ) |
|
378 { |
|
379 CPosRequestor* currentRequestor = NULL; |
|
380 |
|
381 |
|
382 //Check device status of the PSY. If it's in error status, |
|
383 //it will not be used at all. |
|
384 TPositionModuleStatus moduleStatus; |
|
385 iModuleStatusManager.GetModuleStatus( |
|
386 aPsyId, |
|
387 moduleStatus ); |
|
388 if ( moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceError ) |
|
389 { |
|
390 TRACESTRING2( "PSY %x device error", aPsyId ) |
|
391 |
|
392 User::Leave( KErrGeneral ); |
|
393 } |
|
394 |
|
395 //Find if the PSY is already loaded |
|
396 TInt requestorCount = iRequestorArray.Count(); |
|
397 for ( TInt i = 0; i < requestorCount; i++ ) |
|
398 { |
|
399 if ( iRequestorArray[i]->ModuleId() == aPsyId ) |
|
400 { |
|
401 currentRequestor = iRequestorArray[i]; |
|
402 break; |
|
403 } |
|
404 } |
|
405 |
|
406 if ( currentRequestor == NULL ) |
|
407 { |
|
408 //PSY has not been loaded before, load it now |
|
409 TRACESTRING2( "Loading Positioner: %x", aPsyId ) |
|
410 currentRequestor = |
|
411 CPosRequestor::NewL( |
|
412 iDefaultPositioner, |
|
413 aPsyId, |
|
414 *this, |
|
415 *iPsyFixStateManager, |
|
416 iModuleStatusManager ); |
|
417 |
|
418 CleanupStack::PushL( currentRequestor ); |
|
419 |
|
420 //Notify fix state manager that a PSY is loaded |
|
421 iPsyFixStateManager->PsyLoadedL( aPsyId ); |
|
422 |
|
423 //Add this requestor to requestor array |
|
424 User::LeaveIfError( iRequestorArray.Append( |
|
425 currentRequestor ) ); |
|
426 CleanupStack::Pop( currentRequestor ); |
|
427 } |
|
428 |
|
429 //Start tracking if needed |
|
430 TTimeIntervalMicroSeconds interval = iDefaultPositioner.TrackingInterval(); |
|
431 if (interval.Int64() != 0 ) |
|
432 { |
|
433 currentRequestor->StartTrackingL( interval ); |
|
434 } |
|
435 |
|
436 //Make location request to current positioner |
|
437 currentRequestor->MakeLocationRequestL( *iPosInfo ); |
|
438 |
|
439 //Notify external GPS PSY monitor that a PSY is used |
|
440 iExtGpsPsyMonitor->PsyUsed( aPsyId ); |
|
441 } |
|
442 |
|
443 // --------------------------------------------------------- |
|
444 // CPosRequestController::LocationRequestCompleted |
|
445 // --------------------------------------------------------- |
|
446 // |
|
447 void CPosRequestController::LocationRequestCompleted( |
|
448 TPositionModuleId aModuleId, |
|
449 TInt aErr, |
|
450 const TPositionInfoBase& aPosInfo, |
|
451 TBool aIsPosInfoUpToDate ) |
|
452 { |
|
453 TRACESTRING( "CPosRequestController::LocationRequestCompleted start..." ) |
|
454 TRACESTRING2( "PSY: %x", aModuleId ) |
|
455 TRACESTRING2( "Err: %d", aErr ) |
|
456 TRACESTRING2( "Is PosInfo Updated: %d", aIsPosInfoUpToDate ) |
|
457 |
|
458 //Notify the external GPS PSY monitor that a PSY in not used |
|
459 iExtGpsPsyMonitor->PsyNotUsed( aModuleId ); |
|
460 |
|
461 TInt err = aErr; |
|
462 if ( aErr == KPositionPartialUpdate && IsLocationRequestOnGoingOnNetworkPsy() ) |
|
463 { |
|
464 //Partial update is returned when Network PSY is used. |
|
465 //partial update is not forwarded to system. Instead, location |
|
466 //request is made to the loaded PSY again. |
|
467 TInt ignore; |
|
468 TRAP( ignore, TryPositionerL( aModuleId ) ); |
|
469 } |
|
470 else if ( aErr == KErrNone || |
|
471 aErr == KErrPositionBufferOverflow || |
|
472 aErr == KPositionPartialUpdate ) |
|
473 { |
|
474 //Location request succeed or |
|
475 //buffer over flow is returned from a PSY or |
|
476 //partial update is returned when only GPS PSY is used |
|
477 |
|
478 //Copy request info, and complete LR |
|
479 if ( aIsPosInfoUpToDate ) |
|
480 { |
|
481 __ASSERT_DEBUG( |
|
482 aPosInfo.PositionClassSize() == iPosInfo->PositionClassSize(), |
|
483 DefaultProxyPanic( EDefaultProxyPanic_PosInfoSizeMismatch ) ); |
|
484 |
|
485 Mem::Copy( iPosInfo, &aPosInfo, iPosInfo->PositionClassSize() ); |
|
486 } |
|
487 else |
|
488 { |
|
489 TInt cpErr = CopyPosInfoClass( aPosInfo , *iPosInfo ); |
|
490 if ( cpErr != KErrNone && err == KErrNone ) |
|
491 { |
|
492 err = cpErr; |
|
493 } |
|
494 } |
|
495 |
|
496 if ( iPosInfo->ModuleId() != aModuleId ) |
|
497 { |
|
498 err = KErrGeneral; |
|
499 } |
|
500 |
|
501 CompleteRequest( err ); |
|
502 } |
|
503 else |
|
504 { |
|
505 if ( aModuleId == iPsyList[0] ) |
|
506 { |
|
507 //Store the result from first PSY |
|
508 iFirstResult = aErr; |
|
509 |
|
510 //Store module ID of first positioner |
|
511 iPosInfo->SetModuleId( aModuleId ); |
|
512 } |
|
513 } |
|
514 |
|
515 //This will cause the state change notification and generate fallback |
|
516 //if it's a error case. |
|
517 iPsyFixStateManager->SetPsyFixState( aModuleId, aErr ); |
|
518 |
|
519 if ( !IsLocationRequestOnGoing() ) |
|
520 { |
|
521 CompleteRequest( iFirstResult ); |
|
522 } |
|
523 |
|
524 TRACESTRING( "CPosRequestController::LocationRequestCompleted end" ) |
|
525 } |
|
526 |
|
527 // --------------------------------------------------------- |
|
528 // CPosRequestController::IsLocationRequestOnGoing |
|
529 // --------------------------------------------------------- |
|
530 // |
|
531 TBool CPosRequestController::IsLocationRequestOnGoing() const |
|
532 { |
|
533 TInt count = iRequestorArray.Count(); |
|
534 for ( TInt i=0; i < count; i++ ) |
|
535 { |
|
536 const CPosRequestor& requestor = *(iRequestorArray[i]); |
|
537 if ( requestor.IsActive() ) |
|
538 { |
|
539 return ETrue; |
|
540 } |
|
541 } |
|
542 return EFalse; |
|
543 } |
|
544 |
|
545 // --------------------------------------------------------- |
|
546 // CPosRequestController::IsLocationRequestOnGoingOnNetworkPsy |
|
547 // --------------------------------------------------------- |
|
548 // |
|
549 TBool CPosRequestController::IsLocationRequestOnGoingOnNetworkPsy() const |
|
550 { |
|
551 TInt count = iRequestorArray.Count(); |
|
552 for ( TInt i=0; i < count; i++ ) |
|
553 { |
|
554 const CPosRequestor& requestor = *(iRequestorArray[i]); |
|
555 if ( requestor.IsActive() && |
|
556 iPsyListHandler->IsModuleNetworkBased( |
|
557 requestor.ModuleId() ) ) |
|
558 { |
|
559 return ETrue; |
|
560 } |
|
561 } |
|
562 return EFalse; |
|
563 } |
|
564 |
|
565 // --------------------------------------------------------- |
|
566 // CPosRequestController::PsyFixStateChanged |
|
567 // --------------------------------------------------------- |
|
568 // |
|
569 void CPosRequestController::PsyFixStateChanged( |
|
570 TPositionModuleId aModuleId, |
|
571 CPosPsyFixStateManager::TPsyFixState aFixState ) |
|
572 { |
|
573 TRACESTRING( "CPosRequestController::PsyFixStateChanged start..." ) |
|
574 TRACESTRING2( "PSY: %x", aModuleId ) |
|
575 TRACESTRING2( "Fix state: %d", aFixState ) |
|
576 |
|
577 //If there is location request on going and |
|
578 //current can't give a fix, we try next PSY |
|
579 if( iPosRequestStatus && iCurrentPsy<iPsyList.Count() ) |
|
580 { |
|
581 if ( aFixState == CPosPsyFixStateManager::EPsyFixStateNo && |
|
582 iPsyList[iCurrentPsy] == aModuleId ) |
|
583 { |
|
584 TryNextPositioner(); |
|
585 } |
|
586 } |
|
587 |
|
588 TRACESTRING( "CPosRequestController::PsyFixStateChanged end" ) |
|
589 } |
|
590 |
|
591 // --------------------------------------------------------- |
|
592 // CPosRequestController::CompleteRequest |
|
593 // --------------------------------------------------------- |
|
594 // |
|
595 void CPosRequestController::CompleteRequest(TInt aCompleteCode) |
|
596 { |
|
597 TRACESTRING( "CPosRequestController::CompleteRequest start..." ) |
|
598 TRACESTRING2( "Completion code: %d", aCompleteCode ) |
|
599 TRACESTRING2( "Module Id: %x", iPosInfo->ModuleId() ) |
|
600 |
|
601 if (iPosRequestStatus) |
|
602 { |
|
603 User::RequestComplete(iPosRequestStatus, aCompleteCode); |
|
604 iPosRequestStatus = NULL; |
|
605 |
|
606 //Clear all location request if this is not |
|
607 //a partial update |
|
608 if ( aCompleteCode != KPositionPartialUpdate ) |
|
609 { |
|
610 ClearLocationRequests(); |
|
611 } |
|
612 |
|
613 //If there is still location request ongoing to other PSYs, |
|
614 //start cleanup timer |
|
615 TInt count = iRequestorArray.Count(); |
|
616 for ( TInt i = 0; i < count; i++ ) |
|
617 { |
|
618 if ( iRequestorArray[i]->IsActive() ) |
|
619 { |
|
620 |
|
621 if ( !iCleanupTimer->IsActive() ) |
|
622 { |
|
623 iCleanupTimer->Start( |
|
624 iConstManager->GetCleanupTimeoutValue().Int64(), |
|
625 iConstManager->GetCleanupTimeoutValue().Int64(), |
|
626 TCallBack( CleanupTimeoutCallback, this ) |
|
627 ); |
|
628 } |
|
629 } |
|
630 } |
|
631 } |
|
632 TRACESTRING( "CPosRequestController::CompleteRequest end" ) |
|
633 } |
|
634 |
|
635 // --------------------------------------------------------- |
|
636 // CPosRequestController::ClearLocationRequests |
|
637 // --------------------------------------------------------- |
|
638 // |
|
639 void CPosRequestController::ClearLocationRequests() |
|
640 { |
|
641 TInt count = iRequestorArray.Count(); |
|
642 for ( TInt i = 0; i < count; i++ ) |
|
643 { |
|
644 CancelRequest( i, KErrCancel); |
|
645 } |
|
646 } |
|
647 |
|
648 // --------------------------------------------------------- |
|
649 // CPosRequestController::PsyListChanged |
|
650 // --------------------------------------------------------- |
|
651 // |
|
652 void CPosRequestController::PsyListChanged( |
|
653 const TPosPsyListChangeEvent& aEvent ) |
|
654 { |
|
655 TRACESTRING( "CPosRequestController::PsyListChanged start..." ) |
|
656 TRACESTRING2( "Event type: %d", aEvent.iType ) |
|
657 TRACESTRING2( "PSY: %x", aEvent.iPsyId ) |
|
658 |
|
659 switch ( aEvent.iType ) |
|
660 { |
|
661 case EPosPsyListChangeEventPsyDeleted: |
|
662 { |
|
663 //Cancel location request to this PSY |
|
664 CancelRequest( aEvent.iPsyId ); |
|
665 |
|
666 if ( iCurrentPsy >= 0 && iCurrentPsy < iPsyList.Count() ) |
|
667 { |
|
668 //If there is location request on going |
|
669 if ( aEvent.iPsyId == iPsyList[iCurrentPsy] ) |
|
670 { |
|
671 //fallback to next PSY |
|
672 TryNextPositioner(); |
|
673 } |
|
674 } |
|
675 //Delete this PSY from the list |
|
676 TInt index = iPsyList.Find( aEvent.iPsyId ); |
|
677 if ( index != KErrNotFound ) |
|
678 { |
|
679 iPsyList.Remove( index ); |
|
680 } |
|
681 |
|
682 //Unload this PSY |
|
683 UnloadRequestor( aEvent.iPsyId ); |
|
684 } |
|
685 break; |
|
686 case EPosPsyListChangeEventListRebuild: |
|
687 default: |
|
688 //Rebuild the list |
|
689 iPsyListValid = EFalse; |
|
690 break; |
|
691 } |
|
692 |
|
693 TRACESTRING( "CPosRequestController::PsyListChanged end" ) |
|
694 } |
|
695 |
|
696 |
|
697 // --------------------------------------------------------- |
|
698 // CPosRequestController::GetRequestor |
|
699 // --------------------------------------------------------- |
|
700 // |
|
701 CPosRequestor* CPosRequestController::GetRequestor( |
|
702 TPositionModuleId aPsyId ) |
|
703 { |
|
704 TInt count = iRequestorArray.Count(); |
|
705 for ( TInt i = 0; i < count; i++ ) |
|
706 { |
|
707 if ( iRequestorArray[i]->ModuleId() == aPsyId ) |
|
708 { |
|
709 return iRequestorArray[i]; |
|
710 } |
|
711 } |
|
712 return NULL; |
|
713 } |
|
714 |
|
715 // --------------------------------------------------------- |
|
716 // CPosRequestController::UnloadRequestor |
|
717 // --------------------------------------------------------- |
|
718 // |
|
719 void CPosRequestController::UnloadRequestor( TPositionModuleId aPsyId ) |
|
720 { |
|
721 TRACESTRING( "CPosRequestController::UnloadRequestor" ) |
|
722 TRACESTRING2( "PSY: %x", aPsyId ) |
|
723 |
|
724 TInt count = iRequestorArray.Count(); |
|
725 for ( TInt i = count-1; i >= 0; i-- ) |
|
726 { |
|
727 if ( iRequestorArray[i]->ModuleId() == aPsyId ) |
|
728 { |
|
729 delete iRequestorArray[i]; |
|
730 iRequestorArray.Remove( i ); |
|
731 } |
|
732 } |
|
733 } |
|
734 |
|
735 // --------------------------------------------------------- |
|
736 // CPosRequestController::CopyPosInfoClass |
|
737 // --------------------------------------------------------- |
|
738 // |
|
739 TInt CPosRequestController::CopyPosInfoClass( |
|
740 const TPositionInfoBase& aSrc, |
|
741 TPositionInfoBase& aDst ) |
|
742 { |
|
743 TInt err = KErrNone; |
|
744 |
|
745 TUint32 srcClasses = aSrc.PositionClassType(); |
|
746 TUint32 dstClasses = aDst.PositionClassType(); |
|
747 |
|
748 //Handle TPositionInfoBase |
|
749 aDst.SetModuleId( aSrc.ModuleId() ); |
|
750 aDst.SetUpdateType( aSrc.UpdateType() ); |
|
751 |
|
752 //Handle TPositionInfo |
|
753 if ( ( srcClasses & EPositionInfoClass ) && |
|
754 ( dstClasses & EPositionInfoClass ) ) |
|
755 { |
|
756 TPosition pos; |
|
757 static_cast < const TPositionInfo& > ( aSrc ).GetPosition( pos ); |
|
758 static_cast < TPositionInfo& > ( aDst ).SetPosition( pos ); |
|
759 } |
|
760 |
|
761 //Handle TPositionCourseInfo |
|
762 if ( ( srcClasses & EPositionCourseInfoClass ) && |
|
763 ( dstClasses & EPositionCourseInfoClass ) ) |
|
764 { |
|
765 TCourse course; |
|
766 static_cast < const TPositionCourseInfo& > ( aSrc ).GetCourse( course ); |
|
767 static_cast < TPositionCourseInfo& > ( aDst ).SetCourse( course ); |
|
768 } |
|
769 |
|
770 //Handle TPositionSatelliteInfo |
|
771 if ( ( srcClasses & EPositionSatelliteInfoClass ) && |
|
772 ( dstClasses & EPositionSatelliteInfoClass ) ) |
|
773 { |
|
774 const TPositionSatelliteInfo& srcSat = |
|
775 static_cast < const TPositionSatelliteInfo& > ( aSrc ); |
|
776 TPositionSatelliteInfo& dstSat = |
|
777 static_cast < TPositionSatelliteInfo& > ( aDst ); |
|
778 |
|
779 dstSat.SetSatelliteTime( srcSat.SatelliteTime() ); |
|
780 dstSat.SetHorizontalDoP( srcSat.HorizontalDoP() ); |
|
781 dstSat.SetTimeDoP( srcSat.TimeDoP() ); |
|
782 dstSat.SetVerticalDoP( srcSat.VerticalDoP() ); |
|
783 |
|
784 dstSat.ClearSatellitesInView(); |
|
785 TInt numSatData = srcSat.NumSatellitesInView(); |
|
786 |
|
787 for ( TInt i = 0; i < numSatData; i++ ) |
|
788 { |
|
789 TSatelliteData satData; |
|
790 srcSat.GetSatelliteData( i, satData ); |
|
791 err = dstSat.AppendSatelliteData( satData ); |
|
792 if ( err != KErrNone ) |
|
793 { |
|
794 return KErrNone; |
|
795 } |
|
796 } |
|
797 } |
|
798 |
|
799 //Handle HPositionGenericInfo |
|
800 if ( ( srcClasses & EPositionGenericInfoClass ) && |
|
801 ( dstClasses & EPositionGenericInfoClass ) ) |
|
802 { |
|
803 const HPositionGenericInfo& srcGen = |
|
804 static_cast < const HPositionGenericInfo& > ( aSrc ); |
|
805 HPositionGenericInfo& dstGen = |
|
806 static_cast < HPositionGenericInfo& > ( aDst ); |
|
807 |
|
808 err = PosGenericInfoUser::CopyHGenericInfo( srcGen, dstGen ); |
|
809 } |
|
810 |
|
811 return err; |
|
812 } |
|
813 |
|
814 // --------------------------------------------------------- |
|
815 // CPosRequestController::CleanupTimeoutCallback |
|
816 // --------------------------------------------------------- |
|
817 // |
|
818 TInt CPosRequestController::CleanupTimeoutCallback( TAny* aAny ) |
|
819 { |
|
820 reinterpret_cast< CPosRequestController* > ( aAny ) -> |
|
821 CleanupTimeout(); |
|
822 return KErrNone; |
|
823 } |
|
824 |
|
825 // --------------------------------------------------------- |
|
826 // CPosRequestController::CleanupTimeout |
|
827 // --------------------------------------------------------- |
|
828 // |
|
829 void CPosRequestController::CleanupTimeout() |
|
830 { |
|
831 //Cleanup all outstanding location requests |
|
832 ClearLocationRequests(); |
|
833 iCleanupTimer->Cancel(); |
|
834 } |
|
835 |
|
836 // End of file |