sl@0: /* sl@0: * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * Implements CUpsSession. See class and function definitions for sl@0: * more information. sl@0: * sl@0: */ sl@0: sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: #include "upsserver.h" sl@0: #include "policycache.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include "pluginmanager.h" sl@0: #include "viewevaluator.h" sl@0: #include "updateevaluator.h" sl@0: #include "policychangeevaluator.h" sl@0: sl@0: namespace UserPromptService sl@0: { sl@0: sl@0: CUpsSession* CUpsSession::NewL(CUpsServer &aServer) sl@0: /** sl@0: Factory function allocates new instance of CUpsSession. sl@0: sl@0: @return New, initialized instance of CUpsSession sl@0: which is owned by the caller. sl@0: */ sl@0: { sl@0: CUpsSession* self = new(ELeave) CUpsSession(aServer); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); // CScsSession implementation sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CUpsSession::CUpsSession(CUpsServer &aServer) sl@0: /** sl@0: This private constructor prevents direct instantiation. sl@0: */ sl@0: : CScsSession(aServer), iDbViewHandle(aServer.iDbHandle, this) sl@0: { sl@0: // empty. sl@0: //RDebug::Printf("0x%x CUpsSession(server %x) (&iDbViewHandle %x)\n", this, &aServer, &iDbViewHandle); sl@0: } sl@0: sl@0: CUpsSession::~CUpsSession() sl@0: /** sl@0: The base class destructor destroys any remaining subsessions sl@0: or outstanding requests. sl@0: */ sl@0: { sl@0: //RDebug::Printf("0x%x ~CUpsSession (&iDbViewHandle %x)\n", this, &iDbViewHandle); sl@0: CleanupView(); sl@0: iServiceConfig.Close(); sl@0: sl@0: iDbViewHandle.Close(); sl@0: } sl@0: sl@0: TBool CUpsSession::DoServiceL(TInt aFunction, const RMessage2& aMessage) sl@0: /** sl@0: Implement CScsSession by handling the supplied message. sl@0: sl@0: Note the subsession creation command is automatically sent to sl@0: DoCreateSubsessionL, and not this function. sl@0: sl@0: @param aFunction Function identifier without SCS code. sl@0: @param aMessage Standard server-side handle to message. Not used. sl@0: */ sl@0: { sl@0: TSessionFunction f = static_cast(aFunction); sl@0: //RDebug::Printf("0x%x CUpsSession::DoServiceL function %d\n", this, f); sl@0: switch (f) sl@0: { sl@0: case EGetClientConfigLength: sl@0: { sl@0: iServiceConfig.Close(); sl@0: UpsServer()->iPolicyCache->ServiceConfigL(aMessage.SecureId(), iServiceConfig); sl@0: sl@0: TPckgBuf lengthBuf; sl@0: lengthBuf() = iServiceConfig.Count(); sl@0: aMessage.WriteL(0, lengthBuf); sl@0: return ETrue; // Complete request with KErrNone sl@0: } sl@0: sl@0: case EGetClientConfigData: sl@0: { sl@0: TInt count = iServiceConfig.Count(); sl@0: for(TInt i=0; i < count; ++i) sl@0: { sl@0: const TServiceConfig &sc = iServiceConfig[i]; sl@0: TPtrC8 ptr((TUint8 *) &sc, sizeof(TServiceConfig)); sl@0: aMessage.WriteL(0, ptr, i*sizeof(TServiceConfig)); sl@0: } sl@0: iServiceConfig.Close(); sl@0: return ETrue; // Complete request with KErrNone sl@0: } sl@0: sl@0: case EDeleteDatabase: sl@0: TRAPD(err, UpsServer()->iDbHandle->DeleteDatabaseL(UpsServer()->iFs)); sl@0: UpsServer()->iDbHandle.Close(); sl@0: User::LeaveIfError(err); sl@0: return ETrue; // Complete request with KErrNone sl@0: sl@0: case ECreateView: sl@0: { sl@0: if(iManagementView != 0) sl@0: { sl@0: User::Leave(KErrServerBusy); sl@0: } sl@0: sl@0: CViewEvaluator *viewEvaluator = CViewEvaluator::NewLC(this, aMessage); sl@0: viewEvaluator->TransferToScsFrameworkL(); sl@0: CleanupStack::Pop(viewEvaluator); // view now owned by SCS framework sl@0: sl@0: /** sl@0: The CViewEvaluator is now responsible for completing the request, sl@0: so we must NOT leave. sl@0: */ sl@0: viewEvaluator->StartEvaluatingView(); sl@0: return EFalse; // Do not complete client request - view evaulator will... sl@0: } sl@0: sl@0: case ENextMatch: sl@0: { sl@0: if((iManagementView == 0) || (iRecord == 0)) sl@0: { sl@0: User::Leave(KErrAbort); sl@0: } sl@0: sl@0: // Copy the record to arg 0 sl@0: RIpcWriteStream ipcstream; sl@0: ipcstream.Open(aMessage, 0); sl@0: CleanupClosePushL(ipcstream); sl@0: sl@0: ipcstream << *iRecord; sl@0: sl@0: CleanupStack::PopAndDestroy(&ipcstream); sl@0: sl@0: // Update arg 1 with the length of the next record. sl@0: PrefetchRecordAndWriteLengthToClientL(aMessage); sl@0: return ETrue; // Complete client request with KErrNone sl@0: } sl@0: sl@0: case ECloseView: sl@0: { sl@0: CleanupView(); sl@0: return ETrue; // Complete client request with KErrNone sl@0: } sl@0: sl@0: case ERemoveDecisions: sl@0: { sl@0: // Read filter from the client arg 0 sl@0: RIpcReadStream ipcstream; sl@0: ipcstream.Open(aMessage, 0); sl@0: CleanupClosePushL(ipcstream); sl@0: CDecisionFilter *filter = CDecisionFilter::NewLC(); sl@0: ipcstream >> *filter; sl@0: sl@0: UpsServer()->iDbHandle->RemoveDecisionsL(*filter); sl@0: sl@0: CleanupStack::PopAndDestroy(filter); sl@0: CleanupStack::PopAndDestroy(&ipcstream); sl@0: return ETrue; // Complete client request with KErrNone sl@0: } sl@0: sl@0: case EUpdateDecision: sl@0: { sl@0: CUpdateEvaluator *updateEvaluator = CUpdateEvaluator::NewLC(this, aMessage); sl@0: updateEvaluator->TransferToScsFrameworkL(); sl@0: CleanupStack::Pop(updateEvaluator); // view now owned by SCS framework sl@0: sl@0: /** sl@0: The CViewEvaluator is now responsible for completing the request, sl@0: so we must NOT leave. sl@0: */ sl@0: updateEvaluator->StartUpdate(); sl@0: return EFalse; // Do not complete client request - view evaulator will... sl@0: } sl@0: sl@0: case EDeleteDecisionsForExe: sl@0: { sl@0: TUid exeSid; sl@0: exeSid.iUid = aMessage.Int0(); sl@0: sl@0: CDecisionFilter *filter = CDecisionFilter::NewLC(); sl@0: filter->SetClientSid(exeSid, EEqual); sl@0: sl@0: UpsServer()->iDbHandle->RemoveDecisionsL(*filter); sl@0: sl@0: CleanupStack::PopAndDestroy(filter); sl@0: sl@0: return ETrue; // Complete client request with KErrNone sl@0: } sl@0: sl@0: case ENotifyPluginsMayHaveChanged: sl@0: // Tell plugin manager to unload, and hence reload, plugins ASAP. sl@0: UpsServer()->iPluginManager->Unload(); sl@0: return ETrue; // Complete client request with KErrNone sl@0: sl@0: case ENotifyPolicyFilesChanged: sl@0: { sl@0: CPolicyChangeEvaluator *changeEvaluator = CPolicyChangeEvaluator::NewLC(UpsServer()->iPolicyCache, this, aMessage); sl@0: changeEvaluator->TransferToScsFrameworkL(); sl@0: CleanupStack::Pop(changeEvaluator); // Nnow owned by SCS framework sl@0: sl@0: /** sl@0: The CPolicyChangeEvaluator is now responsible for completing the request, sl@0: so we must NOT leave. sl@0: */ sl@0: changeEvaluator->StartUpdate(); sl@0: sl@0: // Release our reference to the policy cache sl@0: UpsServer()->iPolicyCache.Release(); sl@0: sl@0: return EFalse; // Do not complete client request - policy change evaluator will... sl@0: } sl@0: BULLSEYE_OFF sl@0: default: sl@0: break; sl@0: BULLSEYE_RESTORE sl@0: } sl@0: sl@0: BULLSEYE_OFF sl@0: User::Leave(KErrNotSupported); sl@0: /*lint -unreachable */ sl@0: return ETrue; sl@0: BULLSEYE_RESTORE sl@0: } sl@0: sl@0: CScsSubsession* CUpsSession::DoCreateSubsessionL(TInt aFunction, const RMessage2& aMessage) sl@0: /** sl@0: Override CScsSession by allocating a new subsession object. sl@0: sl@0: @param aFunction Function identifier without SCS code. sl@0: @param aMessage Standard server-side handle to message. Not used. sl@0: @return New, initialized instance of CUpsSubsession, which is sl@0: owned by the caller. sl@0: */ sl@0: { sl@0: TSessionFunction f = static_cast(aFunction); sl@0: sl@0: switch (f) sl@0: { sl@0: case ESessSubsessFromThreadId: sl@0: // create a subsession object curried on the supplied thread ID. sl@0: return CUpsSubsession::NewL(*this, aMessage); sl@0: sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: /*lint -unreachable */ sl@0: return 0; // avoid compiler warning sl@0: } sl@0: } sl@0: sl@0: void CUpsSession::PrefetchRecordAndWriteLengthToClientL(const RMessagePtr2& aMessage) sl@0: /** sl@0: Retrieve the next record from the iManagementView and return its length to the sl@0: client in arg 1. sl@0: */ sl@0: { sl@0: if(iManagementView == 0) sl@0: { sl@0: User::Leave(KErrEof); sl@0: } sl@0: sl@0: TPckgBuf nextRecordLenghthBuf; sl@0: sl@0: delete iRecord; sl@0: iRecord = 0; sl@0: TRAPD(err, iRecord = iManagementView->NextDecisionL()); sl@0: if((err != KErrNone) || (iRecord == 0)) sl@0: { sl@0: nextRecordLenghthBuf() = 0; sl@0: } sl@0: else sl@0: { sl@0: RNullWriteStream nullstream; sl@0: nullstream << *iRecord; sl@0: nextRecordLenghthBuf() = nullstream.BytesWritten(); sl@0: } sl@0: sl@0: aMessage.WriteL(1, nextRecordLenghthBuf); sl@0: } sl@0: sl@0: void CUpsSession::CleanupView() sl@0: /** sl@0: Cleanup view objects sl@0: */ sl@0: { sl@0: delete iManagementView; sl@0: iManagementView = 0; sl@0: delete iRecord; sl@0: iRecord = 0; sl@0: } sl@0: sl@0: void CUpsSession::DbHandleAboutToBeDeleted() sl@0: /** sl@0: Master DB handle is about to be deleted, so we must delete our view now. sl@0: This will also cause the next RUpsManageMent::NextMatchL call to leave. sl@0: */ sl@0: { sl@0: if(iManagementView) sl@0: { sl@0: iManagementView->Cancel(); sl@0: CleanupView(); sl@0: } sl@0: } sl@0: sl@0: } // End of namespace UserPromptService sl@0: // End of file