locationsystemui/locationsysui/locsettingsuiservice/locsettingsuiclient/src/locsettingsuiservice.cpp
branchRCL_3
changeset 44 2b4ea9893b66
parent 42 02ba3f1733c6
child 45 6b6920c56e2f
equal deleted inserted replaced
42:02ba3f1733c6 44:2b4ea9893b66
     1 /*
       
     2 * Copyright (c) 2005-2009 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:  Client side resource handle to the UI Server
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // System Includes
       
    20 #include <avkon.hrh>
       
    21 
       
    22 // User Includes
       
    23 #include "locsettingsuiservice.h"
       
    24 #include "loclaunchuiao.h"
       
    25 #include "locsettingsuiserverinterface.h"
       
    26 
       
    27 // Constant Declarations
       
    28 const TInt KNumofConnectAttempts = 200;
       
    29     
       
    30 // ======== MEMBER FUNCTIONS ========
       
    31 
       
    32 // ---------------------------------------------------------------------------
       
    33 // C++ Default Constructor
       
    34 // ---------------------------------------------------------------------------
       
    35 //
       
    36 RLocSettingsUiService::RLocSettingsUiService()
       
    37     :iLaunchAO( NULL ),
       
    38     iRequestStatus( NULL ),
       
    39     iLaunchType( ELaunchNone ),
       
    40     iSrvMonitor( NULL )
       
    41     {
       
    42     }
       
    43 
       
    44 // ---------------------------------------------------------------------------
       
    45 // C++ Destructor
       
    46 // ---------------------------------------------------------------------------
       
    47 //
       
    48 RLocSettingsUiService::~RLocSettingsUiService()
       
    49     {
       
    50     if( ELaunchNone != iLaunchType )
       
    51         {
       
    52         CancelLaunchedSettingsUi();
       
    53         }   
       
    54     }
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 // Launch a Settings UI in an ui app server
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 void RLocSettingsUiService::LaunchSettingsUiL(
       
    61                                     TUid            aImplementationUid,
       
    62                                     TInt            aParams,
       
    63                                     TRequestStatus& aStatus )
       
    64     {
       
    65     
       
    66     // Check the presence of the Active Object
       
    67     if( NULL == iLaunchAO )
       
    68         {
       
    69         User::Leave( KErrNotFound );
       
    70         }
       
    71         
       
    72     // Check if there is any outstanding requests
       
    73     if( ELaunchNone != iLaunchType )
       
    74         {
       
    75         User::Leave( KErrInUse );
       
    76         }
       
    77     
       
    78     // Create the Server Session
       
    79     ConnectServerL();
       
    80     
       
    81     // Store the aStatus variable. This would be used to notify the caller
       
    82     // on completeion of the launch message
       
    83     iRequestStatus = &aStatus;  
       
    84     *iRequestStatus = KRequestPending;
       
    85     
       
    86     // Set request outstanding on the Active object
       
    87     iLaunchAO->SetRequestOutStandingL();
       
    88         
       
    89     // Compose the Message and Issue a Launch call to the server
       
    90     TRequestStatus&     status = iLaunchAO->GetStatusVariable();
       
    91     
       
    92     // Set the Launch Type and the Service state
       
    93     iLaunchType = ELaunchNormal;
       
    94                       
       
    95     TIpcArgs args( aImplementationUid.iUid, aParams );
       
    96     
       
    97 	SendReceive( ELaunchSettings, args, status );
       
    98     
       
    99     iSrvMonitor = NULL;
       
   100     }
       
   101     
       
   102 // ---------------------------------------------------------------------------
       
   103 // Launch a Settings UI as an embedded application
       
   104 // ---------------------------------------------------------------------------
       
   105 //
       
   106 void RLocSettingsUiService::LaunchSettingsUiAsEmbeddedAppL(
       
   107                                             TUid            aImplementationUid,
       
   108                                             TInt            aParams,
       
   109                                             TRequestStatus& aStatus )
       
   110     {
       
   111     
       
   112     // Check the presence of the Active Object
       
   113     if( NULL == iLaunchAO )
       
   114         {
       
   115         User::Leave( KErrNotFound );
       
   116         }
       
   117         
       
   118     // Check if there is any outstanding requests
       
   119     if( ELaunchNone != iLaunchType )
       
   120         {
       
   121         User::Leave( KErrInUse );
       
   122         }
       
   123     
       
   124     // Create the Server Session
       
   125     ConnectChainedAppL( TUid::Uid( KLocSettingsUiServerUid ));
       
   126     
       
   127     // Store the aStatus variable. This would be used to notfy the caller
       
   128     // on completeion of the launch message
       
   129     iRequestStatus = &aStatus;  
       
   130     *iRequestStatus = KRequestPending;
       
   131     
       
   132     // Set request outstanding on the Active object
       
   133     iLaunchAO->SetRequestOutStandingL();
       
   134         
       
   135     // Compose the Message and Issue a Launch call to the server
       
   136     TRequestStatus&     status = iLaunchAO->GetStatusVariable();
       
   137     
       
   138     // Set the Launch Request Type and the Service state
       
   139     iLaunchType = ELaunchEmbedded;  
       
   140                       
       
   141     TIpcArgs args( aImplementationUid.iUid, aParams );
       
   142 	SendReceive( ELaunchSettings, args, status );
       
   143 
       
   144     iSrvMonitor = CApaServerAppExitMonitor::NewL(*this, 
       
   145                                                  *this,
       
   146                                                  CActive::EPriorityStandard);
       
   147     }
       
   148 
       
   149 // ---------------------------------------------------------------------------
       
   150 // Launch a Settings UI in an ui app server
       
   151 // ---------------------------------------------------------------------------
       
   152 //
       
   153 void RLocSettingsUiService::LaunchSettingsUiL(
       
   154                                     TUid            aImplementationUid,
       
   155                                     const TDesC&            aParamsString,
       
   156                                     TRequestStatus& aStatus )
       
   157     {
       
   158     
       
   159     // Check the presence of the Active Object
       
   160     if( NULL == iLaunchAO )
       
   161         {
       
   162         User::Leave( KErrNotFound );
       
   163         }
       
   164         
       
   165     // Check if there is any outstanding requests
       
   166     if( ELaunchNone != iLaunchType )
       
   167         {
       
   168         User::Leave( KErrInUse );
       
   169         }
       
   170     
       
   171     // Create the Server Session
       
   172     ConnectServerL();
       
   173     
       
   174     // Store the aStatus variable. This would be used to notify the caller
       
   175     // on completeion of the launch message
       
   176     iRequestStatus = &aStatus;  
       
   177     *iRequestStatus = KRequestPending;
       
   178     
       
   179     // Set request outstanding on the Active object
       
   180     iLaunchAO->SetRequestOutStandingL();
       
   181         
       
   182     // Compose the Message and Issue a Launch call to the server
       
   183     TRequestStatus&     status = iLaunchAO->GetStatusVariable();
       
   184     
       
   185     // Set the Launch Type and the Service state
       
   186     iLaunchType = ELaunchNormal;
       
   187                       
       
   188     TIpcArgs args( aImplementationUid.iUid, aParamsString.Length(), &aParamsString );
       
   189     
       
   190 	SendReceive( ELaunchSettingsWithString, args, status );
       
   191     
       
   192     iSrvMonitor = NULL;
       
   193     }
       
   194     
       
   195 // ---------------------------------------------------------------------------
       
   196 // Launch a Settings UI as an embedded application
       
   197 // ---------------------------------------------------------------------------
       
   198 //
       
   199 void RLocSettingsUiService::LaunchSettingsUiAsEmbeddedAppL(
       
   200                                             TUid            aImplementationUid,
       
   201                                             const TDesC&            aParamsString,
       
   202                                             TRequestStatus& aStatus )
       
   203     {
       
   204     
       
   205     // Check the presence of the Active Object
       
   206     if( NULL == iLaunchAO )
       
   207         {
       
   208         User::Leave( KErrNotFound );
       
   209         }
       
   210         
       
   211     // Check if there is any outstanding requests
       
   212     if( ELaunchNone != iLaunchType )
       
   213         {
       
   214         User::Leave( KErrInUse );
       
   215         }
       
   216     
       
   217     // Create the Server Session
       
   218     ConnectChainedAppL( TUid::Uid( KLocSettingsUiServerUid ));
       
   219     
       
   220     // Store the aStatus variable. This would be used to notfy the caller
       
   221     // on completeion of the launch message
       
   222     iRequestStatus = &aStatus;  
       
   223     *iRequestStatus = KRequestPending;
       
   224     
       
   225     // Set request outstanding on the Active object
       
   226     iLaunchAO->SetRequestOutStandingL();
       
   227         
       
   228     // Compose the Message and Issue a Launch call to the server
       
   229     TRequestStatus&     status = iLaunchAO->GetStatusVariable();
       
   230     
       
   231     // Set the Launch Request Type and the Service state
       
   232     iLaunchType = ELaunchEmbedded;  
       
   233                       
       
   234     TIpcArgs args( aImplementationUid.iUid, aParamsString.Length(), &aParamsString );
       
   235     
       
   236 	SendReceive( ELaunchSettingsWithString, args, status );
       
   237 
       
   238     iSrvMonitor = CApaServerAppExitMonitor::NewL(*this, 
       
   239                                                  *this,
       
   240                                                  CActive::EPriorityStandard);
       
   241     }
       
   242     
       
   243 // ---------------------------------------------------------------------------
       
   244 // Cancels a Launched request
       
   245 // ---------------------------------------------------------------------------
       
   246 //    
       
   247 TInt RLocSettingsUiService::CancelLaunchedSettingsUi()
       
   248     {
       
   249     // If no request is outstanding then this operation is not supported 
       
   250     // in this context
       
   251     if( ELaunchNone == iLaunchType )
       
   252         {
       
   253         return KErrNotSupported;
       
   254         }
       
   255     
       
   256     // Issue a Cancel message
       
   257     TInt error = SendReceive( ECancelSettings );
       
   258     
       
   259     if ( error )
       
   260         {
       
   261         return error;
       
   262         }
       
   263         
       
   264     // Cancel the Active objects Request
       
   265     iLaunchAO->Cancel();
       
   266 
       
   267     // Delete the Server Exit monitor object before closing the 
       
   268     // server session.
       
   269     delete iSrvMonitor;
       
   270     iSrvMonitor = NULL;        
       
   271 
       
   272     // Delete the Server session
       
   273     RAknAppServiceBase::Close();
       
   274     
       
   275     // Set the Launch type so that next launchs will succeed
       
   276     iLaunchType = ELaunchNone;
       
   277     
       
   278     // Sets the Launch 
       
   279     // Complete the request with KErrCancel
       
   280     TRequestStatus*     status = iRequestStatus;
       
   281     User::RequestComplete( status, KErrCancel );
       
   282     
       
   283     return KErrNone;
       
   284     }
       
   285 
       
   286 // ---------------------------------------------------------------------------
       
   287 // Launch Positioning Settings UI in an ui app server
       
   288 // ---------------------------------------------------------------------------
       
   289 //
       
   290 void RLocSettingsUiService::LaunchPosSettingsL(
       
   291                                             TRequestStatus& aStatus )
       
   292     {
       
   293     // Check the presence of the Active Object
       
   294     if( NULL == iLaunchAO )
       
   295         {
       
   296         User::Leave( KErrNotFound );
       
   297         }
       
   298         
       
   299     // Check if there is any outstanding requests
       
   300     if( ELaunchNone != iLaunchType )
       
   301         {
       
   302         User::Leave( KErrInUse );
       
   303         }
       
   304     
       
   305     // Create the Server Session
       
   306     ConnectServerL();
       
   307     
       
   308     // Store the aStatus variable. This would be used to notify the caller
       
   309     // on completeion of the launch message
       
   310     iRequestStatus = &aStatus;  
       
   311     *iRequestStatus = KRequestPending;
       
   312     
       
   313     // Set request outstanding on the Active object
       
   314     iLaunchAO->SetRequestOutStandingL();
       
   315         
       
   316     // Compose the Message and Issue a Launch call to the server
       
   317     TRequestStatus&     status = iLaunchAO->GetStatusVariable();
       
   318     
       
   319     // Set the Launch Type and the Service state
       
   320     iLaunchType = ELaunchNormal;
       
   321     
       
   322 	SendReceive( ELaunchPosSettings, status );
       
   323     
       
   324     iSrvMonitor = NULL;
       
   325     }
       
   326     
       
   327 // ---------------------------------------------------------------------------
       
   328 // Launch Positioning Settings UI as an embesdded application
       
   329 // ---------------------------------------------------------------------------
       
   330 //
       
   331 void RLocSettingsUiService::LaunchPosSettingsAsEmbeddedAppL(
       
   332                                                 TRequestStatus& aStatus )
       
   333     {
       
   334     // Check the presence of the Active Object
       
   335     if( NULL == iLaunchAO )
       
   336         {
       
   337         User::Leave( KErrNotFound );
       
   338         }
       
   339         
       
   340     // Check if there is any outstanding requests
       
   341     if( ELaunchNone != iLaunchType )
       
   342         {
       
   343         User::Leave( KErrInUse );
       
   344         }
       
   345     
       
   346     // Create the Server Session
       
   347     ConnectChainedAppL( TUid::Uid( KLocSettingsUiServerUid ));
       
   348     
       
   349     // Store the aStatus variable. This would be used to notfy the caller
       
   350     // on completeion of the launch message
       
   351     iRequestStatus = &aStatus;  
       
   352     *iRequestStatus = KRequestPending;
       
   353     
       
   354     // Set request outstanding on the Active object
       
   355     iLaunchAO->SetRequestOutStandingL();
       
   356         
       
   357     // Compose the Message and Issue a Launch call to the server
       
   358     TRequestStatus&     status = iLaunchAO->GetStatusVariable();
       
   359     
       
   360     // Set the Launch Request Type and the Service state
       
   361     iLaunchType = ELaunchEmbedded;  
       
   362 
       
   363 	SendReceive( ELaunchPosSettings, status );
       
   364 
       
   365     iSrvMonitor = CApaServerAppExitMonitor::NewL(*this, 
       
   366                                                  *this,
       
   367                                                  CActive::EPriorityStandard);
       
   368     }
       
   369     
       
   370 // ---------------------------------------------------------------------------
       
   371 // Closes an already launched Positioning Settings UI.
       
   372 // ---------------------------------------------------------------------------
       
   373 //    
       
   374 TInt RLocSettingsUiService::ClosePosSettings()
       
   375     {
       
   376     // If no request is outstanding then this operation is not supported 
       
   377     // in this context
       
   378     if( ELaunchNone == iLaunchType )
       
   379         {
       
   380         return KErrNotSupported;
       
   381         }
       
   382     
       
   383     // Issue a Cancel message
       
   384     TInt error = SendReceive( ECancelPosSettings );
       
   385     
       
   386     if ( error )
       
   387         {
       
   388         return error;
       
   389         }
       
   390         
       
   391     // Cancel the Active objects Request
       
   392     iLaunchAO->Cancel();
       
   393 
       
   394     // Delete the Server Exit monitor object before closing the 
       
   395     // server session.
       
   396     delete iSrvMonitor;
       
   397     iSrvMonitor = NULL;        
       
   398 
       
   399     // Delete the Server session
       
   400     RAknAppServiceBase::Close();
       
   401     
       
   402     // Set the Launch type so that next launchs will succeed
       
   403     iLaunchType = ELaunchNone;
       
   404     
       
   405     // Sets the Launch 
       
   406     // Complete the request with KErrCancel
       
   407     TRequestStatus*     status = iRequestStatus;
       
   408     User::RequestComplete( status, KErrCancel );
       
   409     
       
   410     return KErrNone;
       
   411 
       
   412     }    
       
   413     
       
   414 // ---------------------------------------------------------------------------
       
   415 // Sets the Active Object used for issuing asynshronous requests
       
   416 // ---------------------------------------------------------------------------
       
   417 //
       
   418 void RLocSettingsUiService::SetLaunchAO( CLocLaunchUiAO*&      aLaunchAO )
       
   419     {
       
   420     iLaunchAO = aLaunchAO; 
       
   421     }
       
   422 
       
   423 // ---------------------------------------------------------------------------
       
   424 // Inherited from MLocLaunchUiObserver
       
   425 // ---------------------------------------------------------------------------
       
   426 //
       
   427 void RLocSettingsUiService::LaunchUiComplete( TInt    aError )
       
   428     {
       
   429     // When the server exits due to Exit Command it responds with
       
   430     // EEikCmdExit. In this case the actual Error Code is KErrNone.
       
   431     // This is needed when we have the  following scenario,
       
   432     // 1. If the user does a back from the plugin UI instead of exit,
       
   433     //    then the client library will have to delete the Server Monitor
       
   434     //    object.
       
   435     // 2. If the user does a Exit then the scenario will be handled in
       
   436     //    HandleServerAppExit.
       
   437     if ( EEikCmdExit != aError )
       
   438         {
       
   439         delete iSrvMonitor;
       
   440         iSrvMonitor = NULL;
       
   441 
       
   442         // Delete the Server session
       
   443         Close();
       
   444         }
       
   445     else
       
   446         {
       
   447         // In case the Error value is EEikCmdExit, change it to KErrNone.
       
   448         // The session and the Server Monitor object will be taken care of
       
   449         // by the HandleServerAppExit() which gets triggered by the Server
       
   450         // Exit.
       
   451         aError = KErrNone;
       
   452         }
       
   453 
       
   454     iLaunchType = ELaunchNone;
       
   455     TRequestStatus* status = iRequestStatus;
       
   456     User::RequestComplete( status, aError );
       
   457     }
       
   458 
       
   459 // ---------------------------------------------------------------------------
       
   460 // Returns the Service UID of requested service
       
   461 // ---------------------------------------------------------------------------
       
   462 //
       
   463 TUid RLocSettingsUiService::ServiceUid() const
       
   464     {
       
   465     return TUid::Uid( KLocSettingsUiServiceId );    
       
   466     }
       
   467 
       
   468 // ---------------------------------------------------------------------------
       
   469 // Receive event about server Exit. Triggered only for Embedded Launch case.
       
   470 // ---------------------------------------------------------------------------
       
   471 //
       
   472 void RLocSettingsUiService::HandleServerAppExit(TInt aReason)
       
   473     {
       
   474     // Delete the Server monitor object.
       
   475     delete iSrvMonitor;
       
   476     iSrvMonitor = NULL;
       
   477     // Delete the Server session
       
   478     Close();
       
   479     if ( EEikCmdExit == aReason )
       
   480         {
       
   481         // The base class implementation is a Series60 behaviour. Hence
       
   482         // it works only if the Command ID is EAknCmdExit. Whereas from the
       
   483         // Server side we exit only for EEikCmdExit. Hence this fix is
       
   484         // needed for the correct Exit behaviour for Embedded Launch scenario.
       
   485         aReason = EAknCmdExit;
       
   486         }
       
   487     // Base call the AvKon Implementation.
       
   488     MAknServerAppExitObserver::HandleServerAppExit(aReason);
       
   489     }
       
   490 
       
   491 
       
   492 // ---------------------------------------------------------------------------
       
   493 // Connects to a non embedded server instance.
       
   494 // ---------------------------------------------------------------------------
       
   495 //
       
   496 void RLocSettingsUiService::ConnectServerL()
       
   497     {
       
   498     TInt retry = KNumofConnectAttempts;
       
   499     TInt err = KErrNone;
       
   500 
       
   501     for (;;) // Forever
       
   502     	{
       
   503     	TUid    serviceuid = TUid::Uid( KLocSettingsUiServiceId );
       
   504     	TVersion*    version = reinterpret_cast< TVersion* >( &serviceuid );
       
   505     	err = CreateSession( KLocSettingsUiServerName, 
       
   506     	                     *version,
       
   507     	                     KDefaultMessageSlots );
       
   508     	if ( err != KErrNotFound && err != KErrServerTerminated )
       
   509     		{
       
   510     		break;
       
   511     		}
       
   512 
       
   513     	if ( --retry == 0 )
       
   514     		{
       
   515     		break;
       
   516     		}
       
   517 
       
   518     	err = StartServer();
       
   519 
       
   520     	if ( err != KErrAlreadyExists && err != KErrNone)
       
   521     		{
       
   522     		break;
       
   523     		}
       
   524     	}
       
   525     if( KErrNone != err )
       
   526         {
       
   527         User::Leave( err );
       
   528         }
       
   529     }
       
   530  
       
   531 // ---------------------------------------------------------------------------
       
   532 // Starts a new server instance
       
   533 // ---------------------------------------------------------------------------
       
   534 //   
       
   535 TInt RLocSettingsUiService::StartServer()
       
   536     {
       
   537     const TUidType serverUid(KNullUid, KNullUid, TUid::Uid( KLocSettingsUiServerUid ));
       
   538 
       
   539     // Simultaneous launching of two such processes should be detected 
       
   540     // when the second one attempts to create the server object, 
       
   541     // failing with KErrAlreadyExists.
       
   542     //
       
   543     RProcess server;
       
   544     TInt ret = server.Create( KLocSettingsUiServerExe, KNullDesC, serverUid );
       
   545 
       
   546     if (ret != KErrNone)
       
   547         {
       
   548         return ret;
       
   549         }
       
   550 
       
   551     TRequestStatus died;
       
   552     server.Rendezvous( died );
       
   553 
       
   554     if ( died != KRequestPending )
       
   555         {
       
   556         // logon failed - server is not yet running, so cannot have terminated
       
   557         User::WaitForRequest( died );           // eat signal
       
   558         server.Kill( 0 );                       // abort startup
       
   559         }
       
   560     else
       
   561         {
       
   562         server.Resume();
       
   563         User::WaitForRequest( died );           // wait for start or death
       
   564         }
       
   565 
       
   566     // we can't use the 'exit reason' if the server panicked as this
       
   567     // is the panic 'reason' and may be '0' which cannot be distinguished
       
   568     // from KErrNone
       
   569     ret = ( server.ExitType() == EExitPanic ) ? KErrGeneral : died.Int();
       
   570     server.Close();
       
   571     return ret;
       
   572     }