diff -r f5050f1da672 -r 04becd199f91 javatools/javaapppreconverter/src.s60/preconverter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javatools/javaapppreconverter/src.s60/preconverter.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,931 @@ +/* +* Copyright (c) 2008 - 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Java platform 2.0 javaapppreconverter process. +* This process needs AllFiles capability to be able to read +* the icon files of all midlets and to store midlet data +* to the data cage of the javaappbackconverter process. +* +*/ + + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "javacommonutils.h" +#include "javauids.h" +#include "preconverter.h" +#include "noarmlogs.h" + +const TInt KDelayWhenWaitingAppArc = 500000; +const TUint32 KDBVersion = 0x0200; + +// Name for the system AMS DB policy +_LIT(KUidSSystemAMSDbPolicy, "secure[102045FE]"); + +// Constant needed to access SystemAMS static database +_LIT(KStaticDbFileName, "C:\\private\\100012A5\\DBS_102045FE_MIDP2SystemAMSStaticV2"); + +// This is in the private data cage of javaappbackconverter. +// javaappbackconverter will destroy the files created to this directory +// after it has done the back conversion. +_LIT(KMidletExportDirectory, "C:\\private\\20022D90\\data\\"); + +// This is in the private data cage of usersettingsconfigurator. +_LIT(KMidletExportDirectoryForUserSettings, "C:\\private\\20022E7A\\data\\"); + +// This is in the private data cage of javappconverter +// javaappconverter will destroy the 'uids' file created to this directory +// after it has made the conversion. +_LIT(KUidsExportDirectory, "C:\\private\\2002121C\\data\\"); +_LIT(KUidsExportDataFileName, "uids"); + +// These literals are used for logging midlet information found from db. +_LIT8(KMLName, "\nname: "); +_LIT8(KMLClassName, "\nclassName: "); +_LIT8(KMLIdString, "\nidString: "); + + +/** + * To create new instance of this class. + * + * @param aFs - A reference to the file server. + * @return Reference to the object of this class. + * @exception If construction fails. + */ +CPreConverter* CPreConverter::NewLC(RFs& aFs) +{ + CPreConverter* self = new(ELeave) CPreConverter(aFs); + CleanupStack::PushL(self); + self->ConstructL(); + return self; +} + +/** + * To do 1st phase construction for this object. + * + * Adds this active object to the scheduler. + */ +CPreConverter::CPreConverter(RFs& aFs) : + CActive(EPriorityStandard), iFs(aFs) +{ + CActiveScheduler::Add(this); +} + +/** + * To do 2nd phase construction for this object. + * + * @exception If the method is not able to allocate necessary buffers. + */ +void CPreConverter::ConstructL() +{ + JELOG2(EJavaConverters); + + iMidlets = new(ELeave) CMidletList(); + iState = EConversionDataAlreadyGathered; +} + +/** + * Deletes this object. + * All allocated resources are released. + */ +CPreConverter::~CPreConverter() +{ + JELOG2(EJavaConverters); + Cancel(); + if (iMidlets) + { + iMidlets->ResetAndDestroy(); + delete iMidlets; + iMidlets = NULL; + } +} + +/** + * To start preconversion + */ +void CPreConverter::Start() +{ + JELOG2(EJavaConverters); + iState = EConversionDataAlreadyGathered; + CompleteRequest(); +} + +/** + * To stop whole preconversion. + * Stops the active scheduler. + */ +void CPreConverter::Exit() +{ + Deque(); + CActiveScheduler::Stop(); +} + +/** + * To complete the request for this object. + * + * @Postconditions The following conditions are true immediately after + * returning from this method. + * - iStatus == KErrNone + * - IsActive() == ETrue + */ +void CPreConverter::CompleteRequest() +{ + JELOG2(EJavaConverters); + + TRequestStatus *status = &iStatus; + User::RequestComplete(status, KErrNone); + if (!IsActive()) + { + SetActive(); + } +} + +/** + * To run this active object. + * + * The state logic is: + * + * EConversionDataAlreadyGathered: + * if midlet export data file already exists, + * active object exits from this state + * + * EFindOutInstalledMidlets: + * iterate through all apps in AppArc, + * if java app, + * store all info available from AppArc to iMidlets + * + * EFillDataFromSystemAmsDb: + * add info from SystemAMS DB to iMidlets + * + * EStoreData: + * store data in iMidlets to a file + * + * EStopMidlets: + * stop all running midlets + * + * EUnregisterMidlets + * unregister all midlets in iMidlets from AppArc + * + * EExit: + * free resources and exit + * + */ +void CPreConverter::RunL() +{ + JELOG2(EJavaConverters); + + switch (iState) + { + + case EConversionDataAlreadyGathered: + { + LOG(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered"); + + TFileName exportDataFile(KMidletExportDirectory); + exportDataFile.Append(KMidletExportDataFileName); + TUint attributes; + TInt err = iFs.Att(exportDataFile, attributes); + if (KErrNone == err) + { + LOG(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered " + "data file already exists. Can exit."); + iState = EExit; + } + else + { + if ((KErrNotFound == err) || (KErrPathNotFound == err)) + { + // We come here only when OMJ is not currently installed + // to the device. However, the device may still have + // old OMJ database files. Clean them now to make sure + // that e.g. old db schemas do not cause problems. + LOG(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered " + "Trying to destroy OMJ database files"); + + _LIT(KJavaOtaStorageDbPath, "C:\\private\\10281E17\\[200211dc]JavaOtaStorage.db"); + err = iFs.Delete(KJavaOtaStorageDbPath); + LOG1(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered " + "Destroy C:\\private\\10281E17\\[200211dc]JavaOtaStorage.db, err %d", err); + + _LIT(KJavaOtaStorageJournalPath, "C:\\private\\10281E17\\[200211dc]JavaOtaStorage.db-journal"); + err = iFs.Delete(KJavaOtaStorageJournalPath); + LOG1(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered " + "Destroy C:\\private\\10281E17\\[200211dc]JavaOtaStorage.db-journal, err %d", err); + + _LIT(KJavaStorageDbPath, "C:\\private\\10281E17\\[200211dc]JavaStorage.db"); + err = iFs.Delete(KJavaStorageDbPath); + LOG1(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered " + "Destroy C:\\private\\10281E17\\[200211dc]JavaStorage.db, err %d", err); + + _LIT(KJavaStorageJournalPath, "C:\\private\\10281E17\\[200211dc]JavaStorage.db-journal"); + err = iFs.Delete(KJavaStorageJournalPath); + LOG1(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered " + "Destroy C:\\private\\10281E17\\[200211dc]JavaStorage.db-journal, err %d", err); + + LOG(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered " + "Data file does not exist yet. OK"); + } + else + { + LOG1(EJavaConverters, EInfo, + "CPreConverter::RunL EConversionDataAlreadyGathered " + "Checking data file attributes caused error %d", err); + } + iState = EFindOutInstalledMidlets; + } + CompleteRequest(); + } + break; + + case EFindOutInstalledMidlets: + { + LOG(EJavaConverters, EInfo, + "CPreConverter::RunL EFindOutInstalledMidlets"); + + // Read all installed midlets from AppArc, + // store info to iMidlets + ReadMidletsFromAppArcL(); + + iState = EFillDataFromSystemAmsDb; + CompleteRequest(); + } + break; + + case EFillDataFromSystemAmsDb: + { + LOG(EJavaConverters, EInfo, + "CPreConverter::RunL EFillDataFromSystemAmsDb"); + + // Some of the necessary information is in SystemAMS DB, + // read it now for each midlet in iMidlets + AddDataFromSystemAmsDbL(); + + // Especially in R&D environment it is possible to that + // AppArc contains some midlets that have not really + // been installed to old S60 java environment. + // SystemAMS DB does not contain any information of + // these midlets. They must be removed now. + RemoveInvalidMidlets(); + + iState = EStoreData; + CompleteRequest(); + } + break; + + case EStoreData: + { + LOG(EJavaConverters, EInfo, + "CPreConverter::RunL EStoreData"); + + if (iMidlets->Count() == 0) + { + // No midlets to convert + WLOG(EJavaConverters, "CPreConverter::RunL EStoreData No midlets to convert."); + } + else + { + // Store the data directly to the data cage of + // javaappbackconverter.exe + TFileName exportDirectory(KMidletExportDirectory); + iMidlets->ExportListL(iFs, exportDirectory); + + // Store the data also to the data cage of + // usersettingsconfigurator.exe + TFileName exportDirectoryForUserSettings(KMidletExportDirectoryForUserSettings); + iMidlets->ExportListL(iFs, exportDirectoryForUserSettings); + + // Store the uids of the midlets to be converted + // to the data cage of javaappconverter.exe + StoreUidsL(); + } + + iState = EStopMidlets; + CompleteRequest(); + } + break; + + case EStopMidlets: + { + LOG(EJavaConverters, EInfo, + "CPreConverter::RunL EStopMidlets"); + + CMidletInfo* pMidlet = iMidlets->GetFirst(); + + TFullName foundName; + TFullName searchName; + + while (pMidlet != NULL) + { + searchName = pMidlet->GetMidletName(); + _LIT(KMidletProcessIdString, "[102033e6]*"); + searchName.Append(KMidletProcessIdString); + + LOG1WSTR(EJavaConverters, EInfo, "Searching midlet process named %s", + (wchar_t *)(searchName.PtrZ())); + + TFindProcess find(searchName); + TInt err = find.Next(foundName); + if (KErrNone == err) + { + LOG1WSTR(EJavaConverters, EInfo, "The midlet process %s was found", + (wchar_t *)(foundName.PtrZ())); + RProcess process; + err = process.Open(find); + if (KErrNone == err) + { + LOG(EJavaConverters, EInfo, "Killing the midlet process"); + process.Kill(KErrNone); + process.Close(); + } + } + + pMidlet = iMidlets->GetNext(); + } + + iState = EUnregisterMidlets; + CompleteRequest(); + } + break; + + case EUnregisterMidlets: + { + LOG(EJavaConverters, EInfo, "CPreConverter::RunL EUnregisterMidlets"); + + // Unregister all midlets in iMidlets from AppArc + UnregisterOldJavaAppsL(); + + iState = EExit; + CompleteRequest(); + } + break; + + case EExit: + { + LOG(EJavaConverters, EInfo, "CPreConverter::RunL EExit"); + + FullCleanup(); + + // The whole javaapppreconverter process is stopped. + Exit(); + } + break; + + } +} + +/** + * To handle leave from RunL. + * This method exits this active object using normal state machine + * After calling this method this active object will exit. + * + * @param aError - A reason of error. + * @return KErrNone. + */ +TInt CPreConverter::RunError(TInt aError) +{ + ELOG2(EJavaConverters, + "CPreConverter::RunError(%d) from state %d", aError, iState); + + Cancel(); + + iState = EExit; + CompleteRequest(); + + return KErrNone; +} + +/** + * To do cancelling for this object. + * + */ +void CPreConverter::DoCancel() +{ + ELOG1(EJavaConverters, + "CPreConverter::DoCancel from state %d", iState); + +} + +/** + * To cleanup member variables. + * + */ +void CPreConverter::FullCleanup() +{ + JELOG2(EJavaPreinstaller); + + if (iMidlets) + { + iMidlets->ResetAndDestroy(); + delete iMidlets; + iMidlets = NULL; + } +} + +/** + * Read all midlets from AppArc. + * Store midlet Uid, Midlet name, installation drive, + * group name and icon file path name to iMidlets. + */ +void CPreConverter::ReadMidletsFromAppArcL() +{ + JELOG2(EJavaConverters); + + TInt retryCounter = 10; + TUid appTypeUid; + HBufC *pIconFilePathName = NULL; + TApaAppInfo info; + RApaLsSession apaSession; + TApaAppCapabilityBuf cbuf; + TApaAppCapability capability; + + TBuf8<512> midletDesc; + + + TInt err = apaSession.Connect(); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CPreConverter::ReadMidletsFromAppArcL RApaLsSession Connect error %d", err); + User::Leave(err); + } + CleanupClosePushL(apaSession); + + // Get the process of getting the list of all non native applications + // (mostly java applications) + err = + apaSession.GetFilteredApps( + TApaAppCapability::ENonNative, TApaAppCapability::ENonNative); + + do + { + err = apaSession.GetNextApp(info); + if (RApaLsSession::EAppListInvalid == err) + { + // Application list has not yet been populated, + // try again after a short delay + retryCounter--; + if (retryCounter > 0) + { + User::After(KDelayWhenWaitingAppArc); + continue; + } + else + { + ELOG(EJavaConverters, + "CPreConverter::ReadMidletsFromAppArcL RApaLsSession " + "GetNext returned EAppListInvalid for 10 times, error"); + User::Leave(err); + } + } + else if (KErrNone == err) + { + // Info contains valid app info. Now check whether it is java app + err = apaSession.GetAppType(appTypeUid, info.iUid); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CPreConverter::ReadMidletsFromAppArcL RApaLsSession " + "GetAppType returned error %d", err); + User::Leave(err); + } + if (appTypeUid.iUid == KMidletApplicationTypeUid) + { + // This is java application. Store info to list. + CMidletInfo *midletInfo = new(ELeave) CMidletInfo(); + midletInfo->SetMidletUid(info.iUid); + midletInfo->SetMidletName(info.iCaption); + midletInfo->SetDrive(ExtractDriveNumberFromPathL(info.iFullName)); + + // Get group name + err = apaSession.GetAppCapability(cbuf, info.iUid); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CPreConverter::ReadMidletsFromAppArcL RApaLsSession " + "GetAppCapability returned error %d", err); + User::Leave(err); + } + capability = cbuf(); + midletInfo->SetGroupName(capability.iGroupName); + + // Get icon file path name + err = apaSession.GetAppIcon(info.iUid, pIconFilePathName); + if ((KErrNone != err) || (NULL == pIconFilePathName)) + { + ELOG1(EJavaConverters, + "CPreConverter::ReadMidletsFromAppArcL RApaLsSession " + "GetAppIcon returned error %d", err); + User::Leave(err); + } + midletInfo->SetIconFileName(pIconFilePathName); + delete pIconFilePathName; + pIconFilePathName = NULL; + + err = iMidlets->Append(midletInfo); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CPreConverter::ReadMidletsFromAppArcL CMidletList " + "Append returned error %d", err); + User::Leave(err); + } + else + { + midletInfo->ToString8(midletDesc); + LOG(EJavaConverters, EInfo, + "CPreConverter::ReadMidletsFromAppArcL Added this midlet:"); + midletDesc.ZeroTerminate(); + LOG(EJavaPreinstaller, EInfo, (const char *)(midletDesc.Ptr())); + midletDesc.Zero(); + } + } + } + + } + while (KErrNone == err); + + if (RApaLsSession::ENoMoreAppsInList != err) + { + ELOG1(EJavaConverters, + "CPreConverter::ReadMidletsFromAppArcL RApaLsSession GetNext returned error %d", err); + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // apaSession +} + +/** + * Parse the drive letter from path and return it as TDriveNumber. + * + * @param aPathName full path name. Contains always the drive. + * @return the drive number + * @exception if the drive cannot parsed from path + */ +TDriveNumber CPreConverter::ExtractDriveNumberFromPathL(TFileName &aPathName) +{ + TDriveNumber drive = EDriveE; + TUint driveLetter = aPathName[0]; + + if ((driveLetter >= 'a') && (driveLetter <= 'z')) + { + drive = (TDriveNumber)(driveLetter - 'a'); + } + else if ((driveLetter >= 'A') && (driveLetter <= 'Z')) + { + drive = (TDriveNumber)(driveLetter - 'A'); + } + else + { + ELOG1(EJavaConverters, + "CPreConverter::ExtractDriveNumberFromPathL path starts " + "with illegal char, value %d", drive); + User::Leave(KErrArgument); + } + + return drive; +} + +/** + * Read the midlet id and suite id for each midlet in iMidlets from + * SystemAMS DB and store them to iMidlets + */ +void CPreConverter::AddDataFromSystemAmsDbL() +{ + MIDP::DBv2::MDatabase* database = NULL; + MIDP::DBv2::MMIDletTable* midletTable = NULL; + RDbNamedDatabase dbNamed; + RDbs dbs; + + // Connect to db + TInt err = dbs.Connect(); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CPreConverter::AddDataFromSystemAmsDbL Cannot connect to RDbs, " + "error %d", err); + User::Leave(err); + } + + // Open db + err = dbs.ShareAuto(); + if (KErrNone != err) + { + dbs.Close(); + ELOG1(EJavaConverters, + "CPreConverter::AddDataFromSystemAmsDbL Cannot share RDbs session, " + "error %d", err); + User::Leave(err); + } + err = dbNamed.Open( + iFs, KStaticDbFileName(), KUidSSystemAMSDbPolicy, RDbNamedDatabase::EReadOnly); + if (KErrNone != err) + { + dbs.Close(); + ELOG1(EJavaConverters, + "CPreConverter::AddDataFromSystemAmsDbL Cannot open named db, " + "error %d", err); + User::Leave(err); + } + + // Get db + TRAP(err, database = MIDP::DBv2::GetDatabaseL(KDBVersion)); + if (KErrNone != err) + { + dbNamed.Close(); + dbs.Close(); + ELOG1(EJavaConverters, + "CPreConverter::AddDataFromSystemAmsDbL Cannot get database, " + "error %d", err); + User::Leave(err); + } + + // Get midlet table + TRAP(err, midletTable = database->MIDletTableL()); + if (KErrNone != err) + { + delete database; + dbNamed.Close(); + dbs.Close(); + ELOG1(EJavaConverters, + "CPreConverter::AddDataFromSystemAmsDbL Cannot get midlet table from db, " + "error %d", err); + User::Leave(err); + } + + // Open midlet table + TRAP(err, midletTable->OpenL(dbNamed)); + if (KErrNone != err) + { + delete database; + dbNamed.Close(); + dbs.Close(); + ELOG1(EJavaConverters, + "CPreConverter::AddDataFromSystemAmsDbL Cannot open midlet table in db, " + "error %d", err); + User::Leave(err); + } + + // get iterator to access the data in midlet table + MIDP::DBv2::MMIDletTableIterator* tableIterator = NULL; + // No items must be left in cleanup stack when exiting TRAP macro + TRAP(err, + tableIterator = midletTable->IteratorLC(); + if (KErrNone == err) CleanupStack::Pop(); + ); + if (KErrNone != err) + { + midletTable->Close(); + delete database; + dbNamed.Close(); + dbs.Close(); + ELOG1(EJavaConverters, + "CPreConverter::AddDataFromSystemAmsDbL Cannot get iterator for midlet table in db, " + "error %d", err); + User::Leave(err); + } + + + TBuf8<512> midletDesc; + TInt32 count = 0; + TUint32 msId; + TUint32 id; + TUint32 uid; + TPtrC name; + TPtrC className; + TPtrC idString; + while (tableIterator->HasNext()) + { + TRAP(err, tableIterator->NextL(msId, id, uid, name, className, idString)); + if (KErrNone != err) + { + delete tableIterator; + midletTable->Close(); + delete database; + dbNamed.Close(); + dbs.Close(); + ELOG1(EJavaConverters, + "CPreConverter::AddDataFromSystemAmsDbL Midlet table iterator NextL failed, " + "error %d", err); + User::Leave(err); + } + LOG3(EJavaConverters, EInfo, + "CPreConverter::AddDataFromSystemAmsDbL Found midlet uid %x, suite id %d, midlet id %d", + uid, msId, id); + + midletDesc.Append(KMLName); + midletDesc.Append(name); + midletDesc.Append(KMLClassName); + midletDesc.Append(className); + midletDesc.Append(KMLIdString); + midletDesc.Append(idString); + LOG(EJavaPreinstaller, EInfo, (const char *)midletDesc.PtrZ()); + midletDesc.Zero(); + + iMidlets->SetIds(name, msId, id); + count++; + } + + LOG1(EJavaConverters, EInfo, + "CPreConverter::AddDataFromSystemAmsDbL midlet table had %d midlets.", count); + + // close and free everything + delete tableIterator; + midletTable->Close(); + delete database; + dbNamed.Close(); + dbs.Close(); +} + +/** + * Check all midlets in iMidlets and remove those midlets that do not + * have midlet id and suite id. + */ +void CPreConverter::RemoveInvalidMidlets() +{ + // If midlet id or suite id is KMaxTUint32, it has not been set -> + // remove the midlet + + CMidletInfo *midlet = iMidlets->GetFirst(); + TBuf8<512> midletDesc; + + while (NULL != midlet) + { + if ((midlet->GetMidletId() == KMaxTUint32) || + (midlet->GetSuiteId() == KMaxTUint32)) + { + midlet->ToString8(midletDesc); + WLOG(EJavaConverters, + "CPreConverter::RemoveInvalidMidlets Not going to convert this midlet:"); + midletDesc.ZeroTerminate(); + WLOG(EJavaPreinstaller, (const char *)(midletDesc.Ptr())); + midletDesc.Zero(); + iMidlets->Remove(midlet); + } + + midlet = iMidlets->GetNext(); + } +} + +/** + * Store the uids of the midlets to be converted + * to file 'uids' in the data cage of javaappconverter.exe + */ +void CPreConverter::StoreUidsL() +{ + TFileName exportUidsPath(KUidsExportDirectory); + + // Create directory if it does not exist + TInt err= iFs.MkDirAll(exportUidsPath); + if ((KErrNone != err) && (KErrAlreadyExists != err)) + { + User::Leave(err); + } + + // Store all uids to file 'uids' in the directory + exportUidsPath.Append(KUidsExportDataFileName); + + // Construct write stream so that possibly existing old data file is replaced. + RFileWriteStream writeStream; + User::LeaveIfError(writeStream.Replace(iFs, exportUidsPath, EFileWrite)); + CleanupClosePushL(writeStream); + + // Write the number of midlets + TUint32 nMidlets = iMidlets->Count(); + writeStream.WriteUint32L(nMidlets); + + // Write Uids of the midlets one by one + CMidletInfo *midlet = iMidlets->GetFirst(); + + while (NULL != midlet) + { + writeStream.WriteUint32L(midlet->GetMidletUid().iUid); + midlet = iMidlets->GetNext(); + } + + // Closes writeStream + CleanupStack::PopAndDestroy(); +} + +/** + * Unregisters the applications to be converted from AppArc + * so that Java Installer can make conversion installation + * using the same Uids as the applications now have. + * + * Leaves with error code if AppArc cannot be connected or if + * unregistrations cannot be committed. + */ +void CPreConverter::UnregisterOldJavaAppsL() +{ + // connect to AppArc + RApaLsSession apaSession; + + TInt err = apaSession.Connect(); + if (KErrNone != err) + { + // Fatal error, try to connect again. The midlets cannot be converted + // using the same uids as earlier if the unregistration cannot be done. + TInt retryCount = 0; + do + { + ELOG1(EJavaConverters, + "CPreConverter::UnregisterOldJavaAppsL Cannot connect to " + "AppArc server, err %d", err); + + // wait + User::After(KDelayWhenWaitingAppArc); + + err = apaSession.Connect(); + if (KErrNone == err) + { + break; + } + + retryCount++; + } + while (retryCount < 10); + + if (KErrNone != err) + { + User::Leave(err); + } + } + CleanupClosePushL(apaSession); + + // Delete any pending (un)registrations (possible if + // e.g. device rebooted before commit). + // This call does nothing if there is no pending registrations. + // Ignore errors. + (void)apaSession.RollbackNonNativeApplicationsUpdates(); + + // Prepare for Java application unregistrations + TRAP(err, apaSession.PrepareNonNativeApplicationsUpdatesL()); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CPreConverter::UnregisterOldJavaAppsL: " + "PrepareNonNativeApplicationsUpdatesL leaved with err %d", + err); + User::Leave(err); + } + + // Unregister all apps + CMidletInfo *midlet = iMidlets->GetFirst(); + + while (NULL != midlet) + { + TRAP(err, apaSession.DeregisterNonNativeApplicationL(midlet->GetMidletUid())); + if (KErrNone != err) + { + WLOG2(EJavaConverters, + "CPreConverter::UnregisterOldJavaAppsL: " + "DeregisterNonNativeApplicationL leaved with err %d for uid %d", + err, midlet->GetMidletUid().iUid); + // Ignore error, this particular application cannot be converted. + } + + midlet = iMidlets->GetNext(); + } + + // Commit unregistrations + TRAP(err, apaSession.CommitNonNativeApplicationsUpdatesL()) + { + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CPreConverter::UnregisterOldJavaAppsL: " + "CommitNonNativeApplicationsUpdatesL leaved with err %d", + err); + User::Leave(err); + } + } + + // Closes apaSession + CleanupStack::PopAndDestroy(); +} +