--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datasourcemodules/defaultpositioningmodule/src/epos_cposexternalgpsmonitor.cpp Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,474 @@
+// Copyright (c) 2007-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:
+//
+
+
+
+// INCLUDE FILES
+#include "epos_defaultproxycommon.h"
+#include "epos_cposexternalgpsmonitor.h"
+#include "epos_cpospsylisthandler.h"
+#include "epos_cpospsyfixstatemanager.h"
+#include "epos_cpossingletonmanager.h"
+#include "epos_cposrequestor.h"
+#include "epos_cposconstmanager.h"
+#include "epos_defaultproxycommon.h"
+
+#include <lbs/epos_cpositioner.h>
+
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CPosExternalGpsMonitor::CPosExternalGpsMonitor(
+ MPosModuleStatusManager& aModuleStatusManager )
+ : iModuleStatusManager( aModuleStatusManager )
+ {
+ }
+
+// EPOC default constructor can leave.
+void CPosExternalGpsMonitor::ConstructL()
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::ConstructL start... " )
+
+ iPsyListHandler = CPosPsyListHandler::GetInstanceL();
+ iPsyListHandler->AddListenerL( this );
+
+ iFixStateManager = CPosPsyFixStateManager::GetInstanceL();
+ iConstManager = CPosConstManager::GetInstanceL();
+
+ iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+
+ TRACESTRING( "CPosExternalGpsMonitor::ConstructL end" )
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::GetInstanceL
+// ---------------------------------------------------------
+//
+CPosExternalGpsMonitor* CPosExternalGpsMonitor::GetInstanceL(
+ CPositioner& aDefaultPositioner,
+ MPosModuleStatusManager& aModuleStatusManager )
+ {
+ CPosExternalGpsMonitor* self = reinterpret_cast < CPosExternalGpsMonitor* >
+ ( CPosSingletonManager::GetObject(
+ EPosSigletonObjectExtGpsMonitorId ) );
+
+ if ( !self )
+ {
+ //Construct a new object and store it to CPosSingletonManager
+ self = new ( ELeave ) CPosExternalGpsMonitor(
+ aModuleStatusManager );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CPosSingletonManager::SetObjectL(
+ self,
+ EPosSigletonObjectExtGpsMonitorId );
+ self->iDefaultPositionerArray.AppendL( &aDefaultPositioner );
+ self->ConstructExtGpsPsyArrayL();
+ CleanupStack::Pop(self);
+ }
+ else
+ {
+ self->iDefaultPositionerArray.AppendL( &aDefaultPositioner );
+ }
+
+ self->iRefCount++;
+
+ return self;
+ }
+
+// Destructor
+CPosExternalGpsMonitor::~CPosExternalGpsMonitor()
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::destructor start" )
+
+ if ( iPsyListHandler )
+ {
+ iPsyListHandler->RemoveListener( this );
+ iPsyListHandler->ReleaseInstance();
+ }
+
+ if ( iFixStateManager )
+ {
+ iFixStateManager->ReleaseInstance();
+ }
+
+ if ( iConstManager )
+ {
+ iConstManager->ReleaseInstance();
+ }
+
+ iExtGpsPsyArray.ResetAndDestroy();
+ iExtGpsPsyArray.Close();
+ iExtGpsPsyUsedArray.Close();
+ iDefaultPositionerArray.Close();
+ delete iTimer;
+ TRACESTRING( "CPosExternalGpsMonitor::destructor end" )
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::ReleaseInstance
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::ReleaseInstance(
+ CPositioner& aDefaultPositioner )
+ {
+ TInt index = iDefaultPositionerArray.Find( &aDefaultPositioner );
+ if ( index != KErrNotFound )
+ {
+ iDefaultPositionerArray.Remove( index );
+ }
+
+ iRefCount--;
+ if ( iRefCount == 0 )
+ {
+ //We shall delete the instance
+ CPosSingletonManager::ReleaseObject(
+ EPosSigletonObjectExtGpsMonitorId );
+ }
+ else
+ {
+ // Delete & reconstruct iExtGpsPsyArray
+ iExtGpsPsyArray.ResetAndDestroy();
+ iExtGpsPsyArray.Close();
+
+ TInt ignore = KErrNone;
+ TRAP( ignore, ConstructExtGpsPsyArrayL() ); //error ignored
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::PsyUsed
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::PsyUsed( TPositionModuleId aPsyId )
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::PsyUsed" )
+ TRACESTRING2( "PSY: %x", aPsyId );
+
+ TInt index = GetIndexInPsyArray( aPsyId );
+ //iExtGpsPsyArray and iExtGpsPsyUsedArray are saved in the same
+ //order.
+ if ( index != KErrNotFound )
+ {
+ iExtGpsPsyUsedArray[index]++;
+ }
+
+ //Location request received
+ iIsLoacationRequestMade = ETrue;
+
+ //Update state of Ext GPS PSY used
+ iIsExtGpsPsyUsed = IsExtGpsPsyInUse();
+
+ //Check if we should start timer
+ if ( iExtGpsPsyArray.Count() > 0 &&
+ !iPsyListHandler->IsFirstGpsPsyExternal() &&
+ !IsExtGpsPsyInUse() )
+ {
+ //We start timer if there are GPS PSY availabe, but
+ //the first GPS PSY in the list is not located on external
+ //device.
+ //If a external GPS PSY is already used, then we don't
+ //start the timer
+
+ //Start timer if it's not started yet
+ StartTimer();
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::PsyNotUsed
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::PsyNotUsed( TPositionModuleId aPsyId )
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::PsyNotUsed" )
+ TRACESTRING2( "PSY: %x", aPsyId );
+
+ TInt index = GetIndexInPsyArray( aPsyId );
+ //iExtGpsPsyArray and iExtGpsPsyUsedArray are saved in the same
+ //order.
+ if ( index != KErrNotFound )
+ {
+ if ( iExtGpsPsyUsedArray[index] > 0 )
+ {
+ iExtGpsPsyUsedArray[index]--;
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::ConstructExtGpsPsyArrayL
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::ConstructExtGpsPsyArrayL()
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::ConstructExtGpsPsyArrayL" )
+
+ RArray< TPositionModuleId > extGpsPsyIdArray;
+ CleanupClosePushL( extGpsPsyIdArray );
+ iPsyListHandler->GetExtGpsPsyListL( extGpsPsyIdArray );
+
+ TInt i;
+
+ //Remove those modules that are not in the settings
+ TInt positionerCount = iExtGpsPsyArray.Count();
+
+ //Reserve enough space for iExtGpsPsyUsedArray first
+ iExtGpsPsyUsedArray.ReserveL( positionerCount );
+
+ for ( i = positionerCount-1; i >= 0 ; i-- )
+ {
+ TInt index = extGpsPsyIdArray.Find(
+ iExtGpsPsyArray[i]->ModuleId() );
+ if ( index == KErrNotFound )
+ {
+ delete iExtGpsPsyArray[i];
+ iExtGpsPsyArray.Remove( i );
+ iExtGpsPsyUsedArray.Remove( i );
+ }
+ else
+ {
+ extGpsPsyIdArray.Remove( index );
+ }
+ }
+
+ //Add those PSYs that are not in the PSY array
+ TInt count = extGpsPsyIdArray.Count();
+
+ if ( iDefaultPositionerArray.Count() > 0 )
+ {
+ for ( i = 0; i < count; i++ )
+ {
+ //Add this module to the list
+ CPosRequestor* requestor = CPosRequestor::NewL(
+ *iDefaultPositionerArray[0],
+ extGpsPsyIdArray[i],
+ *this,
+ *iFixStateManager,
+ iModuleStatusManager );
+ CleanupStack::PushL( requestor );
+
+ //Notify fix state manager that a PSY is loaded
+ iFixStateManager->PsyLoadedL(
+ extGpsPsyIdArray[i] );
+
+ //Add this requestor in the array
+ User::LeaveIfError( iExtGpsPsyArray.Append( requestor ) );
+
+ //This function won't fail, since we have enough space already
+ iExtGpsPsyUsedArray.Append( 0 );
+
+ CleanupStack::Pop( requestor );
+ }
+ }
+ CleanupStack::PopAndDestroy( &extGpsPsyIdArray );
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::LocationRequestCompleted
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::LocationRequestCompleted(
+ TPositionModuleId aModuleId,
+ TInt aErr,
+ const TPositionInfoBase& /*aPosInfo*/,
+ TBool /*aIsPosInfoUpToDate*/ )
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::LocationRequestCompleted" )
+ TRACESTRING2( "PSY: %x", aModuleId )
+
+ iFixStateManager->SetExtGpsPsyFixState(
+ aModuleId,
+ aErr );
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::ExtPsyCheckingTimeoutCallback
+// ---------------------------------------------------------
+//
+TInt CPosExternalGpsMonitor::ExtPsyCheckingTimeoutCallback( TAny* aAny )
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::ExtPsyCheckingTimeoutCallback" )
+
+ reinterpret_cast < CPosExternalGpsMonitor* > ( aAny ) ->
+ ExtPsyCheckingTimeout();
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::ExtPsyCheckingTimeout
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::ExtPsyCheckingTimeout()
+ {
+ if ( !iIsLoacationRequestMade )
+ {
+ //Stop timer and cancel all location requests
+ iTimer->Cancel();
+ CancelAllLocationRequests();
+ }
+ else
+ {
+ //If there is location request during this period, but
+ //external GPS has not been tried, then we make location
+ //request to external GPS PSYs.
+ if ( !iIsExtGpsPsyUsed )
+ {
+ MakeLocationRequests();
+ }
+ else
+ {
+ //If external GPS PSY has been used during this period,
+ //We don't need to make location request. All outgoing
+ //location request will be canceled.
+ CancelAllLocationRequests();
+ }
+ }
+ iIsLoacationRequestMade = EFalse;
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::PsyListChanged
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::PsyListChanged(
+ const TPosPsyListChangeEvent& aEvent )
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::PsyListChanged" )
+
+ if ( aEvent.iType == EPosPsyListChangeEventPriorityChanged )
+ {
+ //do nothing
+ return;
+ }
+
+ if ( aEvent.iType == EPosPsyListChangeEventPsyDeleted )
+ {
+ CancelLocationRequest( aEvent.iPsyId );
+ }
+
+ //Reconstruct Ext GPS PSY array
+ TInt ignore = KErrNone;
+ TRAP( ignore, ConstructExtGpsPsyArrayL() ); //error ignored
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::MakeLocationRequests
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::MakeLocationRequests()
+ {
+ TRACESTRING( "CPosExternalGpsMonitor::MakeLocationRequests" )
+
+ TInt count = iExtGpsPsyArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ //If location request is not started
+ if ( !iExtGpsPsyArray[i]->IsActive() )
+ {
+ TInt ignore = KErrNone;
+ TRAP( ignore,
+ iExtGpsPsyArray[i]->MakeLocationRequestL(iPosInfo) );
+ TRACESTRING2( "PSY: %x", iExtGpsPsyArray[i]->ModuleId() )
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::CancelAllLocationRequests
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::CancelAllLocationRequests()
+ {
+ TInt count = iExtGpsPsyArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ iExtGpsPsyArray[i]->Cancel();
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::CancelLocationRequest
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::CancelLocationRequest( TPositionModuleId aPsyId )
+ {
+ TInt count = iExtGpsPsyArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iExtGpsPsyArray[i]->ModuleId() == aPsyId )
+ {
+ iExtGpsPsyArray[i]->Cancel();
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::GetIndexInPsyArray
+// ---------------------------------------------------------
+//
+TInt CPosExternalGpsMonitor::GetIndexInPsyArray( TPositionModuleId aModuleId ) const
+ {
+ TInt count = iExtGpsPsyArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iExtGpsPsyArray[i]->ModuleId() == aModuleId )
+ {
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::StartTimer
+// ---------------------------------------------------------
+//
+void CPosExternalGpsMonitor::StartTimer()
+ {
+ if ( !iTimer->IsActive() )
+ {
+ iTimer->Start(
+ iConstManager->GetExternalGpsCheckingTimeoutValue().Int64(),
+ iConstManager->GetExternalGpsCheckingTimeoutValue().Int64(),
+ TCallBack( ExtPsyCheckingTimeoutCallback, this ) );
+
+ iIsLoacationRequestMade = EFalse;
+ iIsExtGpsPsyUsed = IsExtGpsPsyInUse();
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosExternalGpsMonitor::IsExtGpsPsyInUse
+// ---------------------------------------------------------
+//
+TBool CPosExternalGpsMonitor::IsExtGpsPsyInUse() const
+ {
+ TInt count = iExtGpsPsyUsedArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iExtGpsPsyUsedArray[i] > 0 )
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// End of File