datasourcemodules/defaultpositioningmodule/src/epos_cpospsyfixstatemanager.cpp
changeset 0 9cfd9a3ee49c
child 52 29dbbeac905d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datasourcemodules/defaultpositioningmodule/src/epos_cpospsyfixstatemanager.cpp	Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,435 @@
+// 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_cpospsyfixstatemanager.h"
+#include "epos_cpospsylisthandler.h"
+#include "epos_cpossingletonmanager.h"
+#include "epos_cposfixstatetimer.h"
+#include "epos_defaultproxycommon.h"
+#include "epos_cposconstmanager.h"
+#include "epos_mpospsyfixstatelistener.h"
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CPosPsyFixStateManager::CPosPsyFixStateManager()
+    {
+    }
+
+// EPOC default constructor can leave.
+void CPosPsyFixStateManager::ConstructL()
+    {
+    TRACESTRING( "CPosPsyFixStateManager::ConstructL start... " )
+
+    iConstManager = CPosConstManager::GetInstanceL();
+
+    TRACESTRING( "CPosPsyFixStateManager::ConstructL end " )
+
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::GetInstanceL
+// ---------------------------------------------------------
+//
+CPosPsyFixStateManager* CPosPsyFixStateManager::GetInstanceL()
+    {
+    CPosPsyFixStateManager* self = reinterpret_cast < CPosPsyFixStateManager* > 
+        ( CPosSingletonManager::GetObject( 
+            EPosSigletonObjectIdPsyFixStateManager ) );
+        
+    if ( !self )
+        {
+        //Construct a new object and store it to CPosSingletonManager
+        self = new ( ELeave ) CPosPsyFixStateManager;
+        CleanupStack::PushL(self);
+        self->ConstructL();
+        CPosSingletonManager::SetObjectL(
+            self,
+            EPosSigletonObjectIdPsyFixStateManager );
+        CleanupStack::Pop(self);
+        }
+        
+    self->iRefCount++;
+    
+    return self;
+    }
+
+// Destructor
+CPosPsyFixStateManager::~CPosPsyFixStateManager()
+    {
+    TRACESTRING( "CPosPsyFixStateManager::destructor start... " )
+
+    if ( iConstManager )
+        {
+        iConstManager->ReleaseInstance();
+        }
+        
+    //Clear fix state timer
+    TInt count = iPsyStateArray.Count();
+    for ( TInt i=0; i<count; i++)
+        {
+        delete iPsyStateArray[i].iTimer;
+        }
+        
+    iPsyStateArray.Close();
+    iListenerArray.Close();
+
+    TRACESTRING( "CPosPsyFixStateManager::destructor end... " )
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::ReleaseInstance
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::ReleaseInstance()
+    {
+    iRefCount--;
+    if ( iRefCount == 0 )
+        {
+        //We shall delete the instance
+        CPosSingletonManager::ReleaseObject(
+            EPosSigletonObjectIdPsyFixStateManager );
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::AddListenerL
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::AddListenerL( MPosPsyFixStateListener* aListener )
+    {
+    User::LeaveIfError( iListenerArray.Append( aListener ) );
+    }
+        
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::RemoveListener
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::RemoveListener( MPosPsyFixStateListener* aListener )
+    {
+    TInt count = iListenerArray.Count();
+    for ( TInt i=count -1; i>=0; i-- )
+        {
+        if( iListenerArray[i] == aListener )
+            {
+            iListenerArray.Remove( i );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::PsyLoadedL
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::PsyLoadedL(
+            TPositionModuleId aPsyId )
+    {
+    TRACESTRING( "CPosPsyFixStateManager::PsyLoadedL" )
+    TRACESTRING2( "PSY: %x", aPsyId )    
+    if ( PsyIndex( aPsyId ) == KErrNotFound )
+        {
+        //If PSY is not in the PSY state array, add PSY to 
+        //the array and set the fix state as unkown.
+        CPosFixStateTimer* timer = CPosFixStateTimer::NewL(
+            aPsyId, 
+            *this );
+        CleanupStack::PushL( timer );
+        
+        TPsyAndFixState fixAndState;
+        fixAndState.iPsyId = aPsyId;
+        fixAndState.iPsyState = EPsyFixStateUnknown;
+        fixAndState.iLocationRequestCount = 0;
+        fixAndState.iTimer = timer;
+        User::LeaveIfError( 
+            iPsyStateArray.Append( fixAndState ) );
+            
+        CleanupStack::Pop( timer );
+        }
+    }
+        
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::GetPsyFixState
+// ---------------------------------------------------------
+//
+CPosPsyFixStateManager::TPsyFixState CPosPsyFixStateManager::GetPsyFixState(
+            TPositionModuleId aPsyId )
+    {
+    TInt index = PsyIndex( aPsyId );
+    if ( index != KErrNotFound )
+        {
+        return iPsyStateArray[index].iPsyState;
+        }
+        
+    //If PSY has not been loaded before, return fix state
+    //as unknown.
+    return EPsyFixStateUnknown;
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::PsyUsed
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::PsyUsed( 
+        TPositionModuleId aPsyId,
+        TPositionModuleStatus::TDeviceStatus aPreviousDeviceStatus )
+    {
+    TRACESTRING( "CPosPsyFixStateManager::PsyUsed" )
+    TRACESTRING2( "PSY: %x", aPsyId )
+    TRACESTRING2( "Device status: %d", aPreviousDeviceStatus)
+
+    TInt index = PsyIndex( aPsyId );
+    __ASSERT_DEBUG( index != KErrNotFound,
+        DefaultProxyPanic( EDefaultProxyPanic_PsyNotFoundInStateManager ) );
+    
+    if( index != KErrNotFound )
+        {
+        TPsyAndFixState& fixState = iPsyStateArray[index];
+        //If PSY has not been used before, then start timeshift timer
+        if( fixState.iLocationRequestCount == 0 )
+            {
+            StartTimeshiftTimer( fixState, aPreviousDeviceStatus );
+            }
+            
+        //Cancel unknown timer
+        fixState.iTimer->CancelUnknownTimer();
+            
+        fixState.iLocationRequestCount++;
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::SetPsyFixState
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::SetPsyFixState( 
+            TPositionModuleId aPsyId, 
+            TInt aLRErr  )
+    {
+    TRACESTRING( "CPosPsyFixStateManager::SetPsyFixState" )
+    TRACESTRING2( "PSY: %x", aPsyId )
+    TRACESTRING2( "Err: %d", aLRErr )
+
+    TInt index = PsyIndex( aPsyId );
+    if ( index != KErrNotFound )
+        {
+        TPsyAndFixState& fixState = iPsyStateArray[index];
+
+        TPsyFixState previousFixState = fixState.iPsyState;
+             
+        switch ( aLRErr )
+            {
+            case KErrNone:
+                //Location request completed successfully.
+                //Stop timeshift timer
+                fixState.iPsyState = EPsyFixStateYes;
+                fixState.iTimer->CancelTimeshiftTimer();
+                break;
+            case KPositionPartialUpdate:
+            case KErrPositionBufferOverflow:
+            case KErrCancel:
+                //State not changed.
+                //Leave timeshift timer running
+                break;
+            default:
+                //Stop timeshift timer
+                fixState.iPsyState = EPsyFixStateNo;
+                fixState.iTimer->CancelTimeshiftTimer();
+                break;
+            }
+
+        //Notify liseners
+        NotifyListener( aPsyId, previousFixState );
+        
+
+        //If the decrease the LR count for this PSY
+        if( fixState.iLocationRequestCount > 0 )
+            {
+            fixState.iLocationRequestCount--;
+
+            //Check if the PSY is not used anymore
+            if ( fixState.iLocationRequestCount == 0 )
+                {
+                //if the PSY is not used anymore, start
+                //unknown timer
+                fixState.iTimer->StartUnknownTimer(
+                    iConstManager->GetUnusedTimeoutValue() );
+                }
+            }
+                
+        }
+    //If the PSY has not been loaded, we don't do anything.
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::SetExtGpsPsyFixState
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::SetExtGpsPsyFixState(
+            TPositionModuleId aPsyId, 
+            TInt aLRErr )
+    {
+    TRACESTRING( "CPosPsyFixStateManager::SetExtGpsPsyFixState" )
+    TRACESTRING2( "PSY: %x", aPsyId )
+    TRACESTRING2( "Err: %d", aLRErr )
+
+    TInt index = PsyIndex( aPsyId );
+    if ( index != KErrNotFound )
+        {
+        if ( aLRErr == KErrNone )
+            {
+            TPsyFixState previousFixState = iPsyStateArray[index].iPsyState;
+            iPsyStateArray[index].iPsyState = EPsyFixStateYes;
+            NotifyListener( aPsyId, previousFixState );
+            }
+        //otherwise the state will not be changed.
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::TimeshiftTimerTimeout
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::TimeshiftTimerTimeout( 
+            TPositionModuleId aPsyId )
+    {
+    TRACESTRING( "CPosPsyFixStateManager::TimeshiftTimerTimeout" )
+    TRACESTRING2( "PSY: %x", aPsyId )
+
+    TInt index = PsyIndex( aPsyId );
+    if ( index != KErrNotFound )
+        {
+        TPsyFixState previousFixState = iPsyStateArray[index].iPsyState;
+
+        iPsyStateArray[index].iPsyState = EPsyFixStateNo;
+        
+        TRACESTRING2( "PSY fix sate: %d", 
+            iPsyStateArray[index].iPsyState );
+            
+        //Notify listner that PSY fix state is changed
+        NotifyListener( aPsyId, previousFixState );
+        }
+    }
+            
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::UnknownTimerTimeout
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::UnknownTimerTimeout(
+            TPositionModuleId aPsyId )
+    {
+    TRACESTRING( "CPosPsyFixStateManager::UnknownTimerTimeout" )
+    TRACESTRING2( "PSY: %x", aPsyId )
+
+    TInt index = PsyIndex( aPsyId );
+    if ( index != KErrNotFound )
+        {
+        TPsyFixState previousFixState = iPsyStateArray[index].iPsyState;
+        
+        //Cancel timeshift timer
+        iPsyStateArray[index].iTimer->CancelTimeshiftTimer();
+
+        iPsyStateArray[index].iPsyState = EPsyFixStateUnknown;
+        
+        TRACESTRING2( "PSY fix sate: %d", 
+            iPsyStateArray[index].iPsyState );
+            
+        //Notify listner that PSY fix state is changed
+        NotifyListener( aPsyId, previousFixState );
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::PsyIndex
+// ---------------------------------------------------------
+//
+TInt CPosPsyFixStateManager::PsyIndex(
+            TPositionModuleId aPsyId )
+    {
+    TInt count = iPsyStateArray.Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        if ( iPsyStateArray[i].iPsyId == aPsyId )
+            {
+            return i;
+            }
+        }
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::StartTimeshiftTimer
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::StartTimeshiftTimer(
+            TPsyAndFixState& aFixState,
+            TPositionModuleStatus::TDeviceStatus aPreviousDeviceStatus )
+    {
+    TTimeIntervalMicroSeconds ttff;
+    TTimeIntervalMicroSeconds ttnf;
+    CPosPsyListHandler* listHandler = NULL;
+    TInt ignore = KErrNone;
+    TRAP( ignore, listHandler = 
+            CPosPsyListHandler::GetInstanceL() );
+                
+    __ASSERT_DEBUG( listHandler != NULL,  
+        DefaultProxyPanic( 
+            EDefaultProxyPanic_GlobalObjectNotConstructed ) );
+        
+    listHandler->GetTtffAndTtnf(
+        aFixState.iPsyId,
+        ttff,
+        ttnf );
+            
+    listHandler->ReleaseInstance();
+    //Start timeshift timer
+    aFixState.iTimer->StartTimeshiftTimer(
+        iConstManager->GetTimeshiftValue(
+            ttff,
+            ttnf,
+            aPreviousDeviceStatus ) );
+    }
+
+// ---------------------------------------------------------
+// CPosPsyFixStateManager::NotifyListener
+// ---------------------------------------------------------
+//
+void CPosPsyFixStateManager::NotifyListener(
+            TPositionModuleId aPsyId,
+            TPsyFixState aPreviousFixState )
+    {
+    TInt index = PsyIndex( aPsyId );
+    if ( index != KErrNotFound )
+        {
+        TPsyFixState newState = iPsyStateArray[index].iPsyState;
+        if ( newState != aPreviousFixState )
+            {
+            TInt count = iListenerArray.Count();
+            for ( TInt i = count-1; i >= 0; i-- )
+                {
+                iListenerArray[i]->PsyFixStateChanged(
+                    aPsyId,
+                    newState );
+                }
+            }
+        }
+    }
+
+//  End of File