|
1 /* |
|
2 * Copyright (c) 2008-2010 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 SCR session class which is server-side session object. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 /** |
|
21 @file |
|
22 @internalComponent |
|
23 @released |
|
24 */ |
|
25 |
|
26 #include "scrserver.h" |
|
27 #include "scrsubsession.h" |
|
28 #include "scrrequestimpl.h" |
|
29 #include "usiflog.h" |
|
30 #include "usiferror.h" |
|
31 |
|
32 using namespace Usif; |
|
33 |
|
34 // |
|
35 // CScrSession |
|
36 // |
|
37 |
|
38 CScrSession::CScrSession(CScrServer& aServer) |
|
39 /** |
|
40 Intializes the SCR session object with the server handle. |
|
41 */ |
|
42 : CScsSession(aServer) |
|
43 { |
|
44 DEBUG_PRINTF(_L8("SCR session construction!")); |
|
45 } |
|
46 |
|
47 |
|
48 CScrSession::~CScrSession() |
|
49 /** |
|
50 Destructor for the SCR session object. |
|
51 */ |
|
52 { |
|
53 DEBUG_PRINTF(_L8("SCR session destruction!")); |
|
54 CScrServer *server = static_cast<CScrServer*>(&iServer); |
|
55 // Take care to close all outstanding subsesions first, as we wouldn't be able to roll-back with open statements |
|
56 TRAP_IGNORE(CScsSession::CloseAllSubsessionsL()); |
|
57 // Now roll-back transaction in case it wasn't committed or rolled back explicitly |
|
58 if(server->IsTransactionOwner(this)) |
|
59 { |
|
60 TRAPD(err, server->RequestImpL()->RollbackTransactionL()); |
|
61 if(KErrNone != err) |
|
62 { |
|
63 TRAP_IGNORE(server->ReconnectL()); |
|
64 } |
|
65 server->SetTransactionOwner(NULL); |
|
66 } |
|
67 // Any error during writing log entries can be ignored as it is done in the destructor of SCR session |
|
68 // and error logs are already written inside the function. |
|
69 TRAP_IGNORE(server->RequestImpL()->FlushLogEntriesArrayL()); |
|
70 } |
|
71 |
|
72 |
|
73 CScrSession* CScrSession::NewL(CScrServer &aServer, const RMessage2& aMessage) |
|
74 /** |
|
75 Factory function allocates new instance of CScrSession. |
|
76 |
|
77 @param aServer SCR Server object. |
|
78 @param aMessage Standard server-side handle to message. Not used. |
|
79 @return Newly created instance of CScrSession which is owned by the caller. |
|
80 */ |
|
81 { |
|
82 DEBUG_PRINTF2(_L("A new SCR session for the process(0x%x) is being created."), aMessage.SecureId().iId); |
|
83 (void)aMessage; // Happy the compiler in release mode |
|
84 CScrSession* self = new (ELeave) CScrSession(aServer); |
|
85 CleanupStack::PushL(self); |
|
86 self->ConstructL(); |
|
87 CleanupStack::Pop(self); |
|
88 return self; |
|
89 } |
|
90 |
|
91 void CancelTransaction(TAny* aParam) |
|
92 { |
|
93 CScrServer *server = static_cast<CScrServer*>(aParam); |
|
94 TRAP_IGNORE(server->RequestImpL()->RollbackTransactionL()); |
|
95 server->SetTransactionOwner(NULL); |
|
96 } |
|
97 |
|
98 TBool CScrSession::DoServiceL(TInt aFunction, const RMessage2& aMessage) |
|
99 /** |
|
100 Implement CScsSession by handling the supplied message. |
|
101 |
|
102 @param aFunction Function identifier without SCS code. |
|
103 @param aMessage Standard server-side handle to message. Not used. |
|
104 */ |
|
105 { |
|
106 TScrSessionFunction f = static_cast<TScrSessionFunction>(aFunction); |
|
107 CScrServer *server = static_cast<CScrServer*>(&iServer); |
|
108 |
|
109 TBool isImplicitTransaction = EFalse; |
|
110 MutatingOperationsPreambleL(*server, f, isImplicitTransaction); |
|
111 if(isImplicitTransaction) |
|
112 { |
|
113 CleanupStack::PushL(TCleanupItem(CancelTransaction, server)); |
|
114 } |
|
115 |
|
116 switch(f) |
|
117 { |
|
118 case ECreateTransaction: |
|
119 server->RequestImpL()->CreateTransactionL(); |
|
120 server->SetTransactionOwner(this); |
|
121 break; |
|
122 case ERollbackTransaction: |
|
123 server->RequestImpL()->RollbackTransactionL(); |
|
124 server->SetTransactionOwner(NULL); |
|
125 break; |
|
126 case ECommitTransaction: |
|
127 server->RequestImpL()->CommitTransactionL(); |
|
128 server->SetTransactionOwner(NULL); |
|
129 break; |
|
130 case EAddComponent: |
|
131 server->RequestImpL()->AddComponentL(aMessage); |
|
132 break; |
|
133 case ESetComponentLocalizableProperty: |
|
134 server->RequestImpL()->SetComponentLocalizablePropertyL(aMessage); |
|
135 break; |
|
136 case ESetComponentNumericProperty: |
|
137 server->RequestImpL()->SetComponentIntPropertyL(aMessage); |
|
138 break; |
|
139 case ESetComponentBinaryProperty: |
|
140 server->RequestImpL()->SetComponentBinaryPropertyL(aMessage); |
|
141 break; |
|
142 case ERegisterComponentFile: |
|
143 server->RequestImpL()->RegisterComponentFileL(aMessage); |
|
144 break; |
|
145 case ESetFileStringProperty: |
|
146 server->RequestImpL()->SetFileStrPropertyL(aMessage); |
|
147 break; |
|
148 case ESetFileNumericProperty: |
|
149 server->RequestImpL()->SetFileIntPropertyL(aMessage); |
|
150 break; |
|
151 case ESetComponentName: |
|
152 server->RequestImpL()->SetComponentNameL(aMessage); |
|
153 break; |
|
154 case ESetComponentVendor: |
|
155 server->RequestImpL()->SetVendorNameL(aMessage); |
|
156 break; |
|
157 case ESetComponentVersion: |
|
158 server->RequestImpL()->SetComponentVersionL(aMessage); |
|
159 break; |
|
160 case ESetIsComponentRemovable: |
|
161 server->RequestImpL()->SetIsComponentRemovableL(aMessage); |
|
162 break; |
|
163 case ESetIsComponentDrmProtected: |
|
164 server->RequestImpL()->SetIsComponentDrmProtectedL(aMessage); |
|
165 break; |
|
166 case ESetIsComponentHidden: |
|
167 server->RequestImpL()->SetIsComponentHiddenL(aMessage); |
|
168 break; |
|
169 case ESetIsComponentKnownRevoked: |
|
170 server->RequestImpL()->SetIsComponentKnownRevokedL(aMessage); |
|
171 break; |
|
172 case ESetIsComponentOriginVerified: |
|
173 server->RequestImpL()->SetIsComponentOriginVerifiedL(aMessage); |
|
174 break; |
|
175 case ESetComponentSize: |
|
176 server->RequestImpL()->SetComponentSizeL(aMessage); |
|
177 break; |
|
178 case EDeleteComponentProperty: |
|
179 server->RequestImpL()->DeleteComponentPropertyL(aMessage); |
|
180 break; |
|
181 case EDeleteFileProperty: |
|
182 server->RequestImpL()->DeleteFilePropertyL(aMessage); |
|
183 break; |
|
184 case EUnregisterComponentFile: |
|
185 server->RequestImpL()->UnregisterComponentFileL(aMessage); |
|
186 break; |
|
187 case EDeleteComponent: |
|
188 server->RequestImpL()->DeleteComponentL(aMessage); |
|
189 break; |
|
190 case EGetSingleComponentSize: |
|
191 server->RequestImpL()->GetComponentEntrySizeL(aMessage); |
|
192 break; |
|
193 case EGetSingleComponentData: |
|
194 server->RequestImpL()->GetComponentEntryDataL(aMessage); |
|
195 break; |
|
196 case EGetFilePropertiesSize: |
|
197 server->RequestImpL()->GetFilePropertiesSizeL(aMessage); |
|
198 break; |
|
199 case EGetFilePropertiesData: |
|
200 server->RequestImpL()->GetFilePropertiesDataL(aMessage); |
|
201 break; |
|
202 case EGetSingleFilePropertySize: |
|
203 server->RequestImpL()->GetSingleFilePropertySizeL(aMessage); |
|
204 break; |
|
205 case EGetSingleFilePropertyData: |
|
206 server->RequestImpL()->GetSingleFilePropertyDataL(aMessage); |
|
207 break; |
|
208 case EGetFileComponentsSize: |
|
209 server->RequestImpL()->GetFileComponentsSizeL(aMessage); |
|
210 break; |
|
211 case EGetFileComponentsData: |
|
212 server->RequestImpL()->GetFileComponentsDataL(aMessage); |
|
213 break; |
|
214 case EGetComponentPropertiesSize: |
|
215 server->RequestImpL()->GetComponentPropertiesSizeL(aMessage); |
|
216 break; |
|
217 case EGetComponentPropertiesData: |
|
218 server->RequestImpL()->GetComponentPropertiesDataL(aMessage); |
|
219 break; |
|
220 case EGetComponentSinglePropertySize: |
|
221 server->RequestImpL()->GetComponentSinglePropertySizeL(aMessage); |
|
222 break; |
|
223 case EGetComponentSinglePropertyData: |
|
224 server->RequestImpL()->GetComponentSinglePropertyDataL(aMessage); |
|
225 break; |
|
226 case EGetIsMediaPresent: |
|
227 server->RequestImpL()->GetIsMediaPresentL(aMessage); |
|
228 break; |
|
229 case ESetScomoState: |
|
230 server->RequestImpL()->SetScomoStateL(aMessage); |
|
231 break; |
|
232 case EGetPluginUidWithMimeType: |
|
233 server->RequestImpL()->GetPluginUidWithMimeTypeL(aMessage); |
|
234 break; |
|
235 case EGetPluginUidWithComponentId: |
|
236 server->RequestImpL()->GetPluginUidWithComponentIdL(aMessage); |
|
237 break; |
|
238 case EGetComponentIdListSize: |
|
239 server->RequestImpL()->GetComponentIdListSizeL(aMessage); |
|
240 break; |
|
241 case EGetComponentIdListData: |
|
242 server->RequestImpL()->GetComponentIdListDataL(aMessage); |
|
243 break; |
|
244 case EGetComponentFilesCount: |
|
245 server->RequestImpL()->GetComponentFilesCountL(aMessage); |
|
246 break; |
|
247 case EAddComponentDependency: |
|
248 server->RequestImpL()->AddComponentDependencyL(aMessage); |
|
249 break; |
|
250 case EDeleteComponentDependency: |
|
251 server->RequestImpL()->DeleteComponentDependencyL(aMessage); |
|
252 break; |
|
253 case EGetLocalComponentId: |
|
254 server->RequestImpL()->GetComponentIdL(aMessage); |
|
255 break; |
|
256 case EGetComponentWithGlobalIdSize: |
|
257 server->RequestImpL()->GetComponentWithGlobalIdSizeL(aMessage); |
|
258 break; |
|
259 case EGetComponentWithGlobalIdData: |
|
260 server->RequestImpL()->GetComponentWithGlobalIdDataL(aMessage); |
|
261 break; |
|
262 case EGetSupplierComponentsSize: |
|
263 server->RequestImpL()->GetSupplierComponentsSizeL(aMessage); |
|
264 break; |
|
265 case EGetSupplierComponentsData: |
|
266 server->RequestImpL()->GetSupplierComponentsDataL(aMessage); |
|
267 break; |
|
268 case EGetDependantComponentsSize: |
|
269 server->RequestImpL()->GetDependantComponentsSizeL(aMessage); |
|
270 break; |
|
271 case EGetDependantComponentsData: |
|
272 server->RequestImpL()->GetDependantComponentsDataL(aMessage); |
|
273 break; |
|
274 case EAddSoftwareType: |
|
275 server->RequestImpL()->AddSoftwareTypeL(aMessage); |
|
276 break; |
|
277 case EDeleteSoftwareType: |
|
278 server->RequestImpL()->DeleteSoftwareTypeL(aMessage); |
|
279 break; |
|
280 case EGetDeletedMimeTypes: |
|
281 server->RequestImpL()->GetDeletedMimeTypesL(aMessage); |
|
282 break; |
|
283 case EGetIsComponentOrphaned: |
|
284 server->RequestImpL()->GetIsComponentOrphanedL(aMessage); |
|
285 break; |
|
286 case EGetLogFileHandle: |
|
287 server->RequestImpL()->GetLogFileHandleL(aMessage); |
|
288 //RMessage2 object is closed by both TransferToClient() and SCS framework. |
|
289 //return EFalse to prevent SCS to close the message object. |
|
290 return EFalse; |
|
291 case EGetIsComponentOnReadOnlyDrive: |
|
292 server->RequestImpL()->GetIsComponentOnReadOnlyDriveL(aMessage); |
|
293 break; |
|
294 case EGetIsComponentPresent: |
|
295 server->RequestImpL()->GetIsComponentPresentL(aMessage); |
|
296 break; |
|
297 case ESetIsComponentPresent: |
|
298 server->RequestImpL()->SetIsComponentPresentL(aMessage); |
|
299 break; |
|
300 case EGetComponentSupportedLocalesListSize: |
|
301 server->RequestImpL()->GetComponentSupportedLocalesListSizeL(aMessage); |
|
302 break; |
|
303 case EGetComponentSupportedLocalesListData: |
|
304 server->RequestImpL()->GetComponentSupportedLocalesListDataL(aMessage); |
|
305 break; |
|
306 case EGetLocalizedComponentSize: |
|
307 server->RequestImpL()->GetComponentLocalizedEntrySizeL(aMessage); |
|
308 break; |
|
309 case EGetLocalizedComponentData: |
|
310 server->RequestImpL()->GetComponentLocalizedEntryDataL(aMessage); |
|
311 break; |
|
312 case EAddApplicationEntry: |
|
313 server->RequestImpL()->AddApplicationEntryL(aMessage); |
|
314 break; |
|
315 case EDeleteApplicationEntries: |
|
316 server->RequestImpL()->DeleteAllAppsWithinPackageL(aMessage); |
|
317 break; |
|
318 case EDeleteApplicationEntry: |
|
319 server->RequestImpL()->DeleteApplicationEntryL(aMessage); |
|
320 break; |
|
321 case EGetComponentIdForApp: |
|
322 server->RequestImpL()->GetComponentIdForAppL(aMessage); |
|
323 break; |
|
324 case EGetAppUidsForComponentSize: |
|
325 server->RequestImpL()->GetAppUidsForComponentSizeL(aMessage); |
|
326 break; |
|
327 case EGetAppUidsForComponentData: |
|
328 server->RequestImpL()->GetAppUidsForComponentDataL(aMessage); |
|
329 break; |
|
330 case EGenerateNonNativeAppUid: |
|
331 server->RequestImpL()->GenerateNonNativeAppUidL(aMessage); |
|
332 break; |
|
333 case EGetApplicationLaunchersSize: |
|
334 server->RequestImpL()->GetApplicationLaunchersSizeL(aMessage); |
|
335 break; |
|
336 case EGetApplicationLaunchersData: |
|
337 server->RequestImpL()->GetApplicationLaunchersDataL(aMessage); |
|
338 break; |
|
339 |
|
340 default: |
|
341 User::Leave(KErrNotSupported); |
|
342 break; |
|
343 }//End of switch. |
|
344 |
|
345 if(isImplicitTransaction) |
|
346 { |
|
347 MutatingOperationsPostambleL(*server); |
|
348 CleanupStack::Pop(server); |
|
349 } |
|
350 |
|
351 return ETrue; |
|
352 }//End of function DoServiceL |
|
353 |
|
354 |
|
355 void CScrSession::ApplySubsessionConstraintL(CScrServer& aServer) |
|
356 {// Check whether or not write operation is allowed. if a subsession is in progress |
|
357 // a mutating operation is not allowed to make the subsession results consistent. |
|
358 if(aServer.SubsessionCount() > 0) |
|
359 { |
|
360 DEBUG_PRINTF(_L8("Subsession in progress. Database write access was rejected!")); |
|
361 User::Leave(KErrScrReadOperationInProgress); |
|
362 } |
|
363 } |
|
364 |
|
365 void CScrSession::ApplyTransactionConstraintL(CScrServer& aServer, TBool& aCreateImplicitTransaction) |
|
366 {// Check whether a transaction is in progress and owned by this session. |
|
367 // A mutating operation is not allowed if the transaction owned by another session. |
|
368 if(aServer.IsTransactionInProgress()) |
|
369 {// A transaction is already in progress, check if it is owned by this session. |
|
370 if(!aServer.IsTransactionOwner(this)) |
|
371 { |
|
372 DEBUG_PRINTF(_L8("Transaction in progress owned by another session. Database write access was rejected!")); |
|
373 User::Leave(KErrScrWriteOperationInProgress); |
|
374 } |
|
375 aCreateImplicitTransaction = EFalse; |
|
376 } |
|
377 else if(aCreateImplicitTransaction) |
|
378 {// No transaction is in progress. Start an implicit transaction to improve |
|
379 // the performance of mutating APIs. The implicit transaction must be |
|
380 // committed when the API request is completed successfully, or rolled back |
|
381 // if a failure occurs while performing the request. |
|
382 aServer.RequestImpL()->CreateTransactionL(); |
|
383 aServer.SetTransactionOwner(this); |
|
384 } |
|
385 } |
|
386 |
|
387 void CScrSession::MutatingOperationsPreambleL(CScrServer& aServer, TScrSessionFunction aFunction, TBool& aIsTransactionImplicit) |
|
388 { |
|
389 // In SCR server, there can be ONLY ONE active TRANSACTION. Concurrent and nested |
|
390 // transactions are not supported. A transaction can committed/cancelled only by |
|
391 // its owning session. While a transaction in progress, other sessions can invoke |
|
392 // query APIs, but not mutating APIs. Only the owning session can invoke APIs altering |
|
393 // database data. Moreover, a reading session (subsession) cannot be created while a transaction |
|
394 // is in progress unless the transaction is owned by this session. A transaction cannot be created if a reading subsession exits. |
|
395 |
|
396 switch(aFunction) |
|
397 { |
|
398 case ECreateTransaction: |
|
399 { |
|
400 if(aServer.IsTransactionInProgress()) |
|
401 {// A new transaction cannot be started if there is another in progress |
|
402 User::Leave(KErrScrWriteOperationInProgress); |
|
403 } |
|
404 break; |
|
405 } |
|
406 case ERollbackTransaction: |
|
407 case ECommitTransaction: |
|
408 { |
|
409 if(!aServer.IsTransactionOwner(this)) |
|
410 { |
|
411 DEBUG_PRINTF(_L8("There is no active transaction owned by this session!")); |
|
412 User::Leave(KErrScrNoActiveTransaction); |
|
413 } |
|
414 break; |
|
415 } |
|
416 case ESetComponentLocalizableProperty: |
|
417 case ESetComponentNumericProperty: |
|
418 case ESetComponentBinaryProperty: |
|
419 case ESetFileStringProperty: |
|
420 case ESetFileNumericProperty: |
|
421 case ESetComponentName: |
|
422 case ESetComponentVendor: |
|
423 case ESetComponentVersion: |
|
424 case ESetIsComponentRemovable: |
|
425 case ESetIsComponentDrmProtected: |
|
426 case ESetIsComponentHidden: |
|
427 case ESetIsComponentKnownRevoked: |
|
428 case ESetIsComponentOriginVerified: |
|
429 case ESetComponentSize: |
|
430 case EDeleteComponentProperty: |
|
431 case EDeleteFileProperty: |
|
432 case EAddComponentDependency: |
|
433 case EDeleteComponentDependency: |
|
434 case ESetIsComponentPresent: |
|
435 { |
|
436 // These mutating operations consist of a single mutating database statement. |
|
437 // So, no need to create an implicit transaction |
|
438 TBool createImplicitTransaction = EFalse; |
|
439 ApplyTransactionConstraintL(aServer,createImplicitTransaction); |
|
440 break; |
|
441 } |
|
442 case EAddComponent: |
|
443 case ERegisterComponentFile: |
|
444 case EUnregisterComponentFile: |
|
445 case EDeleteComponent: |
|
446 case EAddSoftwareType: |
|
447 case EDeleteSoftwareType: |
|
448 case EGetDeletedMimeTypes: |
|
449 case EAddApplicationEntry: |
|
450 case EDeleteApplicationEntries: |
|
451 case EDeleteApplicationEntry: |
|
452 { |
|
453 // These mutating operations consist of two or more mutating database statements. |
|
454 // Therefore, an implicit transaction is begun if an explicit one doesn't exist. |
|
455 TBool createImplicitTransaction = ETrue; |
|
456 ApplyTransactionConstraintL(aServer,createImplicitTransaction); |
|
457 aIsTransactionImplicit = createImplicitTransaction; |
|
458 break; |
|
459 } |
|
460 default: |
|
461 // Other operations do NOT require write permission. Do nothing. |
|
462 break; |
|
463 } |
|
464 } |
|
465 |
|
466 void CScrSession::MutatingOperationsPostambleL(CScrServer& aServer) |
|
467 { |
|
468 // This function is called to commit the implicit transaction opened for a specific mutating request. |
|
469 aServer.RequestImpL()->CommitTransactionL(); |
|
470 aServer.SetTransactionOwner(NULL); |
|
471 } |
|
472 |
|
473 CScsSubsession* CScrSession::DoCreateSubsessionL(TInt aFunction, const RMessage2& /*aMessage*/) |
|
474 /** |
|
475 Override CScsSession::DoCreateSubsessionL by allocating a new SCR subsession object. |
|
476 |
|
477 @param aFunction Function identifier without SCS code. |
|
478 @param aMessage Standard server-side handle to message. |
|
479 @return New, initialized instance of CScrSubsession, ownership is transferred. |
|
480 */ |
|
481 { |
|
482 |
|
483 TScrSessionFunction f = static_cast<TScrSessionFunction>(aFunction); |
|
484 CScrServer *server = static_cast<CScrServer*>(&iServer); |
|
485 |
|
486 switch(f) |
|
487 { |
|
488 // Allow read operation even if another transaction is in progress for these views. |
|
489 case ESubSessCreateComponentsView: |
|
490 return CComponentViewSubsession::NewL(*this); |
|
491 case ESubSessCreateAppRegistryView: |
|
492 return CAppRegistrySubsession::NewL(*this); |
|
493 } |
|
494 |
|
495 // A read operation is disallowed for the following views incase a transaction from another session |
|
496 // is already in progress. |
|
497 if(server->IsTransactionInProgress() && !server->IsTransactionOwner(this)) |
|
498 { |
|
499 DEBUG_PRINTF(_L8("Transaction from another session is in progress. Subsession cannot be created!")); |
|
500 User::Leave(KErrScrWriteOperationInProgress); |
|
501 } |
|
502 |
|
503 switch(f) |
|
504 { |
|
505 case ESubSessCreateFileList: |
|
506 return CFileListSubsession::NewL(*this); |
|
507 case ESubSessCreateAppInfoView: |
|
508 return CAppInfoViewSubsession::NewL(*this); |
|
509 case ESubSessCreateAppRegInfo: |
|
510 return CApplicationRegInfoSubsession::NewL(*this); |
|
511 case ESubSessCreateRegInfoForApp: |
|
512 return CRegInfoForApplicationSubsession::NewL(*this); |
|
513 default: |
|
514 User::Leave(KErrNotSupported); |
|
515 /*lint -unreachable */ |
|
516 return 0; // avoid compiler warning |
|
517 } |
|
518 } |