--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javamanager/javacaptain/extensionplugins/preinstallerstarter/src.s60/preinstallerstarter.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,379 @@
+/*
+* Copyright (c) 2008 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: PreinstallerStarter is Java Captain S60 plugin that starts
+* preinstaller process when the device boots or removable drive
+* is added to the device.
+*
+*/
+
+
+#include <e32base.h>
+#include <apgcli.h> // for RApaLsSession
+#include <hal_data.h>
+#include <hal.h>
+#include <sysutil.h>
+
+#include "javaprocessconstants.h"
+#include "javasymbianoslayer.h"
+#include "javauids.h"
+#include "logger.h"
+#include "coreinterface.h"
+#include "booteventprovidermessages.h"
+#include "mmceventprovidermessages.h"
+
+#include "preinstallerstarter.h"
+
+/**
+ * Return pointer to ExtensionPluginInterface implementation for this
+ * extension dll
+ */
+java::captain::ExtensionPluginInterface* getExtensionPlugin()
+{
+ return new java::captain::PreinstallerStarter();
+}
+
+namespace java
+{
+namespace captain
+{
+
+using java::fileutils::driveInfo;
+using java::fileutils::DriveListenerInterface;
+
+/**
+ * Empty contructor
+ */
+PreinstallerStarter::PreinstallerStarter() : mCore(0)
+{
+ JELOG2(EJavaCaptain);
+}
+
+/**
+ * Empty destructor
+ */
+PreinstallerStarter::~PreinstallerStarter()
+{
+ JELOG2(EJavaCaptain);
+}
+
+/**
+ * Implement PluginInterface method
+ */
+void PreinstallerStarter::startPlugin(CoreInterface* core)
+{
+ JELOG2(EJavaCaptain);
+ mCore = core;
+}
+
+/**
+ * Implement PluginInterface method
+ */
+void PreinstallerStarter::stopPlugin()
+{
+ JELOG2(EJavaCaptain);
+ mCore = 0;
+}
+
+/**
+ * Implement ExtensionPluginInterface method
+ */
+EventConsumerInterface* PreinstallerStarter::getEventConsumer()
+{
+ JELOG2(EJavaCaptain);
+ return this;
+}
+
+/**
+ * Handle Java Captain events sent by Boot event provider or
+ * MMC event provider. If IAD boot (Java Captain has been started
+ * after OMJ sis package has been installed), start preinstaller process
+ * with 'iad' paramater, otherwise start preinstaller process
+ * without the parameter.
+ *
+ * Implement EventConsumerInterface method
+ */
+void PreinstallerStarter::event(const std::string& eventProvider,
+ java::comms::CommsMessage& aMsg)
+{
+ JELOG2(EJavaCaptain);
+ if (eventProvider == BOOT_EVENT_PROVIDER)
+ {
+ int bootType = NORMAL_BOOT_C;
+ getBootMessageParams(aMsg, bootType);
+ LOG1(
+ EJavaCaptain,
+ EInfo,
+ "PreinstallerStarter::event() boot event received (type=%d)",
+ bootType);
+ switch (bootType)
+ {
+ case IAD_BOOT_C:
+ {
+ // This event is received after OMJ has been (IAD) installed
+ // to device.
+
+ // Preinstaller will be started with 'iad' command line option
+ // so that it knows that it has been started for the first
+ // time after java 2.0 IAD installation.
+ startPreinstaller(ETrue);
+ }
+ break;
+
+ case FIRST_DEVICE_BOOT_C:
+ case NORMAL_BOOT_C:
+ {
+ registerMidletApplicationTypeHandler();
+
+ // Start preinstaller normally (without 'iad' option).
+ startPreinstaller(EFalse);
+ }
+ break;
+
+ default:
+ {
+ WLOG1(EJavaCaptain,
+ "DriveListenerInterface: event() unknown boot event (type=%d)", bootType);
+ }
+ break;
+ }
+ }
+ else if (eventProvider == MMC_EVENT_PROVIDER)
+ {
+ int operation = 0;
+ driveInfo di;
+ getMmcChangedMessageParams(aMsg, operation, di);
+ LOG1(
+ EJavaCaptain,
+ EInfo,
+ "PreinstallerStarter::event() mmc event received (operation=%d)",
+ operation);
+
+ switch (operation)
+ {
+ // Preinstaller started reacts only to this one event.
+ // All other MMC events are ignored.
+ case DriveListenerInterface::REMOVABLE_MEDIA_INSERTED_C:
+ {
+ startPreinstaller(EFalse);
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * Start preinstaller process if it is not yet running.
+ * The name of the executable is javapreinstaller.exe
+ * When it is started, it checks all preinstall directories in the device
+ * and preinstalls those java applications in the directories that have not
+ * yet been installed. After that preinstaller exits.
+ *
+ * @param aIadBoot when true, starts preinstaller with 'iad' parameter
+ */
+void PreinstallerStarter::startPreinstaller(TBool aIadBoot)
+{
+ JELOG2(EJavaCaptain);
+
+ // Check that the device has enough free memory (800kB) to start preinstaller process
+ // and (if needed) also java installer
+ TInt freeMemory = 0;
+ TInt err = HAL::Get(HALData::EMemoryRAMFree, freeMemory);
+ if (KErrNone == err)
+ {
+ if (freeMemory < 819200)
+ {
+ if (freeMemory > 40960)
+ {
+ // The device has enough memory to log the error
+ ELOG(EJavaCaptain,
+ "PreinstallerStarter: Not enough free mem to start preinstaller");
+ }
+ return;
+ }
+ }
+ else
+ {
+ WLOG1(EJavaCaptain, "PreinstallerStarter: Cannot check free mem, err %d", err);
+ }
+
+ // Check that the device has enough also free disk space in C: (800kB) to start
+ // preinstaller process
+ if (SysUtil::FFSSpaceBelowCriticalLevelL(NULL, 819200))
+ {
+ if (!SysUtil::FFSSpaceBelowCriticalLevelL(NULL, 40960))
+ {
+ // The device has enough disk space to log the error
+ ELOG(EJavaCaptain,
+ "PreinstallerStarter: Not enough space in phone mem to start preinstaller");
+ }
+ return;
+ }
+
+ // Start preinstaller process
+ _LIT(KPreinstallerMatch, "javapreinstaller*");
+ TFindProcess finder(KPreinstallerMatch);
+ TFullName name;
+
+ // Check all processes found
+ while (KErrNone == finder.Next(name))
+ {
+ // Check the state of the already existing preinstaller process
+ RProcess oldPreinstaller;
+ TInt ret = oldPreinstaller.Open(name);
+ if (KErrNone != ret)
+ {
+ WLOG1(EJavaCaptain,
+ "PreinstallerStarter: Cannot open existing preinstaller process, error %d", ret);
+ oldPreinstaller.Close();
+ return;
+ }
+ else
+ {
+ TExitType exitType = oldPreinstaller.ExitType();
+ if (EExitPending == exitType)
+ {
+ // Strange, preinstaller is already/still running, do nothing
+ WLOG(EJavaCaptain, "PreinstallerStarter: preinstaller is already running.");
+ oldPreinstaller.Close();
+ return;
+ }
+ else
+ {
+ // The old preinstaller process has actually already exited,
+ // but it is still in the process list due to an Open C 1.5.1 functionalities.
+ LOG1(EJavaCaptain,
+ EInfo,
+ "PreinstallerStarter: old preinstaller process had exited, exit type is %d",
+ exitType);
+ oldPreinstaller.Close();
+ }
+ }
+ }
+ // No preinstaller processes were found or they were all zombies.
+
+ // Start new preinstaller process.
+ {
+ // Build command line used to pass all necessary info
+ TBuf<128> commandLine; // Actual len of cmd line will be max 20 characters
+ int len = strlen(java::runtime::JAVA_PREINSTALLER_STARTER_DLL);
+ TPtr8 ptr8((TUint8 *)java::runtime::JAVA_PREINSTALLER_STARTER_DLL, len, len);
+ commandLine.Copy(ptr8);
+
+ if (aIadBoot)
+ {
+ commandLine.Append(_L(" iad"));
+ }
+
+ // start preinstaller
+ RProcess preinstaller;
+ TBuf<64> preinstallerProcess; // Actual len of the process name is 9
+ len = strlen(java::runtime::JAVA_PROCESS);
+ TPtr8 ptr8Process((TUint8 *)java::runtime::JAVA_PROCESS, len, len);
+ preinstallerProcess.Copy(ptr8Process);
+ TInt err = preinstaller.Create(preinstallerProcess, commandLine);
+ if (KErrNone == err)
+ {
+ // process has been created, allow it to run
+ preinstaller.Resume();
+ preinstaller.Close();
+ if (aIadBoot)
+ {
+ LOG(
+ EJavaCaptain,
+ EInfo,
+ "PreinstallerStarter: started preinstaller with iad parameter");
+ }
+ else
+ {
+ LOG(EJavaCaptain, EInfo, "PreinstallerStarter: started preinstaller");
+ }
+ }
+ else
+ {
+ ELOG1(
+ EJavaCaptain,
+ "PreinstallerStarter: starting preinstaller failed, err %d",
+ err);
+ }
+ }
+}
+
+/**
+ * Register 'javalauncher.exe' as the midlet application type handler
+ * in AppArc. If necessary unregister old handler first.
+ */
+void PreinstallerStarter::registerMidletApplicationTypeHandler()
+{
+ _LIT(KMidpAppArcPlugin, "javalauncher.exe");
+
+ RApaLsSession appLstSession;
+ CleanupClosePushL(appLstSession);
+ TInt err = appLstSession.Connect();
+ if (KErrNone == err)
+ {
+ TRAP(err, appLstSession.RegisterNonNativeApplicationTypeL(
+ TUid::Uid(KMidletApplicationTypeUid), KMidpAppArcPlugin()));
+ if (KErrNone == err)
+ {
+ // All is well
+ }
+ else if (KErrAlreadyExists == err)
+ {
+#ifdef RD_JAVA_S60_RELEASE_5_0_IAD
+ // S60 Java has registered MIDlet application type handler StubMIDP2RecogExe.exe,
+ // must change that register
+ WLOG(EJavaCaptain,
+ "PreinstallerStarter: MIDlet application type is already "
+ "registered (by Java 1.x).");
+ TRAP(err, appLstSession.DeregisterNonNativeApplicationTypeL(
+ TUid::Uid(KMidletApplicationTypeUid)));
+ TRAP(err, appLstSession.RegisterNonNativeApplicationTypeL(
+ TUid::Uid(KMidletApplicationTypeUid), KMidpAppArcPlugin()));
+ if (KErrNone == err)
+ {
+ WLOG(EJavaCaptain,
+ "PreinstallerStarter: Registered MIDlet application "
+ "type again (for Java 2.x).");
+ }
+ else
+ {
+ ELOG1(EJavaCaptain,
+ "PreinstallerStarter: Reregistering MIDlet application "
+ "type failed with err %d",
+ err);
+ }
+#endif
+
+ // In 9.2 and later environments this situation is OK.
+ // We have already made the registration successfully.
+ }
+ else
+ {
+ ELOG1(EJavaCaptain,
+ "PreinstallerStarter: Registering MIDlet application type failed with err %d",
+ err);
+ }
+ CleanupStack::PopAndDestroy(&appLstSession);
+ }
+ else
+ {
+ ELOG1(EJavaCaptain,
+ "PreinstallerStarter: registerMidletApplicationTypeHandler: "
+ "Connecting to AppArc failed with error %d",
+ err);
+ }
+}
+
+} // namespace captain
+} // namespace java