os/security/authorisation/userpromptservice/server/source/upsserver/upspolicycachehandle.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 * Implements the UPS database handle manager.	See class and function
    16 * definitions for more information.
    17 *
    18 */
    19 
    20 
    21 /**
    22  @file
    23 */
    24 #include <f32file.h>
    25 #include "upscommon.h"
    26 #include "policycache.h"
    27 #include "upspolicycachehandle.h"
    28 
    29 namespace UserPromptService
    30 {
    31 
    32 NONSHARABLE_CLASS(CPolicyCacheContainer) : public CBase
    33 	{
    34 public:
    35 	static CPolicyCacheContainer *NewL(RFs &aFs);
    36 
    37 	void IncrementReferenceCount();
    38 	void DecrementReferenceCount();
    39 	inline CPolicyCache *PolicyCache();
    40 
    41 	TInt ReferenceCount() const;
    42 
    43 	void NotifyOnRef1(TRequestStatus &aStatus);
    44 	void CancelNotifyOnRef1();
    45 
    46 private:
    47 	void ConstructL(RFs &aFs);
    48 	~CPolicyCacheContainer();
    49 	
    50 	TInt iReferenceCount;
    51 	CPolicyCache *iPolicyCache;
    52 	TRequestStatus *iClientRequest;
    53 	};
    54 
    55 inline CPolicyCache *CPolicyCacheContainer::PolicyCache()
    56 	{
    57 	ASSERT(iPolicyCache != 0);
    58 	return iPolicyCache;
    59 	}
    60 
    61 inline TInt CPolicyCacheContainer::ReferenceCount() const
    62 	{
    63 	return iReferenceCount;
    64 	}
    65 
    66 RPolicyCacheCountedHandle::RPolicyCacheCountedHandle(RFs &aFs)
    67 	: iFs(aFs), iContainer(0)
    68 	{
    69 	}
    70 
    71 RPolicyCacheCountedHandle::RPolicyCacheCountedHandle(RPolicyCacheCountedHandle &aPolicyCacheManager)
    72 	: iFs(aPolicyCacheManager.iFs), iContainer(0)
    73 	{
    74 	*this = aPolicyCacheManager;
    75 	}
    76 
    77 RPolicyCacheCountedHandle &RPolicyCacheCountedHandle::operator=(const RPolicyCacheCountedHandle &aRhs)
    78 	{
    79 	if(this == &aRhs) return *this;
    80 	
    81 	Release();
    82 
    83 	if(aRhs.iContainer)
    84 		{
    85 		iContainer = aRhs.iContainer;
    86 		iContainer->IncrementReferenceCount();
    87 		}
    88 	
    89 	return *this;
    90 	}
    91 
    92 RPolicyCacheCountedHandle::~RPolicyCacheCountedHandle()
    93 /**
    94 	Destructor - make sure cache container is released.
    95 */
    96 	{
    97 	Release();
    98 	}
    99 
   100 void RPolicyCacheCountedHandle::OpenL()
   101 /**
   102 	Create/Open a new policy cache. If this manager is already opened then the existing cache is
   103 	released first (see Release()).
   104 */
   105 	{
   106 	// First release any existing container/policy cache.
   107 	Release();
   108 
   109 	// Now create a new one
   110 	iContainer = CPolicyCacheContainer::NewL(iFs);
   111 	}
   112 
   113 void RPolicyCacheCountedHandle::Release()
   114 /**
   115 	Release the current policy cache container. If this decreases its reference count to 0, it will be
   116 	deleted.
   117 */
   118 	{
   119 	if(iContainer)
   120 		{
   121 		iContainer->DecrementReferenceCount();
   122 		iContainer = 0;
   123 		}
   124 	}
   125 
   126 TBool RPolicyCacheCountedHandle::IsOpen() const
   127 	{
   128 	return iContainer != 0;
   129 	}
   130 
   131 CPolicyCache *RPolicyCacheCountedHandle::operator->()
   132 /**
   133 	Returns the CPolicyCache ptr so -> can be used to call policy cache functions.
   134 
   135 	If the class is not already open, then we will attempt to open ourself using OpenL().
   136 
   137 	Note that this operator can leave...
   138 */
   139 	{
   140 	if(iContainer == 0)
   141 		{
   142 		OpenL();
   143 		ASSERT(iContainer);
   144 		}
   145 	return iContainer->PolicyCache();
   146 	}
   147 
   148 void RPolicyCacheCountedHandle::NotifyOnRef1(TRequestStatus &aStatus)
   149 /**
   150 	Register for notifcation when the underlying CPolicyCacheContainer reference
   151 	count reaches 1, presumably when the client holds the only reference.
   152 
   153 	Only one client is allowed to register against a single CPolicyCacheContainer.
   154 */
   155 	{
   156 	if((iContainer == 0) || (iContainer->ReferenceCount() <= 1))
   157 		{
   158 		// No container or ref count is 1, so complete now.
   159 		TRequestStatus *rs = &aStatus;
   160 		*rs = KRequestPending;
   161 		User::RequestComplete(rs, KErrNone);
   162 		return;
   163 		}
   164 	iContainer->NotifyOnRef1(aStatus);
   165 	}
   166 
   167 void RPolicyCacheCountedHandle::CancelNotifyOnRef1()
   168 /**
   169 	Cancel the call to NotifyOnRef1. The request will be completed immediately.
   170 */
   171 	{
   172 	if(!iContainer)
   173 		{
   174 		return;
   175 		}
   176 	iContainer->CancelNotifyOnRef1();
   177 	}
   178 
   179 CPolicyCacheContainer *CPolicyCacheContainer::NewL(RFs &aFs)
   180 /**
   181 	Create a CPolicyCacheContainer containing a CPolicyCache with a reference count of 1.
   182 */
   183 	{
   184 	CPolicyCacheContainer *self = new(ELeave) CPolicyCacheContainer();
   185 	CleanupStack::PushL(self);
   186 	self->ConstructL(aFs);
   187 	CleanupStack::Pop(self);
   188 	return self;
   189 	}
   190 
   191 void CPolicyCacheContainer::IncrementReferenceCount()
   192 /**
   193 	Increment the reference count.
   194 */
   195 	{
   196 	ASSERT(iReferenceCount > 0);
   197 	++iReferenceCount;
   198 	}
   199 
   200 void CPolicyCacheContainer::DecrementReferenceCount()
   201 /**
   202 	Decrement the reference count and delete self if it reaches 0.
   203 */
   204 	{
   205 	--iReferenceCount;
   206 	if(iReferenceCount <= 1)
   207 		{
   208 		if(iClientRequest && iClientRequest->Int() == KRequestPending)
   209 			{
   210 			User::RequestComplete(iClientRequest, KErrNone);
   211 			}
   212 		}
   213 
   214 	if(iReferenceCount <= 0)
   215 		{
   216 		delete this;
   217 		}
   218 	}
   219 
   220 void CPolicyCacheContainer::NotifyOnRef1(TRequestStatus &aStatus)
   221 /**
   222 	Register for notifcation when the reference count reduces to 1, presumably 
   223 	when the client holds the only reference.
   224 
   225 	Only one client is allowed to register against a single CPolicyCacheContainer.
   226 */
   227 	{
   228 	BULLSEYE_OFF
   229 	if(iClientRequest != 0)
   230 		{
   231 		TRequestStatus *rs = &aStatus;
   232 		*rs = KRequestPending;
   233 		User::RequestComplete(rs, KErrServerBusy);
   234 		return;
   235 		}
   236 	BULLSEYE_RESTORE
   237 
   238 	// Initialise client request
   239 	iClientRequest = &aStatus;
   240 	*iClientRequest = KRequestPending;
   241 
   242 	// Are we already at ref 1?
   243 	if(iReferenceCount <= 1)
   244 		{
   245 		User::RequestComplete(iClientRequest, KErrNone);
   246 		}
   247 	}
   248 
   249 void CPolicyCacheContainer::CancelNotifyOnRef1()
   250 /**
   251 	Cancel the previous call to NotifyOnRef1.
   252 */
   253 	{
   254 	if((iClientRequest != 0) && (iClientRequest->Int() == KRequestPending))
   255 		{
   256 		User::RequestComplete(iClientRequest, KErrCancel);
   257 		return;
   258 		}
   259 	}	
   260 
   261 void CPolicyCacheContainer::ConstructL(RFs &aFs)
   262 	{
   263 	_LIT(KPolicyDir,"\\private\\10283558\\policies\\");
   264 	iPolicyCache = CPolicyCache::NewL(aFs, KPolicyDir());
   265 	iReferenceCount = 1;
   266 	}
   267 
   268 CPolicyCacheContainer::~CPolicyCacheContainer()
   269 	{
   270 	delete iPolicyCache;
   271 	iPolicyCache = 0;
   272 
   273 	if(iClientRequest && iClientRequest->Int() == KRequestPending)
   274 		{
   275 		User::RequestComplete(iClientRequest, KErrNone);
   276 		iClientRequest = 0;
   277 		}
   278 	}
   279 
   280 } // End of UserPromptService namespace
   281 
   282 // End of file
   283