datasourcemodules/defaultpositioningmodule/src/epos_cpospsylisthandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 17 Sep 2010 08:37:32 +0300
changeset 60 9a7e3d5f461a
parent 0 9cfd9a3ee49c
child 54 0c2046328c85
permissions -rw-r--r--
Revision: 201037 Kit: 201037

// 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_cpospsylisthandler.h"
#include "epos_cpossingletonmanager.h"
#include "epos_cpospsyfixstatemanager.h"
#include "epos_defaultproxyprivatecrkeys.h"
#include "epos_cposconstmanager.h"
#include "epos_defaultproxycommon.h"

#include <lbs/epos_cposmodules.h>
#include <lbs/epos_cposmoduleidlist.h>
#include <centralrepository.h>


// ================= MEMBER FUNCTIONS =======================

// C++ default constructor can NOT contain any code, that
// might leave.
//
CPosPsyListHandler::CPosPsyListHandler()
    {
    }

// EPOC default constructor can leave.
void CPosPsyListHandler::ConstructL()
    {
    TRACESTRING( "CPosPsyListHandler::ConstructL start... " )

    iFixStateManager = CPosPsyFixStateManager::GetInstanceL();
    iFixStateManager->AddListenerL( this );
    
    iConstManager = CPosConstManager::GetInstanceL();

    TRACESTRING( "CPosPsyListHandler::ConstructL end " )
    }

// ---------------------------------------------------------
// CPosPsyListHandler::GetInstanceL
// ---------------------------------------------------------
//
CPosPsyListHandler* CPosPsyListHandler::GetInstanceL()
    {
    CPosPsyListHandler* self = reinterpret_cast < CPosPsyListHandler* > 
        ( CPosSingletonManager::GetObject( 
            EPosSigletonObjectIdPsyListHandlerId ) );
        
    if ( !self )
        {
        //Construct a new object and store it to CPosSingletonManager
        self = new ( ELeave ) CPosPsyListHandler;
        CleanupStack::PushL(self);
        self->ConstructL();
        CPosSingletonManager::SetObjectL(
            self,
            EPosSigletonObjectIdPsyListHandlerId );
        CleanupStack::Pop(self);
        }
        
    self->iRefCount++;
    
    return self;
    }

// ---------------------------------------------------------
// CPosPsyListHandler::ReleaseInstance
// ---------------------------------------------------------
//
void CPosPsyListHandler::ReleaseInstance()
    {
    iRefCount--;
    if ( iRefCount == 0 )
        {
        //We shall delete the instance
        CPosSingletonManager::ReleaseObject(
            EPosSigletonObjectIdPsyListHandlerId );
        }
    }

// Destructor
CPosPsyListHandler::~CPosPsyListHandler()
    {
    TRACESTRING( "CPosPsyListHandler::destructor start... " )

    if ( iConstManager )
        {
        iConstManager->ReleaseInstance();
        }
        
    if ( iFixStateManager )
        {
        iFixStateManager->RemoveListener( this );
        iFixStateManager->ReleaseInstance();
        }
    
    if ( iModulesSettings )
        {
        iModulesSettings->RemoveListener( *this );
        }
    
    iModuleInfoArray.Close();

    iListenerArray.Close();
    TRACESTRING( "CPosPsyListHandler::destructor end" )
    }

// ---------------------------------------------------------
// CPosPsyListHandler::SetModuleSettingsManagerL
// ---------------------------------------------------------
//
void CPosPsyListHandler::SetModuleSettingsManagerL(
            MPosModuleSettingsManager& aManager )
    {
    if ( iModulesSettings == NULL )
        {
        iModulesSettings = &aManager;
        iModulesSettings->AddListenerL( *this );

        UpdateModuleListL();

        //Move last working GPS PSY to the front of the list
        MovePsyToTop( iConstManager->GetLastWorkingGpsPsyId() );
        }
    }

