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