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 CAuthoriser. See class and function definitions for
|
sl@0
|
16 |
* 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 |
|
sl@0
|
25 |
#include "upsserver.h"
|
sl@0
|
26 |
#include "policycache.h"
|
sl@0
|
27 |
#include "authoriser.h"
|
sl@0
|
28 |
#include <ups/upsdbw.h>
|
sl@0
|
29 |
#include "upslog.h"
|
sl@0
|
30 |
#include <ups/dialogcreator.h>
|
sl@0
|
31 |
#include <ups/policyevaluator.h>
|
sl@0
|
32 |
|
sl@0
|
33 |
namespace UserPromptService
|
sl@0
|
34 |
{
|
sl@0
|
35 |
|
sl@0
|
36 |
CAuthoriser* CAuthoriser::NewL(RPolicyCacheCountedHandle &aPolicyCache,
|
sl@0
|
37 |
CUpsSession* aSession, CUpsSubsession* aSubsession, TBool aServerCheckOk,
|
sl@0
|
38 |
TThreadId &aClientTid, TProcessId &aClientPId,
|
sl@0
|
39 |
const RMessage2& aMessage, const TServiceId& aServiceId,
|
sl@0
|
40 |
RBuf &aDestination, RBuf8 &aOpaqueData)
|
sl@0
|
41 |
/**
|
sl@0
|
42 |
Factory function allocates a new, initialized instance of CAuthoriser,
|
sl@0
|
43 |
registered for the supplied session and subsession.
|
sl@0
|
44 |
|
sl@0
|
45 |
If construction is successful, the caller should pass ownership to
|
sl@0
|
46 |
the SCS framework (TransferToScsFrameworkL), and pop the
|
sl@0
|
47 |
CAuthoriser from the cleanupstack. From this point onwards the
|
sl@0
|
48 |
request should be completed by the CAuthoriser/CAsyncRequst code,
|
sl@0
|
49 |
so the caller must not return or leave with any code except
|
sl@0
|
50 |
KErrScsSetupAsync. This is why the StartProcessingRequest function
|
sl@0
|
51 |
is defined as non-leaving.
|
sl@0
|
52 |
|
sl@0
|
53 |
@param aPolicyCache The server policy cache manager.
|
sl@0
|
54 |
@param aSession Session on which this request was launched.
|
sl@0
|
55 |
@param aSubsession Subsession on which this request was launched.
|
sl@0
|
56 |
@param aServerCheckOk Did the system server checks pass?
|
sl@0
|
57 |
@param aClientThread Handle to the user client thread.
|
sl@0
|
58 |
@param aMessage Standard server-side handle to message.
|
sl@0
|
59 |
@param aDestination We take ownership of the RBuf and close the callers handle
|
sl@0
|
60 |
@param aOpaqueData We take ownership of the RBuf and close the callers handle
|
sl@0
|
61 |
@return New, initialized instance of CAuthoriser, which
|
sl@0
|
62 |
is owned by the server's collection of outstanding
|
sl@0
|
63 |
requests.
|
sl@0
|
64 |
*/
|
sl@0
|
65 |
{
|
sl@0
|
66 |
CAuthoriser* self = new(ELeave) CAuthoriser(aPolicyCache, aSession, aSubsession, aMessage);
|
sl@0
|
67 |
CleanupStack::PushL(self);
|
sl@0
|
68 |
self->ConstructL(aServerCheckOk, aClientTid, aClientPId, aServiceId, aDestination, aOpaqueData);
|
sl@0
|
69 |
CleanupStack::Pop(self);
|
sl@0
|
70 |
return self;
|
sl@0
|
71 |
}
|
sl@0
|
72 |
|
sl@0
|
73 |
CAuthoriser::CAuthoriser(RPolicyCacheCountedHandle &aPolicyCache,
|
sl@0
|
74 |
CUpsSession* aSession, CUpsSubsession* aSubsession,
|
sl@0
|
75 |
const RMessage2& aMessage)
|
sl@0
|
76 |
/**
|
sl@0
|
77 |
This private constructor initializes the superclass and prevents direct instantiation.
|
sl@0
|
78 |
|
sl@0
|
79 |
@param aPolicyCache The server policy cache manager.
|
sl@0
|
80 |
@param aSession Session on which this request was launched.
|
sl@0
|
81 |
@param aSubsession Subsession on which this request was launched.
|
sl@0
|
82 |
@param aMessage Standard server-side handle to message.
|
sl@0
|
83 |
@param aDestination HBufC description, takes ownership.
|
sl@0
|
84 |
@param aOpaqueData 0 or HBufC opaqueData, takes ownership.
|
sl@0
|
85 |
*/
|
sl@0
|
86 |
: CAsyncRequest(aSession, aSubsession, aMessage),
|
sl@0
|
87 |
iPolicyCache(aPolicyCache)
|
sl@0
|
88 |
{
|
sl@0
|
89 |
// empty.
|
sl@0
|
90 |
}
|
sl@0
|
91 |
|
sl@0
|
92 |
void CAuthoriser::ConstructL(TBool aServerCheckOk, TThreadId &aClientTid, TProcessId &aClientPid, const TServiceId& aServiceId, RBuf &aDestination, RBuf8 &aOpaqueData)
|
sl@0
|
93 |
/**
|
sl@0
|
94 |
Second-phase constructor allocates the timer which is used to generate
|
sl@0
|
95 |
a delay, and adds this object to the server's collection of outstanding
|
sl@0
|
96 |
requests.
|
sl@0
|
97 |
*/
|
sl@0
|
98 |
{
|
sl@0
|
99 |
iState = ECheckPolicy;
|
sl@0
|
100 |
|
sl@0
|
101 |
RProcess clientProcess;
|
sl@0
|
102 |
TInt r = clientProcess.Open(aClientPid);
|
sl@0
|
103 |
if(r != KErrNone)
|
sl@0
|
104 |
{
|
sl@0
|
105 |
User::Leave(KErrUpsBadClientProcessId);
|
sl@0
|
106 |
}
|
sl@0
|
107 |
CleanupClosePushL(clientProcess);
|
sl@0
|
108 |
|
sl@0
|
109 |
// Create a CPromptReqest for the policy lookup
|
sl@0
|
110 |
iPromptRequest = CPromptRequest::NewL(clientProcess.SecureId(), // Client details
|
sl@0
|
111 |
clientProcess.VendorId(),
|
sl@0
|
112 |
aClientTid,
|
sl@0
|
113 |
aClientPid,
|
sl@0
|
114 |
iMessagePtr2.SecureId(), // Server SID
|
sl@0
|
115 |
aServiceId, // Server service ID
|
sl@0
|
116 |
aDestination, // Request detail, takes ownership
|
sl@0
|
117 |
aOpaqueData, // takes ownership
|
sl@0
|
118 |
aServerCheckOk);
|
sl@0
|
119 |
|
sl@0
|
120 |
CleanupStack::PopAndDestroy(&clientProcess);
|
sl@0
|
121 |
}
|
sl@0
|
122 |
|
sl@0
|
123 |
void CAuthoriser::ProcessEventL(TAuthoriserEvent aEvent)
|
sl@0
|
124 |
{
|
sl@0
|
125 |
// DEBUG_PRINTF4(_L8("0x%x CAuthoriser::ProcessEventL state %d, event %d\n"), this, iState, aEvent);
|
sl@0
|
126 |
_LIT(KServerPanicState, "UPS-ProcessEventL");
|
sl@0
|
127 |
switch(iState)
|
sl@0
|
128 |
{
|
sl@0
|
129 |
case ECheckPolicy:
|
sl@0
|
130 |
CheckPolicyStateL(aEvent);
|
sl@0
|
131 |
return;
|
sl@0
|
132 |
case ECreatingFingerprints:
|
sl@0
|
133 |
CreatingFingerprintsStateL(aEvent);
|
sl@0
|
134 |
return;
|
sl@0
|
135 |
case ECheckDatabase:
|
sl@0
|
136 |
CheckDatabaseStateL(aEvent);
|
sl@0
|
137 |
return;
|
sl@0
|
138 |
case EPreparingDialog:
|
sl@0
|
139 |
PreparingDialogStateL(aEvent);
|
sl@0
|
140 |
return;
|
sl@0
|
141 |
case EExecutingDialog:
|
sl@0
|
142 |
ExecutingDialogStateL(aEvent);
|
sl@0
|
143 |
return;
|
sl@0
|
144 |
BULLSEYE_OFF
|
sl@0
|
145 |
}
|
sl@0
|
146 |
|
sl@0
|
147 |
// Should not get here
|
sl@0
|
148 |
User::Panic(KServerPanicState, iState);
|
sl@0
|
149 |
BULLSEYE_RESTORE
|
sl@0
|
150 |
}
|
sl@0
|
151 |
|
sl@0
|
152 |
|
sl@0
|
153 |
void CAuthoriser::CheckPolicyStateL(TAuthoriserEvent aEvent)
|
sl@0
|
154 |
{
|
sl@0
|
155 |
switch(aEvent)
|
sl@0
|
156 |
{
|
sl@0
|
157 |
case EInternalRequestComplete:
|
sl@0
|
158 |
// Caused by the ups sub session code calling Wakeup
|
sl@0
|
159 |
// to start the request processing. We are now within the
|
sl@0
|
160 |
// active scheduler error handling framework.
|
sl@0
|
161 |
|
sl@0
|
162 |
// This call will lookup the policy and move to the next
|
sl@0
|
163 |
// state, or leave.
|
sl@0
|
164 |
LookupPolicyL();
|
sl@0
|
165 |
break;
|
sl@0
|
166 |
|
sl@0
|
167 |
BULLSEYE_OFF
|
sl@0
|
168 |
case EClearedToDisplayDialog:
|
sl@0
|
169 |
ASSERT(EFalse);
|
sl@0
|
170 |
break;
|
sl@0
|
171 |
BULLSEYE_RESTORE
|
sl@0
|
172 |
|
sl@0
|
173 |
case ECancel:
|
sl@0
|
174 |
// This WILL happen if am authorise request is made and immediately cancelled (before CAuthoriser::Runl has
|
sl@0
|
175 |
// the chance to run). We should complete our "fake" internal request so we do not block
|
sl@0
|
176 |
// when we return to the DoCancel/CActive::Cancel which caused this event.
|
sl@0
|
177 |
CompleteSelf();
|
sl@0
|
178 |
break;
|
sl@0
|
179 |
BULLSEYE_OFF
|
sl@0
|
180 |
}
|
sl@0
|
181 |
BULLSEYE_RESTORE
|
sl@0
|
182 |
}
|
sl@0
|
183 |
|
sl@0
|
184 |
void CAuthoriser::CreatingFingerprintsStateL(TAuthoriserEvent aEvent)
|
sl@0
|
185 |
{
|
sl@0
|
186 |
switch(aEvent)
|
sl@0
|
187 |
{
|
sl@0
|
188 |
case EInternalRequestComplete:
|
sl@0
|
189 |
// This will move to the next state and lookup the fingerprints, or leave.
|
sl@0
|
190 |
LookupFingerprintsL();
|
sl@0
|
191 |
break;
|
sl@0
|
192 |
|
sl@0
|
193 |
BULLSEYE_OFF
|
sl@0
|
194 |
case EClearedToDisplayDialog:
|
sl@0
|
195 |
ASSERT(EFalse);
|
sl@0
|
196 |
break;
|
sl@0
|
197 |
BULLSEYE_RESTORE
|
sl@0
|
198 |
|
sl@0
|
199 |
case ECancel:
|
sl@0
|
200 |
// Cancel the request to create the fingerprints
|
sl@0
|
201 |
iPolicyEvaluator->Imp().Cancel();
|
sl@0
|
202 |
break;
|
sl@0
|
203 |
BULLSEYE_OFF
|
sl@0
|
204 |
}
|
sl@0
|
205 |
BULLSEYE_RESTORE
|
sl@0
|
206 |
}
|
sl@0
|
207 |
|
sl@0
|
208 |
void CAuthoriser::CheckDatabaseStateL(TAuthoriserEvent aEvent)
|
sl@0
|
209 |
{
|
sl@0
|
210 |
switch(aEvent)
|
sl@0
|
211 |
{
|
sl@0
|
212 |
case EInternalRequestComplete:
|
sl@0
|
213 |
// Normally the create fingerprints state code will call
|
sl@0
|
214 |
// LookupFingerprintsL to move to this state and do the
|
sl@0
|
215 |
// lookup, but if we need to re-lookup the fingerprints a
|
sl@0
|
216 |
// "fake" request will be issued and this code will be
|
sl@0
|
217 |
// used.
|
sl@0
|
218 |
LookupFingerprintsL();
|
sl@0
|
219 |
break;
|
sl@0
|
220 |
case EClearedToDisplayDialog:
|
sl@0
|
221 |
// Change state and ask the dialog creator to start creating
|
sl@0
|
222 |
// the dialog, or leave.
|
sl@0
|
223 |
PrepareDialogL();
|
sl@0
|
224 |
break;
|
sl@0
|
225 |
case ECancel:
|
sl@0
|
226 |
// Complete the fake request which was issued to try and
|
sl@0
|
227 |
// get us to redo the fingerprint lookup.
|
sl@0
|
228 |
CompleteSelf();
|
sl@0
|
229 |
break;
|
sl@0
|
230 |
BULLSEYE_OFF
|
sl@0
|
231 |
}
|
sl@0
|
232 |
BULLSEYE_RESTORE
|
sl@0
|
233 |
}
|
sl@0
|
234 |
|
sl@0
|
235 |
void CAuthoriser::PreparingDialogStateL(TAuthoriserEvent aEvent)
|
sl@0
|
236 |
{
|
sl@0
|
237 |
switch(aEvent)
|
sl@0
|
238 |
{
|
sl@0
|
239 |
case EInternalRequestComplete:
|
sl@0
|
240 |
// Created dialog, now change state to execute and display
|
sl@0
|
241 |
// it.
|
sl@0
|
242 |
ExecuteDialogL();
|
sl@0
|
243 |
break;
|
sl@0
|
244 |
|
sl@0
|
245 |
BULLSEYE_OFF
|
sl@0
|
246 |
case EClearedToDisplayDialog:
|
sl@0
|
247 |
ASSERT(EFalse);
|
sl@0
|
248 |
break;
|
sl@0
|
249 |
BULLSEYE_RESTORE
|
sl@0
|
250 |
|
sl@0
|
251 |
case ECancel:
|
sl@0
|
252 |
// Cancel the request to create the dialog
|
sl@0
|
253 |
iDialogCreator->Imp().Cancel();
|
sl@0
|
254 |
break;
|
sl@0
|
255 |
BULLSEYE_OFF
|
sl@0
|
256 |
}
|
sl@0
|
257 |
BULLSEYE_RESTORE
|
sl@0
|
258 |
}
|
sl@0
|
259 |
|
sl@0
|
260 |
void CAuthoriser::ExecutingDialogStateL(TAuthoriserEvent aEvent)
|
sl@0
|
261 |
{
|
sl@0
|
262 |
switch(aEvent)
|
sl@0
|
263 |
{
|
sl@0
|
264 |
case EInternalRequestComplete:
|
sl@0
|
265 |
// Dialog complete, process the result and complete the
|
sl@0
|
266 |
// client request.
|
sl@0
|
267 |
ProcessDialogResultL();
|
sl@0
|
268 |
break;
|
sl@0
|
269 |
|
sl@0
|
270 |
BULLSEYE_OFF
|
sl@0
|
271 |
case EClearedToDisplayDialog:
|
sl@0
|
272 |
ASSERT(EFalse);
|
sl@0
|
273 |
break;
|
sl@0
|
274 |
BULLSEYE_RESTORE
|
sl@0
|
275 |
|
sl@0
|
276 |
case ECancel:
|
sl@0
|
277 |
// Cancel the request to execute the dialog
|
sl@0
|
278 |
iDialogCreator->Imp().Cancel();
|
sl@0
|
279 |
break;
|
sl@0
|
280 |
BULLSEYE_OFF
|
sl@0
|
281 |
}
|
sl@0
|
282 |
BULLSEYE_RESTORE
|
sl@0
|
283 |
}
|
sl@0
|
284 |
|
sl@0
|
285 |
void CAuthoriser::Wakeup()
|
sl@0
|
286 |
/**
|
sl@0
|
287 |
Raise and complete a request against self. Will cause RunL to
|
sl@0
|
288 |
be run within the active scheduler.
|
sl@0
|
289 |
*/
|
sl@0
|
290 |
{
|
sl@0
|
291 |
iStatus = KRequestPending;
|
sl@0
|
292 |
SetActive();
|
sl@0
|
293 |
CompleteSelf();
|
sl@0
|
294 |
}
|
sl@0
|
295 |
|
sl@0
|
296 |
void CAuthoriser::CompleteSelf()
|
sl@0
|
297 |
{
|
sl@0
|
298 |
_LIT(KServerPanicState, "UPS-CompleteSelf");
|
sl@0
|
299 |
switch(iState)
|
sl@0
|
300 |
{
|
sl@0
|
301 |
case ECheckPolicy:
|
sl@0
|
302 |
case ECheckDatabase:
|
sl@0
|
303 |
break;
|
sl@0
|
304 |
|
sl@0
|
305 |
BULLSEYE_OFF
|
sl@0
|
306 |
case ECreatingFingerprints:
|
sl@0
|
307 |
case EPreparingDialog:
|
sl@0
|
308 |
case EExecutingDialog:
|
sl@0
|
309 |
User::Panic(KServerPanicState, iState);
|
sl@0
|
310 |
/*lint -unreachable */
|
sl@0
|
311 |
return; // Not legal in these states
|
sl@0
|
312 |
}
|
sl@0
|
313 |
BULLSEYE_RESTORE
|
sl@0
|
314 |
|
sl@0
|
315 |
if(iStatus == KRequestPending)
|
sl@0
|
316 |
{
|
sl@0
|
317 |
TRequestStatus *status = &iStatus;
|
sl@0
|
318 |
User::RequestComplete(status, KErrNone);
|
sl@0
|
319 |
}
|
sl@0
|
320 |
}
|
sl@0
|
321 |
|
sl@0
|
322 |
|
sl@0
|
323 |
|
sl@0
|
324 |
void CAuthoriser::ClearedToDisplayL()
|
sl@0
|
325 |
/**
|
sl@0
|
326 |
The UPS server GateKeeper has granted us permission to proceed
|
sl@0
|
327 |
with dialog generation and display.
|
sl@0
|
328 |
*/
|
sl@0
|
329 |
{
|
sl@0
|
330 |
ProcessEventL(EClearedToDisplayDialog);
|
sl@0
|
331 |
}
|
sl@0
|
332 |
|
sl@0
|
333 |
|
sl@0
|
334 |
|
sl@0
|
335 |
|
sl@0
|
336 |
|
sl@0
|
337 |
|
sl@0
|
338 |
CAuthoriser::~CAuthoriser()
|
sl@0
|
339 |
/**
|
sl@0
|
340 |
Close the timer which was initialized in ConstructL.
|
sl@0
|
341 |
*/
|
sl@0
|
342 |
{
|
sl@0
|
343 |
iDialogFingerprint = 0; // MUST not delete, owned by CDialogCreator
|
sl@0
|
344 |
|
sl@0
|
345 |
delete iDialogCreator;
|
sl@0
|
346 |
iDialogCreator = 0;
|
sl@0
|
347 |
|
sl@0
|
348 |
iDialogCreatorParams = 0; // MUST not delete, owned by evaluator
|
sl@0
|
349 |
|
sl@0
|
350 |
iClientEntity = 0; // MUST not delete, owned by evaluator
|
sl@0
|
351 |
|
sl@0
|
352 |
iFingerprints.ResetAndDestroy();
|
sl@0
|
353 |
|
sl@0
|
354 |
delete iPolicyEvaluator;
|
sl@0
|
355 |
iPolicyEvaluator = 0;
|
sl@0
|
356 |
|
sl@0
|
357 |
iPolicyCache.Release();
|
sl@0
|
358 |
iPolicy = 0; // MUST not delete, ownded by policy cache
|
sl@0
|
359 |
|
sl@0
|
360 |
delete iPromptRequest;
|
sl@0
|
361 |
iPromptRequest = 0;
|
sl@0
|
362 |
}
|
sl@0
|
363 |
|
sl@0
|
364 |
void CAuthoriser::RunL()
|
sl@0
|
365 |
{
|
sl@0
|
366 |
// Wake up the next pending request now (if any), to make sure it
|
sl@0
|
367 |
// will be processed ahead of any incoming requests.
|
sl@0
|
368 |
UpsServer()->WakeupNextPendingL();
|
sl@0
|
369 |
|
sl@0
|
370 |
// Reset our priority to standard
|
sl@0
|
371 |
if(Priority() != CActive::EPriorityStandard)
|
sl@0
|
372 |
{
|
sl@0
|
373 |
SetPriority(CActive::EPriorityStandard);
|
sl@0
|
374 |
}
|
sl@0
|
375 |
User::LeaveIfError(iStatus.Int());
|
sl@0
|
376 |
|
sl@0
|
377 |
ProcessEventL(EInternalRequestComplete);
|
sl@0
|
378 |
}
|
sl@0
|
379 |
|
sl@0
|
380 |
|
sl@0
|
381 |
void CAuthoriser::DoCleanup()
|
sl@0
|
382 |
{
|
sl@0
|
383 |
if(iPromptForced)
|
sl@0
|
384 |
{
|
sl@0
|
385 |
// Have previously called ForcePromptL on a database record and it told us to
|
sl@0
|
386 |
// prompt, so have previously marked the record as disputed.
|
sl@0
|
387 |
TRAP_IGNORE(UpsServer()->UnDisputeRecordIdL(iPromptForcedRecordId));
|
sl@0
|
388 |
iPromptForced = EFalse;
|
sl@0
|
389 |
}
|
sl@0
|
390 |
|
sl@0
|
391 |
// Cancel current internal operation
|
sl@0
|
392 |
Cancel();
|
sl@0
|
393 |
|
sl@0
|
394 |
// Let the server know we are done
|
sl@0
|
395 |
UpsServer()->AuthoriserDone(this);
|
sl@0
|
396 |
|
sl@0
|
397 |
// The framework will complete the client request and schedule us
|
sl@0
|
398 |
// for deletion.
|
sl@0
|
399 |
}
|
sl@0
|
400 |
|
sl@0
|
401 |
|
sl@0
|
402 |
|
sl@0
|
403 |
|
sl@0
|
404 |
void CAuthoriser::DoCancel()
|
sl@0
|
405 |
/**
|
sl@0
|
406 |
Cancel the current operation. This does not complete the client
|
sl@0
|
407 |
request or mark this object for deletion.
|
sl@0
|
408 |
*/
|
sl@0
|
409 |
{
|
sl@0
|
410 |
TRAP_IGNORE(
|
sl@0
|
411 |
// Wake up the next pending request now (if any), to make sure it
|
sl@0
|
412 |
// will be processed ahead of any incoming requests.
|
sl@0
|
413 |
UpsServer()->WakeupNextPendingL();
|
sl@0
|
414 |
ProcessEventL(ECancel);
|
sl@0
|
415 |
);
|
sl@0
|
416 |
}
|
sl@0
|
417 |
|
sl@0
|
418 |
void CAuthoriser::LookupPolicyL()
|
sl@0
|
419 |
{
|
sl@0
|
420 |
// This returns a ptr into the cache, so we have to be careful not to use it after the cache is deleted.
|
sl@0
|
421 |
// This is why we wrap the cache in a RPolicyCacheCountedHandle.
|
sl@0
|
422 |
iPolicy = iPolicyCache->MatchL(*iPromptRequest);
|
sl@0
|
423 |
|
sl@0
|
424 |
ASSERT(iPolicy);
|
sl@0
|
425 |
|
sl@0
|
426 |
if(iPolicy->PromptRequired())
|
sl@0
|
427 |
{
|
sl@0
|
428 |
// Policy contains both yes and no responses...
|
sl@0
|
429 |
// Start creating the fingerprints
|
sl@0
|
430 |
CreateFingerprintsL();
|
sl@0
|
431 |
return;
|
sl@0
|
432 |
}
|
sl@0
|
433 |
|
sl@0
|
434 |
// Return result to system server
|
sl@0
|
435 |
TUpsDecisionPckgBuf decisionBuf;
|
sl@0
|
436 |
decisionBuf() = MapCPolicyTOptions2TUpsDecision(iPolicy->Options());
|
sl@0
|
437 |
iMessagePtr2.WriteL(0, decisionBuf);
|
sl@0
|
438 |
|
sl@0
|
439 |
CompleteAndMarkForDeletion(KErrNone);
|
sl@0
|
440 |
}
|
sl@0
|
441 |
|
sl@0
|
442 |
|
sl@0
|
443 |
void CAuthoriser::CreateFingerprintsL()
|
sl@0
|
444 |
/**
|
sl@0
|
445 |
Load Policy Evaluator and tell it to start generating the fingerprints
|
sl@0
|
446 |
*/
|
sl@0
|
447 |
{
|
sl@0
|
448 |
iState = ECreatingFingerprints;
|
sl@0
|
449 |
|
sl@0
|
450 |
iPolicyEvaluator = UpsServer()->iPluginManager->CreateEvaluatorL(iPolicy->PolicyEvaluator());
|
sl@0
|
451 |
|
sl@0
|
452 |
iPolicyEvaluator->Imp().GenerateFingerprints(*iPromptRequest, *iPolicy,
|
sl@0
|
453 |
iFingerprints, iClientEntity, iDialogCreatorParams, iStatus);
|
sl@0
|
454 |
|
sl@0
|
455 |
SetActive();
|
sl@0
|
456 |
}
|
sl@0
|
457 |
|
sl@0
|
458 |
_LIT8(KDefaultFingerprint,"*");
|
sl@0
|
459 |
//_LIT(KServerPanicDb, "UPS-BadDB");
|
sl@0
|
460 |
static const char * const KCorruptDb = "UPS-BadDB error=%d line=%d\n";
|
sl@0
|
461 |
|
sl@0
|
462 |
void CAuthoriser::LookupFingerprintsL()
|
sl@0
|
463 |
{
|
sl@0
|
464 |
// Lookup in DB
|
sl@0
|
465 |
iState = ECheckDatabase;
|
sl@0
|
466 |
|
sl@0
|
467 |
TPtrC8 clientEntityName(KNullDesC8());
|
sl@0
|
468 |
if(iClientEntity)
|
sl@0
|
469 |
{
|
sl@0
|
470 |
clientEntityName.Set(iClientEntity->Name());
|
sl@0
|
471 |
}
|
sl@0
|
472 |
|
sl@0
|
473 |
CDecisionFilter *filter = CDecisionFilter::NewLC(iPromptRequest->ClientSid(),
|
sl@0
|
474 |
iPolicy->PolicyEvaluator(),
|
sl@0
|
475 |
iPromptRequest->ServiceId(),
|
sl@0
|
476 |
iPromptRequest->ServerSid(),
|
sl@0
|
477 |
KDefaultFingerprint(),
|
sl@0
|
478 |
clientEntityName,
|
sl@0
|
479 |
iPolicy->MajorVersion());
|
sl@0
|
480 |
//
|
sl@0
|
481 |
// Lookup the fingerprints in the DB and return the first match
|
sl@0
|
482 |
//
|
sl@0
|
483 |
CDecisionRecord *record = 0;
|
sl@0
|
484 |
TInt fingerprintCount = iFingerprints.Count();
|
sl@0
|
485 |
for(TInt i=0; i<fingerprintCount; ++i)
|
sl@0
|
486 |
{
|
sl@0
|
487 |
filter->SetFingerprintL(iFingerprints[i]->Fingerprint(), EEqual);
|
sl@0
|
488 |
record = 0;
|
sl@0
|
489 |
TRAPD(err, record = UpsServer()->iDbHandle->GetDecisionL(*filter));
|
sl@0
|
490 |
if(err != KErrNone)
|
sl@0
|
491 |
{
|
sl@0
|
492 |
HandleDbErrorL(err);
|
sl@0
|
493 |
}
|
sl@0
|
494 |
|
sl@0
|
495 |
if(record)
|
sl@0
|
496 |
{
|
sl@0
|
497 |
break;
|
sl@0
|
498 |
}
|
sl@0
|
499 |
}
|
sl@0
|
500 |
|
sl@0
|
501 |
if(record)
|
sl@0
|
502 |
{
|
sl@0
|
503 |
// Found record
|
sl@0
|
504 |
CleanupStack::PushL(record);
|
sl@0
|
505 |
// Read current eval info value from record.
|
sl@0
|
506 |
iDialogEvaluatorInfo = record->iEvaluatorInfo;
|
sl@0
|
507 |
|
sl@0
|
508 |
if(UpsServer()->IsRecordIdDisputed(record->iRecordId))
|
sl@0
|
509 |
{
|
sl@0
|
510 |
// Matching record is under dispute so a dialog must be in progress.
|
sl@0
|
511 |
// Queue for later re-evaluation.
|
sl@0
|
512 |
UpsServer()->GateKeeperL(this);
|
sl@0
|
513 |
return;
|
sl@0
|
514 |
}
|
sl@0
|
515 |
|
sl@0
|
516 |
if(iPromptForced && (record->iRecordId != iPromptForcedRecordId))
|
sl@0
|
517 |
{
|
sl@0
|
518 |
// Have previously called ForcePromptL on a database record and it told us to
|
sl@0
|
519 |
// prompt, BUT we have now matched a different record ID! Presumably
|
sl@0
|
520 |
// someone else overwrote or deleted our record....
|
sl@0
|
521 |
//
|
sl@0
|
522 |
// We need to undispute the old record id and continue as if ForcePromptL had
|
sl@0
|
523 |
// never been called/returned yes.
|
sl@0
|
524 |
iPromptForced = EFalse;
|
sl@0
|
525 |
UpsServer()->UnDisputeRecordIdL(iPromptForcedRecordId);
|
sl@0
|
526 |
}
|
sl@0
|
527 |
|
sl@0
|
528 |
// Call ForcePrompt to see if we need to prompt anyway
|
sl@0
|
529 |
TUint newDialogEvaluatorInfo = iDialogEvaluatorInfo;
|
sl@0
|
530 |
TBool forcePrompt = iPolicyEvaluator->Imp().ForcePromptL(*record, newDialogEvaluatorInfo);
|
sl@0
|
531 |
if(forcePrompt)
|
sl@0
|
532 |
{
|
sl@0
|
533 |
iPromptForced = ETrue;
|
sl@0
|
534 |
iPromptForcedRecordId = record->iRecordId;
|
sl@0
|
535 |
UpsServer()->DisputeRecordIdL(iPromptForcedRecordId);
|
sl@0
|
536 |
}
|
sl@0
|
537 |
|
sl@0
|
538 |
if(newDialogEvaluatorInfo != iDialogEvaluatorInfo)
|
sl@0
|
539 |
{
|
sl@0
|
540 |
// Eavluator info changes, update our member variable copy
|
sl@0
|
541 |
// so it is used in the dialog
|
sl@0
|
542 |
iDialogEvaluatorInfo = newDialogEvaluatorInfo;
|
sl@0
|
543 |
// If we ARE displaying a prompt, then when it completes,
|
sl@0
|
544 |
// we will delete the existing record. If the user choice
|
sl@0
|
545 |
// requires a new record we will use the evaluator value
|
sl@0
|
546 |
// from our member variable
|
sl@0
|
547 |
if(!forcePrompt)
|
sl@0
|
548 |
{
|
sl@0
|
549 |
// Not forcing a prompt, so update the DB now.
|
sl@0
|
550 |
record->iEvaluatorInfo = newDialogEvaluatorInfo;
|
sl@0
|
551 |
// If the update fails, we carry on anyway...
|
sl@0
|
552 |
TRAPD(err, UpsServer()->iDbHandle->UpdateDecisionL(*filter, *record));
|
sl@0
|
553 |
if(err != KErrNone)
|
sl@0
|
554 |
{
|
sl@0
|
555 |
HandleDbErrorL(err);
|
sl@0
|
556 |
}
|
sl@0
|
557 |
}
|
sl@0
|
558 |
}
|
sl@0
|
559 |
|
sl@0
|
560 |
if(!forcePrompt)
|
sl@0
|
561 |
{
|
sl@0
|
562 |
// Return the result found in the DB to the system server
|
sl@0
|
563 |
TUpsDecisionPckgBuf decisionBuf;
|
sl@0
|
564 |
decisionBuf() = MapCPolicyTOptions2TUpsDecision((record->iResult) ? (CPolicy::EAlways) : (CPolicy::ENever));
|
sl@0
|
565 |
iMessagePtr2.WriteL(0, decisionBuf);
|
sl@0
|
566 |
|
sl@0
|
567 |
CleanupStack::PopAndDestroy(record);
|
sl@0
|
568 |
CleanupStack::PopAndDestroy(filter);
|
sl@0
|
569 |
CompleteAndMarkForDeletion(KErrNone);
|
sl@0
|
570 |
return;
|
sl@0
|
571 |
}
|
sl@0
|
572 |
|
sl@0
|
573 |
// Prompt is being forced, so fall through
|
sl@0
|
574 |
CleanupStack::PopAndDestroy(record);
|
sl@0
|
575 |
}
|
sl@0
|
576 |
|
sl@0
|
577 |
// Record not found, or prompt forced
|
sl@0
|
578 |
CleanupStack::PopAndDestroy(filter);
|
sl@0
|
579 |
|
sl@0
|
580 |
// Queue for clearence to display a dialog
|
sl@0
|
581 |
UpsServer()->GateKeeperL(this);
|
sl@0
|
582 |
}
|
sl@0
|
583 |
|
sl@0
|
584 |
void CAuthoriser::PrepareDialogL()
|
sl@0
|
585 |
{
|
sl@0
|
586 |
iState = EPreparingDialog;
|
sl@0
|
587 |
|
sl@0
|
588 |
iDialogCreator = UpsServer()->iPluginManager->CreateDialogCreatorL(iPolicy->DialogCreator());
|
sl@0
|
589 |
|
sl@0
|
590 |
iDialogCreator->Imp().PrepareDialog(*iPromptRequest, *iPolicy, iFingerprints,
|
sl@0
|
591 |
iClientEntity, iDialogCreatorParams, iStatus);
|
sl@0
|
592 |
SetActive();
|
sl@0
|
593 |
}
|
sl@0
|
594 |
|
sl@0
|
595 |
|
sl@0
|
596 |
|
sl@0
|
597 |
|
sl@0
|
598 |
void CAuthoriser::ExecuteDialogL()
|
sl@0
|
599 |
{
|
sl@0
|
600 |
iState = EExecutingDialog;
|
sl@0
|
601 |
iDialogCreator->Imp().DisplayDialog(iDialogSelectedOption, iDialogFingerprint, iDialogEvaluatorInfo, iStatus);
|
sl@0
|
602 |
SetActive();
|
sl@0
|
603 |
}
|
sl@0
|
604 |
|
sl@0
|
605 |
void CAuthoriser::ProcessDialogResultL()
|
sl@0
|
606 |
{
|
sl@0
|
607 |
if(iPromptForced)
|
sl@0
|
608 |
{
|
sl@0
|
609 |
// Pormpt was forced therefore we must have matched an existing record in the
|
sl@0
|
610 |
// database.
|
sl@0
|
611 |
// Delete the old decision.
|
sl@0
|
612 |
CDecisionFilter *filter = CDecisionFilter::NewLC();
|
sl@0
|
613 |
filter->SetRecordId(iPromptForcedRecordId, EEqual);
|
sl@0
|
614 |
TRAPD(err, UpsServer()->iDbHandle->RemoveDecisionsL(*filter));
|
sl@0
|
615 |
CleanupStack::PopAndDestroy(filter);
|
sl@0
|
616 |
if(err != KErrNone)
|
sl@0
|
617 |
{
|
sl@0
|
618 |
HandleDbErrorL(err);
|
sl@0
|
619 |
}
|
sl@0
|
620 |
|
sl@0
|
621 |
// No longer disputing the record ID because we have a new decision
|
sl@0
|
622 |
iPromptForced = EFalse;
|
sl@0
|
623 |
UpsServer()->UnDisputeRecordIdL(iPromptForcedRecordId);
|
sl@0
|
624 |
}
|
sl@0
|
625 |
|
sl@0
|
626 |
TUpsDecisionPckgBuf decisionBuf;
|
sl@0
|
627 |
// Mask out any illegal responses - ie buttons which we did not
|
sl@0
|
628 |
// ask to be displayed...
|
sl@0
|
629 |
iDialogSelectedOption = CPolicy::TOptions(TUint(iDialogSelectedOption) & TUint(iPolicy->Options()));
|
sl@0
|
630 |
|
sl@0
|
631 |
decisionBuf() = MapCPolicyTOptions2TUpsDecision(iDialogSelectedOption);
|
sl@0
|
632 |
|
sl@0
|
633 |
if((iDialogSelectedOption & CPolicy::EAlways) || (iDialogSelectedOption & CPolicy::ENever))
|
sl@0
|
634 |
{
|
sl@0
|
635 |
|
sl@0
|
636 |
__ASSERT_ALWAYS(NULL != iDialogFingerprint,
|
sl@0
|
637 |
User::Panic(KUpsServerName,
|
sl@0
|
638 |
KErrUpsBadFingerprintLength));
|
sl@0
|
639 |
|
sl@0
|
640 |
// Save yes/no result to database
|
sl@0
|
641 |
TPtrC8 clientEntityName(KNullDesC8());
|
sl@0
|
642 |
if(iClientEntity)
|
sl@0
|
643 |
{
|
sl@0
|
644 |
clientEntityName.Set(iClientEntity->Name());
|
sl@0
|
645 |
}
|
sl@0
|
646 |
|
sl@0
|
647 |
CDecisionRecord *record = CDecisionRecord::NewLC(iPromptRequest->ClientSid(),
|
sl@0
|
648 |
iPolicy->PolicyEvaluator(),
|
sl@0
|
649 |
iPromptRequest->ServiceId(),
|
sl@0
|
650 |
iPromptRequest->ServerSid(),
|
sl@0
|
651 |
iDialogFingerprint->Fingerprint(),
|
sl@0
|
652 |
clientEntityName,
|
sl@0
|
653 |
iDialogFingerprint->Description(),
|
sl@0
|
654 |
((iDialogSelectedOption & CPolicy::EAlways) != 0),
|
sl@0
|
655 |
iPolicy->MajorVersion(),
|
sl@0
|
656 |
iDialogEvaluatorInfo);
|
sl@0
|
657 |
|
sl@0
|
658 |
// Create new record - Failure is not fatal...
|
sl@0
|
659 |
TRAPD(err, UpsServer()->iDbHandle->CreateDecisionL(*record));
|
sl@0
|
660 |
if(err == KErrAlreadyExists)
|
sl@0
|
661 |
{
|
sl@0
|
662 |
/// You might think this will never happen, but under OOM conditions it can/does. The original database query can fail,
|
sl@0
|
663 |
/// even though there is a matching record in the database, we then choose to display a prompt, then the above code attempts to
|
sl@0
|
664 |
/// insert a "new" record and fails.... We recover by just updating the existing record.
|
sl@0
|
665 |
CDecisionFilter *filter = CDecisionFilter::NewLC(iPromptRequest->ClientSid(),
|
sl@0
|
666 |
iPolicy->PolicyEvaluator(),
|
sl@0
|
667 |
iPromptRequest->ServiceId(),
|
sl@0
|
668 |
iPromptRequest->ServerSid(),
|
sl@0
|
669 |
iDialogFingerprint->Fingerprint(),
|
sl@0
|
670 |
clientEntityName,
|
sl@0
|
671 |
iPolicy->MajorVersion());
|
sl@0
|
672 |
|
sl@0
|
673 |
TRAP(err, UpsServer()->iDbHandle->UpdateDecisionL(*filter, *record));
|
sl@0
|
674 |
CleanupStack::PopAndDestroy(filter);
|
sl@0
|
675 |
}
|
sl@0
|
676 |
if(err != KErrNone)
|
sl@0
|
677 |
{
|
sl@0
|
678 |
HandleDbErrorL(err);
|
sl@0
|
679 |
}
|
sl@0
|
680 |
|
sl@0
|
681 |
CleanupStack::PopAndDestroy(record);
|
sl@0
|
682 |
}
|
sl@0
|
683 |
|
sl@0
|
684 |
iMessagePtr2.WriteL(0, decisionBuf);
|
sl@0
|
685 |
|
sl@0
|
686 |
CompleteAndMarkForDeletion(KErrNone);
|
sl@0
|
687 |
}
|
sl@0
|
688 |
|
sl@0
|
689 |
TUpsDecision CAuthoriser::MapCPolicyTOptions2TUpsDecision(CPolicy::TOptions aOptions)
|
sl@0
|
690 |
/**
|
sl@0
|
691 |
Map the specified policy option bitmap (normally only a single bit should be set) into
|
sl@0
|
692 |
a TUpsDecision.
|
sl@0
|
693 |
|
sl@0
|
694 |
If the server supports session decisions, then return never/always as EUpsDecSessionNo/EUpsDecSessionYes.
|
sl@0
|
695 |
|
sl@0
|
696 |
Usually a single option should be specified, but we consider the options in the order which
|
sl@0
|
697 |
minimises UPS traffic...
|
sl@0
|
698 |
*/
|
sl@0
|
699 |
{
|
sl@0
|
700 |
if( (aOptions & (CPolicy::ENever | CPolicy::ESessionNo)) != 0)
|
sl@0
|
701 |
{
|
sl@0
|
702 |
// A Never - If the session supports "session no" then return it to cut down on UPS traffic
|
sl@0
|
703 |
if(iPolicy->Options() & CPolicy::ESessionNo)
|
sl@0
|
704 |
{
|
sl@0
|
705 |
return EUpsDecSessionNo;
|
sl@0
|
706 |
}
|
sl@0
|
707 |
// Otherwise return "single shot no" so the server will re-query us later (we may silently answer).
|
sl@0
|
708 |
return EUpsDecNo;
|
sl@0
|
709 |
}
|
sl@0
|
710 |
|
sl@0
|
711 |
if( (aOptions & (CPolicy::EAlways| CPolicy::ESessionYes)) != 0)
|
sl@0
|
712 |
{
|
sl@0
|
713 |
// An Always - If the session supports "session yes" then return it to cut down on UPS traffic
|
sl@0
|
714 |
if(iPolicy->Options() & CPolicy::ESessionYes)
|
sl@0
|
715 |
{
|
sl@0
|
716 |
return EUpsDecSessionYes;
|
sl@0
|
717 |
}
|
sl@0
|
718 |
// Otherwise return "single shot yes" so the server will re-query us later (so force prompt handling works).
|
sl@0
|
719 |
return EUpsDecYes;
|
sl@0
|
720 |
}
|
sl@0
|
721 |
|
sl@0
|
722 |
if( (aOptions & CPolicy::ENo) != 0)
|
sl@0
|
723 |
{
|
sl@0
|
724 |
// A "single shot no"
|
sl@0
|
725 |
return EUpsDecNo;
|
sl@0
|
726 |
}
|
sl@0
|
727 |
|
sl@0
|
728 |
// Only possibility left is a single shot yes
|
sl@0
|
729 |
// If it is not one, then map to no
|
sl@0
|
730 |
BULLSEYE_OFF
|
sl@0
|
731 |
if( (aOptions & CPolicy::EYes) == 0)
|
sl@0
|
732 |
{
|
sl@0
|
733 |
return EUpsDecNo; // No option set!
|
sl@0
|
734 |
}
|
sl@0
|
735 |
BULLSEYE_RESTORE
|
sl@0
|
736 |
|
sl@0
|
737 |
// A "single shot yes"
|
sl@0
|
738 |
return EUpsDecYes;
|
sl@0
|
739 |
}
|
sl@0
|
740 |
|
sl@0
|
741 |
void CAuthoriser::HandleDbErrorL(TInt aError)
|
sl@0
|
742 |
{
|
sl@0
|
743 |
if((aError != KErrNoMemory) && (aError != KErrDiskFull))
|
sl@0
|
744 |
{
|
sl@0
|
745 |
RDebug::Printf(KCorruptDb, aError, __LINE__);
|
sl@0
|
746 |
UpsServer()->iDbHandle->DeleteDatabaseL(UpsServer()->iFs);
|
sl@0
|
747 |
UpsServer()->iDbHandle.Close(); // Will auto-reopen when next used
|
sl@0
|
748 |
User::Leave(aError);
|
sl@0
|
749 |
}
|
sl@0
|
750 |
UpsServer()->iDbHandle.Close(); // Will auto-reopen when next used
|
sl@0
|
751 |
}
|
sl@0
|
752 |
|
sl@0
|
753 |
CAuthoriserFifo* CAuthoriserFifo::NewL()
|
sl@0
|
754 |
/**
|
sl@0
|
755 |
Create a new CAuthoriserFifo instance
|
sl@0
|
756 |
*/
|
sl@0
|
757 |
{
|
sl@0
|
758 |
CAuthoriserFifo *self = new(ELeave) CAuthoriserFifo;
|
sl@0
|
759 |
return self;
|
sl@0
|
760 |
}
|
sl@0
|
761 |
|
sl@0
|
762 |
CAuthoriserFifo::~CAuthoriserFifo()
|
sl@0
|
763 |
/**
|
sl@0
|
764 |
Does not delete CAuthoriser objects in the FIFO, just frees
|
sl@0
|
765 |
storage used by the FIFO itself.
|
sl@0
|
766 |
*/
|
sl@0
|
767 |
{
|
sl@0
|
768 |
iPtrArray.Close();
|
sl@0
|
769 |
}
|
sl@0
|
770 |
|
sl@0
|
771 |
|
sl@0
|
772 |
|
sl@0
|
773 |
void CAuthoriserFifo::PushL(CAuthoriser *aAuthoriser)
|
sl@0
|
774 |
/**
|
sl@0
|
775 |
@param aAuthoriser The CAuthoriser to be pushed onto the FIFO.
|
sl@0
|
776 |
|
sl@0
|
777 |
This class does NOT take ownership.
|
sl@0
|
778 |
*/
|
sl@0
|
779 |
{
|
sl@0
|
780 |
iPtrArray.AppendL(aAuthoriser);
|
sl@0
|
781 |
}
|
sl@0
|
782 |
|
sl@0
|
783 |
CAuthoriser *CAuthoriserFifo::PopL()
|
sl@0
|
784 |
{
|
sl@0
|
785 |
/**
|
sl@0
|
786 |
@return A CAuthoriser ptr, or Leaves KErrUnderflow if FIFO is empty.
|
sl@0
|
787 |
*/
|
sl@0
|
788 |
TInt count = iPtrArray.Count();
|
sl@0
|
789 |
BULLSEYE_OFF
|
sl@0
|
790 |
if(count == 0)
|
sl@0
|
791 |
{
|
sl@0
|
792 |
User::Leave(KErrUnderflow);
|
sl@0
|
793 |
}
|
sl@0
|
794 |
BULLSEYE_RESTORE
|
sl@0
|
795 |
|
sl@0
|
796 |
CAuthoriser *ret = iPtrArray[0];
|
sl@0
|
797 |
iPtrArray.Remove(0);
|
sl@0
|
798 |
return ret;
|
sl@0
|
799 |
}
|
sl@0
|
800 |
|
sl@0
|
801 |
void CAuthoriserFifo::RemoveL(CAuthoriser *aAuthoriser)
|
sl@0
|
802 |
/**
|
sl@0
|
803 |
Remove the specified object from the FIFO.
|
sl@0
|
804 |
|
sl@0
|
805 |
It is not considered to be an error if the object is not in the
|
sl@0
|
806 |
FIFO.
|
sl@0
|
807 |
|
sl@0
|
808 |
@param aAuthoriser The CAuthoriser to be removed from the FIFO.
|
sl@0
|
809 |
*/
|
sl@0
|
810 |
{
|
sl@0
|
811 |
TInt i = iPtrArray.Find(aAuthoriser);
|
sl@0
|
812 |
BULLSEYE_OFF
|
sl@0
|
813 |
if( i == KErrNotFound)
|
sl@0
|
814 |
{
|
sl@0
|
815 |
return; // Not found is not considered an error.
|
sl@0
|
816 |
}
|
sl@0
|
817 |
BULLSEYE_RESTORE
|
sl@0
|
818 |
|
sl@0
|
819 |
User::LeaveIfError(i);
|
sl@0
|
820 |
iPtrArray.Remove(i);
|
sl@0
|
821 |
}
|
sl@0
|
822 |
|
sl@0
|
823 |
|
sl@0
|
824 |
TBool CAuthoriserFifo::IsEmpty() const
|
sl@0
|
825 |
/**
|
sl@0
|
826 |
@return ETrue if empty
|
sl@0
|
827 |
*/
|
sl@0
|
828 |
{
|
sl@0
|
829 |
return (iPtrArray.Count() == 0);
|
sl@0
|
830 |
}
|
sl@0
|
831 |
|
sl@0
|
832 |
void CAuthoriserFifo::Compress()
|
sl@0
|
833 |
/**
|
sl@0
|
834 |
Reduce memory usage as much as possible. Typically used during OOM testing.
|
sl@0
|
835 |
*/
|
sl@0
|
836 |
{
|
sl@0
|
837 |
iPtrArray.Compress();
|
sl@0
|
838 |
}
|
sl@0
|
839 |
|
sl@0
|
840 |
|
sl@0
|
841 |
|
sl@0
|
842 |
|
sl@0
|
843 |
} // End of namespace UserPromptService
|
sl@0
|
844 |
// End of file
|