javamanager/javainstaller/installer/src.s60/applicationregistrator/applicationregistrator.cpp
changeset 21 2a9601315dfc
child 23 98ccebc37403
child 24 0fd27995241b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javamanager/javainstaller/installer/src.s60/applicationregistrator/applicationregistrator.cpp	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,975 @@
+/*
+* Copyright (c) 2008-2010 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:  The JNI code for Java Installer component
+*                ApplicationRegistrator.
+*
+*/
+
+
+#include <apaid.h>
+#include <f32file.h>
+#include <apgcli.h>
+#include <utf.h>
+#include <s32mem.h>
+#include <bautils.h>
+#include <w32std.h>
+#include <apgtask.h>
+#include <apacmdln.h>
+#include <centralrepository.h>
+#include <AknUtils.h>
+#include <hal.h>
+
+#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <apgicnfl.h>
+#else
+#include <apgicnflpartner.h>
+#endif
+
+
+
+// JNI header must be included before iconconverter.h. Latter includes some
+// other header file which defines WIN32 macro, causing incorrect definitions
+// to be taken from jniport.h when WINSCW compilation is made.
+// This error situation can be seen from linker warnings which complain
+// about not frozen exports for JNI methods.
+#include "com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator.h"
+#include "iconconverter.h"
+#include "javacommonutils.h"
+#include "logger.h"
+
+// NAMESPACE DECLARATION
+using namespace java;
+
+/**
+ * MIDP Stub SIS file UID. The application type Uid for MIDlets in S60
+ */
+const TUid KMidletApplicationTypeUid = { 0x10210E26 };
+
+/**
+ * Symbian file path separator
+ */
+_LIT(KPathSeperator, "\\");
+
+/**
+ * Postfix for the fake application name generated only to make AppArc happy
+ */
+_LIT(KAppPostfix, ".fakeapp");
+
+// ------------------------
+
+/**
+ * Internal wrapper method that is used to make TRAPping the leaves in the
+ * native Symbian code easier.
+ * Used from JNI method ...1registerApplication()
+ * @see Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1registerApplication
+ */
+jint registerApplicationL(JNIEnv *aEnv, jclass aClass, jint aSessionHandle,
+                          jint aUid, HBufC16 *aGroupName, HBufC16 *aMIDletName, HBufC16 *aTargetDrive,
+                          HBufC16 *aIconFileName, HBufC16 *aJarFileName, jboolean aHidden,
+                          jboolean aBackground);
+
+/**
+ * Internal helper method for checking whether Application Shell is already running
+ * Used JNI method ...1startAppShellUi
+ *
+ * @return ETrue if AppShell is running
+ */
+TBool isAppShellUiRunning();
+
+/**
+ * Internal helper method for checking whether this code is executing in
+ * a device that has correctly working version of
+ * RApaLsSession::ForceCommitNonNativeApplicationsUpdatesL()
+ *
+ * @return ETrue if force commit works well
+ */
+TBool isForceCommitSupported();
+
+/**
+ * Internal helper method for starting menu application
+ *
+ * @return KErrNone or Symbian error code
+ */
+TInt startAppShellApplicationL();
+
+// --------------------------
+
+/**
+ * Starts native application registration session.
+ *
+ * @return native session handle or Symbian error code (negative number)
+ */
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1startSession
+(JNIEnv *, jclass)
+{
+    TInt err;
+    RApaLsSession *pApaSession = new RApaLsSession;
+
+    if (NULL == pApaSession)
+    {
+        // Could not create session
+        return KErrGeneral;
+    }
+
+    err = pApaSession->Connect();
+    if (KErrNone != err)
+    {
+        // Cannot connect to AppArc server
+        return err;
+    }
+
+#if 1
+//#ifndef RD_JAVA_USIF_APP_REG
+    // 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)pApaSession->RollbackNonNativeApplicationsUpdates();
+
+    // Prepare for Java application registrations / unregistrations
+    TRAP(err, pApaSession->PrepareNonNativeApplicationsUpdatesL());
+    if (KErrNone != err)
+    {
+        // Close session and return error
+        pApaSession->Close();
+        return err;
+    }
+#endif // RD_JAVA_USIF_APP_REG
+
+    // Return handle to session. Utilize the fact that in Symbian
+    // all pointer addresses are MOD 4 so the last 2 bits are 0
+    // and can be shifted out. This way the returned handle is
+    // always positive whereas Symbian error codes are always negative.
+    return reinterpret_cast<TUint>(pApaSession)>>2;
+}
+
+
+/**
+ * Registers Java Application to S60 AppArc
+ *
+ * @param[in] aSessionHandle
+ * @param[in] aUid The Uid of the application.
+ * @param[in] aGroupName  Max group name len is 16 in AppArc
+ * @param[in] aMIDletName
+ * @param[in] aTargetDrive Must be "C:", "E:", ..., "J:"
+ * @param[in] aIconFileName The name of the icon
+ * @param[in] aJarFileName The full path name of the jar file
+ * @param[in] aHidden
+ * @param[in] aBackground
+ * @return 0 if registration succeeded or Symbian error code
+ */
+#if 0
+//#ifdef RD_JAVA_USIF_APP_REG
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1registerApplication
+(JNIEnv */*aEnv*/, jclass /*aClass*/, jint /*aSessionHandle*/, jint /*aUid*/, jstring /*aGroupName*/,
+ jstring /*aMIDletName*/, jstring /*aTargetDrive*/, jstring /*aIconFileName*/,
+ jstring /*aJarFileName*/, jboolean /*aHidden*/, jboolean /*aBackground*/)
+{
+    return KErrNone;
+}
+#else
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1registerApplication
+(JNIEnv *aEnv, jclass aClass, jint aSessionHandle, jint aUid, jstring aGroupName,
+ jstring aMIDletName, jstring aTargetDrive, jstring aIconFileName,
+ jstring aJarFileName, jboolean aHidden, jboolean aBackground)
+{
+    TInt err(KErrNone);
+    TBool fStayInLoop(EFalse);
+
+    HBufC16 *unicodeIconFileName(NULL);
+    HBufC16 *unicodeGroupName(NULL);
+    HBufC16 *unicodeMIDletName(NULL);
+    HBufC16 *unicodeTargetDrive(NULL);
+    HBufC16 *unicodeJarFileName(NULL);
+
+    // create loop that is executed only once to make error handling easier
+    do
+    {
+        // Copy the unicode characters in jstrings to Symbian buffers so that
+        // they can be used in S60 code
+        const jchar *iconFileName = aEnv->GetStringChars(aIconFileName, 0);
+        if (NULL == iconFileName)
+        {
+            ELOG(
+                EJavaInstaller,
+                "Cannot register application, getting icon file name as unicode failed in JNI");
+            err = KErrArgument;
+            break;
+        }
+        unicodeIconFileName = HBufC16::New(aEnv->GetStringLength(aIconFileName) + 1);
+        if (NULL == unicodeIconFileName)
+        {
+            err = KErrNoMemory;
+            break;
+        }
+        *unicodeIconFileName = iconFileName;
+        aEnv->ReleaseStringChars(aIconFileName, iconFileName);
+
+        const jchar *groupName = aEnv->GetStringChars(aGroupName, 0);
+        if (NULL == groupName)
+        {
+            ELOG(
+                EJavaInstaller,
+                "Cannot register application, getting group name as unicode failed in JNI");
+            err = KErrArgument;
+            break;
+        }
+        unicodeGroupName = HBufC16::New(aEnv->GetStringLength(aGroupName) + 1);
+        if (NULL == unicodeGroupName)
+        {
+            err = KErrNoMemory;
+            break;
+        }
+        *unicodeGroupName = groupName;
+        aEnv->ReleaseStringChars(aGroupName, groupName);
+
+        const jchar *midletName = aEnv->GetStringChars(aMIDletName, 0);
+        if (NULL == midletName)
+        {
+            ELOG(
+                EJavaInstaller,
+                "Cannot register application, getting midlet name as unicode failed in JNI");
+            err = KErrArgument;
+            break;
+        }
+        unicodeMIDletName = HBufC16::New(aEnv->GetStringLength(aMIDletName) + 1);
+        if (NULL == unicodeMIDletName)
+        {
+            err = KErrNoMemory;
+            break;
+        }
+        *unicodeMIDletName = midletName;
+        aEnv->ReleaseStringChars(aMIDletName, midletName);
+
+        const jchar *targetDrive = aEnv->GetStringChars(aTargetDrive, 0);
+        if (NULL == targetDrive)
+        {
+            ELOG(
+                EJavaInstaller,
+                "Cannot register application, getting target drive as unicode failed in JNI");
+            err = KErrArgument;
+            break;
+        }
+        unicodeTargetDrive = HBufC16::New(aEnv->GetStringLength(aTargetDrive) + 1);
+        if (NULL == unicodeTargetDrive)
+        {
+            err = KErrNoMemory;
+            break;
+        }
+        *unicodeTargetDrive = targetDrive;
+        aEnv->ReleaseStringChars(aTargetDrive, targetDrive);
+
+        const jchar *jarFileName = aEnv->GetStringChars(aJarFileName, 0);
+        if (NULL == jarFileName)
+        {
+            ELOG(
+                EJavaInstaller,
+                "Cannot register application, getting jar file name as unicode failed in JNI");
+            err = KErrArgument;
+            break;
+        }
+        unicodeJarFileName = HBufC16::New(aEnv->GetStringLength(aJarFileName) + 1);
+        if (NULL == unicodeTargetDrive)
+        {
+            err = KErrNoMemory;
+            break;
+        }
+        *unicodeJarFileName = jarFileName;
+        aEnv->ReleaseStringChars(aJarFileName, jarFileName);
+    }
+    while (fStayInLoop);
+
+    if (KErrNone != err)
+    {
+        delete unicodeIconFileName;
+        delete unicodeGroupName;
+        delete unicodeMIDletName;
+        delete unicodeTargetDrive;
+        delete unicodeJarFileName;
+
+        return err;
+    }
+
+    // Call the actual register method inside TRAP harness
+    TInt ret = KErrNone;
+    TRAP(err,
+         ret = registerApplicationL(
+                   aEnv, aClass, aSessionHandle, aUid, unicodeGroupName,
+                   unicodeMIDletName, unicodeTargetDrive, unicodeIconFileName,
+                   unicodeJarFileName, aHidden, aBackground));
+
+    LOG1WSTR(
+        EJavaInstaller,
+        EInfo,
+        "Registering application, midlet name (%s)",
+        (wchar_t *)(unicodeMIDletName->Des().PtrZ()));
+    LOG1WSTR(
+        EJavaInstaller,
+        EInfo,
+        "Registering application, icon file name (%s)",
+        (wchar_t *)(unicodeIconFileName->Des().PtrZ()));
+
+    if (KErrNone != err)
+    {
+        ELOG1(EJavaInstaller,
+              "Cannot register application, err code is %d ",
+              err);
+    }
+    if (KErrNone != ret)
+    {
+        // error even though the code did not leave
+        err = ret;
+
+        ELOG1(EJavaInstaller,
+              "Cannot register application, non-leaving error %d",
+              ret);
+    }
+
+    // Free all Symbian buffers containing copies of jstring data
+    delete unicodeIconFileName;
+    delete unicodeGroupName;
+    delete unicodeMIDletName;
+    delete unicodeTargetDrive;
+    delete unicodeJarFileName;
+
+    return err;
+}
+#endif // RD_JAVA_USIF_APP_REG
+
+
+/**
+ * See JNI method __1registerApplication.
+ * This method makes all calls that may leave (the actual registering)
+ */
+jint registerApplicationL(
+    JNIEnv *, jclass, jint aSessionHandle, jint aUid, HBufC16 *aGroupName,
+    HBufC16 *aMIDletName, HBufC16 *aTargetDrive, HBufC16 *aIconFileName,
+    HBufC16 * /*aJarFileName*/, jboolean aHidden, jboolean aBackground)
+{
+    RFs         fileServ;
+    RFile       appArcIcon;
+    TUid        midletUid;
+    TInt        err;
+    TInt        numberOfIcons = 1; // Conversion results always one icon in mbm.
+    // Also default mbm has one icon.
+
+    midletUid.iUid = aUid;
+
+    // AppArc requires open RFile handle
+    err = fileServ.Connect();
+    if (KErrNone != err)
+    {
+        // Will not register application without icon
+        ELOG1(EJavaInstaller,
+              "Cannot open RFs connection, err code is %d ", err);
+        return err;
+    }
+    CleanupClosePushL(fileServ);
+
+    // The session must be shared so that AppArc can
+    // use the same icon file handle
+    err = fileServ.ShareProtected();
+    if (KErrNone != err)
+    {
+        ELOG1(EJavaInstaller,
+              "Cannot share file server session, err code is %d ", err);
+        User::Leave(err);
+    }
+
+    // Default icon has been copied from ROM, so the icon may have ReadOnly
+    // flag on. Must remove that flag.
+    fileServ.SetAtt(*aIconFileName, 0, KEntryAttReadOnly);
+
+    // open the icon
+    err = appArcIcon.Open(
+              fileServ,
+              *aIconFileName,
+              (EFileShareReadersOrWriters | EFileWrite));
+    if (KErrNone != err)
+    {
+        ELOG1(EJavaInstaller,
+              "registerApplicationL: Cannot open icon, err code is %d ", err);
+        User::Leave(err);
+    }
+
+    // Now icon is open
+    CleanupClosePushL(appArcIcon);
+
+    // Generate the executable name name using the same
+    // algorithm as used earlier in S60 platform
+    // in case some external S60 application
+    // needs to parse the Uid from the executable name.
+    TFileName appName;
+    appName.Copy(KPathSeperator);
+    appName.AppendNum(midletUid.iUid);
+    appName.Append(KAppPostfix);
+
+    // Create writer needed for actual registration
+    CApaRegistrationResourceFileWriter *writer = NULL;
+    writer = CApaRegistrationResourceFileWriter::NewL(
+                 midletUid,
+                 appName,
+                 TApaAppCapability::ENonNative);
+    CleanupStack::PushL(writer);
+
+    writer->SetGroupNameL(*aGroupName);
+    if (aBackground)
+    {
+        // By default this is false, so the value needs to be set
+        // only if it is true
+        writer->SetLaunchInBackgroundL(ETrue);
+    }
+    if (aHidden)
+    {
+        // By default this is false, so the value needs to be set
+        // only if it is true
+        writer->SetAppIsHiddenL(ETrue);
+    }
+
+    // write application Uid to opaque data   (needed by MIDlet launcher)
+    TBuf8<4>         opaqueData;     // opaque data will contain one signed 32-bit int
+    RDesWriteStream  writeStream(opaqueData);
+    writeStream.WriteInt32L(midletUid.iUid);
+    writeStream.CommitL();
+    writer->SetOpaqueDataL(opaqueData);
+
+    CApaLocalisableResourceFileWriter*  lWriter = NULL;
+    lWriter =
+        CApaLocalisableResourceFileWriter::NewL(
+            KNullDesC,  // short caption
+            *aMIDletName,  // caption
+            numberOfIcons,
+            KNullDesC);
+    CleanupStack::PushL(lWriter);
+
+    TDriveUnit targetDrive(*aTargetDrive);
+
+    // Convert session handle to pointer.
+    RApaLsSession *pApaSession =
+        reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
+
+    // Register application to AppArc
+    pApaSession->RegisterNonNativeApplicationL(
+        KMidletApplicationTypeUid,
+        targetDrive,
+        *writer,
+        lWriter,
+        &appArcIcon);
+
+    CleanupStack::PopAndDestroy(lWriter);
+    CleanupStack::PopAndDestroy(writer);
+    // close icon file handle
+    CleanupStack::PopAndDestroy(&appArcIcon);
+
+    // close file server connection
+    CleanupStack::PopAndDestroy(&fileServ);
+
+    return err;
+}
+
+
+/**
+ * Unregisters Java Application from S60 AppArc
+ *
+ * @param[in] aSessionHandle
+ * @param[in] aUid The Uid of the application to be unregistered..
+ * @return 0 if unregistration succeeded or Symbian error code
+ */
+#if 0
+//#ifdef RD_JAVA_USIF_APP_REG
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1unregisterApplication
+(JNIEnv *, jclass, jint /*aSessionHandle*/, jint /*aUid*/)
+{
+    return KErrNone;
+}
+#else
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1unregisterApplication
+(JNIEnv *, jclass, jint aSessionHandle, jint aUid)
+{
+    // Convert session handle to pointer.
+    RApaLsSession *pApaSession =
+        reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
+
+    TUid appUid;
+    appUid.iUid = aUid;
+    TRAPD(err, pApaSession->DeregisterNonNativeApplicationL(appUid));
+    return err;
+}
+#endif // RD_JAVA_USIF_APP_REG
+
+
+/**
+ * Commits native application registration session.
+ * If commit succeeds the native session is closed.
+ *
+ * @param[in] aSessionHandle
+ * @param[in] aSynchronous if true, makes synchronous commit
+ * @return 0 or Symbian error code (negative number)
+ */
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1commitSession
+(JNIEnv *, jclass, jint aSessionHandle, jboolean aSynchronous)
+{
+    // Convert session handle to pointer.
+    RApaLsSession *pApaSession =
+        reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
+
+    TInt err = KErrNone;
+
+#if 1
+//#ifndef RD_JAVA_USIF_APP_REG
+    if (aSynchronous)
+    {
+        // Make synchronous commit
+        TRAP(err, pApaSession->CommitNonNativeApplicationsUpdatesL());
+        if (KErrNone == err)
+        {
+            pApaSession->Close();
+            delete pApaSession;
+        }
+        return err;
+    }
+
+    // Otherwise check whether the device supports asynchronous commit
+    // (has a working version of new AppArc method ForceCommitNonNativeApplicationsUpdatesL)
+    // Latest S60 5.0 builds contain fix for Symbian
+    // defect PDEF129466 (PDEF129467 for Symbian OS 9.5).
+    if (!isForceCommitSupported())
+    {
+        // Use old API
+        TRAP(err, pApaSession->CommitNonNativeApplicationsUpdatesL());
+    }
+    else
+    {
+#ifdef __WINS__
+        // Use always this synchronous commit when running in emulator
+        // to make writing autotest cases easier.
+        TRAP(err, pApaSession->CommitNonNativeApplicationsUpdatesL());
+#else
+        // asynchronous commit
+        TRAP(err, pApaSession->ForceCommitNonNativeApplicationsUpdatesL());
+#endif // __WINS__
+    }
+#endif // RD_JAVA_USIF_APP_REG
+
+    if (KErrNone == err)
+    {
+        pApaSession->Close();
+        delete pApaSession;
+    }
+    return err;
+}
+
+
+/**
+ * Rolls back and closes native application registration session.
+ *
+ * @param[in] aSessionHandle
+ * @return 0 or Symbian error code (negative number)
+ */
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1rollbackSession
+(JNIEnv *, jclass, jint aSessionHandle)
+{
+    // Convert session handle to pointer.
+    RApaLsSession *pApaSession =
+        reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
+
+    TInt err = KErrNone;
+#if 1
+//#ifndef RD_JAVA_USIF_APP_REG
+    err = pApaSession->RollbackNonNativeApplicationsUpdates();
+#endif // RD_JAVA_USIF_APP_REG
+    pApaSession->Close();
+    delete pApaSession;
+
+    return err;
+}
+
+
+/**
+ * Tells whether the uid is in use in AppArc.
+ * Calls AppArc RApaLsSession::GetAppType
+ *
+ * @param[in] aSessionHandle
+ * @param[in] aUid
+ * @return 0 if the uid is not in use,
+ *  1 if the uid is in use
+ */
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1uidInUse
+(JNIEnv *, jclass, jint aSessionHandle, jint aUid)
+{
+    // Convert session handle to pointer.
+    RApaLsSession *pApaSession =
+        reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
+
+    TUid typeUid;
+    TUid appUid;
+    appUid.iUid = aUid;
+    TInt err = pApaSession->GetAppType(typeUid, appUid);
+    if (KErrNone == err)
+    {
+        // AppArc knows the app type -> the uid is in use
+        return 1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+
+/**
+ * Returns the logical group name of the application.
+ * Calls AppArc RApaLsSession::GetAppCapability
+ *
+ * @param[in] aSessionHandle
+ * @param[in] aUid
+ * @param[out] aGroupName should be "" when called, will contain group name
+ *  when function returns if call was successfull.
+ *  Note that max group name len is 16.
+ * @return Symbian error code (negative number) if fails, otherwise 0
+ */
+JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1getGroupName
+(JNIEnv *aEnv, jclass aClass, jint aSessionHandle, jint aUid, jobject aGroupName)
+{
+    if (0 == aGroupName)
+    {
+        // Cannot return logical group name because StringBuffer param is null
+        return KErrArgument;
+    }
+
+    // Convert session handle to pointer.
+    RApaLsSession *pApaSession =
+        reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
+
+    TInt    err;
+    TUid    midletUid;
+    TApaAppCapabilityBuf cap;
+
+    midletUid.iUid = aUid;
+
+    err = pApaSession->GetAppCapability(cap, midletUid);
+    if (KErrNone != err)
+    {
+        return err;
+    }
+
+    // The name is available in Unicode format from cap, convert it to UTF8
+    // Then lenght of the buffer has '+1' to reserve space for zero terminator
+    // needed to convert string to Java string
+    TBuf8<KApaMaxAppGroupName+1> nameBuf;   // max group name len is 16
+    err = CnvUtfConverter::ConvertFromUnicodeToUtf8(nameBuf, cap().iGroupName);
+    if (KErrNone != err)
+    {
+        return err;
+    }
+
+    // Get class handle to StringBuffer
+    aClass = aEnv->GetObjectClass(aGroupName);
+
+    // Get method ID to StringBuffer StringBuffer.append(String)
+    jmethodID methodID = aEnv->GetMethodID(
+                             aClass,
+                             "append",
+                             "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+    if (0 == methodID)
+    {
+        return KErrGeneral;
+    }
+
+    // Create new Java String
+    jstring logicalName = aEnv->NewStringUTF((const char*)(nameBuf.PtrZ()));
+
+    // Append it to aGroupName parameter
+    aEnv->CallObjectMethod(aGroupName, methodID, logicalName);
+
+    return 0;
+}
+
+
+/**
+ * Closes native application registration session.
+ *
+ * @param[in] aSessionHandle the session to be closed
+ */
+JNIEXPORT void JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1closeSession
+(JNIEnv *, jclass, jint aSessionHandle)
+{
+    // Convert session handle to pointer.
+    RApaLsSession *pApaSession =
+        reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
+
+    pApaSession->Close();
+    delete pApaSession;
+}
+
+
+/**
+ * Converts icon to S60 specific format. SVG icons are converted to MIF,
+ * other icons to MBM.
+ *
+ * @param[in] aInputIconFilename file name of the original icon inside .jar
+ * @param[in] aOutputIconFilename file name for converted (output) icon
+ * @param[in] aJarFilename jar file name. In S60 the icon is always
+ *   inside the .jar file
+ * @param[out] aIconSuffix the correct suffix of the icon is returned through
+ *    this parameter, will contain '.mbm' or '.mif' when function returns
+ * @return true if the conversion succeeds
+ */
+JNIEXPORT jboolean JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1convertIcon
+(JNIEnv *aEnv, jclass aClass, jstring aInputIconFilename,
+ jstring aOutputIconFilename, jstring aJarFilename, jobject aIconSuffix)
+{
+    jboolean conversionSucceeded = JNI_TRUE;
+    RFs      fileServ;
+
+    // IconConverter requires open RFile handle
+    TInt err = fileServ.Connect();
+    if (KErrNone != err)
+    {
+        // Cannot convert icons without file server connection
+        ELOG1(EJavaInstaller,
+              "_1convertIcon: Cannot open RFs connection, err code is %d ", err);
+        return err;
+    }
+
+    // Copy the unicode characters in jstrings to Symbian buffers so that
+    // they can be used in S60 code
+    const jchar *iconFileName = aEnv->GetStringChars(aInputIconFilename, 0);
+    if (NULL == iconFileName)
+    {
+        ELOG(
+            EJavaInstaller,
+            "Cannot convert icon, getting icon file name as unicode failed in JNI");
+        fileServ.Close();
+        return JNI_FALSE;
+    }
+    HBufC16 *unicodeIconFileName = HBufC16::New(aEnv->GetStringLength(aInputIconFilename) + 1);
+    if (NULL == unicodeIconFileName)
+    {
+        fileServ.Close();
+        return JNI_FALSE;
+    }
+    *unicodeIconFileName = iconFileName;
+    aEnv->ReleaseStringChars(aInputIconFilename, iconFileName);
+
+    const jchar *jarFileName = aEnv->GetStringChars(aJarFilename, 0);
+    if (NULL == jarFileName)
+    {
+        ELOG(
+            EJavaInstaller,
+            "Cannot convert icon, getting jar file name as unicode failed in JNI");
+        delete unicodeIconFileName;
+        fileServ.Close();
+        return JNI_FALSE;
+    }
+    HBufC16 *unicodeJarFileName = HBufC16::New(aEnv->GetStringLength(aJarFilename) + 1);
+    if (NULL == unicodeJarFileName)
+    {
+        delete unicodeIconFileName;
+        fileServ.Close();
+        return JNI_FALSE;
+    }
+    *unicodeJarFileName = jarFileName;
+    aEnv->ReleaseStringChars(aJarFilename, jarFileName);
+
+    const jchar *outputFileName = aEnv->GetStringChars(aOutputIconFilename, 0);
+    if (NULL == outputFileName)
+    {
+        ELOG(
+            EJavaInstaller,
+            "Cannot convert icon, getting output file name as unicode failed in JNI");
+        delete unicodeIconFileName;
+        delete unicodeJarFileName;
+        fileServ.Close();
+        return JNI_FALSE;
+    }
+    HBufC16 *unicodeOutputFileName = HBufC16::New(aEnv->GetStringLength(aOutputIconFilename) + 1);
+    if (NULL == unicodeOutputFileName)
+    {
+        delete unicodeIconFileName;
+        delete unicodeJarFileName;
+        fileServ.Close();
+        return JNI_FALSE;
+    }
+    *unicodeOutputFileName = outputFileName;
+    aEnv->ReleaseStringChars(aOutputIconFilename, outputFileName);
+
+    CIconConverter *pConv = NULL;
+    TRAP(err, pConv= CIconConverter::NewL(fileServ));
+    if (KErrNone != err)
+    {
+        ELOG1(EJavaInstaller, "Cannot create icon converter, error %d ", err);
+        delete unicodeIconFileName;
+        delete unicodeJarFileName;
+        delete unicodeOutputFileName;
+        fileServ.Close();
+        return JNI_FALSE;
+    }
+
+    // read icon from .jar file, convert it to MIF/MBM and store to file
+    TBool isMbmIcon = EFalse;
+    err = pConv->Convert(*unicodeJarFileName, *unicodeIconFileName,
+                         *unicodeOutputFileName, &isMbmIcon);
+    delete pConv;
+    if (KErrNone != err)
+    {
+        WLOG1(EJavaInstaller,
+              "Cannot convert icon, err code is %d.",
+              err);
+        conversionSucceeded = JNI_FALSE;
+    }
+
+    // Free all Symbian buffers containing copies of jstring data
+    delete unicodeIconFileName;
+    delete unicodeJarFileName;
+    delete unicodeOutputFileName;
+    fileServ.Close();
+
+    // set the value of aIconSuffix to '.mbm' or '.mif'
+    if (0 == aIconSuffix)
+    {
+        // Cannot return icon suffix name because StringBuffer param is null
+        WLOG(EJavaInstaller,
+             "_1convertIcon cannot return the correct icon suffix because param is null");
+        return JNI_FALSE;
+    }
+
+    // Get class handle to StringBuffer
+    aClass = aEnv->GetObjectClass(aIconSuffix);
+
+    // Get method ID to StringBuffer StringBuffer.append(String)
+    jmethodID methodID = aEnv->GetMethodID(
+                             aClass,
+                             "append",
+                             "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+    if (0 == methodID)
+    {
+        WLOG(EJavaInstaller, "_1convertIcon: JNI: getting append method failed.");
+        return JNI_FALSE;
+    }
+
+    // Create new Java String, Multibitmap file name suffix is '.mbm',
+    // suffix for mif wrapped svg is '.mif'
+    jstring suffix;
+    if (isMbmIcon)
+    {
+        suffix = aEnv->NewStringUTF(".mbm");
+    }
+    else
+    {
+        suffix = aEnv->NewStringUTF(".mif");
+    }
+
+    // Append it to aIconSuffix parameter
+    aEnv->CallObjectMethod(aIconSuffix, methodID, suffix);
+
+    return conversionSucceeded;
+}
+
+
+/**
+ * Returns true if the current device is touch screen
+ * device without physical LSK and RSK
+ *
+ * @return true if virtual on screen keypad is needed
+ */
+JNIEXPORT jboolean JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1isOnDeviceKeypadNeeded
+(JNIEnv *, jclass)
+{
+    // Return TRUE -> OnScreenKeypad attribute will be given
+    // default value if the attribute has not been defined in
+    // .jad file or manifest.
+    // The runtime code will check whether the device has touch
+    // screen using AknLayoutUtils::PenEnabled() and show the
+    // keypad only if needed.
+    return JNI_TRUE;
+}
+
+
+/**
+ * Sends a process to process notification to the parent process
+ * of Java Installer telling that Installer is about to start
+ * displaying UI dialogs.
+ */
+JNIEXPORT void JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1notifyLauncherThatUiIsReady
+(JNIEnv *, jclass)
+{
+    RProcess currentProcess;
+    currentProcess.Rendezvous(EJavaInstaller);
+
+    return;
+}
+
+
+/**
+ * Returns true if the code is executed in Symbian 9.2
+ * emulator environment.
+ *
+ * @return if Symbian 9.2 emulator environment
+ */
+JNIEXPORT jboolean JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1runningIn92Emulator
+(JNIEnv *, jclass)
+{
+#if !defined(RD_JAVA_S60_RELEASE_5_0_IAD) && defined(__WINS__)
+    return JNI_TRUE;
+#else
+    return JNI_FALSE;
+#endif
+}
+
+
+/**
+ * Internal helper method for checking whether this code is executing in
+ * a device that has correctly working version of
+ * RApaLsSession::ForceCommitNonNativeApplicationsUpdatesL()
+ *
+ * The device family based on Nokia XpressMusic5800 did not have
+ * working version of force commit
+ *
+ * @return ETrue if current device does not belong to Nokia XpressMusic5800
+ *  device family
+ */
+TBool isForceCommitSupported()
+{
+    TInt err;
+    TInt value;
+
+    err = HAL::Get(HAL::EModel, value);
+    if (KErrNone == err)
+    {
+        LOG1(EJavaInstaller, EInfo, "Device model is %d", value);
+    }
+    else
+    {
+        WLOG1(EJavaInstaller, "Cannot get device model id, error %d", err);
+        // It is safest to assume that force commit is not supported
+        return EFalse;
+    }
+
+    // Check against all current (28. Aug 2009) members of the device family.
+    // Note that several closely related devices share the same model id.
+    if ((0x2000DA56 != value) &&
+            (0x2001DE9D != value) &&
+            (0x2000DA60 != value) &&
+            (0x20023765 != value))
+    {
+        // The device does not belong to Nokia 5800 XpressMusic device family,
+        // so it supports foce commit
+        return ETrue;
+    }
+    else
+    {
+        return EFalse;
+    }
+}