diff -r e8e63152f320 -r 2a9601315dfc javatools/javapostupdater/src/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javatools/javapostupdater/src/main.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,427 @@ +/* +* Copyright (c) 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: OMJ S60 environment post updater process. +* This process is executed when OMJ is installed, after +* the native installer exits. +* Register new Java 2.0 midlet starter to AppArc. +* Execute javaappconverter.exe and javausersettingsconfigurator.exe. +* Destroy one PS key owned by the native installer. +* Create new PS keys used by new Java Installer. +* Refresh midlet icons shown in menu application. +* +*/ + + +#include +#include +#include +#include +#include +#include +#include // for RApaLsSession + +#include + +#include "javaprocessconstants.h" +#include "javauids.h" +#include "logger.h" + + +_LIT8(KAppJavaType, "application/java"); + + +/** + * Ask javainstaller to create the new PS keys + * that other processes can later use to get information of + * the progress of the installation of Java applications. + */ +static void CreateNewJavaInstallerPSKeys() +{ + LOG(EJavaConverters, EInfo, "javapostupdater: CreateNewJavaInstallerPSKeys() was called"); + + RProcess rJavaInstaller; + TFileName fileName; + // Pass just 'register' command + TBuf<128> commandLine; + + // Build command line used to pass all necessary info to Java Installer + TInt len = strlen(java::runtime::JAVA_INSTALLER_STARTER_DLL); + TPtr8 ptr8InstallerDll((TUint8 *)java::runtime::JAVA_INSTALLER_STARTER_DLL, len, len); + commandLine.Copy(ptr8InstallerDll); + + commandLine.Append(_L(" register")); + + LOG(EJavaConverters, EInfo, + "javapostupdater: CreateNewJavaInstallerPSKeys() starting Java " + "Installer for registering PS keys"); + + // start JavaInstaller + TBuf<64> installerProcess; // Actual len of the process name is 9 + len = strlen(java::runtime::JAVA_PROCESS); + TPtr8 ptr8Process((TUint8 *)java::runtime::JAVA_PROCESS, len, len); + installerProcess.Copy(ptr8Process); + + TInt err = rJavaInstaller.Create(installerProcess, commandLine); + if (KErrNone == err) + { + LOG(EJavaConverters, EInfo, + "javapostupdater: CreateNewJavaInstallerPSKeys() calling Resume"); + rJavaInstaller.Resume(); + } + + LOG(EJavaConverters, EInfo, + "javapostupdater: CreateNewJavaInstallerPSKeys() calling RProcess::Close"); + // free resources before returning + rJavaInstaller.Close(); +} + + +/** + * Make a dummy call to Installer using SwiUI::RSWInstSilentLauncher + * so that OMJ appinstuiplugin gets called from AppInstUi process + * and can remove one conflicting P&S key created by old S60 Java Installer + */ +static void DeleteOldJavaInstallerPSKeyL() +{ + SwiUI::RSWInstSilentLauncher installer; + SwiUI::TUninstallOptions options; + SwiUI::TUninstallOptionsPckg pckg; + + // use default options + pckg = options; + + LOG(EJavaConverters, EInfo, "javapostupdater: DeleteOldJavaInstallerPSKey() called"); + + TInt err = installer.Connect(); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "javapostupdater: DeleteOldJavaInstallerPSKey: RSWInstSilentLauncher " + "connect error %d", err); + return; + } + + CleanupClosePushL(installer); + + // Calling AppInstUi silent install API immediately after OMJ has been + // installed may fail because the AppInstUI has not yet exited or new OMJ + // ECOM plugin is not yet in use. + // Make the calls in a loop and wait a couple of seconds between + const TUid illegalAppUid = {KRandomIllegalAppUid}; + TInt nRetries = 7; + do + { + // This call returns KErrCancel even if the PS key was destroyed + err = installer.SilentUninstall(illegalAppUid, pckg, KAppJavaType); + if ((KErrNone != err) && (KErrCancel != err)) + { + WLOG1(EJavaConverters, + "javapostupdater: DeleteOldJavaInstallerPSKey: SilentUninstall error %d", err); + } + + // Wait 3 sec so that AppInstUi has time to finish previous operation + // and exit so that new ECom OMJ specific plugin will be loaded + User::After(3000000); + nRetries--; + } + while ((KErrCancel != err) && (KErrNone != err) && (nRetries > 0)); + + if (nRetries == 0) + { + ELOG1(EJavaConverters, + "javapostupdater: DeleteOldJavaInstallerPSKey: Could not delete PS key, error %d", + err); + } + else + { + LOG(EJavaConverters, + EInfo, "javapostupdater: DeleteOldJavaInstallerPSKey() PS Key was deleted"); + } + + + CleanupStack::PopAndDestroy(&installer); +} + + +/** + * Start javaappconverter.exe process and wait until it exits. After that + * start javausersettingsconfigurator.exe process and wait until it exits. + */ +static void runConverters() +{ + JELOG2(EJavaPreinstaller); + + // Start converter process + RProcess converter; + TInt err = converter.Create(_L("javaappconverter.exe"), KNullDesC); + if (KErrNone == err) + { + // Process has been created + LOG(EJavaConverters, EInfo, + "runConverter: created javaappconverter process"); + + // Get ready to wait until the process ends + TRequestStatus status; + converter.Logon(status); + + // Make the main thread of the process runnable + converter.Resume(); + LOG(EJavaConverters, EInfo, + "runConverter: started javaappconverter"); + + // Wait until the process ends. + User::WaitForRequest(status); + converter.Close(); + + if (status.Int() == KErrAlreadyExists) + { + // Old S60 midlets have already been converted. + // This is an OMJ upgrade installation. + LOG(EJavaConverters, EInfo, + "runConverter: no need to execute javausersettingsconfigurator process"); + return; + } + else + { + LOG1(EJavaConverters, EInfo, + "runConverter: javaappconverter ended with status %d", status.Int()); + } + } + else + { + ELOG1( + EJavaConverters, + "runConverter: starting javaappconverter failed, err %d", + err); + return; + } + + // Configure the user settings of the newly installed applications + // (based on how they were configured in the legacy java) + RProcess userSettingsTool; + err = userSettingsTool.Create(_L("javausersettingsconfigurator.exe"), KNullDesC); + if (err == KErrNone) + { + // Process has been created + LOG(EJavaConverters, EInfo, + "runConverter: created javausersettingsconfigurator process"); + + // Get ready to wait until the process ends + TRequestStatus status; + userSettingsTool.Logon(status); + + // Make the main thread of the process runnable + userSettingsTool.Resume(); + LOG(EJavaConverters, EInfo, + "runConverter: started javausersettingsconfigurator"); + + // Wait until the process ends. + User::WaitForRequest(status); + + LOG1(EJavaConverters, EInfo, + "runConverter: javausersettingsconfigurator ended with status %d", status.Int()); + + userSettingsTool.Close(); + } + else + { + ELOG1( + EJavaConverters, + "startConverter: starting javausersettingsconfigurator failed, err %d", + err); + } +} + +/** + * Register 'javalauncher.exe' as the midlet application type handler + * in AppArc. If necessary unregister old handler first. + */ +static void registerMidletApplicationTypeHandler() +{ + _LIT(KMidpAppArcPlugin, "javalauncher.exe"); + + RApaLsSession appLstSession; + TInt err = appLstSession.Connect(); + if (KErrNone == err) + { + TRAP(err, appLstSession.RegisterNonNativeApplicationTypeL( + TUid::Uid(KMidletApplicationTypeUid), KMidpAppArcPlugin())); + if (KErrNone == err) + { + // All is well + LOG(EJavaConverters, EInfo, + "registerMidletApplicationTypeHandler: Registered MIDlet application " + "type for Java 2.x"); + } + else if (KErrAlreadyExists == err) + { + // Java 1.x has registered MIDlet application type handler StubMIDP2RecogExe.exe, + // must change that registration + LOG(EJavaConverters, EInfo, + "registerMidletApplicationTypeHandler: MIDlet application type was already " + "registered by Java 1.x"); + TRAP_IGNORE(appLstSession.DeregisterNonNativeApplicationTypeL( + TUid::Uid(KMidletApplicationTypeUid))); + TRAP(err, appLstSession.RegisterNonNativeApplicationTypeL( + TUid::Uid(KMidletApplicationTypeUid), KMidpAppArcPlugin())); + if (KErrNone == err) + { + LOG(EJavaConverters, EInfo, + "registerMidletApplicationTypeHandler: Registered MIDlet application " + "type again (for Java 2.x)."); + } + else + { + ELOG1(EJavaConverters, + "registerMidletApplicationTypeHandler: Reregistering MIDlet application " + "type failed with err %d", + err); + } + } + else + { + ELOG1(EJavaConverters, + "registerMidletApplicationTypeHandler: Registering MIDlet " + "application type failed with err %d", + err); + } + + // Launch rescan of all applications so that all java applications + // will be shown in Menu + TRAP(err, appLstSession.PrepareNonNativeApplicationsUpdatesL()); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "registerMidletApplicationTypeHandler: PrepareNonNativeApplicationsUpdatesL error %d", + err); + } + else + { + LOG(EJavaConverters, EInfo, + "registerMidletApplicationTypeHandler: PrepareNonNativeApplicationsUpdatesL OK"); + } + + TRAP(err, appLstSession.CommitNonNativeApplicationsUpdatesL()); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "registerMidletApplicationTypeHandler: CommitNonNativeApplicationsUpdatesL error %d", + err); + } + else + { + LOG(EJavaConverters, EInfo, + "registerMidletApplicationTypeHandler: CommitNonNativeApplicationsUpdatesL OK"); + } + + appLstSession.Close(); + } + else + { + ELOG1(EJavaConverters, + "registerMidletApplicationTypeHandler: Connecting to AppArc failed with error %d", + err); + } +} + +/** + * Menu application has a central repository key that can be used in + * devices belonging to Nokia 5800 XpressMusic device family to request + * that the Menu application would rescan all applications it contains. + */ +static void UseCRKeyToUpdateAppShellDataL() +{ + const TUid KCRUidMenu = { 0x101F8847 }; + const TUint32 KMenuUpdateData = 0x00000001; + + // Update Central Rep + CRepository *pCenRep = CRepository::NewL(KCRUidMenu); + + TInt value = 1; + TInt err = pCenRep->Set(KMenuUpdateData, value); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "javapostupdater: UseCRKeyToUpdateAppShellDataL: " + "setting cenrep value failed, error %d ", + err); + } + + delete pCenRep; +} + +/** + * If OMJ is upgraded the Application Shell (menu application) of the + * Nokia 5800 XpressMusic device family does not + * display the icons of the java applications that have been installed to + * only OMJ environment. The icons are shown after the device is booted. + * Tell menu application to scan again all applications so that the icons + * will be shown. + */ +static void AddAllJavaAppIconsToMenuApp() +{ + LOG(EJavaConverters, EInfo, "javapostupdater: AddAllJavaAppIconsToMenuApp called."); + + TRAPD(err, UseCRKeyToUpdateAppShellDataL()); + if (KErrNotFound == err) + { + // Only Nokia XPressMusic 5800 device family supports this feature, + // N97 and later devices no longer support it but they have new Menu + // application that shows all Java application icons anyway. + LOG(EJavaConverters, EInfo, + "javapostupdater: AddAllJavaAppIconsToMenuApp: This device does not " + "support refreshing Menu using CR keys."); + } + else if (KErrNone != err) + { + ELOG1(EJavaConverters, + "javapostupdater: AddAllJavaAppIconsToMenuApp: Error: %d", err); + } +} + +/** + * Create cleanup stack and run the post updater code inside TRAP harness + * to log unexpected leaves. + */ +TInt E32Main() +{ + __UHEAP_MARK; + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + + LOG(EJavaConverters, EInfo, "javapostupdater process starts"); + + // Java 2.0 midlet starter handles midlet application type + registerMidletApplicationTypeHandler(); + + // Convert existing midlets to Java 2.0 midlets + runConverters(); + + // Delete one old PS key owned by native installer (appinstui) + TRAPD(error, DeleteOldJavaInstallerPSKeyL()); + if (KErrNone != error) + { + ELOG1(EJavaConverters, + "javapostupdater: DeleteOldJavaInstallerPSKeyL() leaved with %d", error); + } + + // Create new PS keys that Java 2.0 Java Installer will use + CreateNewJavaInstallerPSKeys(); + + // Make sure all Java application icons are shown in menu. + AddAllJavaAppIconsToMenuApp(); + + delete cleanupStack; + __UHEAP_MARKEND; + return error; +}