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 the UPS database handle manager. See class and function sl@0: * definitions for more information. sl@0: * sl@0: */ sl@0: sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: #include sl@0: #include "upscommon.h" sl@0: #include "policycache.h" sl@0: #include "upspolicycachehandle.h" sl@0: sl@0: namespace UserPromptService sl@0: { sl@0: sl@0: NONSHARABLE_CLASS(CPolicyCacheContainer) : public CBase sl@0: { sl@0: public: sl@0: static CPolicyCacheContainer *NewL(RFs &aFs); sl@0: sl@0: void IncrementReferenceCount(); sl@0: void DecrementReferenceCount(); sl@0: inline CPolicyCache *PolicyCache(); sl@0: sl@0: TInt ReferenceCount() const; sl@0: sl@0: void NotifyOnRef1(TRequestStatus &aStatus); sl@0: void CancelNotifyOnRef1(); sl@0: sl@0: private: sl@0: void ConstructL(RFs &aFs); sl@0: ~CPolicyCacheContainer(); sl@0: sl@0: TInt iReferenceCount; sl@0: CPolicyCache *iPolicyCache; sl@0: TRequestStatus *iClientRequest; sl@0: }; sl@0: sl@0: inline CPolicyCache *CPolicyCacheContainer::PolicyCache() sl@0: { sl@0: ASSERT(iPolicyCache != 0); sl@0: return iPolicyCache; sl@0: } sl@0: sl@0: inline TInt CPolicyCacheContainer::ReferenceCount() const sl@0: { sl@0: return iReferenceCount; sl@0: } sl@0: sl@0: RPolicyCacheCountedHandle::RPolicyCacheCountedHandle(RFs &aFs) sl@0: : iFs(aFs), iContainer(0) sl@0: { sl@0: } sl@0: sl@0: RPolicyCacheCountedHandle::RPolicyCacheCountedHandle(RPolicyCacheCountedHandle &aPolicyCacheManager) sl@0: : iFs(aPolicyCacheManager.iFs), iContainer(0) sl@0: { sl@0: *this = aPolicyCacheManager; sl@0: } sl@0: sl@0: RPolicyCacheCountedHandle &RPolicyCacheCountedHandle::operator=(const RPolicyCacheCountedHandle &aRhs) sl@0: { sl@0: if(this == &aRhs) return *this; sl@0: sl@0: Release(); sl@0: sl@0: if(aRhs.iContainer) sl@0: { sl@0: iContainer = aRhs.iContainer; sl@0: iContainer->IncrementReferenceCount(); sl@0: } sl@0: sl@0: return *this; sl@0: } sl@0: sl@0: RPolicyCacheCountedHandle::~RPolicyCacheCountedHandle() sl@0: /** sl@0: Destructor - make sure cache container is released. sl@0: */ sl@0: { sl@0: Release(); sl@0: } sl@0: sl@0: void RPolicyCacheCountedHandle::OpenL() sl@0: /** sl@0: Create/Open a new policy cache. If this manager is already opened then the existing cache is sl@0: released first (see Release()). sl@0: */ sl@0: { sl@0: // First release any existing container/policy cache. sl@0: Release(); sl@0: sl@0: // Now create a new one sl@0: iContainer = CPolicyCacheContainer::NewL(iFs); sl@0: } sl@0: sl@0: void RPolicyCacheCountedHandle::Release() sl@0: /** sl@0: Release the current policy cache container. If this decreases its reference count to 0, it will be sl@0: deleted. sl@0: */ sl@0: { sl@0: if(iContainer) sl@0: { sl@0: iContainer->DecrementReferenceCount(); sl@0: iContainer = 0; sl@0: } sl@0: } sl@0: sl@0: TBool RPolicyCacheCountedHandle::IsOpen() const sl@0: { sl@0: return iContainer != 0; sl@0: } sl@0: sl@0: CPolicyCache *RPolicyCacheCountedHandle::operator->() sl@0: /** sl@0: Returns the CPolicyCache ptr so -> can be used to call policy cache functions. sl@0: sl@0: If the class is not already open, then we will attempt to open ourself using OpenL(). sl@0: sl@0: Note that this operator can leave... sl@0: */ sl@0: { sl@0: if(iContainer == 0) sl@0: { sl@0: OpenL(); sl@0: ASSERT(iContainer); sl@0: } sl@0: return iContainer->PolicyCache(); sl@0: } sl@0: sl@0: void RPolicyCacheCountedHandle::NotifyOnRef1(TRequestStatus &aStatus) sl@0: /** sl@0: Register for notifcation when the underlying CPolicyCacheContainer reference sl@0: count reaches 1, presumably when the client holds the only reference. sl@0: sl@0: Only one client is allowed to register against a single CPolicyCacheContainer. sl@0: */ sl@0: { sl@0: if((iContainer == 0) || (iContainer->ReferenceCount() <= 1)) sl@0: { sl@0: // No container or ref count is 1, so complete now. sl@0: TRequestStatus *rs = &aStatus; sl@0: *rs = KRequestPending; sl@0: User::RequestComplete(rs, KErrNone); sl@0: return; sl@0: } sl@0: iContainer->NotifyOnRef1(aStatus); sl@0: } sl@0: sl@0: void RPolicyCacheCountedHandle::CancelNotifyOnRef1() sl@0: /** sl@0: Cancel the call to NotifyOnRef1. The request will be completed immediately. sl@0: */ sl@0: { sl@0: if(!iContainer) sl@0: { sl@0: return; sl@0: } sl@0: iContainer->CancelNotifyOnRef1(); sl@0: } sl@0: sl@0: CPolicyCacheContainer *CPolicyCacheContainer::NewL(RFs &aFs) sl@0: /** sl@0: Create a CPolicyCacheContainer containing a CPolicyCache with a reference count of 1. sl@0: */ sl@0: { sl@0: CPolicyCacheContainer *self = new(ELeave) CPolicyCacheContainer(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aFs); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: void CPolicyCacheContainer::IncrementReferenceCount() sl@0: /** sl@0: Increment the reference count. sl@0: */ sl@0: { sl@0: ASSERT(iReferenceCount > 0); sl@0: ++iReferenceCount; sl@0: } sl@0: sl@0: void CPolicyCacheContainer::DecrementReferenceCount() sl@0: /** sl@0: Decrement the reference count and delete self if it reaches 0. sl@0: */ sl@0: { sl@0: --iReferenceCount; sl@0: if(iReferenceCount <= 1) sl@0: { sl@0: if(iClientRequest && iClientRequest->Int() == KRequestPending) sl@0: { sl@0: User::RequestComplete(iClientRequest, KErrNone); sl@0: } sl@0: } sl@0: sl@0: if(iReferenceCount <= 0) sl@0: { sl@0: delete this; sl@0: } sl@0: } sl@0: sl@0: void CPolicyCacheContainer::NotifyOnRef1(TRequestStatus &aStatus) sl@0: /** sl@0: Register for notifcation when the reference count reduces to 1, presumably sl@0: when the client holds the only reference. sl@0: sl@0: Only one client is allowed to register against a single CPolicyCacheContainer. sl@0: */ sl@0: { sl@0: BULLSEYE_OFF sl@0: if(iClientRequest != 0) sl@0: { sl@0: TRequestStatus *rs = &aStatus; sl@0: *rs = KRequestPending; sl@0: User::RequestComplete(rs, KErrServerBusy); sl@0: return; sl@0: } sl@0: BULLSEYE_RESTORE sl@0: sl@0: // Initialise client request sl@0: iClientRequest = &aStatus; sl@0: *iClientRequest = KRequestPending; sl@0: sl@0: // Are we already at ref 1? sl@0: if(iReferenceCount <= 1) sl@0: { sl@0: User::RequestComplete(iClientRequest, KErrNone); sl@0: } sl@0: } sl@0: sl@0: void CPolicyCacheContainer::CancelNotifyOnRef1() sl@0: /** sl@0: Cancel the previous call to NotifyOnRef1. sl@0: */ sl@0: { sl@0: if((iClientRequest != 0) && (iClientRequest->Int() == KRequestPending)) sl@0: { sl@0: User::RequestComplete(iClientRequest, KErrCancel); sl@0: return; sl@0: } sl@0: } sl@0: sl@0: void CPolicyCacheContainer::ConstructL(RFs &aFs) sl@0: { sl@0: _LIT(KPolicyDir,"\\private\\10283558\\policies\\"); sl@0: iPolicyCache = CPolicyCache::NewL(aFs, KPolicyDir()); sl@0: iReferenceCount = 1; sl@0: } sl@0: sl@0: CPolicyCacheContainer::~CPolicyCacheContainer() sl@0: { sl@0: delete iPolicyCache; sl@0: iPolicyCache = 0; sl@0: sl@0: if(iClientRequest && iClientRequest->Int() == KRequestPending) sl@0: { sl@0: User::RequestComplete(iClientRequest, KErrNone); sl@0: iClientRequest = 0; sl@0: } sl@0: } sl@0: sl@0: } // End of UserPromptService namespace sl@0: sl@0: // End of file sl@0: