javamanager/javacaptain/extensionplugins/preinstallerstarter/src.s60/preinstallerstarter.cpp
branchRCL_3
changeset 19 04becd199f91
child 35 85266cc22c7f
child 60 6c158198356e
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 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:  PreinstallerStarter is Java Captain S60 plugin that starts
       
    15 *               preinstaller process when the device boots or removable drive
       
    16 *               is added to the device.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #include <e32base.h>
       
    22 #include <apgcli.h> // for RApaLsSession
       
    23 #include <hal_data.h>
       
    24 #include <hal.h>
       
    25 #include <sysutil.h>
       
    26 
       
    27 #include "javaprocessconstants.h"
       
    28 #include "javasymbianoslayer.h"
       
    29 #include "javauids.h"
       
    30 #include "logger.h"
       
    31 #include "coreinterface.h"
       
    32 #include "booteventprovidermessages.h"
       
    33 #include "mmceventprovidermessages.h"
       
    34 
       
    35 #include "preinstallerstarter.h"
       
    36 
       
    37 /**
       
    38  * Return pointer to ExtensionPluginInterface implementation for this
       
    39  * extension dll
       
    40  */
       
    41 java::captain::ExtensionPluginInterface* getExtensionPlugin()
       
    42 {
       
    43     return new java::captain::PreinstallerStarter();
       
    44 }
       
    45 
       
    46 namespace java
       
    47 {
       
    48 namespace captain
       
    49 {
       
    50 
       
    51 using java::fileutils::driveInfo;
       
    52 using java::fileutils::DriveListenerInterface;
       
    53 
       
    54 /**
       
    55  * Empty contructor
       
    56  */
       
    57 PreinstallerStarter::PreinstallerStarter() : mCore(0)
       
    58 {
       
    59     JELOG2(EJavaCaptain);
       
    60 }
       
    61 
       
    62 /**
       
    63  * Empty destructor
       
    64  */
       
    65 PreinstallerStarter::~PreinstallerStarter()
       
    66 {
       
    67     JELOG2(EJavaCaptain);
       
    68 }
       
    69 
       
    70 /**
       
    71  * Implement PluginInterface method
       
    72  */
       
    73 void PreinstallerStarter::startPlugin(CoreInterface* core)
       
    74 {
       
    75     JELOG2(EJavaCaptain);
       
    76     mCore = core;
       
    77 }
       
    78 
       
    79 /**
       
    80  * Implement PluginInterface method
       
    81  */
       
    82 void PreinstallerStarter::stopPlugin()
       
    83 {
       
    84     JELOG2(EJavaCaptain);
       
    85     mCore = 0;
       
    86 }
       
    87 
       
    88 /**
       
    89  * Implement ExtensionPluginInterface method
       
    90  */
       
    91 EventConsumerInterface* PreinstallerStarter::getEventConsumer()
       
    92 {
       
    93     JELOG2(EJavaCaptain);
       
    94     return this;
       
    95 }
       
    96 
       
    97 /**
       
    98  * Handle Java Captain events sent by Boot event provider or
       
    99  * MMC event provider. If IAD boot (Java Captain has been started
       
   100  * after OMJ sis package has been installed), start preinstaller process
       
   101  * with 'iad' paramater, otherwise start preinstaller process
       
   102  * without the parameter.
       
   103  *
       
   104  * Implement EventConsumerInterface method
       
   105  */
       
   106 void PreinstallerStarter::event(const std::string& eventProvider,
       
   107                                 java::comms::CommsMessage& aMsg)
       
   108 {
       
   109     JELOG2(EJavaCaptain);
       
   110     if (eventProvider == BOOT_EVENT_PROVIDER)
       
   111     {
       
   112         int bootType = NORMAL_BOOT_C;
       
   113         getBootMessageParams(aMsg, bootType);
       
   114         LOG1(
       
   115             EJavaCaptain,
       
   116             EInfo,
       
   117             "PreinstallerStarter::event() boot event received (type=%d)",
       
   118             bootType);
       
   119         switch (bootType)
       
   120         {
       
   121         case IAD_BOOT_C:
       
   122         {
       
   123             // This event is received after OMJ has been (IAD) installed
       
   124             // to device.
       
   125 
       
   126             // Preinstaller will be started with 'iad' command line option
       
   127             // so that it knows that it has been started for the first
       
   128             // time after java 2.0 IAD installation.
       
   129             startPreinstaller(ETrue);
       
   130         }
       
   131         break;
       
   132 
       
   133         case FIRST_DEVICE_BOOT_C:
       
   134         case NORMAL_BOOT_C:
       
   135         {
       
   136             registerMidletApplicationTypeHandler();
       
   137 
       
   138             // Start preinstaller normally (without 'iad' option).
       
   139             startPreinstaller(EFalse);
       
   140         }
       
   141         break;
       
   142 
       
   143         default:
       
   144         {
       
   145             WLOG1(EJavaCaptain,
       
   146                   "DriveListenerInterface: event() unknown boot event (type=%d)", bootType);
       
   147         }
       
   148         break;
       
   149         }
       
   150     }
       
   151     else if (eventProvider == MMC_EVENT_PROVIDER)
       
   152     {
       
   153         int operation = 0;
       
   154         driveInfo di;
       
   155         getMmcChangedMessageParams(aMsg, operation, di);
       
   156         LOG1(
       
   157             EJavaCaptain,
       
   158             EInfo,
       
   159             "PreinstallerStarter::event() mmc event received (operation=%d)",
       
   160             operation);
       
   161 
       
   162         switch (operation)
       
   163         {
       
   164             // Preinstaller started reacts only to this one event.
       
   165             // All other MMC events are ignored.
       
   166         case DriveListenerInterface::REMOVABLE_MEDIA_INSERTED_C:
       
   167         {
       
   168             startPreinstaller(EFalse);
       
   169         }
       
   170         break;
       
   171         }
       
   172     }
       
   173 }
       
   174 
       
   175 /**
       
   176  * Start preinstaller process if it is not yet running.
       
   177  * The name of the executable is javapreinstaller.exe
       
   178  * When it is started, it checks all preinstall directories in the device
       
   179  * and preinstalls those java applications in the directories that have not
       
   180  * yet been installed. After that preinstaller exits.
       
   181  *
       
   182  * @param aIadBoot when true, starts preinstaller with 'iad' parameter
       
   183  */
       
   184 void PreinstallerStarter::startPreinstaller(TBool aIadBoot)
       
   185 {
       
   186     JELOG2(EJavaCaptain);
       
   187 
       
   188     // Check that the device has enough free memory (800kB) to start preinstaller process
       
   189     // and (if needed) also java installer
       
   190     TInt freeMemory = 0;
       
   191     TInt err = HAL::Get(HALData::EMemoryRAMFree, freeMemory);
       
   192     if (KErrNone == err)
       
   193     {
       
   194         if (freeMemory < 819200)
       
   195         {
       
   196             if (freeMemory > 40960)
       
   197             {
       
   198                 // The device has enough memory to log the error
       
   199                 ELOG(EJavaCaptain,
       
   200                      "PreinstallerStarter: Not enough free mem to start preinstaller");
       
   201             }
       
   202             return;
       
   203         }
       
   204     }
       
   205     else
       
   206     {
       
   207         WLOG1(EJavaCaptain, "PreinstallerStarter: Cannot check free mem, err %d", err);
       
   208     }
       
   209 
       
   210     // Check that the device has enough also free disk space in C: (800kB) to start
       
   211     // preinstaller process
       
   212     if (SysUtil::FFSSpaceBelowCriticalLevelL(NULL, 819200))
       
   213     {
       
   214         if (!SysUtil::FFSSpaceBelowCriticalLevelL(NULL, 40960))
       
   215         {
       
   216             // The device has enough disk space to log the error
       
   217             ELOG(EJavaCaptain,
       
   218                  "PreinstallerStarter: Not enough space in phone mem to start preinstaller");
       
   219         }
       
   220         return;
       
   221     }
       
   222 
       
   223     // Start preinstaller process
       
   224     _LIT(KPreinstallerMatch, "javapreinstaller*");
       
   225     TFindProcess finder(KPreinstallerMatch);
       
   226     TFullName name;
       
   227 
       
   228     // Check all processes found
       
   229     while (KErrNone == finder.Next(name))
       
   230     {
       
   231         // Check the state of the already existing preinstaller process
       
   232         RProcess oldPreinstaller;
       
   233         TInt ret = oldPreinstaller.Open(name);
       
   234         if (KErrNone != ret)
       
   235         {
       
   236             WLOG1(EJavaCaptain,
       
   237                   "PreinstallerStarter: Cannot open existing preinstaller process, error %d", ret);
       
   238             oldPreinstaller.Close();
       
   239             return;
       
   240         }
       
   241         else
       
   242         {
       
   243             TExitType exitType = oldPreinstaller.ExitType();
       
   244             if (EExitPending == exitType)
       
   245             {
       
   246                 // Strange, preinstaller is already/still running, do nothing
       
   247                 WLOG(EJavaCaptain, "PreinstallerStarter: preinstaller is already running.");
       
   248                 oldPreinstaller.Close();
       
   249                 return;
       
   250             }
       
   251             else
       
   252             {
       
   253                 // The old preinstaller process has actually already exited,
       
   254                 // but it is still in the process list due to an Open C 1.5.1 functionalities.
       
   255                 LOG1(EJavaCaptain,
       
   256                      EInfo,
       
   257                      "PreinstallerStarter: old preinstaller process had exited, exit type is %d",
       
   258                      exitType);
       
   259                 oldPreinstaller.Close();
       
   260             }
       
   261         }
       
   262     }
       
   263     // No preinstaller processes were found or they were all zombies.
       
   264 
       
   265     // Start new preinstaller process.
       
   266     {
       
   267         // Build command line used to pass all necessary info
       
   268         TBuf<128> commandLine;  // Actual len of cmd line will be max 20 characters
       
   269         int len = strlen(java::runtime::JAVA_PREINSTALLER_STARTER_DLL);
       
   270         TPtr8 ptr8((TUint8 *)java::runtime::JAVA_PREINSTALLER_STARTER_DLL, len, len);
       
   271         commandLine.Copy(ptr8);
       
   272 
       
   273         if (aIadBoot)
       
   274         {
       
   275             commandLine.Append(_L(" iad"));
       
   276         }
       
   277 
       
   278         // start preinstaller
       
   279         RProcess preinstaller;
       
   280         TBuf<64> preinstallerProcess;  // Actual len of the process name is 9
       
   281         len = strlen(java::runtime::JAVA_PROCESS);
       
   282         TPtr8 ptr8Process((TUint8 *)java::runtime::JAVA_PROCESS, len, len);
       
   283         preinstallerProcess.Copy(ptr8Process);
       
   284         TInt err = preinstaller.Create(preinstallerProcess, commandLine);
       
   285         if (KErrNone == err)
       
   286         {
       
   287             // process has been created, allow it to run
       
   288             preinstaller.Resume();
       
   289             preinstaller.Close();
       
   290             if (aIadBoot)
       
   291             {
       
   292                 LOG(
       
   293                     EJavaCaptain,
       
   294                     EInfo,
       
   295                     "PreinstallerStarter: started preinstaller with iad parameter");
       
   296             }
       
   297             else
       
   298             {
       
   299                 LOG(EJavaCaptain, EInfo, "PreinstallerStarter: started preinstaller");
       
   300             }
       
   301         }
       
   302         else
       
   303         {
       
   304             ELOG1(
       
   305                 EJavaCaptain,
       
   306                 "PreinstallerStarter: starting preinstaller failed, err %d",
       
   307                 err);
       
   308         }
       
   309     }
       
   310 }
       
   311 
       
   312 /**
       
   313  * Register 'javalauncher.exe' as the midlet application type handler
       
   314  * in AppArc. If necessary unregister old handler first.
       
   315  */
       
   316 void PreinstallerStarter::registerMidletApplicationTypeHandler()
       
   317 {
       
   318     _LIT(KMidpAppArcPlugin, "javalauncher.exe");
       
   319 
       
   320     RApaLsSession appLstSession;
       
   321     CleanupClosePushL(appLstSession);
       
   322     TInt err = appLstSession.Connect();
       
   323     if (KErrNone == err)
       
   324     {
       
   325         TRAP(err, appLstSession.RegisterNonNativeApplicationTypeL(
       
   326                  TUid::Uid(KMidletApplicationTypeUid), KMidpAppArcPlugin()));
       
   327         if (KErrNone == err)
       
   328         {
       
   329             // All is well
       
   330         }
       
   331         else if (KErrAlreadyExists == err)
       
   332         {
       
   333 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD
       
   334             // S60 Java has registered MIDlet application type handler StubMIDP2RecogExe.exe,
       
   335             // must change that register
       
   336             WLOG(EJavaCaptain,
       
   337                  "PreinstallerStarter: MIDlet application type is already "
       
   338                  "registered (by Java 1.x).");
       
   339             TRAP(err, appLstSession.DeregisterNonNativeApplicationTypeL(
       
   340                      TUid::Uid(KMidletApplicationTypeUid)));
       
   341             TRAP(err, appLstSession.RegisterNonNativeApplicationTypeL(
       
   342                      TUid::Uid(KMidletApplicationTypeUid), KMidpAppArcPlugin()));
       
   343             if (KErrNone == err)
       
   344             {
       
   345                 WLOG(EJavaCaptain,
       
   346                      "PreinstallerStarter: Registered MIDlet application "
       
   347                      "type again (for Java 2.x).");
       
   348             }
       
   349             else
       
   350             {
       
   351                 ELOG1(EJavaCaptain,
       
   352                       "PreinstallerStarter: Reregistering MIDlet application "
       
   353                       "type failed with err %d",
       
   354                       err);
       
   355             }
       
   356 #endif
       
   357 
       
   358             // In 9.2 and later environments this situation is OK.
       
   359             // We have already made the registration successfully.
       
   360         }
       
   361         else
       
   362         {
       
   363             ELOG1(EJavaCaptain,
       
   364                   "PreinstallerStarter: Registering MIDlet application type failed with err %d",
       
   365                   err);
       
   366         }
       
   367         CleanupStack::PopAndDestroy(&appLstSession);
       
   368     }
       
   369     else
       
   370     {
       
   371         ELOG1(EJavaCaptain,
       
   372               "PreinstallerStarter: registerMidletApplicationTypeHandler: "
       
   373               "Connecting to AppArc failed with error %d",
       
   374               err);
       
   375     }
       
   376 }
       
   377 
       
   378 } // namespace captain
       
   379 } // namespace java