locationsystemui/locationsysui/posindicator/posindicatorhelperserver/src/posindicatorlocationrequestor.cpp
branchRCL_3
changeset 44 2b4ea9893b66
equal deleted inserted replaced
42:02ba3f1733c6 44:2b4ea9893b66
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Implementation of location requestor class.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "posindicatorlocationrequestor.h"
       
    19 #include "posindicatorserverconst.h"
       
    20 #include "posindicatorlogger.h"
       
    21 
       
    22 #include <epos_poslandmarkserialization.h>
       
    23 #include <ecom.h>
       
    24 
       
    25 _LIT( KServer,"PositionIndicatorServer" );
       
    26 static const TInt KMaxUpdateAge = 10;
       
    27 static const TInt KUpdateTimeOut = 5000000;
       
    28 
       
    29 // -----------------------------------------------------------------------------
       
    30 // CPosIndicatorLocationRequestor::NewL
       
    31 // -----------------------------------------------------------------------------
       
    32 CPosIndicatorLocationRequestor* CPosIndicatorLocationRequestor::NewL()
       
    33     {
       
    34     FUNC("CPosIndicatorLocationRequestor::NewL");
       
    35     CPosIndicatorLocationRequestor* self = new ( ELeave ) 
       
    36                                         CPosIndicatorLocationRequestor;
       
    37     CleanupStack::PushL( self );
       
    38     self->ConstructL();
       
    39     CleanupStack::Pop();
       
    40     return self;
       
    41     }
       
    42     
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CPosIndicatorLocationRequestor::~CPosIndicatorLocationRequestor
       
    46 // -----------------------------------------------------------------------------
       
    47 CPosIndicatorLocationRequestor::~CPosIndicatorLocationRequestor()
       
    48     {
       
    49     FUNC("CPosIndicatorLocationRequestor::~CPosIndicatorLocationRequestor");
       
    50     
       
    51     // Cancel the current operation.
       
    52     Cancel();
       
    53     
       
    54     iPositionRequestQueue.Close();
       
    55     iAddressRequestQueue.Close();
       
    56     iPositioner.Close();
       
    57     iPosServer.Close();    
       
    58     delete iReverseGeoCodeInterface;
       
    59     iReverseGeoCodeInterface = NULL;
       
    60     delete iLandmark;
       
    61     iLandmark = NULL;
       
    62     delete iLandmarkPackage;
       
    63     iLandmarkPackage = NULL;
       
    64     // Release all landmark resources
       
    65     ReleaseLandmarkResources();
       
    66     
       
    67     // Release all ECOM resources
       
    68     REComSession::FinalClose();	
       
    69     }
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CPosIndicatorLocationRequestor::CPosIndicatorLocationRequestor
       
    73 // -----------------------------------------------------------------------------
       
    74 CPosIndicatorLocationRequestor::CPosIndicatorLocationRequestor():CActive( 
       
    75                                                               EPriorityStandard )
       
    76     {
       
    77     FUNC("CPosIndicatorLocationRequestor::CPosIndicatorLocationRequestor");
       
    78     CActiveScheduler::Add( this );
       
    79     }
       
    80  
       
    81 // -----------------------------------------------------------------------------
       
    82 // CPosIndicatorLocationRequestor::ConstructL
       
    83 // -----------------------------------------------------------------------------
       
    84 void CPosIndicatorLocationRequestor::ConstructL()
       
    85     {
       
    86     FUNC("CPosIndicatorLocationRequestor::ConstructL");
       
    87     iOperation = ENone;
       
    88     
       
    89     User::LeaveIfError( iPosServer.Connect() );
       
    90     
       
    91     TInt error = iPositioner.Open( iPosServer );
       
    92     
       
    93     User::LeaveIfError( iPositioner.SetRequestor( 
       
    94                         CRequestor::ERequestorService,
       
    95                         CRequestor::EFormatApplication,
       
    96                         KServer ) );
       
    97 
       
    98     TPositionUpdateOptions updateops;
       
    99     updateops.SetUpdateTimeOut(TTimeIntervalMicroSeconds(KUpdateTimeOut));
       
   100     User::LeaveIfError( iPositioner.SetUpdateOptions( updateops ));
       
   101  
       
   102     iReverseGeoCodeInterface = CPosReverseGeocodeInterface::NewL( *this );
       
   103     
       
   104     iLandmark = CPosLandmark::NewL();
       
   105     
       
   106     iLandmarkPackage = NULL;
       
   107     }
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // CPosIndicatorLocationRequestor::GetCurrentPosition
       
   111 // -----------------------------------------------------------------------------
       
   112 void CPosIndicatorLocationRequestor::GetCurrentPosition( const RMessage2&
       
   113                                                          aMessage )
       
   114     { 
       
   115     FUNC("CPosIndicatorLocationRequestor::GetCurrentPosition");
       
   116     // If location fix is already available and this is waiting for address info,
       
   117     // reply the message with the fix available
       
   118     if( iOperation == ECurrentAddress )
       
   119         {
       
   120         FUNC("iOperation == ECurrentAddress");
       
   121         TPckg<TPositionSatelliteInfo> posSatPckg( iPositionInfo );
       
   122         TInt error = aMessage.Write( KParamCurrentPosition,posSatPckg );
       
   123         aMessage.Complete( error );
       
   124         }
       
   125     else 
       
   126         {
       
   127         FUNC("iOperation != ECurrentAddress");
       
   128         // Store client's message
       
   129         iPositionRequestQueue.Append( aMessage );   
       
   130         // If the requestor is idle without doing any operation, request
       
   131         // current location.
       
   132         if( iOperation == ENone )
       
   133             {
       
   134             FUNC("iOperation == ENone");
       
   135             iOperation = ELastKnownPosition;
       
   136             
       
   137             // Last known position.
       
   138             iPositioner.GetLastKnownPosition( iLastKnownInfo,iStatus );
       
   139             SetActive();
       
   140             }
       
   141         }
       
   142     }
       
   143 
       
   144 // -----------------------------------------------------------------------------
       
   145 // CPosIndicatorLocationRequestor::GetCurrentAddressInfoSizeL
       
   146 // -----------------------------------------------------------------------------
       
   147 void CPosIndicatorLocationRequestor::GetCurrentAddressInfoSizeL( const RMessage2& 
       
   148                                                                  aMessage )
       
   149     {
       
   150     FUNC("CPosIndicatorLocationRequestor::GetCurrentAddressInfoSizeL");
       
   151     // Store client's message
       
   152     iAddressRequestQueue.Append( aMessage );
       
   153     
       
   154     // If the requestor is idle without doing any operation, request
       
   155     // address information.
       
   156     if( iOperation == ENone )
       
   157         {
       
   158         iOperation = ECurrentAddress;
       
   159         // Clear previous landmark information.
       
   160         iLandmark->RemoveLandmarkAttributes( CPosLandmark::EAllAttributes );
       
   161         TPosition position;
       
   162         iPositionInfo.GetPosition( position );
       
   163         iLandmark->SetPositionL( position );
       
   164         iReverseGeoCodeInterface->GetAddressByCoordinateL( *iLandmark );
       
   165         }
       
   166     }
       
   167 
       
   168 // -----------------------------------------------------------------------------
       
   169 // CPosIndicatorLocationRequestor::GetCurrentAddressInfoL
       
   170 // -----------------------------------------------------------------------------
       
   171 void CPosIndicatorLocationRequestor::GetCurrentAddressInfoL( const RMessage2& 
       
   172                                                              aMessage )
       
   173     {
       
   174     FUNC("CPosIndicatorLocationRequestor::GetCurrentAddressInfoL");
       
   175     TInt error = aMessage.Write( KParamCurrentAddress,*iLandmarkPackage );
       
   176     aMessage.Complete( error );
       
   177     }
       
   178 
       
   179 
       
   180 // -----------------------------------------------------------------------------
       
   181 // CPosIndicatorLocationRequestor::RunL
       
   182 // -----------------------------------------------------------------------------
       
   183 void CPosIndicatorLocationRequestor::RunL()
       
   184     {
       
   185     FUNC("CPosIndicatorLocationRequestor::RunL");
       
   186     LOG("Error Status : ", iStatus.Int());
       
   187     switch( iOperation )
       
   188         {
       
   189         case ELastKnownPosition:
       
   190             {
       
   191                 // Check the time stamp of the last fix, if the fix is 10 sec
       
   192                 // old, request for the new fix.
       
   193                 TPosition position;
       
   194                 iLastKnownInfo.GetPosition( position );
       
   195                 TTime timeOfFix = position.Time();
       
   196                 TTime currentTime;
       
   197                 currentTime.HomeTime();
       
   198                 timeOfFix += TTimeIntervalSeconds( KMaxUpdateAge );
       
   199                 if( iStatus.Int() == KErrNone && timeOfFix < currentTime && 
       
   200                 	!(Math::IsNaN( position.Latitude() ) || Math::IsNaN( position.Longitude() ) ) )
       
   201                     {
       
   202                     // Set the last knowm position to position info to send it to
       
   203                     // client.
       
   204                     iPositionInfo.SetPosition( position );
       
   205                     }
       
   206                 else
       
   207                     {
       
   208                     iOperation = ECurrentPosition;
       
   209                  
       
   210                     // Request current position.
       
   211                     iPositioner.NotifyPositionUpdate( iPositionInfo,iStatus );
       
   212                     SetActive();
       
   213                     return;
       
   214                     }
       
   215             	}
       
   216         case ECurrentPosition:
       
   217             {
       
   218             // Reset operation id
       
   219             iOperation = ENone;
       
   220             // Pack the satellite position information 
       
   221             TPckg<TPositionSatelliteInfo> posSatPckg( iPositionInfo );
       
   222             TInt count = iPositionRequestQueue.Count();
       
   223             for( TInt i=0;i<count;++i )
       
   224                 {
       
   225                 TInt error = iStatus.Int();
       
   226                 if( error == KErrNone )
       
   227                     {
       
   228                     error = iPositionRequestQueue[i].Write( KParamCurrentPosition,posSatPckg );
       
   229                     }
       
   230                 iPositionRequestQueue[i].Complete( error );
       
   231                 }
       
   232             // All the messages in the position request queue are completed. Hence reset the list.
       
   233             iPositionRequestQueue.Reset();
       
   234             break;
       
   235             }
       
   236         case ECurrentAddress:
       
   237             {
       
   238             FUNC("ECurrentAddress");
       
   239             // Reset operation id
       
   240             iOperation = ENone;
       
   241             // Pack landmarks information
       
   242             delete iLandmarkPackage;
       
   243 			iLandmarkPackage = NULL;
       
   244             iLandmarkPackage = PosLandmarkSerialization::PackL( *iLandmark );
       
   245             TInt count = iAddressRequestQueue.Count();
       
   246             for( TInt i=0;i<count;i++ )
       
   247                 {
       
   248                 TInt error = iStatus.Int();
       
   249                 if( error == KErrNone )
       
   250                     {
       
   251                     TPckg<TInt> size( iLandmarkPackage->Size() );
       
   252                     error = iAddressRequestQueue[i].Write( KParamCurrentAddressSize,size );
       
   253                     }
       
   254                 iAddressRequestQueue[i].Complete( error );
       
   255                 }
       
   256             // All the messages in the address request queue are completed. Hence reset the list.
       
   257             iAddressRequestQueue.Reset();
       
   258             break;
       
   259             }
       
   260 
       
   261         default:
       
   262             {
       
   263             FUNC("- CPosIndicatorLocationRequestor::RunL default case");
       
   264             break;
       
   265             }
       
   266         }
       
   267     }
       
   268 
       
   269 // -----------------------------------------------------------------------------
       
   270 // CPosIndicatorLocationRequestor::CancelRequest
       
   271 // -----------------------------------------------------------------------------
       
   272 void CPosIndicatorLocationRequestor::CancelRequest( const RMessage2& aMessage )
       
   273     {
       
   274     // Iterate through the outstanding request and check whether there are 
       
   275     // outstanding request from the subsession from which cancel call is 
       
   276     // received.
       
   277     RMessage2 outStandingMessage;
       
   278     TBool outStandingFlag = EFalse;
       
   279     TInt count = iPositionRequestQueue.Count();
       
   280     for( TInt i=0;i<count;++i )
       
   281         {
       
   282         if( iPositionRequestQueue[i].SecureId() == aMessage.SecureId() &&
       
   283             iPositionRequestQueue[i].Int3() == aMessage.Int3() )
       
   284             {
       
   285             outStandingMessage = iPositionRequestQueue[i];
       
   286             iPositionRequestQueue.Remove(i);
       
   287             outStandingFlag = ETrue;
       
   288             break;
       
   289             }
       
   290         }
       
   291     
       
   292     // If the outstanding request is not found in the position request queue,
       
   293     // search address request queue.
       
   294     if( !outStandingFlag )
       
   295         {   
       
   296         count = iAddressRequestQueue.Count();
       
   297         for( TInt i=0;i<count;++i )
       
   298             {
       
   299             if( iAddressRequestQueue[i].SecureId() == aMessage.SecureId() &&
       
   300                 iAddressRequestQueue[i].Int3() == aMessage.Int3() )
       
   301                 {
       
   302                 outStandingMessage = iAddressRequestQueue[i];
       
   303                 iAddressRequestQueue.Remove(i);
       
   304                 outStandingFlag = ETrue;
       
   305                 break;
       
   306                 }
       
   307             }
       
   308         }
       
   309     
       
   310     // If the both position and address request queue are zero, cancel outstanding request
       
   311     if( !iAddressRequestQueue.Count() &&
       
   312         !iPositionRequestQueue.Count() )
       
   313         {
       
   314         Cancel();
       
   315         }
       
   316     if( outStandingFlag )
       
   317         {
       
   318         outStandingMessage.Complete( KErrCancel );
       
   319         }
       
   320     // Complete cancel request.
       
   321     aMessage.Complete( KErrNone );
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // CPosIndicatorLocationRequestor::DoCancel
       
   326 // -----------------------------------------------------------------------------
       
   327 void CPosIndicatorLocationRequestor::DoCancel()
       
   328     {
       
   329     FUNC("CPosIndicatorLocationRequestor::DoCancel");
       
   330     switch( iOperation )
       
   331         {
       
   332         case ELastKnownPosition:
       
   333             {
       
   334             iPositioner.CancelRequest( RPositionerSubSessionBase::EReqGetLastKnownPosition );
       
   335             break;
       
   336             }
       
   337         case ECurrentPosition:
       
   338             {
       
   339             iPositioner.CancelRequest( RPositionerSubSessionBase::EReqNotifyPositionUpdate );
       
   340             break;
       
   341             }    
       
   342         case ECurrentAddress:    
       
   343             {
       
   344             iReverseGeoCodeInterface->Cancel();
       
   345             break;
       
   346             }
       
   347         default:
       
   348             break;
       
   349         }
       
   350     }
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 // CPosIndicatorLocationRequestor::ReverseGeocodeComplete
       
   354 // -----------------------------------------------------------------------------
       
   355 void CPosIndicatorLocationRequestor::ReverseGeocodeComplete( TInt aErrorcode )
       
   356     {
       
   357     FUNC("CPosIndicatorLocationRequestor::ReverseGeocodeComplete");
       
   358     // Here we self complete our active to release the control from this 
       
   359     // call back method.
       
   360     iStatus = KRequestPending;
       
   361     SetActive();
       
   362     TRequestStatus* statusPtr = &iStatus;
       
   363     User::RequestComplete( statusPtr,aErrorcode );
       
   364     }
       
   365 
       
   366 // End of file.