// ---------------------------------------------------------
// CPosPsyListHandler::AddListenerL
// ---------------------------------------------------------
//
void CPosPsyListHandler::AddListenerL(
            MPosPsyListListener* aListener )
    {
    User::LeaveIfError( iListenerArray.Append( aListener ) );
    }
            
// ---------------------------------------------------------
// CPosPsyListHandler::RemoveListener
// ---------------------------------------------------------
//
void CPosPsyListHandler::RemoveListener(
            MPosPsyListListener* aListener )
    {
    TInt count = iListenerArray.Count();
    for ( TInt i = count -1; i >= 0; i-- )
        {
        if ( iListenerArray[i] == aListener )
            {
            iListenerArray.Remove( i );
            }
        }
    }

// ---------------------------------------------------------
// CPosPsyListHandler::GetPsyListL
// ---------------------------------------------------------
//
void CPosPsyListHandler::GetPsyListL(
            RArray< TPositionModuleId >& aPsyList )
    {
    TRACESTRING( "CPosPsyListHandler::GetPsyListL" )
    aPsyList.Reset();

    TBool integratedGpsAdded = EFalse;
    
    TInt count = iModuleInfoArray.Count();
    for( TInt i = 0; i < count; i++ )
        {
        const TPositionModuleInfo& moduleInfo = iModuleInfoArray[i];
        if( moduleInfo.IsAvailable() )
            {
            if ( IsGpsTechnology( moduleInfo ) && 
                moduleInfo.DeviceLocation() == TPositionModuleInfo::EDeviceInternal )
                {
                if ( !integratedGpsAdded )
                    {
                    TRACESTRING2( "PSY: %x", moduleInfo.ModuleId() )
                    aPsyList.AppendL( moduleInfo.ModuleId() );
                    integratedGpsAdded = ETrue;
                    }
                }
            else
                {
                TRACESTRING2( "PSY: %x", moduleInfo.ModuleId() )
                aPsyList.AppendL( moduleInfo.ModuleId() );
                }
            }
        }
    }

// ---------------------------------------------------------
// CPosPsyListHandler::GetExtGpsPsyListL
// ---------------------------------------------------------
//
void CPosPsyListHandler::GetExtGpsPsyListL(
        RArray< TPositionModuleId >& aPsyList )
    {
    TRACESTRING( "CPosPsyListHandler::GetExtGpsPsyListL" )

    aPsyList.Reset();
    
    TInt count = iModuleInfoArray.Count();
    for( TInt i = 0; i < count; i++ )
        {
        const TPositionModuleInfo& moduleInfo = iModuleInfoArray[i];
        if( moduleInfo.IsAvailable() && 
            IsGpsTechnology( moduleInfo ) && 
            moduleInfo.DeviceLocation() == TPositionModuleInfo::EDeviceExternal )
            {
            TRACESTRING2( "PSY: %x", moduleInfo.ModuleId() )
            aPsyList.AppendL( moduleInfo.ModuleId() );
            }
        }
    }

// ---------------------------------------------------------
// CPosPsyListHandler::IsClassSupported
// ---------------------------------------------------------
//
TBool CPosPsyListHandler::IsClassSupported(
            TUint32 aClassType,
            TPositionModuleId aModuleId ) const
    {
    TInt index = ModuleIndex( aModuleId );
    if ( index != KErrNotFound )
        {
        const TPositionModuleInfo& moduleInfo = iModuleInfoArray[index];
        
        TUint32 classesSupported =
                moduleInfo.ClassesSupported(EPositionInfoFamily);

        return ( aClassType == ( aClassType & classesSupported ) ) &&
                        ( aClassType & EPositionInfoClass );
        }
    return EFalse;
    }

