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