diff -r 000000000000 -r 4e1aa6a622a0 sysstatemgmt/systemstatemgr/ssm/src/ssmserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysstatemgmt/systemstatemgr/ssm/src/ssmserver.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,277 @@ +// Copyright (c) 2008-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: +// + +#include +#include +#include + +#include "ssmserverpanic.h" +#include "ssmserver.h" +#include "ssmsession.h" +#include "ssmclisrv.h" +#include "clesessionproxy.h" +#include "ssmstatepolicyresolver.h" +#include "ssmstatetransitionengine.h" +#include "ssmstatepolicyresolverproxy.h" +#include "ssmstatetransitionrequest.h" +#include "ssmstatepolicyframe.h" +#include "ssmswppolicyresolver.h" +#include "ssmswprequesthandler.h" + +// ------------------- Policy Server Security Setup ---------------------- + +const TUint KRangeCount = 3; +const TInt KRanges[KRangeCount] = + { + 0, // op-code 0 not used + KSsmFirstUsedOpCode, //range: KFirstUsedSsmOpCode...(EEndOfSsmOpCodes-1) inclusive + EEndOfSsmOpCodes + }; + +/** + Specifies the appropriate action for each range in KRanges. + The nth element of KElementsIndex specifies the appropriate action for the nth range in KRanges. + */ +const TUint8 KElementsIndex[KRangeCount] = + { + CPolicyServer::ENotSupported, + CPolicyServer::EAlwaysPass, //All request will be accepted and passed on to policy DLL for security checks + CPolicyServer::ENotSupported, + }; + +/** + Setup a security policy that always allows connection requests for all requests. + */ +const CPolicyServer::TPolicy KSsmServerPolicy = + { + CPolicyServer::EAlwaysPass, // Always allow connection requests + KRangeCount, + KRanges, + KElementsIndex, + NULL + }; + +// ------------------- SsmServer Implementation ---------------------- + +/** + EPriorityHigh to make sure the server is always scheduled before other AO such + as CSsmStateTransitionEngine. + */ +CSsmServer::CSsmServer() : CPolicyServer(EPriorityHigh, KSsmServerPolicy) + { + } + +/** + */ +CSsmServer::~CSsmServer() + { + const TInt ignore = User::SetCritical(User::ENotCritical); + + delete iStateTransitionEngine; + delete iSwpRequestHandler; + delete iSwpResolver; + if(NULL != iSwpCleSession) + { + iSwpCleSession->ReleaseCle(); + } + + } //lint !e529 not subsequently referenced + +/** + */ +CSsmServer* CSsmServer::NewLC() + { + return CSsmServer::NewLC(ESsmStartup, EDoValidateCommandLists); + } + +/** + */ +CSsmServer* CSsmServer::NewLC(TUint16 aInitialState) + { + return CSsmServer::NewLC(aInitialState, EDoValidateCommandLists); + } + +/** + */ +CSsmServer* CSsmServer::NewLC(TUint16 aInitialState, TValidation aSetting) + { + CSsmServer* server = new(ELeave) CSsmServer(); + CleanupStack::PushL(server); + server->ConstructL(aInitialState, aSetting); + server->StartL(KSsmServerName); + return server; + } + +#ifdef TEST_SSM_SERVER +/** + Factory method used by automated tests to avoid clash with production server name. + */ +CSsmServer* CSsmServer::NewLC(const TDesC& aServerName, TUint16 aInitialState) + { + CSsmServer* server = new(ELeave) CSsmServer(); + CleanupStack::PushL(server); + server->ConstructL(aInitialState, ENoCommandListValidation); + server->StartL(aServerName); + return server; + } +#endif //TEST_SSM_SERVER +/** + */ +void CSsmServer::ConstructL(TUint16 aInitialState, TValidation aSetting) + { + __ASSERT_ALWAYS( KErrNone == User::SetCritical(User::ESystemCritical), PanicNow(KPanicSysStateMgr,ESsmServerError1)); + __ASSERT_ALWAYS( KErrNone == User::RenameThread(KSsmServerName), PanicNow(KPanicSysStateMgr,ESsmServerError2)); + + // --- Instantiate the "System State" handling classes --- + // Create a state policy resolver and load the initial policy + CSsmStatePolicyResolver* stateResolver = CSsmStatePolicyResolver::NewLC(); + const TSsmState initalState = TSsmState(aInitialState, KSsmAnySubState); + stateResolver->GetStatePolicyL(initalState); + CCleSessionProxy* stateCleSession = CCleSessionProxy::NewL(); + CleanupStack::PushL(stateCleSession); + // Create the state transition engine and let it take ownership of stateResolver and stateCleSession + iStateTransitionEngine = CSsmStateTransitionEngine::NewL(stateResolver, stateCleSession); + CleanupStack::Pop(2, stateResolver); + // Configure engine + iStateTransitionEngine->PerformCommandListValidation(EDoValidateCommandLists==aSetting); + + // --- Instantiate the SWP handling classes --- + iSwpResolver = CSsmSwpPolicyResolver::NewL(); + iSwpCleSession = CCleSessionProxy::NewL(); // Thought: Perhaps the CleSessionProxy should be a CLE session factory, thus allowing a separate session to be created for each engine + // Create the swp request handler and wire it up to the proxies + iSwpRequestHandler = CSsmSwpRequestHandler::NewL(); + iSwpRequestHandler->SetSwpPolicyResolverProxy(iSwpResolver); + iSwpRequestHandler->SetCleSessionProxy(iSwpCleSession); + iSwpRequestHandler->PerformCommandListValidation(EDoValidateCommandLists==aSetting); + + //Request initial actions + const TSsmStateTransition doStartup(initalState, 0); + iStateTransitionEngine->SubmitL(doStartup); + } + +/** + */ +CSession2* CSsmServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const + { + // Check we're the right version + TVersion version(KSsmServMajorVersionNumber,KSsmServMinorVersionNumber,KSsmServBuildVersionNumber); + if (!User::QueryVersionSupported(version,aVersion)) + { + User::Leave(KErrNotSupported); + } + + // version supported, go ahead + return CSsmSession::NewL(); + } + +/** + */ +void CSsmServer::RequestStateTransitionL(const TSsmState& aState, TInt aReason, const RMessage2& aMessage) + { + __ASSERT_DEBUG(iStateTransitionEngine, PanicNow(KPanicSysStateMgr,ESsmServerError3)); + + const TSsmStateTransition request(aState, aReason); + const MSsmStatePolicy::TResponse response = iStateTransitionEngine->TransitionAllowed(request, aMessage); + switch(response) + { + case MSsmStatePolicy::EDefinitelyAllowed: + case MSsmStatePolicy::ECurrentRemainReplaceQueued: + { + // A leave here will complete the client-request with KErrNoMemory + iStateTransitionEngine->SubmitL(request, aMessage); + break; + } + + case MSsmStatePolicy::EReplaceCurrentClearQueue: + { + iStateTransitionEngine->Cancel(NULL); + iStateTransitionEngine->SubmitL(request, aMessage); + break; + } + + case MSsmStatePolicy::ENotAllowed: + default: + { + aMessage.Complete(KErrNotSupported); + break; + } + } + } + +/** + Cancel any transition job that is accepted but not yet started. + */ +void CSsmServer::RequestStateTransitionCancel(CSession2* aSession) + { + iStateTransitionEngine->Cancel(aSession); + } + +/** + Initiate processing of the request for a system wide property change + */ +void CSsmServer::RequestSwpChangeL(const TSsmSwp& aSwp, const RMessage2& aMessage) + { + iSwpRequestHandler->SubmitRequestL(aSwp, aMessage); + } + +/** + Cancel processing of pending and running system wide property change requests + */ +void CSsmServer::RequestSwpChangeCancel(CSession2* aSession) + { + iSwpRequestHandler->Cancel(aSession); + } + +/** + Register the policy file name for this swp + This also marks the actual existence of the swp + */ +void CSsmServer::RequestRegisterSwpMappingL(TUint aSwpKey, const TDesC& aFilename) + { + iSwpResolver->RegisterSwpMappingL(aSwpKey, aFilename); + } //lint !e1746 Suppress parameter 'aSwpKey' could be made const reference + +/** + * Used only for testing purposes + * DeRegister the policy file name for this swp + */ +#ifdef _DEBUG +void CSsmServer::RequestDeRegisterSwpMappingL(TUint aSwpKey, const TDesC& aFilename) + { + iSwpResolver->DeRegisterSwpMappingL(aSwpKey, aFilename); + } +#endif + +/** + * Used only for testing purposes + * Cleanup Transition Engine after the test is over + */ +#ifdef _DEBUG +void CSsmServer::DoCleanupStateTransitionEngine() + { + iStateTransitionEngine->CleanupTransitionEngine(); + } +#endif + +/** + * Used only for testing purposes + * Cleanup Request Handler after the test is over + */ +#ifdef _DEBUG +void CSsmServer::DoCleanupSwpRequestHandler() + { + iSwpRequestHandler->CleanupSwpTransitionScheduler(); + } +#endif