authorisation/userpromptservice/server/source/upsserver/upspolicycachehandle.cpp
changeset 8 35751d3474b7
equal deleted inserted replaced
2:675a964f4eb5 8:35751d3474b7
       
     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