locationsystemui/locationsysui/locsettingsuiservice/locsettingsuiclient/src/locsettingsuiservice.cpp
changeset 0 667063e416a2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationsystemui/locationsysui/locsettingsuiservice/locsettingsuiclient/src/locsettingsuiservice.cpp	Tue Feb 02 01:06:48 2010 +0200
@@ -0,0 +1,572 @@
+/*
+* Copyright (c) 2005-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:  Client side resource handle to the UI Server
+*
+*/
+
+
+// System Includes
+#include <avkon.hrh>
+
+// User Includes
+#include "locsettingsuiservice.h"
+#include "loclaunchuiao.h"
+#include "locsettingsuiserverinterface.h"
+
+// Constant Declarations
+const TInt KNumofConnectAttempts = 200;
+    
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// C++ Default Constructor
+// ---------------------------------------------------------------------------
+//
+RLocSettingsUiService::RLocSettingsUiService()
+    :iLaunchAO( NULL ),
+    iRequestStatus( NULL ),
+    iLaunchType( ELaunchNone ),
+    iSrvMonitor( NULL )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// C++ Destructor
+// ---------------------------------------------------------------------------
+//
+RLocSettingsUiService::~RLocSettingsUiService()
+    {
+    if( ELaunchNone != iLaunchType )
+        {
+        CancelLaunchedSettingsUi();
+        }   
+    }
+
+// ---------------------------------------------------------------------------
+// Launch a Settings UI in an ui app server
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::LaunchSettingsUiL(
+                                    TUid            aImplementationUid,
+                                    TInt            aParams,
+                                    TRequestStatus& aStatus )
+    {
+    
+    // Check the presence of the Active Object
+    if( NULL == iLaunchAO )
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Check if there is any outstanding requests
+    if( ELaunchNone != iLaunchType )
+        {
+        User::Leave( KErrInUse );
+        }
+    
+    // Create the Server Session
+    ConnectServerL();
+    
+    // Store the aStatus variable. This would be used to notify the caller
+    // on completeion of the launch message
+    iRequestStatus = &aStatus;  
+    *iRequestStatus = KRequestPending;
+    
+    // Set request outstanding on the Active object
+    iLaunchAO->SetRequestOutStandingL();
+        
+    // Compose the Message and Issue a Launch call to the server
+    TRequestStatus&     status = iLaunchAO->GetStatusVariable();
+    
+    // Set the Launch Type and the Service state
+    iLaunchType = ELaunchNormal;
+                      
+    TIpcArgs args( aImplementationUid.iUid, aParams );
+    
+	SendReceive( ELaunchSettings, args, status );
+    
+    iSrvMonitor = NULL;
+    }
+    
+// ---------------------------------------------------------------------------
+// Launch a Settings UI as an embedded application
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::LaunchSettingsUiAsEmbeddedAppL(
+                                            TUid            aImplementationUid,
+                                            TInt            aParams,
+                                            TRequestStatus& aStatus )
+    {
+    
+    // Check the presence of the Active Object
+    if( NULL == iLaunchAO )
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Check if there is any outstanding requests
+    if( ELaunchNone != iLaunchType )
+        {
+        User::Leave( KErrInUse );
+        }
+    
+    // Create the Server Session
+    ConnectChainedAppL( TUid::Uid( KLocSettingsUiServerUid ));
+    
+    // Store the aStatus variable. This would be used to notfy the caller
+    // on completeion of the launch message
+    iRequestStatus = &aStatus;  
+    *iRequestStatus = KRequestPending;
+    
+    // Set request outstanding on the Active object
+    iLaunchAO->SetRequestOutStandingL();
+        
+    // Compose the Message and Issue a Launch call to the server
+    TRequestStatus&     status = iLaunchAO->GetStatusVariable();
+    
+    // Set the Launch Request Type and the Service state
+    iLaunchType = ELaunchEmbedded;  
+                      
+    TIpcArgs args( aImplementationUid.iUid, aParams );
+	SendReceive( ELaunchSettings, args, status );
+
+    iSrvMonitor = CApaServerAppExitMonitor::NewL(*this, 
+                                                 *this,
+                                                 CActive::EPriorityStandard);
+    }
+
+// ---------------------------------------------------------------------------
+// Launch a Settings UI in an ui app server
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::LaunchSettingsUiL(
+                                    TUid            aImplementationUid,
+                                    const TDesC&            aParamsString,
+                                    TRequestStatus& aStatus )
+    {
+    
+    // Check the presence of the Active Object
+    if( NULL == iLaunchAO )
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Check if there is any outstanding requests
+    if( ELaunchNone != iLaunchType )
+        {
+        User::Leave( KErrInUse );
+        }
+    
+    // Create the Server Session
+    ConnectServerL();
+    
+    // Store the aStatus variable. This would be used to notify the caller
+    // on completeion of the launch message
+    iRequestStatus = &aStatus;  
+    *iRequestStatus = KRequestPending;
+    
+    // Set request outstanding on the Active object
+    iLaunchAO->SetRequestOutStandingL();
+        
+    // Compose the Message and Issue a Launch call to the server
+    TRequestStatus&     status = iLaunchAO->GetStatusVariable();
+    
+    // Set the Launch Type and the Service state
+    iLaunchType = ELaunchNormal;
+                      
+    TIpcArgs args( aImplementationUid.iUid, aParamsString.Length(), &aParamsString );
+    
+	SendReceive( ELaunchSettingsWithString, args, status );
+    
+    iSrvMonitor = NULL;
+    }
+    
+// ---------------------------------------------------------------------------
+// Launch a Settings UI as an embedded application
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::LaunchSettingsUiAsEmbeddedAppL(
+                                            TUid            aImplementationUid,
+                                            const TDesC&            aParamsString,
+                                            TRequestStatus& aStatus )
+    {
+    
+    // Check the presence of the Active Object
+    if( NULL == iLaunchAO )
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Check if there is any outstanding requests
+    if( ELaunchNone != iLaunchType )
+        {
+        User::Leave( KErrInUse );
+        }
+    
+    // Create the Server Session
+    ConnectChainedAppL( TUid::Uid( KLocSettingsUiServerUid ));
+    
+    // Store the aStatus variable. This would be used to notfy the caller
+    // on completeion of the launch message
+    iRequestStatus = &aStatus;  
+    *iRequestStatus = KRequestPending;
+    
+    // Set request outstanding on the Active object
+    iLaunchAO->SetRequestOutStandingL();
+        
+    // Compose the Message and Issue a Launch call to the server
+    TRequestStatus&     status = iLaunchAO->GetStatusVariable();
+    
+    // Set the Launch Request Type and the Service state
+    iLaunchType = ELaunchEmbedded;  
+                      
+    TIpcArgs args( aImplementationUid.iUid, aParamsString.Length(), &aParamsString );
+    
+	SendReceive( ELaunchSettingsWithString, args, status );
+
+    iSrvMonitor = CApaServerAppExitMonitor::NewL(*this, 
+                                                 *this,
+                                                 CActive::EPriorityStandard);
+    }
+    
+// ---------------------------------------------------------------------------
+// Cancels a Launched request
+// ---------------------------------------------------------------------------
+//    
+TInt RLocSettingsUiService::CancelLaunchedSettingsUi()
+    {
+    // If no request is outstanding then this operation is not supported 
+    // in this context
+    if( ELaunchNone == iLaunchType )
+        {
+        return KErrNotSupported;
+        }
+    
+    // Issue a Cancel message
+    TInt error = SendReceive( ECancelSettings );
+    
+    if ( error )
+        {
+        return error;
+        }
+        
+    // Cancel the Active objects Request
+    iLaunchAO->Cancel();
+
+    // Delete the Server Exit monitor object before closing the 
+    // server session.
+    delete iSrvMonitor;
+    iSrvMonitor = NULL;        
+
+    // Delete the Server session
+    RAknAppServiceBase::Close();
+    
+    // Set the Launch type so that next launchs will succeed
+    iLaunchType = ELaunchNone;
+    
+    // Sets the Launch 
+    // Complete the request with KErrCancel
+    TRequestStatus*     status = iRequestStatus;
+    User::RequestComplete( status, KErrCancel );
+    
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Launch Positioning Settings UI in an ui app server
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::LaunchPosSettingsL(
+                                            TRequestStatus& aStatus )
+    {
+    // Check the presence of the Active Object
+    if( NULL == iLaunchAO )
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Check if there is any outstanding requests
+    if( ELaunchNone != iLaunchType )
+        {
+        User::Leave( KErrInUse );
+        }
+    
+    // Create the Server Session
+    ConnectServerL();
+    
+    // Store the aStatus variable. This would be used to notify the caller
+    // on completeion of the launch message
+    iRequestStatus = &aStatus;  
+    *iRequestStatus = KRequestPending;
+    
+    // Set request outstanding on the Active object
+    iLaunchAO->SetRequestOutStandingL();
+        
+    // Compose the Message and Issue a Launch call to the server
+    TRequestStatus&     status = iLaunchAO->GetStatusVariable();
+    
+    // Set the Launch Type and the Service state
+    iLaunchType = ELaunchNormal;
+    
+	SendReceive( ELaunchPosSettings, status );
+    
+    iSrvMonitor = NULL;
+    }
+    
+// ---------------------------------------------------------------------------
+// Launch Positioning Settings UI as an embesdded application
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::LaunchPosSettingsAsEmbeddedAppL(
+                                                TRequestStatus& aStatus )
+    {
+    // Check the presence of the Active Object
+    if( NULL == iLaunchAO )
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Check if there is any outstanding requests
+    if( ELaunchNone != iLaunchType )
+        {
+        User::Leave( KErrInUse );
+        }
+    
+    // Create the Server Session
+    ConnectChainedAppL( TUid::Uid( KLocSettingsUiServerUid ));
+    
+    // Store the aStatus variable. This would be used to notfy the caller
+    // on completeion of the launch message
+    iRequestStatus = &aStatus;  
+    *iRequestStatus = KRequestPending;
+    
+    // Set request outstanding on the Active object
+    iLaunchAO->SetRequestOutStandingL();
+        
+    // Compose the Message and Issue a Launch call to the server
+    TRequestStatus&     status = iLaunchAO->GetStatusVariable();
+    
+    // Set the Launch Request Type and the Service state
+    iLaunchType = ELaunchEmbedded;  
+
+	SendReceive( ELaunchPosSettings, status );
+
+    iSrvMonitor = CApaServerAppExitMonitor::NewL(*this, 
+                                                 *this,
+                                                 CActive::EPriorityStandard);
+    }
+    
+// ---------------------------------------------------------------------------
+// Closes an already launched Positioning Settings UI.
+// ---------------------------------------------------------------------------
+//    
+TInt RLocSettingsUiService::ClosePosSettings()
+    {
+    // If no request is outstanding then this operation is not supported 
+    // in this context
+    if( ELaunchNone == iLaunchType )
+        {
+        return KErrNotSupported;
+        }
+    
+    // Issue a Cancel message
+    TInt error = SendReceive( ECancelPosSettings );
+    
+    if ( error )
+        {
+        return error;
+        }
+        
+    // Cancel the Active objects Request
+    iLaunchAO->Cancel();
+
+    // Delete the Server Exit monitor object before closing the 
+    // server session.
+    delete iSrvMonitor;
+    iSrvMonitor = NULL;        
+
+    // Delete the Server session
+    RAknAppServiceBase::Close();
+    
+    // Set the Launch type so that next launchs will succeed
+    iLaunchType = ELaunchNone;
+    
+    // Sets the Launch 
+    // Complete the request with KErrCancel
+    TRequestStatus*     status = iRequestStatus;
+    User::RequestComplete( status, KErrCancel );
+    
+    return KErrNone;
+
+    }    
+    
+// ---------------------------------------------------------------------------
+// Sets the Active Object used for issuing asynshronous requests
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::SetLaunchAO( CLocLaunchUiAO*&      aLaunchAO )
+    {
+    iLaunchAO = aLaunchAO; 
+    }
+
+// ---------------------------------------------------------------------------
+// Inherited from MLocLaunchUiObserver
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::LaunchUiComplete( TInt    aError )
+    {
+    // When the server exits due to Exit Command it responds with
+    // EEikCmdExit. In this case the actual Error Code is KErrNone.
+    // This is needed when we have the  following scenario,
+    // 1. If the user does a back from the plugin UI instead of exit,
+    //    then the client library will have to delete the Server Monitor
+    //    object.
+    // 2. If the user does a Exit then the scenario will be handled in
+    //    HandleServerAppExit.
+    if ( EEikCmdExit != aError )
+        {
+        delete iSrvMonitor;
+        iSrvMonitor = NULL;
+
+        // Delete the Server session
+        Close();
+        }
+    else
+        {
+        // In case the Error value is EEikCmdExit, change it to KErrNone.
+        // The session and the Server Monitor object will be taken care of
+        // by the HandleServerAppExit() which gets triggered by the Server
+        // Exit.
+        aError = KErrNone;
+        }
+
+    iLaunchType = ELaunchNone;
+    TRequestStatus* status = iRequestStatus;
+    User::RequestComplete( status, aError );
+    }
+
+// ---------------------------------------------------------------------------
+// Returns the Service UID of requested service
+// ---------------------------------------------------------------------------
+//
+TUid RLocSettingsUiService::ServiceUid() const
+    {
+    return TUid::Uid( KLocSettingsUiServiceId );    
+    }
+
+// ---------------------------------------------------------------------------
+// Receive event about server Exit. Triggered only for Embedded Launch case.
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::HandleServerAppExit(TInt aReason)
+    {
+    // Delete the Server monitor object.
+    delete iSrvMonitor;
+    iSrvMonitor = NULL;
+    // Delete the Server session
+    Close();
+    if ( EEikCmdExit == aReason )
+        {
+        // The base class implementation is a Series60 behaviour. Hence
+        // it works only if the Command ID is EAknCmdExit. Whereas from the
+        // Server side we exit only for EEikCmdExit. Hence this fix is
+        // needed for the correct Exit behaviour for Embedded Launch scenario.
+        aReason = EAknCmdExit;
+        }
+    // Base call the AvKon Implementation.
+    MAknServerAppExitObserver::HandleServerAppExit(aReason);
+    }
+
+
+// ---------------------------------------------------------------------------
+// Connects to a non embedded server instance.
+// ---------------------------------------------------------------------------
+//
+void RLocSettingsUiService::ConnectServerL()
+    {
+    TInt retry = KNumofConnectAttempts;
+    TInt err = KErrNone;
+
+    for (;;) // Forever
+    	{
+    	TUid    serviceuid = TUid::Uid( KLocSettingsUiServiceId );
+    	TVersion*    version = reinterpret_cast< TVersion* >( &serviceuid );
+    	err = CreateSession( KLocSettingsUiServerName, 
+    	                     *version,
+    	                     KDefaultMessageSlots );
+    	if ( err != KErrNotFound && err != KErrServerTerminated )
+    		{
+    		break;
+    		}
+
+    	if ( --retry == 0 )
+    		{
+    		break;
+    		}
+
+    	err = StartServer();
+
+    	if ( err != KErrAlreadyExists && err != KErrNone)
+    		{
+    		break;
+    		}
+    	}
+    if( KErrNone != err )
+        {
+        User::Leave( err );
+        }
+    }
+ 
+// ---------------------------------------------------------------------------
+// Starts a new server instance
+// ---------------------------------------------------------------------------
+//   
+TInt RLocSettingsUiService::StartServer()
+    {
+    const TUidType serverUid(KNullUid, KNullUid, TUid::Uid( KLocSettingsUiServerUid ));
+
+    // Simultaneous launching of two such processes should be detected 
+    // when the second one attempts to create the server object, 
+    // failing with KErrAlreadyExists.
+    //
+    RProcess server;
+    TInt ret = server.Create( KLocSettingsUiServerExe, KNullDesC, serverUid );
+
+    if (ret != KErrNone)
+        {
+        return ret;
+        }
+
+    TRequestStatus died;
+    server.Rendezvous( died );
+
+    if ( died != KRequestPending )
+        {
+        // logon failed - server is not yet running, so cannot have terminated
+        User::WaitForRequest( died );           // eat signal
+        server.Kill( 0 );                       // abort startup
+        }
+    else
+        {
+        server.Resume();
+        User::WaitForRequest( died );           // wait for start or death
+        }
+
+    // we can't use the 'exit reason' if the server panicked as this
+    // is the panic 'reason' and may be '0' which cannot be distinguished
+    // from KErrNone
+    ret = ( server.ExitType() == EExitPanic ) ? KErrGeneral : died.Int();
+    server.Close();
+    return ret;
+    }