// ---------------------------------------------------------
// CPosPsyListHandler::PsyFixStateChanged
// ---------------------------------------------------------
//
void CPosPsyListHandler::PsyFixStateChanged( 
            TPositionModuleId aModuleId,
            CPosPsyFixStateManager::TPsyFixState aFixState )
    {
    TRACESTRING( "CPosPsyListHandler::PsyFixStateChanged start..." )
    TRACESTRING2( "PSY: %x", aModuleId )
    TRACESTRING2( "Fix state: %d", aFixState )

    TInt index = ModuleIndex( aModuleId );
    
    if ( index != KErrNotFound )
	    {
    	TPositionModuleInfo moduleInfo = iModuleInfoArray[index];
	    
	    if ( IsGpsTechnology( moduleInfo ) && 
	        aFixState == CPosPsyFixStateManager::EPsyFixStateYes )
	        {
	        //Move this one to the top of the list if it's not 
	        //already on top
	        TBool isListModified = MovePsyToTop( aModuleId );
	        
	        //If the list is modified, notify listeners
	        if ( isListModified )
	            {
	            //Write last working GPS PSY UID to CenRep
	            iConstManager->SetLastWorkingGpsPsyId( aModuleId );
	            
	            TPosPsyListChangeEvent event;
	            event.iType = EPosPsyListChangeEventPriorityChanged;
	            NotifyListeners( event );
	            }
	        }
    	}
    }

// ---------------------------------------------------------
// CPosPsyListHandler::HandleModuleSettingsChangedL
// ---------------------------------------------------------
//
void CPosPsyListHandler::HandleModuleSettingsChangedL(
            TPosModulesEvent aEvent )
    {
    TRACESTRING( "CPosPsyListHandler::HandleModuleSettingsChagnedL start..." )
    TRACESTRING2( "Event type: %x", aEvent.iType )
    TRACESTRING2( "PSY: %x", aEvent.iModuleId )

    TInt index = ModuleIndex(aEvent.iModuleId);
    TPosPsyListChangeEvent event;

    switch (aEvent.iType)
        {
        case EPosModulesEventModuleRemoved:
            {
            //Remove module from the array
            if ( index != KErrNotFound )
                {
                iModuleInfoArray.Remove( index );
                //notify listener module removed
                event.iType = EPosPsyListChangeEventPsyDeleted;
                event.iPsyId = aEvent.iModuleId;
                NotifyListeners( event );
                }
            }
            break;
        case EPosModulesEventAvailabilityChanged:
            {
            //Get new module info
            TPositionModuleInfo moduleInfo;
            iModulesSettings->GetModuleInfoL( 
                aEvent.iModuleId, 
                moduleInfo );
                
            TBool isModuleAvailable = moduleInfo.IsAvailable();
            
            //Update the list
            UpdateModuleListL();
            
            if ( !isModuleAvailable )
                {
                //Module is disabled. 
                //notify listener module removed
                event.iType = EPosPsyListChangeEventPsyDeleted;
                event.iPsyId = aEvent.iModuleId;
                NotifyListeners( event );
                }
            else
                {
                //If module is enabled. Current location request
                //will not be affected. We only notify listeners
                //to rebuild the PSY list
                event.iType = EPosPsyListChangeEventListRebuild;
                event.iPsyId = aEvent.iModuleId;
                NotifyListeners( event );
                }
            }
            break;
        case EPosModulesEventVisibilityChanged:
            {
            TBool isModuleVisible = iModulesSettings->IsModuleVisibleL(
                aEvent.iModuleId );

            //Update the list
            UpdateModuleListL();
            
            if ( !isModuleVisible )
                {
                //Module is becoming invisible. 
                //notify listener module removed
                event.iType = EPosPsyListChangeEventPsyDeleted;
                event.iPsyId = aEvent.iModuleId;
                NotifyListeners( event );
                }
            else
                {
                //If module is becoming visible. Current location request
                //will not be affected. We only notify listeners
                //to rebuild the PSY list
                event.iType = EPosPsyListChangeEventListRebuild;
                event.iPsyId = aEvent.iModuleId;
                NotifyListeners( event );
                }
            }
            break;
        case EPosModulesEventPrioritiesChanged:
        case EPosModulesEventModuleInstalled:
        case EPosModulesEventUnspecified:
            {
            UpdateModuleListL();
            event.iType = EPosPsyListChangeEventListRebuild;
            NotifyListeners( event );
            }
            break;
        default:
            //Other change has no effect on default proxy
            break;
        }
    }

