os/security/authorisation/userpromptservice/server/source/upsserver/policychangeevaluator.cpp
Update contrib.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * Process RUpsManagement::NotifyPolicyFilesChanged.
24 #include "upsserver.h"
25 #include <ups/upsdbw.h>
26 #include <e32property.h>
27 #include "policycache.h"
28 #include "policychangeevaluator.h"
30 namespace UserPromptService
32 inline CUpsSession *CPolicyChangeEvaluator::UpsSession()
34 return static_cast<CUpsSession*>(iSession);
37 inline CUpsServer *CPolicyChangeEvaluator::UpsServer()
39 return static_cast<CUpsServer *>(
40 &static_cast<CUpsSession*>(iSession)->iServer);
43 CPolicyChangeEvaluator* CPolicyChangeEvaluator::NewLC(RPolicyCacheCountedHandle &aPolicyCacheHandle, CUpsSession* aSession, const RMessage2& aMessage)
45 CPolicyChangeEvaluator* self = new(ELeave) CPolicyChangeEvaluator(aPolicyCacheHandle, aSession, aMessage);
46 CleanupStack::PushL(self);
50 CPolicyChangeEvaluator::CPolicyChangeEvaluator(RPolicyCacheCountedHandle &aPolicyCacheHandle, CUpsSession* aSession, const RMessage2& aMessage)
51 : CAsyncRequest(aSession, 0, aMessage),
52 iPolicyCacheHandle(aPolicyCacheHandle),
53 iUpdateDbHandle(UpsServer()->iDbHandle, this)
57 CPolicyChangeEvaluator::~CPolicyChangeEvaluator()
59 Normally cleanup should be done when DoCleanup function is called by the framework.
60 Sometime later, possibly after our parent CUpsSession has been deleted, this
61 destructor will be run. In this case the framework will have cleared our iSession variable
62 and we must do NOTHING.
64 Unfortunately there is a special case where this object fails inside ConstructL, when we must do
65 some cleanup. We can detect this be seeing iSession (and hence UpsServer()) is non-NULL.
68 CUpsSession *session = UpsSession();
71 /*lint -save -e1506*/ // ignore warning about calling a virtual function in a destructor
78 void CPolicyChangeEvaluator::StartUpdate()
79 /// Starts evaluating the database view
81 iPolicyCacheHandle.NotifyOnRef1(iStatus);
85 void CPolicyChangeEvaluator::ProcessEventL(TPolicyChangeEvent aEvent)
87 Process either a DoCancel call or a request completing through RunL
92 case EWaitForPolicyCacheIdle:
93 WaitForPolicyCacheIdleStateL(aEvent);
97 ScanDatabaseStateL(aEvent);
103 // Should not get here
104 _LIT(KServerPanicState, "UPS-CPolicyChangeEvaluator");
105 User::Panic(KServerPanicState, iState);
108 void CPolicyChangeEvaluator::DoCleanup()
109 /// implement CAsyncRequest
118 iUpdateDbHandle.Close();
120 iPolicyCacheHandle.Release();
123 void CPolicyChangeEvaluator::DoCancel()
124 /// implement CActive - Cancel
126 TRAP_IGNORE(ProcessEventL(ECancel));
130 void CPolicyChangeEvaluator::RunL()
131 /// implement CActive, override CAsyncRequset
133 User::LeaveIfError(iStatus.Int());
135 ProcessEventL(EInternalRequestComplete);
138 TInt CPolicyChangeEvaluator::RunError(TInt aError)
140 iUpdateDbHandle.CloseMaster();
141 return CAsyncRequest::RunError(aError);
144 void CPolicyChangeEvaluator::DbHandleAboutToBeDeleted()
146 Called just before the master database handle is shut.
147 Need to cancel and cleanup/delete our view and fail the client request.
150 // Make sure our request is cancelled
153 // Cleanup/delete our view object
156 // Abort the client view request.
157 CompleteAndMarkForDeletion(KErrAbort);
160 void CPolicyChangeEvaluator::WaitForPolicyCacheIdleStateL(TPolicyChangeEvent aEvent)
164 case EInternalRequestComplete:
166 // Cache is idle so now create the view and walk the database
167 CDecisionFilter *filter= CDecisionFilter::NewLC();
168 iUpdateView = iUpdateDbHandle->CreateViewL(*filter);
169 CleanupStack::PopAndDestroy(filter);
171 // Update state and start evaluating the view
172 iState = EScanDatabase;
173 iUpdateView->EvaluateView(iStatus);
178 iPolicyCacheHandle.CancelNotifyOnRef1();
186 void CPolicyChangeEvaluator::ScanDatabaseStateL(TPolicyChangeEvent aEvent)
190 case EInternalRequestComplete:
192 // Finished evaluating the view
193 BuildServerServicePolicyVersionTableL();
195 // If the server policy cache handle has not already been
196 // re-opened, open it.
197 if(!UpsServer()->iPolicyCache.IsOpen())
199 UpsServer()->iPolicyCache.OpenL();
201 // Assign the server handle to ours - this will increment the reference count.
202 iPolicyCacheHandle = UpsServer()->iPolicyCache;
204 // Set the property, the value does not matter.
205 // We do not need to change the value, setting to the same value still notifies all clients of
207 User::LeaveIfError(RProperty::Set(KUpsServerUid, KUpsServiceConfigProperty, 42));
209 // Process the iSSPVarray and delete uneeded database entries
210 DeleteUnneededEntriesL();
213 CompleteAndMarkForDeletion(KErrNone);
217 iUpdateView->Cancel();
226 TInt CPolicyChangeEvaluator::OrderServerServicePolicyVersion(const TServerServicePolicyVersion &aLhs,
227 const TServerServicePolicyVersion &aRhs)
229 TInt t = aLhs.iServerId - aRhs.iServerId;
231 t = aLhs.iServiceId - aRhs.iServiceId;
233 t = aLhs.iMajorVersion - aRhs.iMajorVersion;
237 void CPolicyChangeEvaluator::BuildServerServicePolicyVersionTableL()
239 TLinearOrder<TServerServicePolicyVersion> linearOrder(OrderServerServicePolicyVersion);
241 while(CDecisionRecord *record = iUpdateView->NextDecisionL())
243 TServerServicePolicyVersion ent = { record->iServerSid.iId,
244 record->iServiceId.iUid,
245 record->iMajorPolicyVersion };
248 TInt r = iSSPVarray.InsertInOrder(ent, linearOrder);
249 if((r != KErrNone) && (r != KErrAlreadyExists))
258 static TBool CompareServiceId(const TServiceId* k, const TServiceConfig& t)
260 return TUint(k->iUid) == t.iServiceId;
263 void CPolicyChangeEvaluator::DeleteUnneededEntriesL()
265 TInt count = iSSPVarray.Count();
267 if(count == 0) return; // No database entries!
269 TSecureId serverSid(0); // ID of server currently being processed. 0 is illegal
270 RArray<TServiceConfig> serviceConfigArray;
271 CleanupClosePushL(serviceConfigArray);
272 for(TInt i=0; i<count; ++i)
274 const TServerServicePolicyVersion &sspv = iSSPVarray[i];
275 TServiceId serviceId = {sspv.iServiceId};
277 // The iSSPVarray is sorted by server/service/version. This means
278 // all entries for a single server will be adjacent to each other
279 if(serverSid != sspv.iServerId)
281 // 0 is not a valid server SID, so this will always run the first time
283 serviceConfigArray.Close();
284 serverSid = sspv.iServerId;
285 iPolicyCacheHandle->ServiceConfigL(serverSid, serviceConfigArray);
288 CDecisionFilter *filter = CDecisionFilter::NewLC();
289 filter->SetServerSid(serverSid, EEqual);
290 filter->SetServiceId(serviceId, EEqual);
292 // Now attempt to lookup the current ServiceId in the serviceconfig for
293 // the current server.
294 TInt serviceIndex = serviceConfigArray.Find(serviceId, CompareServiceId);
295 if(serviceIndex != KErrNotFound)
297 DEBUG_PRINTF5(_L8("i=%d Found server %x service %x at index %d\n"),
298 i, sspv.iServerId, sspv.iServiceId, serviceIndex);
299 TServiceConfig &serviceConfig = serviceConfigArray[serviceIndex];
300 filter->SetMajorPolicyVersion(serviceConfig.iMajorVersion, ENotEqual);
301 DEBUG_PRINTF4(_L8("Deleting OLD decisions where server=0x%x service=0x%x MajorVersion!=%d\n"),
302 serverSid.iId, serviceId.iUid, serviceConfig.iMajorVersion);
306 DEBUG_PRINTF3(_L8("Deleting ALL decisions where server=0x%x service=0x%x MajorVersion==*\n"),
307 serverSid.iId, serviceId.iUid);
310 TRAP_IGNORE(iUpdateDbHandle->RemoveDecisionsL(*filter));
311 CleanupStack::PopAndDestroy(filter);
314 CleanupStack::PopAndDestroy(&serviceConfigArray);
318 } // End of namespace UserPromptServer