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 CViewEvaluator. 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: #include "upsserver.h" sl@0: #include "viewevaluator.h" sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace UserPromptService sl@0: { sl@0: inline CUpsSession *CViewEvaluator::UpsSession() sl@0: { sl@0: return static_cast(iSession); sl@0: } sl@0: sl@0: CViewEvaluator* CViewEvaluator::NewLC(CUpsSession* aSession, const RMessage2& aMessage) sl@0: { sl@0: CViewEvaluator* self = new(ELeave) CViewEvaluator(aSession, aMessage); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aMessage); sl@0: return self; sl@0: } sl@0: sl@0: CViewEvaluator::~CViewEvaluator() sl@0: /** sl@0: Normally cleanup should be done when DoCleanup function is called by the framework. sl@0: Sometime later, possibly after our parent CUpsSession has been deleted, this sl@0: destructor will be run. In this case the framework will have cleared our iSession variable sl@0: and we must do NOTHING. sl@0: sl@0: Unfortunately there is a special case where this object fails inside ConstructL, when we must do sl@0: some cleanup. We can detect this be seeing iSession (and hence UpsServer()) is non-NULL. sl@0: */ sl@0: { sl@0: CUpsSession *session = UpsSession(); sl@0: if(session) sl@0: { sl@0: /*lint -save -e1506 */ // ignore warning about calling virtual function in destructor sl@0: DoCleanup(); sl@0: /*lint -restore */ sl@0: } sl@0: } sl@0: sl@0: void CViewEvaluator::StartEvaluatingView() sl@0: /// Starts evaluating the database view sl@0: { sl@0: UpsSession()->iManagementView->EvaluateView(iStatus); sl@0: SetActive(); sl@0: } sl@0: sl@0: CViewEvaluator::CViewEvaluator(CUpsSession* aSession, const RMessage2& aMessage) sl@0: : CAsyncRequest(aSession, 0, aMessage) sl@0: { sl@0: } sl@0: sl@0: void CViewEvaluator::ConstructL(const RMessage2& aMessage) sl@0: { sl@0: // Read filter from the client 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: // Set the session slave DB handle callback to us, so we know if the handle is about to be sl@0: // deleted... sl@0: //RDebug::Printf("CViewEvaluator::ConstructL calling SetCallback(%x)\n", this); sl@0: UpsSession()->iDbViewHandle.SetCallback(this); sl@0: sl@0: // Create the CDecisionView object sl@0: // nb. We do not need to check iManagementView is NULL here because CUpsSession would have failed the request with KErrServerBusy if it were not. sl@0: UpsSession()->iManagementView = UpsSession()->iDbViewHandle->CreateViewL(*filter); sl@0: sl@0: CleanupStack::PopAndDestroy(filter); sl@0: CleanupStack::PopAndDestroy(&ipcstream); sl@0: } sl@0: sl@0: sl@0: void CViewEvaluator::DoCleanup() sl@0: /// implement CAsyncRequest sl@0: { sl@0: Cancel(); sl@0: // Reset slave DB handle callback to the session object sl@0: //RDebug::Printf("CViewEvaluator::DoCleanup - %x calling SetCallback(%x)\n", this, UpsSession()); sl@0: UpsSession()->iDbViewHandle.SetCallback(UpsSession()); sl@0: } sl@0: sl@0: void CViewEvaluator::DoCancel() sl@0: /// implement CActive - Cancel the database CreateView sl@0: { sl@0: CDecisionView *view = UpsSession()->iManagementView; sl@0: ASSERT(view != 0); sl@0: view->Cancel(); sl@0: sl@0: // Cancelled so cleanup view sl@0: UpsSession()->CleanupView(); sl@0: } sl@0: sl@0: sl@0: void CViewEvaluator::RunL() sl@0: /// implement CActive, override CAsyncRequset sl@0: { sl@0: User::LeaveIfError(iStatus.Int()); sl@0: UpsSession()->PrefetchRecordAndWriteLengthToClientL(iMessagePtr2); sl@0: CompleteAndMarkForDeletion(KErrNone); sl@0: } sl@0: sl@0: TInt CViewEvaluator::RunError(TInt aError) sl@0: { sl@0: // Something bad happened so delete the view objects sl@0: UpsSession()->CleanupView(); sl@0: return CAsyncRequest::RunError(aError); sl@0: } sl@0: sl@0: void CViewEvaluator::DbHandleAboutToBeDeleted() sl@0: /** sl@0: Called just before the master database handle is shut. sl@0: Need to cancel and cleanup/delete our view and fail the client request. sl@0: */ sl@0: { sl@0: // Make sure our request is cancelled sl@0: // If the view create is in progress, or has completed but our RunL hasn't had a chance to run yet, we will still be active sl@0: // so the DoCancel will get called and cleanup the view. sl@0: // If RunL fails, RunError will cleanup the view, if it completes we will no longer be registered to be called. sl@0: Cancel(); sl@0: sl@0: // Abort the client view request. sl@0: CompleteAndMarkForDeletion(KErrAbort); sl@0: } sl@0: } sl@0: // End of file