locationsystemui/locationsysui/posindicator/posindicatorhelperserver/src/posindicatorlocationrequestor.cpp
branchRCL_3
changeset 44 2b4ea9893b66
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationsystemui/locationsysui/posindicator/posindicatorhelperserver/src/posindicatorlocationrequestor.cpp	Tue Aug 31 15:37:04 2010 +0300
@@ -0,0 +1,366 @@
+/*
+* Copyright (c) 2010 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: Implementation of location requestor class.
+*
+*/
+
+#include "posindicatorlocationrequestor.h"
+#include "posindicatorserverconst.h"
+#include "posindicatorlogger.h"
+
+#include <epos_poslandmarkserialization.h>
+#include <ecom.h>
+
+_LIT( KServer,"PositionIndicatorServer" );
+static const TInt KMaxUpdateAge = 10;
+static const TInt KUpdateTimeOut = 5000000;
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::NewL
+// -----------------------------------------------------------------------------
+CPosIndicatorLocationRequestor* CPosIndicatorLocationRequestor::NewL()
+    {
+    FUNC("CPosIndicatorLocationRequestor::NewL");
+    CPosIndicatorLocationRequestor* self = new ( ELeave ) 
+                                        CPosIndicatorLocationRequestor;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::~CPosIndicatorLocationRequestor
+// -----------------------------------------------------------------------------
+CPosIndicatorLocationRequestor::~CPosIndicatorLocationRequestor()
+    {
+    FUNC("CPosIndicatorLocationRequestor::~CPosIndicatorLocationRequestor");
+    
+    // Cancel the current operation.
+    Cancel();
+    
+    iPositionRequestQueue.Close();
+    iAddressRequestQueue.Close();
+    iPositioner.Close();
+    iPosServer.Close();    
+    delete iReverseGeoCodeInterface;
+    iReverseGeoCodeInterface = NULL;
+    delete iLandmark;
+    iLandmark = NULL;
+    delete iLandmarkPackage;
+    iLandmarkPackage = NULL;
+    // Release all landmark resources
+    ReleaseLandmarkResources();
+    
+    // Release all ECOM resources
+    REComSession::FinalClose();	
+    }
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::CPosIndicatorLocationRequestor
+// -----------------------------------------------------------------------------
+CPosIndicatorLocationRequestor::CPosIndicatorLocationRequestor():CActive( 
+                                                              EPriorityStandard )
+    {
+    FUNC("CPosIndicatorLocationRequestor::CPosIndicatorLocationRequestor");
+    CActiveScheduler::Add( this );
+    }
+ 
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::ConstructL
+// -----------------------------------------------------------------------------
+void CPosIndicatorLocationRequestor::ConstructL()
+    {
+    FUNC("CPosIndicatorLocationRequestor::ConstructL");
+    iOperation = ENone;
+    
+    User::LeaveIfError( iPosServer.Connect() );
+    
+    TInt error = iPositioner.Open( iPosServer );
+    
+    User::LeaveIfError( iPositioner.SetRequestor( 
+                        CRequestor::ERequestorService,
+                        CRequestor::EFormatApplication,
+                        KServer ) );
+
+    TPositionUpdateOptions updateops;
+    updateops.SetUpdateTimeOut(TTimeIntervalMicroSeconds(KUpdateTimeOut));
+    User::LeaveIfError( iPositioner.SetUpdateOptions( updateops ));
+ 
+    iReverseGeoCodeInterface = CPosReverseGeocodeInterface::NewL( *this );
+    
+    iLandmark = CPosLandmark::NewL();
+    
+    iLandmarkPackage = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::GetCurrentPosition
+// -----------------------------------------------------------------------------
+void CPosIndicatorLocationRequestor::GetCurrentPosition( const RMessage2&
+                                                         aMessage )
+    { 
+    FUNC("CPosIndicatorLocationRequestor::GetCurrentPosition");
+    // If location fix is already available and this is waiting for address info,
+    // reply the message with the fix available
+    if( iOperation == ECurrentAddress )
+        {
+        FUNC("iOperation == ECurrentAddress");
+        TPckg<TPositionSatelliteInfo> posSatPckg( iPositionInfo );
+        TInt error = aMessage.Write( KParamCurrentPosition,posSatPckg );
+        aMessage.Complete( error );
+        }
+    else 
+        {
+        FUNC("iOperation != ECurrentAddress");
+        // Store client's message
+        iPositionRequestQueue.Append( aMessage );   
+        // If the requestor is idle without doing any operation, request
+        // current location.
+        if( iOperation == ENone )
+            {
+            FUNC("iOperation == ENone");
+            iOperation = ELastKnownPosition;
+            
+            // Last known position.
+            iPositioner.GetLastKnownPosition( iLastKnownInfo,iStatus );
+            SetActive();
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::GetCurrentAddressInfoSizeL
+// -----------------------------------------------------------------------------
+void CPosIndicatorLocationRequestor::GetCurrentAddressInfoSizeL( const RMessage2& 
+                                                                 aMessage )
+    {
+    FUNC("CPosIndicatorLocationRequestor::GetCurrentAddressInfoSizeL");
+    // Store client's message
+    iAddressRequestQueue.Append( aMessage );
+    
+    // If the requestor is idle without doing any operation, request
+    // address information.
+    if( iOperation == ENone )
+        {
+        iOperation = ECurrentAddress;
+        // Clear previous landmark information.
+        iLandmark->RemoveLandmarkAttributes( CPosLandmark::EAllAttributes );
+        TPosition position;
+        iPositionInfo.GetPosition( position );
+        iLandmark->SetPositionL( position );
+        iReverseGeoCodeInterface->GetAddressByCoordinateL( *iLandmark );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::GetCurrentAddressInfoL
+// -----------------------------------------------------------------------------
+void CPosIndicatorLocationRequestor::GetCurrentAddressInfoL( const RMessage2& 
+                                                             aMessage )
+    {
+    FUNC("CPosIndicatorLocationRequestor::GetCurrentAddressInfoL");
+    TInt error = aMessage.Write( KParamCurrentAddress,*iLandmarkPackage );
+    aMessage.Complete( error );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::RunL
+// -----------------------------------------------------------------------------
+void CPosIndicatorLocationRequestor::RunL()
+    {
+    FUNC("CPosIndicatorLocationRequestor::RunL");
+    LOG("Error Status : ", iStatus.Int());
+    switch( iOperation )
+        {
+        case ELastKnownPosition:
+            {
+                // Check the time stamp of the last fix, if the fix is 10 sec
+                // old, request for the new fix.
+                TPosition position;
+                iLastKnownInfo.GetPosition( position );
+                TTime timeOfFix = position.Time();
+                TTime currentTime;
+                currentTime.HomeTime();
+                timeOfFix += TTimeIntervalSeconds( KMaxUpdateAge );
+                if( iStatus.Int() == KErrNone && timeOfFix < currentTime && 
+                	!(Math::IsNaN( position.Latitude() ) || Math::IsNaN( position.Longitude() ) ) )
+                    {
+                    // Set the last knowm position to position info to send it to
+                    // client.
+                    iPositionInfo.SetPosition( position );
+                    }
+                else
+                    {
+                    iOperation = ECurrentPosition;
+                 
+                    // Request current position.
+                    iPositioner.NotifyPositionUpdate( iPositionInfo,iStatus );
+                    SetActive();
+                    return;
+                    }
+            	}
+        case ECurrentPosition:
+            {
+            // Reset operation id
+            iOperation = ENone;
+            // Pack the satellite position information 
+            TPckg<TPositionSatelliteInfo> posSatPckg( iPositionInfo );
+            TInt count = iPositionRequestQueue.Count();
+            for( TInt i=0;i<count;++i )
+                {
+                TInt error = iStatus.Int();
+                if( error == KErrNone )
+                    {
+                    error = iPositionRequestQueue[i].Write( KParamCurrentPosition,posSatPckg );
+                    }
+                iPositionRequestQueue[i].Complete( error );
+                }
+            // All the messages in the position request queue are completed. Hence reset the list.
+            iPositionRequestQueue.Reset();
+            break;
+            }
+        case ECurrentAddress:
+            {
+            FUNC("ECurrentAddress");
+            // Reset operation id
+            iOperation = ENone;
+            // Pack landmarks information
+            delete iLandmarkPackage;
+			iLandmarkPackage = NULL;
+            iLandmarkPackage = PosLandmarkSerialization::PackL( *iLandmark );
+            TInt count = iAddressRequestQueue.Count();
+            for( TInt i=0;i<count;i++ )
+                {
+                TInt error = iStatus.Int();
+                if( error == KErrNone )
+                    {
+                    TPckg<TInt> size( iLandmarkPackage->Size() );
+                    error = iAddressRequestQueue[i].Write( KParamCurrentAddressSize,size );
+                    }
+                iAddressRequestQueue[i].Complete( error );
+                }
+            // All the messages in the address request queue are completed. Hence reset the list.
+            iAddressRequestQueue.Reset();
+            break;
+            }
+
+        default:
+            {
+            FUNC("- CPosIndicatorLocationRequestor::RunL default case");
+            break;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::CancelRequest
+// -----------------------------------------------------------------------------
+void CPosIndicatorLocationRequestor::CancelRequest( const RMessage2& aMessage )
+    {
+    // Iterate through the outstanding request and check whether there are 
+    // outstanding request from the subsession from which cancel call is 
+    // received.
+    RMessage2 outStandingMessage;
+    TBool outStandingFlag = EFalse;
+    TInt count = iPositionRequestQueue.Count();
+    for( TInt i=0;i<count;++i )
+        {
+        if( iPositionRequestQueue[i].SecureId() == aMessage.SecureId() &&
+            iPositionRequestQueue[i].Int3() == aMessage.Int3() )
+            {
+            outStandingMessage = iPositionRequestQueue[i];
+            iPositionRequestQueue.Remove(i);
+            outStandingFlag = ETrue;
+            break;
+            }
+        }
+    
+    // If the outstanding request is not found in the position request queue,
+    // search address request queue.
+    if( !outStandingFlag )
+        {   
+        count = iAddressRequestQueue.Count();
+        for( TInt i=0;i<count;++i )
+            {
+            if( iAddressRequestQueue[i].SecureId() == aMessage.SecureId() &&
+                iAddressRequestQueue[i].Int3() == aMessage.Int3() )
+                {
+                outStandingMessage = iAddressRequestQueue[i];
+                iAddressRequestQueue.Remove(i);
+                outStandingFlag = ETrue;
+                break;
+                }
+            }
+        }
+    
+    // If the both position and address request queue are zero, cancel outstanding request
+    if( !iAddressRequestQueue.Count() &&
+        !iPositionRequestQueue.Count() )
+        {
+        Cancel();
+        }
+    if( outStandingFlag )
+        {
+        outStandingMessage.Complete( KErrCancel );
+        }
+    // Complete cancel request.
+    aMessage.Complete( KErrNone );
+    }
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::DoCancel
+// -----------------------------------------------------------------------------
+void CPosIndicatorLocationRequestor::DoCancel()
+    {
+    FUNC("CPosIndicatorLocationRequestor::DoCancel");
+    switch( iOperation )
+        {
+        case ELastKnownPosition:
+            {
+            iPositioner.CancelRequest( RPositionerSubSessionBase::EReqGetLastKnownPosition );
+            break;
+            }
+        case ECurrentPosition:
+            {
+            iPositioner.CancelRequest( RPositionerSubSessionBase::EReqNotifyPositionUpdate );
+            break;
+            }    
+        case ECurrentAddress:    
+            {
+            iReverseGeoCodeInterface->Cancel();
+            break;
+            }
+        default:
+            break;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPosIndicatorLocationRequestor::ReverseGeocodeComplete
+// -----------------------------------------------------------------------------
+void CPosIndicatorLocationRequestor::ReverseGeocodeComplete( TInt aErrorcode )
+    {
+    FUNC("CPosIndicatorLocationRequestor::ReverseGeocodeComplete");
+    // Here we self complete our active to release the control from this 
+    // call back method.
+    iStatus = KRequestPending;
+    SetActive();
+    TRequestStatus* statusPtr = &iStatus;
+    User::RequestComplete( statusPtr,aErrorcode );
+    }
+
+// End of file.