1 /* |
|
2 * Copyright (c) 2008 - 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 "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: Java platform 2.0 javaapppreconverter process. |
|
15 * This process needs AllFiles capability to be able to read |
|
16 * the icon files of all midlets and to store midlet data |
|
17 * to the data cage of the javaappbackconverter process. |
|
18 * |
|
19 */ |
|
20 |
|
21 |
|
22 #include <e32base.h> |
|
23 #include <pathinfo.h> |
|
24 #include <driveinfo.h> |
|
25 #include <apgcli.h> |
|
26 #include <d32dbms.h> |
|
27 |
|
28 #include <mdatabasev2.h> |
|
29 #include <mmidlettablev2.h> |
|
30 #include <mmidlettableiterator.h> |
|
31 |
|
32 #include "javacommonutils.h" |
|
33 #include "javauids.h" |
|
34 #include "preconverter.h" |
|
35 #include "noarmlogs.h" |
|
36 |
|
37 const TInt KDelayWhenWaitingAppArc = 500000; |
|
38 const TUint32 KDBVersion = 0x0200; |
|
39 |
|
40 // Name for the system AMS DB policy |
|
41 _LIT(KUidSSystemAMSDbPolicy, "secure[102045FE]"); |
|
42 |
|
43 // Constant needed to access SystemAMS static database |
|
44 _LIT(KStaticDbFileName, "C:\\private\\100012A5\\DBS_102045FE_MIDP2SystemAMSStaticV2"); |
|
45 |
|
46 // This is in the private data cage of javaappbackconverter. |
|
47 // javaappbackconverter will destroy the files created to this directory |
|
48 // after it has done the back conversion. |
|
49 _LIT(KMidletExportDirectory, "C:\\private\\20022D90\\data\\"); |
|
50 |
|
51 // This is in the private data cage of usersettingsconfigurator. |
|
52 _LIT(KMidletExportDirectoryForUserSettings, "C:\\private\\20022E7A\\data\\"); |
|
53 |
|
54 // This is in the private data cage of javappconverter |
|
55 // javaappconverter will destroy the 'uids' file created to this directory |
|
56 // after it has made the conversion. |
|
57 _LIT(KUidsExportDirectory, "C:\\private\\2002121C\\data\\"); |
|
58 _LIT(KUidsExportDataFileName, "uids"); |
|
59 |
|
60 // These literals are used for logging midlet information found from db. |
|
61 _LIT8(KMLName, "\nname: "); |
|
62 _LIT8(KMLClassName, "\nclassName: "); |
|
63 _LIT8(KMLIdString, "\nidString: "); |
|
64 |
|
65 |
|
66 /** |
|
67 * To create new instance of this class. |
|
68 * |
|
69 * @param aFs - A reference to the file server. |
|
70 * @return Reference to the object of this class. |
|
71 * @exception If construction fails. |
|
72 */ |
|
73 CPreConverter* CPreConverter::NewLC(RFs& aFs) |
|
74 { |
|
75 CPreConverter* self = new(ELeave) CPreConverter(aFs); |
|
76 CleanupStack::PushL(self); |
|
77 self->ConstructL(); |
|
78 return self; |
|
79 } |
|
80 |
|
81 /** |
|
82 * To do 1st phase construction for this object. |
|
83 * |
|
84 * Adds this active object to the scheduler. |
|
85 */ |
|
86 CPreConverter::CPreConverter(RFs& aFs) : |
|
87 CActive(EPriorityStandard), iFs(aFs) |
|
88 { |
|
89 CActiveScheduler::Add(this); |
|
90 } |
|
91 |
|
92 /** |
|
93 * To do 2nd phase construction for this object. |
|
94 * |
|
95 * @exception If the method is not able to allocate necessary buffers. |
|
96 */ |
|
97 void CPreConverter::ConstructL() |
|
98 { |
|
99 JELOG2(EJavaConverters); |
|
100 |
|
101 iMidlets = new(ELeave) CMidletList(); |
|
102 iState = EConversionDataAlreadyGathered; |
|
103 } |
|
104 |
|
105 /** |
|
106 * Deletes this object. |
|
107 * All allocated resources are released. |
|
108 */ |
|
109 CPreConverter::~CPreConverter() |
|
110 { |
|
111 JELOG2(EJavaConverters); |
|
112 Cancel(); |
|
113 if (iMidlets) |
|
114 { |
|
115 iMidlets->ResetAndDestroy(); |
|
116 delete iMidlets; |
|
117 iMidlets = NULL; |
|
118 } |
|
119 } |
|
120 |
|
121 /** |
|
122 * To start preconversion |
|
123 */ |
|
124 void CPreConverter::Start() |
|
125 { |
|
126 JELOG2(EJavaConverters); |
|
127 iState = EConversionDataAlreadyGathered; |
|
128 CompleteRequest(); |
|
129 } |
|
130 |
|
131 /** |
|
132 * To stop whole preconversion. |
|
133 * Stops the active scheduler. |
|
134 */ |
|
135 void CPreConverter::Exit() |
|
136 { |
|
137 Deque(); |
|
138 CActiveScheduler::Stop(); |
|
139 } |
|
140 |
|
141 /** |
|
142 * To complete the request for this object. |
|
143 * |
|
144 * @Postconditions The following conditions are true immediately after |
|
145 * returning from this method. |
|
146 * - iStatus == KErrNone |
|
147 * - IsActive() == ETrue |
|
148 */ |
|
149 void CPreConverter::CompleteRequest() |
|
150 { |
|
151 JELOG2(EJavaConverters); |
|
152 |
|
153 TRequestStatus *status = &iStatus; |
|
154 User::RequestComplete(status, KErrNone); |
|
155 if (!IsActive()) |
|
156 { |
|
157 SetActive(); |
|
158 } |
|
159 } |
|
160 |
|
161 /** |
|
162 * To run this active object. |
|
163 * |
|
164 * The state logic is: |
|
165 * |
|
166 * EConversionDataAlreadyGathered: |
|
167 * if midlet export data file already exists, |
|
168 * active object exits from this state |
|
169 * |
|
170 * EFindOutInstalledMidlets: |
|
171 * iterate through all apps in AppArc, |
|
172 * if java app, |
|
173 * store all info available from AppArc to iMidlets |
|
174 * |
|
175 * EFillDataFromSystemAmsDb: |
|
176 * add info from SystemAMS DB to iMidlets |
|
177 * |
|
178 * EStoreData: |
|
179 * store data in iMidlets to a file |
|
180 * |
|
181 * EStopMidlets: |
|
182 * stop all running midlets |
|
183 * |
|
184 * EUnregisterMidlets |
|
185 * unregister all midlets in iMidlets from AppArc |
|
186 * |
|
187 * EExit: |
|
188 * free resources and exit |
|
189 * |
|
190 */ |
|
191 void CPreConverter::RunL() |
|
192 { |
|
193 JELOG2(EJavaConverters); |
|
194 |
|
195 switch (iState) |
|
196 { |
|
197 |
|
198 case EConversionDataAlreadyGathered: |
|
199 { |
|
200 LOG(EJavaConverters, EInfo, |
|
201 "CPreConverter::RunL EConversionDataAlreadyGathered"); |
|
202 |
|
203 TFileName exportDataFile(KMidletExportDirectory); |
|
204 exportDataFile.Append(KMidletExportDataFileName); |
|
205 TUint attributes; |
|
206 TInt err = iFs.Att(exportDataFile, attributes); |
|
207 if (KErrNone == err) |
|
208 { |
|
209 LOG(EJavaConverters, EInfo, |
|
210 "CPreConverter::RunL EConversionDataAlreadyGathered " |
|
211 "data file already exists. Can exit."); |
|
212 iState = EExit; |
|
213 } |
|
214 else |
|
215 { |
|
216 if ((KErrNotFound == err) || (KErrPathNotFound == err)) |
|
217 { |
|
218 // We come here only when OMJ is not currently installed |
|
219 // to the device. However, the device may still have |
|
220 // old OMJ database files. Clean them now to make sure |
|
221 // that e.g. old db schemas do not cause problems. |
|
222 LOG(EJavaConverters, EInfo, |
|
223 "CPreConverter::RunL EConversionDataAlreadyGathered " |
|
224 "Trying to destroy OMJ database files"); |
|
225 |
|
226 _LIT(KJavaOtaStorageDbPath, "C:\\private\\10281E17\\[200211dc]JavaOtaStorage.db"); |
|
227 err = iFs.Delete(KJavaOtaStorageDbPath); |
|
228 LOG1(EJavaConverters, EInfo, |
|
229 "CPreConverter::RunL EConversionDataAlreadyGathered " |
|
230 "Destroy C:\\private\\10281E17\\[200211dc]JavaOtaStorage.db, err %d", err); |
|
231 |
|
232 _LIT(KJavaOtaStorageJournalPath, "C:\\private\\10281E17\\[200211dc]JavaOtaStorage.db-journal"); |
|
233 err = iFs.Delete(KJavaOtaStorageJournalPath); |
|
234 LOG1(EJavaConverters, EInfo, |
|
235 "CPreConverter::RunL EConversionDataAlreadyGathered " |
|
236 "Destroy C:\\private\\10281E17\\[200211dc]JavaOtaStorage.db-journal, err %d", err); |
|
237 |
|
238 _LIT(KJavaStorageDbPath, "C:\\private\\10281E17\\[200211dc]JavaStorage.db"); |
|
239 err = iFs.Delete(KJavaStorageDbPath); |
|
240 LOG1(EJavaConverters, EInfo, |
|
241 "CPreConverter::RunL EConversionDataAlreadyGathered " |
|
242 "Destroy C:\\private\\10281E17\\[200211dc]JavaStorage.db, err %d", err); |
|
243 |
|
244 _LIT(KJavaStorageJournalPath, "C:\\private\\10281E17\\[200211dc]JavaStorage.db-journal"); |
|
245 err = iFs.Delete(KJavaStorageJournalPath); |
|
246 LOG1(EJavaConverters, EInfo, |
|
247 "CPreConverter::RunL EConversionDataAlreadyGathered " |
|
248 "Destroy C:\\private\\10281E17\\[200211dc]JavaStorage.db-journal, err %d", err); |
|
249 |
|
250 LOG(EJavaConverters, EInfo, |
|
251 "CPreConverter::RunL EConversionDataAlreadyGathered " |
|
252 "Data file does not exist yet. OK"); |
|
253 } |
|
254 else |
|
255 { |
|
256 LOG1(EJavaConverters, EInfo, |
|
257 "CPreConverter::RunL EConversionDataAlreadyGathered " |
|
258 "Checking data file attributes caused error %d", err); |
|
259 } |
|
260 iState = EFindOutInstalledMidlets; |
|
261 } |
|
262 CompleteRequest(); |
|
263 } |
|
264 break; |
|
265 |
|
266 case EFindOutInstalledMidlets: |
|
267 { |
|
268 LOG(EJavaConverters, EInfo, |
|
269 "CPreConverter::RunL EFindOutInstalledMidlets"); |
|
270 |
|
271 // Read all installed midlets from AppArc, |
|
272 // store info to iMidlets |
|
273 ReadMidletsFromAppArcL(); |
|
274 |
|
275 iState = EFillDataFromSystemAmsDb; |
|
276 CompleteRequest(); |
|
277 } |
|
278 break; |
|
279 |
|
280 case EFillDataFromSystemAmsDb: |
|
281 { |
|
282 LOG(EJavaConverters, EInfo, |
|
283 "CPreConverter::RunL EFillDataFromSystemAmsDb"); |
|
284 |
|
285 // Some of the necessary information is in SystemAMS DB, |
|
286 // read it now for each midlet in iMidlets |
|
287 AddDataFromSystemAmsDbL(); |
|
288 |
|
289 // Especially in R&D environment it is possible to that |
|
290 // AppArc contains some midlets that have not really |
|
291 // been installed to old S60 java environment. |
|
292 // SystemAMS DB does not contain any information of |
|
293 // these midlets. They must be removed now. |
|
294 RemoveInvalidMidlets(); |
|
295 |
|
296 iState = EStoreData; |
|
297 CompleteRequest(); |
|
298 } |
|
299 break; |
|
300 |
|
301 case EStoreData: |
|
302 { |
|
303 LOG(EJavaConverters, EInfo, |
|
304 "CPreConverter::RunL EStoreData"); |
|
305 |
|
306 if (iMidlets->Count() == 0) |
|
307 { |
|
308 // No midlets to convert |
|
309 WLOG(EJavaConverters, "CPreConverter::RunL EStoreData No midlets to convert."); |
|
310 } |
|
311 else |
|
312 { |
|
313 // Store the data directly to the data cage of |
|
314 // javaappbackconverter.exe |
|
315 TFileName exportDirectory(KMidletExportDirectory); |
|
316 iMidlets->ExportListL(iFs, exportDirectory); |
|
317 |
|
318 // Store the data also to the data cage of |
|
319 // usersettingsconfigurator.exe |
|
320 TFileName exportDirectoryForUserSettings(KMidletExportDirectoryForUserSettings); |
|
321 iMidlets->ExportListL(iFs, exportDirectoryForUserSettings); |
|
322 |
|
323 // Store the uids of the midlets to be converted |
|
324 // to the data cage of javaappconverter.exe |
|
325 StoreUidsL(); |
|
326 } |
|
327 |
|
328 iState = EStopMidlets; |
|
329 CompleteRequest(); |
|
330 } |
|
331 break; |
|
332 |
|
333 case EStopMidlets: |
|
334 { |
|
335 LOG(EJavaConverters, EInfo, |
|
336 "CPreConverter::RunL EStopMidlets"); |
|
337 |
|
338 CMidletInfo* pMidlet = iMidlets->GetFirst(); |
|
339 |
|
340 TFullName foundName; |
|
341 TFullName searchName; |
|
342 |
|
343 while (pMidlet != NULL) |
|
344 { |
|
345 searchName = pMidlet->GetMidletName(); |
|
346 _LIT(KMidletProcessIdString, "[102033e6]*"); |
|
347 searchName.Append(KMidletProcessIdString); |
|
348 |
|
349 LOG1WSTR(EJavaConverters, EInfo, "Searching midlet process named %s", |
|
350 (wchar_t *)(searchName.PtrZ())); |
|
351 |
|
352 TFindProcess find(searchName); |
|
353 TInt err = find.Next(foundName); |
|
354 if (KErrNone == err) |
|
355 { |
|
356 LOG1WSTR(EJavaConverters, EInfo, "The midlet process %s was found", |
|
357 (wchar_t *)(foundName.PtrZ())); |
|
358 RProcess process; |
|
359 err = process.Open(find); |
|
360 if (KErrNone == err) |
|
361 { |
|
362 LOG(EJavaConverters, EInfo, "Killing the midlet process"); |
|
363 process.Kill(KErrNone); |
|
364 process.Close(); |
|
365 } |
|
366 } |
|
367 |
|
368 pMidlet = iMidlets->GetNext(); |
|
369 } |
|
370 |
|
371 iState = EUnregisterMidlets; |
|
372 CompleteRequest(); |
|
373 } |
|
374 break; |
|
375 |
|
376 case EUnregisterMidlets: |
|
377 { |
|
378 LOG(EJavaConverters, EInfo, "CPreConverter::RunL EUnregisterMidlets"); |
|
379 |
|
380 // Unregister all midlets in iMidlets from AppArc |
|
381 UnregisterOldJavaAppsL(); |
|
382 |
|
383 iState = EExit; |
|
384 CompleteRequest(); |
|
385 } |
|
386 break; |
|
387 |
|
388 case EExit: |
|
389 { |
|
390 LOG(EJavaConverters, EInfo, "CPreConverter::RunL EExit"); |
|
391 |
|
392 FullCleanup(); |
|
393 |
|
394 // The whole javaapppreconverter process is stopped. |
|
395 Exit(); |
|
396 } |
|
397 break; |
|
398 |
|
399 } |
|
400 } |
|
401 |
|
402 /** |
|
403 * To handle leave from RunL. |
|
404 * This method exits this active object using normal state machine |
|
405 * After calling this method this active object will exit. |
|
406 * |
|
407 * @param aError - A reason of error. |
|
408 * @return KErrNone. |
|
409 */ |
|
410 TInt CPreConverter::RunError(TInt aError) |
|
411 { |
|
412 ELOG2(EJavaConverters, |
|
413 "CPreConverter::RunError(%d) from state %d", aError, iState); |
|
414 |
|
415 Cancel(); |
|
416 |
|
417 iState = EExit; |
|
418 CompleteRequest(); |
|
419 |
|
420 return KErrNone; |
|
421 } |
|
422 |
|
423 /** |
|
424 * To do cancelling for this object. |
|
425 * |
|
426 */ |
|
427 void CPreConverter::DoCancel() |
|
428 { |
|
429 ELOG1(EJavaConverters, |
|
430 "CPreConverter::DoCancel from state %d", iState); |
|
431 |
|
432 } |
|
433 |
|
434 /** |
|
435 * To cleanup member variables. |
|
436 * |
|
437 */ |
|
438 void CPreConverter::FullCleanup() |
|
439 { |
|
440 JELOG2(EJavaPreinstaller); |
|
441 |
|
442 if (iMidlets) |
|
443 { |
|
444 iMidlets->ResetAndDestroy(); |
|
445 delete iMidlets; |
|
446 iMidlets = NULL; |
|
447 } |
|
448 } |
|
449 |
|
450 /** |
|
451 * Read all midlets from AppArc. |
|
452 * Store midlet Uid, Midlet name, installation drive, |
|
453 * group name and icon file path name to iMidlets. |
|
454 */ |
|
455 void CPreConverter::ReadMidletsFromAppArcL() |
|
456 { |
|
457 JELOG2(EJavaConverters); |
|
458 |
|
459 TInt retryCounter = 10; |
|
460 TUid appTypeUid; |
|
461 HBufC *pIconFilePathName = NULL; |
|
462 TApaAppInfo info; |
|
463 RApaLsSession apaSession; |
|
464 TApaAppCapabilityBuf cbuf; |
|
465 TApaAppCapability capability; |
|
466 |
|
467 TBuf8<512> midletDesc; |
|
468 |
|
469 |
|
470 TInt err = apaSession.Connect(); |
|
471 if (KErrNone != err) |
|
472 { |
|
473 ELOG1(EJavaConverters, |
|
474 "CPreConverter::ReadMidletsFromAppArcL RApaLsSession Connect error %d", err); |
|
475 User::Leave(err); |
|
476 } |
|
477 CleanupClosePushL(apaSession); |
|
478 |
|
479 // Get the process of getting the list of all non native applications |
|
480 // (mostly java applications) |
|
481 err = |
|
482 apaSession.GetFilteredApps( |
|
483 TApaAppCapability::ENonNative, TApaAppCapability::ENonNative); |
|
484 |
|
485 do |
|
486 { |
|
487 err = apaSession.GetNextApp(info); |
|
488 if (RApaLsSession::EAppListInvalid == err) |
|
489 { |
|
490 // Application list has not yet been populated, |
|
491 // try again after a short delay |
|
492 retryCounter--; |
|
493 if (retryCounter > 0) |
|
494 { |
|
495 User::After(KDelayWhenWaitingAppArc); |
|
496 continue; |
|
497 } |
|
498 else |
|
499 { |
|
500 ELOG(EJavaConverters, |
|
501 "CPreConverter::ReadMidletsFromAppArcL RApaLsSession " |
|
502 "GetNext returned EAppListInvalid for 10 times, error"); |
|
503 User::Leave(err); |
|
504 } |
|
505 } |
|
506 else if (KErrNone == err) |
|
507 { |
|
508 // Info contains valid app info. Now check whether it is java app |
|
509 err = apaSession.GetAppType(appTypeUid, info.iUid); |
|
510 if (KErrNone != err) |
|
511 { |
|
512 ELOG1(EJavaConverters, |
|
513 "CPreConverter::ReadMidletsFromAppArcL RApaLsSession " |
|
514 "GetAppType returned error %d", err); |
|
515 User::Leave(err); |
|
516 } |
|
517 if (appTypeUid.iUid == KMidletApplicationTypeUid) |
|
518 { |
|
519 // This is java application. Store info to list. |
|
520 CMidletInfo *midletInfo = new(ELeave) CMidletInfo(); |
|
521 midletInfo->SetMidletUid(info.iUid); |
|
522 midletInfo->SetMidletName(info.iCaption); |
|
523 midletInfo->SetDrive(ExtractDriveNumberFromPathL(info.iFullName)); |
|
524 |
|
525 // Get group name |
|
526 err = apaSession.GetAppCapability(cbuf, info.iUid); |
|
527 if (KErrNone != err) |
|
528 { |
|
529 ELOG1(EJavaConverters, |
|
530 "CPreConverter::ReadMidletsFromAppArcL RApaLsSession " |
|
531 "GetAppCapability returned error %d", err); |
|
532 User::Leave(err); |
|
533 } |
|
534 capability = cbuf(); |
|
535 midletInfo->SetGroupName(capability.iGroupName); |
|
536 |
|
537 // Get icon file path name |
|
538 err = apaSession.GetAppIcon(info.iUid, pIconFilePathName); |
|
539 if ((KErrNone != err) || (NULL == pIconFilePathName)) |
|
540 { |
|
541 ELOG1(EJavaConverters, |
|
542 "CPreConverter::ReadMidletsFromAppArcL RApaLsSession " |
|
543 "GetAppIcon returned error %d", err); |
|
544 User::Leave(err); |
|
545 } |
|
546 midletInfo->SetIconFileName(pIconFilePathName); |
|
547 delete pIconFilePathName; |
|
548 pIconFilePathName = NULL; |
|
549 |
|
550 err = iMidlets->Append(midletInfo); |
|
551 if (KErrNone != err) |
|
552 { |
|
553 ELOG1(EJavaConverters, |
|
554 "CPreConverter::ReadMidletsFromAppArcL CMidletList " |
|
555 "Append returned error %d", err); |
|
556 User::Leave(err); |
|
557 } |
|
558 else |
|
559 { |
|
560 midletInfo->ToString8(midletDesc); |
|
561 LOG(EJavaConverters, EInfo, |
|
562 "CPreConverter::ReadMidletsFromAppArcL Added this midlet:"); |
|
563 midletDesc.ZeroTerminate(); |
|
564 LOG(EJavaPreinstaller, EInfo, (const char *)(midletDesc.Ptr())); |
|
565 midletDesc.Zero(); |
|
566 } |
|
567 } |
|
568 } |
|
569 |
|
570 } |
|
571 while (KErrNone == err); |
|
572 |
|
573 if (RApaLsSession::ENoMoreAppsInList != err) |
|
574 { |
|
575 ELOG1(EJavaConverters, |
|
576 "CPreConverter::ReadMidletsFromAppArcL RApaLsSession GetNext returned error %d", err); |
|
577 User::Leave(err); |
|
578 } |
|
579 |
|
580 CleanupStack::PopAndDestroy(); // apaSession |
|
581 } |
|
582 |
|
583 /** |
|
584 * Parse the drive letter from path and return it as TDriveNumber. |
|
585 * |
|
586 * @param aPathName full path name. Contains always the drive. |
|
587 * @return the drive number |
|
588 * @exception if the drive cannot parsed from path |
|
589 */ |
|
590 TDriveNumber CPreConverter::ExtractDriveNumberFromPathL(TFileName &aPathName) |
|
591 { |
|
592 TDriveNumber drive = EDriveE; |
|
593 TUint driveLetter = aPathName[0]; |
|
594 |
|
595 if ((driveLetter >= 'a') && (driveLetter <= 'z')) |
|
596 { |
|
597 drive = (TDriveNumber)(driveLetter - 'a'); |
|
598 } |
|
599 else if ((driveLetter >= 'A') && (driveLetter <= 'Z')) |
|
600 { |
|
601 drive = (TDriveNumber)(driveLetter - 'A'); |
|
602 } |
|
603 else |
|
604 { |
|
605 ELOG1(EJavaConverters, |
|
606 "CPreConverter::ExtractDriveNumberFromPathL path starts " |
|
607 "with illegal char, value %d", drive); |
|
608 User::Leave(KErrArgument); |
|
609 } |
|
610 |
|
611 return drive; |
|
612 } |
|
613 |
|
614 /** |
|
615 * Read the midlet id and suite id for each midlet in iMidlets from |
|
616 * SystemAMS DB and store them to iMidlets |
|
617 */ |
|
618 void CPreConverter::AddDataFromSystemAmsDbL() |
|
619 { |
|
620 MIDP::DBv2::MDatabase* database = NULL; |
|
621 MIDP::DBv2::MMIDletTable* midletTable = NULL; |
|
622 RDbNamedDatabase dbNamed; |
|
623 RDbs dbs; |
|
624 |
|
625 // Connect to db |
|
626 TInt err = dbs.Connect(); |
|
627 if (KErrNone != err) |
|
628 { |
|
629 ELOG1(EJavaConverters, |
|
630 "CPreConverter::AddDataFromSystemAmsDbL Cannot connect to RDbs, " |
|
631 "error %d", err); |
|
632 User::Leave(err); |
|
633 } |
|
634 |
|
635 // Open db |
|
636 err = dbs.ShareAuto(); |
|
637 if (KErrNone != err) |
|
638 { |
|
639 dbs.Close(); |
|
640 ELOG1(EJavaConverters, |
|
641 "CPreConverter::AddDataFromSystemAmsDbL Cannot share RDbs session, " |
|
642 "error %d", err); |
|
643 User::Leave(err); |
|
644 } |
|
645 err = dbNamed.Open( |
|
646 iFs, KStaticDbFileName(), KUidSSystemAMSDbPolicy, RDbNamedDatabase::EReadOnly); |
|
647 if (KErrNone != err) |
|
648 { |
|
649 dbs.Close(); |
|
650 ELOG1(EJavaConverters, |
|
651 "CPreConverter::AddDataFromSystemAmsDbL Cannot open named db, " |
|
652 "error %d", err); |
|
653 User::Leave(err); |
|
654 } |
|
655 |
|
656 // Get db |
|
657 TRAP(err, database = MIDP::DBv2::GetDatabaseL(KDBVersion)); |
|
658 if (KErrNone != err) |
|
659 { |
|
660 dbNamed.Close(); |
|
661 dbs.Close(); |
|
662 ELOG1(EJavaConverters, |
|
663 "CPreConverter::AddDataFromSystemAmsDbL Cannot get database, " |
|
664 "error %d", err); |
|
665 User::Leave(err); |
|
666 } |
|
667 |
|
668 // Get midlet table |
|
669 TRAP(err, midletTable = database->MIDletTableL()); |
|
670 if (KErrNone != err) |
|
671 { |
|
672 delete database; |
|
673 dbNamed.Close(); |
|
674 dbs.Close(); |
|
675 ELOG1(EJavaConverters, |
|
676 "CPreConverter::AddDataFromSystemAmsDbL Cannot get midlet table from db, " |
|
677 "error %d", err); |
|
678 User::Leave(err); |
|
679 } |
|
680 |
|
681 // Open midlet table |
|
682 TRAP(err, midletTable->OpenL(dbNamed)); |
|
683 if (KErrNone != err) |
|
684 { |
|
685 delete database; |
|
686 dbNamed.Close(); |
|
687 dbs.Close(); |
|
688 ELOG1(EJavaConverters, |
|
689 "CPreConverter::AddDataFromSystemAmsDbL Cannot open midlet table in db, " |
|
690 "error %d", err); |
|
691 User::Leave(err); |
|
692 } |
|
693 |
|
694 // get iterator to access the data in midlet table |
|
695 MIDP::DBv2::MMIDletTableIterator* tableIterator = NULL; |
|
696 // No items must be left in cleanup stack when exiting TRAP macro |
|
697 TRAP(err, |
|
698 tableIterator = midletTable->IteratorLC(); |
|
699 if (KErrNone == err) CleanupStack::Pop(); |
|
700 ); |
|
701 if (KErrNone != err) |
|
702 { |
|
703 midletTable->Close(); |
|
704 delete database; |
|
705 dbNamed.Close(); |
|
706 dbs.Close(); |
|
707 ELOG1(EJavaConverters, |
|
708 "CPreConverter::AddDataFromSystemAmsDbL Cannot get iterator for midlet table in db, " |
|
709 "error %d", err); |
|
710 User::Leave(err); |
|
711 } |
|
712 |
|
713 |
|
714 TBuf8<512> midletDesc; |
|
715 TInt32 count = 0; |
|
716 TUint32 msId; |
|
717 TUint32 id; |
|
718 TUint32 uid; |
|
719 TPtrC name; |
|
720 TPtrC className; |
|
721 TPtrC idString; |
|
722 while (tableIterator->HasNext()) |
|
723 { |
|
724 TRAP(err, tableIterator->NextL(msId, id, uid, name, className, idString)); |
|
725 if (KErrNone != err) |
|
726 { |
|
727 delete tableIterator; |
|
728 midletTable->Close(); |
|
729 delete database; |
|
730 dbNamed.Close(); |
|
731 dbs.Close(); |
|
732 ELOG1(EJavaConverters, |
|
733 "CPreConverter::AddDataFromSystemAmsDbL Midlet table iterator NextL failed, " |
|
734 "error %d", err); |
|
735 User::Leave(err); |
|
736 } |
|
737 LOG3(EJavaConverters, EInfo, |
|
738 "CPreConverter::AddDataFromSystemAmsDbL Found midlet uid %x, suite id %d, midlet id %d", |
|
739 uid, msId, id); |
|
740 |
|
741 midletDesc.Append(KMLName); |
|
742 midletDesc.Append(name); |
|
743 midletDesc.Append(KMLClassName); |
|
744 midletDesc.Append(className); |
|
745 midletDesc.Append(KMLIdString); |
|
746 midletDesc.Append(idString); |
|
747 LOG(EJavaPreinstaller, EInfo, (const char *)midletDesc.PtrZ()); |
|
748 midletDesc.Zero(); |
|
749 |
|
750 iMidlets->SetIds(name, msId, id); |
|
751 count++; |
|
752 } |
|
753 |
|
754 LOG1(EJavaConverters, EInfo, |
|
755 "CPreConverter::AddDataFromSystemAmsDbL midlet table had %d midlets.", count); |
|
756 |
|
757 // close and free everything |
|
758 delete tableIterator; |
|
759 midletTable->Close(); |
|
760 delete database; |
|
761 dbNamed.Close(); |
|
762 dbs.Close(); |
|
763 } |
|
764 |
|
765 /** |
|
766 * Check all midlets in iMidlets and remove those midlets that do not |
|
767 * have midlet id and suite id. |
|
768 */ |
|
769 void CPreConverter::RemoveInvalidMidlets() |
|
770 { |
|
771 // If midlet id or suite id is KMaxTUint32, it has not been set -> |
|
772 // remove the midlet |
|
773 |
|
774 CMidletInfo *midlet = iMidlets->GetFirst(); |
|
775 TBuf8<512> midletDesc; |
|
776 |
|
777 while (NULL != midlet) |
|
778 { |
|
779 if ((midlet->GetMidletId() == KMaxTUint32) || |
|
780 (midlet->GetSuiteId() == KMaxTUint32)) |
|
781 { |
|
782 midlet->ToString8(midletDesc); |
|
783 WLOG(EJavaConverters, |
|
784 "CPreConverter::RemoveInvalidMidlets Not going to convert this midlet:"); |
|
785 midletDesc.ZeroTerminate(); |
|
786 WLOG(EJavaPreinstaller, (const char *)(midletDesc.Ptr())); |
|
787 midletDesc.Zero(); |
|
788 iMidlets->Remove(midlet); |
|
789 } |
|
790 |
|
791 midlet = iMidlets->GetNext(); |
|
792 } |
|
793 } |
|
794 |
|
795 /** |
|
796 * Store the uids of the midlets to be converted |
|
797 * to file 'uids' in the data cage of javaappconverter.exe |
|
798 */ |
|
799 void CPreConverter::StoreUidsL() |
|
800 { |
|
801 TFileName exportUidsPath(KUidsExportDirectory); |
|
802 |
|
803 // Create directory if it does not exist |
|
804 TInt err= iFs.MkDirAll(exportUidsPath); |
|
805 if ((KErrNone != err) && (KErrAlreadyExists != err)) |
|
806 { |
|
807 User::Leave(err); |
|
808 } |
|
809 |
|
810 // Store all uids to file 'uids' in the directory |
|
811 exportUidsPath.Append(KUidsExportDataFileName); |
|
812 |
|
813 // Construct write stream so that possibly existing old data file is replaced. |
|
814 RFileWriteStream writeStream; |
|
815 User::LeaveIfError(writeStream.Replace(iFs, exportUidsPath, EFileWrite)); |
|
816 CleanupClosePushL(writeStream); |
|
817 |
|
818 // Write the number of midlets |
|
819 TUint32 nMidlets = iMidlets->Count(); |
|
820 writeStream.WriteUint32L(nMidlets); |
|
821 |
|
822 // Write Uids of the midlets one by one |
|
823 CMidletInfo *midlet = iMidlets->GetFirst(); |
|
824 |
|
825 while (NULL != midlet) |
|
826 { |
|
827 writeStream.WriteUint32L(midlet->GetMidletUid().iUid); |
|
828 midlet = iMidlets->GetNext(); |
|
829 } |
|
830 |
|
831 // Closes writeStream |
|
832 CleanupStack::PopAndDestroy(); |
|
833 } |
|
834 |
|
835 /** |
|
836 * Unregisters the applications to be converted from AppArc |
|
837 * so that Java Installer can make conversion installation |
|
838 * using the same Uids as the applications now have. |
|
839 * |
|
840 * Leaves with error code if AppArc cannot be connected or if |
|
841 * unregistrations cannot be committed. |
|
842 */ |
|
843 void CPreConverter::UnregisterOldJavaAppsL() |
|
844 { |
|
845 // connect to AppArc |
|
846 RApaLsSession apaSession; |
|
847 |
|
848 TInt err = apaSession.Connect(); |
|
849 if (KErrNone != err) |
|
850 { |
|
851 // Fatal error, try to connect again. The midlets cannot be converted |
|
852 // using the same uids as earlier if the unregistration cannot be done. |
|
853 TInt retryCount = 0; |
|
854 do |
|
855 { |
|
856 ELOG1(EJavaConverters, |
|
857 "CPreConverter::UnregisterOldJavaAppsL Cannot connect to " |
|
858 "AppArc server, err %d", err); |
|
859 |
|
860 // wait |
|
861 User::After(KDelayWhenWaitingAppArc); |
|
862 |
|
863 err = apaSession.Connect(); |
|
864 if (KErrNone == err) |
|
865 { |
|
866 break; |
|
867 } |
|
868 |
|
869 retryCount++; |
|
870 } |
|
871 while (retryCount < 10); |
|
872 |
|
873 if (KErrNone != err) |
|
874 { |
|
875 User::Leave(err); |
|
876 } |
|
877 } |
|
878 CleanupClosePushL(apaSession); |
|
879 |
|
880 // Delete any pending (un)registrations (possible if |
|
881 // e.g. device rebooted before commit). |
|
882 // This call does nothing if there is no pending registrations. |
|
883 // Ignore errors. |
|
884 (void)apaSession.RollbackNonNativeApplicationsUpdates(); |
|
885 |
|
886 // Prepare for Java application unregistrations |
|
887 TRAP(err, apaSession.PrepareNonNativeApplicationsUpdatesL()); |
|
888 if (KErrNone != err) |
|
889 { |
|
890 ELOG1(EJavaConverters, |
|
891 "CPreConverter::UnregisterOldJavaAppsL: " |
|
892 "PrepareNonNativeApplicationsUpdatesL leaved with err %d", |
|
893 err); |
|
894 User::Leave(err); |
|
895 } |
|
896 |
|
897 // Unregister all apps |
|
898 CMidletInfo *midlet = iMidlets->GetFirst(); |
|
899 |
|
900 while (NULL != midlet) |
|
901 { |
|
902 TRAP(err, apaSession.DeregisterNonNativeApplicationL(midlet->GetMidletUid())); |
|
903 if (KErrNone != err) |
|
904 { |
|
905 WLOG2(EJavaConverters, |
|
906 "CPreConverter::UnregisterOldJavaAppsL: " |
|
907 "DeregisterNonNativeApplicationL leaved with err %d for uid %d", |
|
908 err, midlet->GetMidletUid().iUid); |
|
909 // Ignore error, this particular application cannot be converted. |
|
910 } |
|
911 |
|
912 midlet = iMidlets->GetNext(); |
|
913 } |
|
914 |
|
915 // Commit unregistrations |
|
916 TRAP(err, apaSession.CommitNonNativeApplicationsUpdatesL()) |
|
917 { |
|
918 if (KErrNone != err) |
|
919 { |
|
920 ELOG1(EJavaConverters, |
|
921 "CPreConverter::UnregisterOldJavaAppsL: " |
|
922 "CommitNonNativeApplicationsUpdatesL leaved with err %d", |
|
923 err); |
|
924 User::Leave(err); |
|
925 } |
|
926 } |
|
927 |
|
928 // Closes apaSession |
|
929 CleanupStack::PopAndDestroy(); |
|
930 } |
|
931 |
|