--- /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;
+ }