// ---------------------------------------------------------
// CPosPsyListHandler::UpdateModuleListL
// ---------------------------------------------------------
//
void CPosPsyListHandler::UpdateModuleListL()
    {
    TRACESTRING( "CPosPsyListHandler::UpdateModuleListL start..." )


    iModuleInfoArray.Reset();
    
    TInt index;
    
    // Read Module Info from settings and fill array
    CPosModuleIdList* idList = iModulesSettings->ModuleIdListL();
    CleanupStack::PushL( idList );

    TInt count = idList->Count();
    
    for ( index = 0; index < count; index++ )
        {
        TPositionModuleInfo moduleInfo;

        iModulesSettings->GetModuleInfoL( ( *idList )[index], moduleInfo );

        User::LeaveIfError( iModuleInfoArray.Append( moduleInfo ) );
        TRACESTRING2( "PSY: %x", moduleInfo.ModuleId() )
        }

    CleanupStack::PopAndDestroy(idList);

    /*
    iModuleInfoArray.Reset();
    
    TInt index;
    
    // Read Module Info from settings and fill array
    CPosModuleIdList* idList = iModulesSettings->ModuleIdListL();
    CleanupStack::PushL( idList );

    TInt count = idList->Count();
    
    TBool integratedGpsAdded = EFalse;
    
    for ( index = 0; index < count; index++ )
        {
        TPositionModuleInfo moduleInfo;

        iModulesSettings->GetModuleInfoL( ( *idList )[index], moduleInfo );

        //only one internal GPS PSY sppears in the list
        if ( IsGpsTechnology( moduleInfo ) && 
            moduleInfo.DeviceLocation() == TPositionModuleInfo::EDeviceInternal )
            {
            if ( !integratedGpsAdded )
                {
                User::LeaveIfError( iModuleInfoArray.Append( moduleInfo ) );
                integratedGpsAdded = ETrue;
                TRACESTRING2( "PSY: %x", moduleInfo.ModuleId() )
                }
            }
        else
            {
            User::LeaveIfError( iModuleInfoArray.Append( moduleInfo ) );
            TRACESTRING2( "PSY: %x", moduleInfo.ModuleId() )
            }
        }

    CleanupStack::PopAndDestroy(idList);
    */
    }

// ---------------------------------------------------------
// CPosPsyListHandler::ModuleIndex
// ---------------------------------------------------------
//
TInt CPosPsyListHandler::ModuleIndex( TPositionModuleId aModuleId ) const
    {
    TInt count = iModuleInfoArray.Count();
    for ( TInt i = 0; i < count; i++ )
        {
        const TPositionModuleInfo& moduleInfo = iModuleInfoArray[i];
        if( moduleInfo.ModuleId() == aModuleId )
            {
            return i;
            }
        }
    return KErrNotFound;
    }

// ---------------------------------------------------------
// CPosPsyListHandler::NotifyListeners
// ---------------------------------------------------------
//
void CPosPsyListHandler::NotifyListeners( 
            const TPosPsyListChangeEvent& aEvent )
    {
    TInt count = iListenerArray.Count();
    for ( TInt i = 0; i < count; i++ )
        {
        iListenerArray[i]->PsyListChanged( aEvent );
        }
    }
    
// ---------------------------------------------------------
// CPosPsyListHandler::GetTtffAndTtnf
// ---------------------------------------------------------
//
TInt CPosPsyListHandler::GetTtffAndTtnf(
            TPositionModuleId aModuleId,
            TTimeIntervalMicroSeconds& aTtff,
            TTimeIntervalMicroSeconds& aTtnf ) const
    {
    TInt index = ModuleIndex( aModuleId );
    if ( index != KErrNotFound )
        {
        const TPositionModuleInfo& moduleInfo = iModuleInfoArray[index];
        TPositionQuality quality;
        moduleInfo.GetPositionQuality( quality );
        
        aTtff = quality.TimeToFirstFix();
        aTtnf = quality.TimeToNextFix();

        TRACESTRING2( "Module Id: %x", aModuleId )
        TRACESTRING2( "TTFF: %d", aTtff.Int64() )
        TRACESTRING2( "TTNF: %d", aTtnf.Int64() )

        return KErrNone;
        }
    return KErrNotFound;
    }

