authorisation/userpromptservice/server/source/upsserver/upspolicycachehandle.cpp
changeset 8 35751d3474b7
--- /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
+