javatools/javapostupdater/src/main.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 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:  OMJ S60 environment post updater process.
       
    15 *               This process is executed when OMJ is installed, after
       
    16 *               the native installer exits.
       
    17 *               Register new Java 2.0 midlet starter to AppArc.
       
    18 *               Execute javaappconverter.exe and javausersettingsconfigurator.exe.
       
    19 *               Destroy one PS key owned by the native installer.
       
    20 *               Create new PS keys used by new Java Installer.
       
    21 *               Refresh midlet icons shown in menu application.
       
    22 *
       
    23 */
       
    24 
       
    25 
       
    26 #include <e32std.h>
       
    27 #include <e32base.h>
       
    28 #include <f32file.h>
       
    29 #include <w32std.h>
       
    30 #include <centralrepository.h>
       
    31 #include <swinstapi.h>
       
    32 #include <apgcli.h> // for RApaLsSession
       
    33 
       
    34 #include <javadomainpskeys.h>
       
    35 
       
    36 #include "javaprocessconstants.h"
       
    37 #include "javauids.h"
       
    38 #include "logger.h"
       
    39 
       
    40 
       
    41 _LIT8(KAppJavaType, "application/java");
       
    42 
       
    43 
       
    44 /**
       
    45  * Ask javainstaller to create the new PS keys
       
    46  * that other processes can later use to get information of
       
    47  * the progress of the installation of Java applications.
       
    48  */
       
    49 static void CreateNewJavaInstallerPSKeys()
       
    50 {
       
    51     LOG(EJavaConverters, EInfo, "javapostupdater: CreateNewJavaInstallerPSKeys() was called");
       
    52 
       
    53     RProcess rJavaInstaller;
       
    54     TFileName fileName;
       
    55     // Pass just 'register' command
       
    56     TBuf<128> commandLine;
       
    57 
       
    58     // Build command line used to pass all necessary info to Java Installer
       
    59     TInt len = strlen(java::runtime::JAVA_INSTALLER_STARTER_DLL);
       
    60     TPtr8 ptr8InstallerDll((TUint8 *)java::runtime::JAVA_INSTALLER_STARTER_DLL, len, len);
       
    61     commandLine.Copy(ptr8InstallerDll);
       
    62 
       
    63     commandLine.Append(_L(" register"));
       
    64 
       
    65     LOG(EJavaConverters, EInfo,
       
    66         "javapostupdater: CreateNewJavaInstallerPSKeys() starting Java "
       
    67         "Installer for registering PS keys");
       
    68 
       
    69     // start JavaInstaller
       
    70     TBuf<64> installerProcess;  // Actual len of the process name is 9
       
    71     len = strlen(java::runtime::JAVA_PROCESS);
       
    72     TPtr8 ptr8Process((TUint8 *)java::runtime::JAVA_PROCESS, len, len);
       
    73     installerProcess.Copy(ptr8Process);
       
    74 
       
    75     TInt err = rJavaInstaller.Create(installerProcess, commandLine);
       
    76     if (KErrNone == err)
       
    77     {
       
    78         LOG(EJavaConverters, EInfo,
       
    79             "javapostupdater: CreateNewJavaInstallerPSKeys() calling Resume");
       
    80         rJavaInstaller.Resume();
       
    81     }
       
    82 
       
    83     LOG(EJavaConverters, EInfo,
       
    84         "javapostupdater: CreateNewJavaInstallerPSKeys() calling RProcess::Close");
       
    85     // free resources before returning
       
    86     rJavaInstaller.Close();
       
    87 }
       
    88 
       
    89 
       
    90 /**
       
    91  * Make a dummy call to Installer using SwiUI::RSWInstSilentLauncher
       
    92  * so that OMJ appinstuiplugin gets called from AppInstUi process
       
    93  * and can remove one conflicting P&S key created by old S60 Java Installer
       
    94  */
       
    95 static void DeleteOldJavaInstallerPSKeyL()
       
    96 {
       
    97     SwiUI::RSWInstSilentLauncher   installer;
       
    98     SwiUI::TUninstallOptions       options;
       
    99     SwiUI::TUninstallOptionsPckg   pckg;
       
   100 
       
   101     // use default options
       
   102     pckg = options;
       
   103 
       
   104     LOG(EJavaConverters, EInfo, "javapostupdater: DeleteOldJavaInstallerPSKey() called");
       
   105 
       
   106     TInt err = installer.Connect();
       
   107     if (KErrNone != err)
       
   108     {
       
   109         ELOG1(EJavaConverters,
       
   110               "javapostupdater: DeleteOldJavaInstallerPSKey: RSWInstSilentLauncher "
       
   111               "connect error %d", err);
       
   112         return;
       
   113     }
       
   114 
       
   115     CleanupClosePushL(installer);
       
   116 
       
   117     // Calling AppInstUi silent install API immediately after OMJ has been
       
   118     // installed may fail because the AppInstUI has not yet exited or new OMJ
       
   119     // ECOM plugin is not yet in use.
       
   120     // Make the calls in a loop and wait a couple of seconds between
       
   121     const TUid illegalAppUid = {KRandomIllegalAppUid};
       
   122     TInt nRetries = 7;
       
   123     do
       
   124     {
       
   125         // This call returns KErrCancel even if the PS key was destroyed
       
   126         err = installer.SilentUninstall(illegalAppUid, pckg, KAppJavaType);
       
   127         if ((KErrNone != err) && (KErrCancel != err))
       
   128         {
       
   129             WLOG1(EJavaConverters,
       
   130                   "javapostupdater: DeleteOldJavaInstallerPSKey: SilentUninstall error %d", err);
       
   131         }
       
   132 
       
   133         // Wait 3 sec so that AppInstUi has time to finish previous operation
       
   134         // and exit so that new ECom OMJ specific plugin will be loaded
       
   135         User::After(3000000);
       
   136         nRetries--;
       
   137     }
       
   138     while ((KErrCancel != err) && (KErrNone != err) && (nRetries > 0));
       
   139 
       
   140     if (nRetries == 0)
       
   141     {
       
   142         ELOG1(EJavaConverters,
       
   143               "javapostupdater: DeleteOldJavaInstallerPSKey: Could not delete PS key, error %d",
       
   144               err);
       
   145     }
       
   146     else
       
   147     {
       
   148         LOG(EJavaConverters,
       
   149             EInfo, "javapostupdater: DeleteOldJavaInstallerPSKey() PS Key was deleted");
       
   150     }
       
   151 
       
   152 
       
   153     CleanupStack::PopAndDestroy(&installer);
       
   154 }
       
   155 
       
   156 
       
   157 /**
       
   158  * Start javaappconverter.exe process and wait until it exits. After that
       
   159  * start javausersettingsconfigurator.exe process and wait until it exits.
       
   160  */
       
   161 static void runConverters()
       
   162 {
       
   163     JELOG2(EJavaPreinstaller);
       
   164 
       
   165     // Start converter process
       
   166     RProcess converter;
       
   167     TInt err = converter.Create(_L("javaappconverter.exe"), KNullDesC);
       
   168     if (KErrNone == err)
       
   169     {
       
   170         // Process has been created
       
   171         LOG(EJavaConverters, EInfo,
       
   172             "runConverter: created javaappconverter process");
       
   173 
       
   174         // Get ready to wait until the process ends
       
   175         TRequestStatus status;
       
   176         converter.Logon(status);
       
   177 
       
   178         // Make the main thread of the process runnable
       
   179         converter.Resume();
       
   180         LOG(EJavaConverters, EInfo,
       
   181             "runConverter: started javaappconverter");
       
   182 
       
   183         // Wait until the process ends.
       
   184         User::WaitForRequest(status);
       
   185         converter.Close();
       
   186 
       
   187         if (status.Int() == KErrAlreadyExists)
       
   188         {
       
   189             // Old S60 midlets have already been converted.
       
   190             // This is an OMJ upgrade installation.
       
   191             LOG(EJavaConverters, EInfo,
       
   192                 "runConverter: no need to execute javausersettingsconfigurator process");
       
   193             return;
       
   194         }
       
   195         else
       
   196         {
       
   197             LOG1(EJavaConverters, EInfo,
       
   198                  "runConverter: javaappconverter ended with status %d", status.Int());
       
   199         }
       
   200     }
       
   201     else
       
   202     {
       
   203         ELOG1(
       
   204             EJavaConverters,
       
   205             "runConverter: starting javaappconverter failed, err %d",
       
   206             err);
       
   207         return;
       
   208     }
       
   209 
       
   210     // Configure the user settings of the newly installed applications
       
   211     // (based on how they were configured in the legacy java)
       
   212     RProcess userSettingsTool;
       
   213     err = userSettingsTool.Create(_L("javausersettingsconfigurator.exe"), KNullDesC);
       
   214     if (err == KErrNone)
       
   215     {
       
   216         // Process has been created
       
   217         LOG(EJavaConverters, EInfo,
       
   218             "runConverter: created javausersettingsconfigurator process");
       
   219 
       
   220         // Get ready to wait until the process ends
       
   221         TRequestStatus status;
       
   222         userSettingsTool.Logon(status);
       
   223 
       
   224         // Make the main thread of the process runnable
       
   225         userSettingsTool.Resume();
       
   226         LOG(EJavaConverters, EInfo,
       
   227             "runConverter: started javausersettingsconfigurator");
       
   228 
       
   229         // Wait until the process ends.
       
   230         User::WaitForRequest(status);
       
   231 
       
   232         LOG1(EJavaConverters, EInfo,
       
   233              "runConverter: javausersettingsconfigurator ended with status %d", status.Int());
       
   234 
       
   235         userSettingsTool.Close();
       
   236     }
       
   237     else
       
   238     {
       
   239         ELOG1(
       
   240             EJavaConverters,
       
   241             "startConverter: starting javausersettingsconfigurator failed, err %d",
       
   242             err);
       
   243     }
       
   244 }
       
   245 
       
   246 /**
       
   247  * Register 'javalauncher.exe' as the midlet application type handler
       
   248  * in AppArc. If necessary unregister old handler first.
       
   249  */
       
   250 static void registerMidletApplicationTypeHandler()
       
   251 {
       
   252     _LIT(KMidpAppArcPlugin, "javalauncher.exe");
       
   253 
       
   254     RApaLsSession appLstSession;
       
   255     TInt err = appLstSession.Connect();
       
   256     if (KErrNone == err)
       
   257     {
       
   258         TRAP(err, appLstSession.RegisterNonNativeApplicationTypeL(
       
   259                  TUid::Uid(KMidletApplicationTypeUid), KMidpAppArcPlugin()));
       
   260         if (KErrNone == err)
       
   261         {
       
   262             // All is well
       
   263             LOG(EJavaConverters, EInfo,
       
   264                 "registerMidletApplicationTypeHandler: Registered MIDlet application "
       
   265                 "type for Java 2.x");
       
   266         }
       
   267         else if (KErrAlreadyExists == err)
       
   268         {
       
   269             // Java 1.x has registered MIDlet application type handler StubMIDP2RecogExe.exe,
       
   270             // must change that registration
       
   271             LOG(EJavaConverters, EInfo,
       
   272                 "registerMidletApplicationTypeHandler: MIDlet application type was already "
       
   273                 "registered by Java 1.x");
       
   274             TRAP_IGNORE(appLstSession.DeregisterNonNativeApplicationTypeL(
       
   275                             TUid::Uid(KMidletApplicationTypeUid)));
       
   276             TRAP(err, appLstSession.RegisterNonNativeApplicationTypeL(
       
   277                      TUid::Uid(KMidletApplicationTypeUid), KMidpAppArcPlugin()));
       
   278             if (KErrNone == err)
       
   279             {
       
   280                 LOG(EJavaConverters, EInfo,
       
   281                     "registerMidletApplicationTypeHandler: Registered MIDlet application "
       
   282                     "type again (for Java 2.x).");
       
   283             }
       
   284             else
       
   285             {
       
   286                 ELOG1(EJavaConverters,
       
   287                       "registerMidletApplicationTypeHandler: Reregistering MIDlet application "
       
   288                       "type failed with err %d",
       
   289                       err);
       
   290             }
       
   291         }
       
   292         else
       
   293         {
       
   294             ELOG1(EJavaConverters,
       
   295                   "registerMidletApplicationTypeHandler: Registering MIDlet "
       
   296                   "application type failed with err %d",
       
   297                   err);
       
   298         }
       
   299 
       
   300         // Launch rescan of all applications so that all java applications
       
   301         // will be shown in Menu
       
   302         TRAP(err, appLstSession.PrepareNonNativeApplicationsUpdatesL());
       
   303         if (KErrNone != err)
       
   304         {
       
   305             ELOG1(EJavaConverters,
       
   306                   "registerMidletApplicationTypeHandler: PrepareNonNativeApplicationsUpdatesL error %d",
       
   307                   err);
       
   308         }
       
   309         else
       
   310         {
       
   311             LOG(EJavaConverters, EInfo,
       
   312                 "registerMidletApplicationTypeHandler: PrepareNonNativeApplicationsUpdatesL OK");
       
   313         }
       
   314 
       
   315         TRAP(err, appLstSession.CommitNonNativeApplicationsUpdatesL());
       
   316         if (KErrNone != err)
       
   317         {
       
   318             ELOG1(EJavaConverters,
       
   319                   "registerMidletApplicationTypeHandler: CommitNonNativeApplicationsUpdatesL error %d",
       
   320                   err);
       
   321         }
       
   322         else
       
   323         {
       
   324             LOG(EJavaConverters, EInfo,
       
   325                 "registerMidletApplicationTypeHandler: CommitNonNativeApplicationsUpdatesL OK");
       
   326         }
       
   327 
       
   328         appLstSession.Close();
       
   329     }
       
   330     else
       
   331     {
       
   332         ELOG1(EJavaConverters,
       
   333               "registerMidletApplicationTypeHandler: Connecting to AppArc failed with error %d",
       
   334               err);
       
   335     }
       
   336 }
       
   337 
       
   338 /**
       
   339  * Menu application has a central repository key that can be used in
       
   340  * devices belonging to Nokia 5800 XpressMusic device family to request
       
   341  * that the Menu application would rescan all applications it contains.
       
   342  */
       
   343 static void UseCRKeyToUpdateAppShellDataL()
       
   344 {
       
   345     const TUid KCRUidMenu = { 0x101F8847 };
       
   346     const TUint32 KMenuUpdateData = 0x00000001;
       
   347 
       
   348     // Update Central Rep
       
   349     CRepository *pCenRep = CRepository::NewL(KCRUidMenu);
       
   350 
       
   351     TInt value = 1;
       
   352     TInt err = pCenRep->Set(KMenuUpdateData, value);
       
   353     if (KErrNone != err)
       
   354     {
       
   355         ELOG1(EJavaConverters,
       
   356               "javapostupdater: UseCRKeyToUpdateAppShellDataL: "
       
   357               "setting cenrep value failed, error %d ",
       
   358               err);
       
   359     }
       
   360 
       
   361     delete pCenRep;
       
   362 }
       
   363 
       
   364 /**
       
   365  * If OMJ is upgraded the Application Shell (menu application) of the
       
   366  * Nokia 5800 XpressMusic device family does not
       
   367  * display the icons of the java applications that have been installed to
       
   368  * only OMJ environment. The icons are shown after the device is booted.
       
   369  * Tell menu application to scan again all applications so that the icons
       
   370  * will be shown.
       
   371  */
       
   372 static void AddAllJavaAppIconsToMenuApp()
       
   373 {
       
   374     LOG(EJavaConverters, EInfo, "javapostupdater: AddAllJavaAppIconsToMenuApp called.");
       
   375 
       
   376     TRAPD(err, UseCRKeyToUpdateAppShellDataL());
       
   377     if (KErrNotFound == err)
       
   378     {
       
   379         // Only Nokia XPressMusic 5800 device family supports this feature,
       
   380         // N97 and later devices no longer support it but they have new Menu
       
   381         // application that shows all Java application icons anyway.
       
   382         LOG(EJavaConverters, EInfo,
       
   383             "javapostupdater: AddAllJavaAppIconsToMenuApp: This device does not "
       
   384             "support refreshing Menu using CR keys.");
       
   385     }
       
   386     else if (KErrNone != err)
       
   387     {
       
   388         ELOG1(EJavaConverters,
       
   389               "javapostupdater: AddAllJavaAppIconsToMenuApp: Error: %d", err);
       
   390     }
       
   391 }
       
   392 
       
   393 /**
       
   394  * Create cleanup stack and run the post updater code inside TRAP harness
       
   395  * to log unexpected leaves.
       
   396  */
       
   397 TInt E32Main()
       
   398 {
       
   399     __UHEAP_MARK;
       
   400     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   401 
       
   402     LOG(EJavaConverters, EInfo, "javapostupdater process starts");
       
   403 
       
   404     // Java 2.0 midlet starter handles midlet application type
       
   405     registerMidletApplicationTypeHandler();
       
   406 
       
   407     // Convert existing midlets to Java 2.0 midlets
       
   408     runConverters();
       
   409 
       
   410     // Delete one old PS key owned by native installer (appinstui)
       
   411     TRAPD(error, DeleteOldJavaInstallerPSKeyL());
       
   412     if (KErrNone != error)
       
   413     {
       
   414         ELOG1(EJavaConverters,
       
   415               "javapostupdater: DeleteOldJavaInstallerPSKeyL() leaved with %d", error);
       
   416     }
       
   417 
       
   418     // Create new PS keys that Java 2.0 Java Installer will use
       
   419     CreateNewJavaInstallerPSKeys();
       
   420 
       
   421     // Make sure all Java application icons are shown in menu.
       
   422     AddAllJavaAppIconsToMenuApp();
       
   423 
       
   424     delete cleanupStack;
       
   425     __UHEAP_MARKEND;
       
   426     return error;
       
   427 }