// ---------------------------------------------------------
// CPosPsyListHandler::IsGpsTechnology
// ---------------------------------------------------------
//
TBool CPosPsyListHandler::IsGpsTechnology( 
            const TPositionModuleInfo& aModuleInfo ) const
    {
    //When the module support satellite info, it is a type GPS technolgy
    TUint32 classesSupported =
        aModuleInfo.ClassesSupported(EPositionInfoFamily);

    return ( classesSupported & EPositionSatelliteInfoClass );
    }

// ---------------------------------------------------------
// CPosPsyListHandler::IsFirstGpsPsyExternal
// ---------------------------------------------------------
//
TBool CPosPsyListHandler::IsFirstGpsPsyExternal() const
    {
    TInt count = iModuleInfoArray.Count();
    for( TInt i = 0; i < count; i++ )
        {
        const TPositionModuleInfo& moduleInfo = iModuleInfoArray[i];
        if( moduleInfo.IsAvailable() && 
            IsGpsTechnology( moduleInfo ) )
            {
            if ( moduleInfo.DeviceLocation() == TPositionModuleInfo::EDeviceExternal )
                {
                return ETrue;
                }
            else
                {
                return EFalse;
                }
            }
        }
    return ETrue;
    }

// ---------------------------------------------------------
// CPosPsyListHandler::IsModuleNetworkBased
// ---------------------------------------------------------
//
TBool CPosPsyListHandler::IsModuleNetworkBased(
    TPositionModuleId aModuleId ) const
    {
    TInt index = ModuleIndex( aModuleId );
    
    if ( index != KErrNotFound )
        {
        const TPositionModuleInfo& moduleInfo = iModuleInfoArray[index];
        return ( moduleInfo.TechnologyType() & 
            TPositionModuleInfo::ETechnologyNetwork );
        }
        
    return EFalse;
    }


// ---------------------------------------------------------
// CPosPsyListHandler::MovePsyToTop
// ---------------------------------------------------------
//
TBool CPosPsyListHandler::MovePsyToTop( TPositionModuleId aId )
    {
    if ( aId == KPositionNullModuleId )
        {
        return EFalse;
        }
        
    TInt index = ModuleIndex( aId );
    if ( index == KErrNotFound )
        {
        return EFalse;
        }
        
    TRACESTRING2( "MovePsyToTop: Id: %x", aId)
    
    TPositionModuleInfo moduleInfo = iModuleInfoArray[index];
        
    TBool isFirstSwitch = ETrue;
    
    TInt count = iModuleInfoArray.Count();
    for ( TInt i = 0; i < count; i++ )
        {
        TPositionModuleInfo info = iModuleInfoArray[i];
        if ( IsGpsTechnology( info ) )
            {
            if ( isFirstSwitch )
                {
                if( info.ModuleId() == aId || 
                    ( moduleInfo.DeviceLocation() == 
                        TPositionModuleInfo::EDeviceInternal &&
                      info.DeviceLocation() == 
                        TPositionModuleInfo::EDeviceExternal &&
                     iFixStateManager->GetPsyFixState(
                         info.ModuleId() ) == 
                         CPosPsyFixStateManager::EPsyFixStateYes ) )
                    {
                    //We dont move in this case.
                    return EFalse;
                    }
                      
                }
            //switch
            iModuleInfoArray[i] = moduleInfo;
            moduleInfo = info;
            isFirstSwitch = EFalse;
            if( moduleInfo.ModuleId() == aId )
                {
                return ETrue;
                }
            }
        }
    return ETrue;
    }

//  End of File