javamanager/javainstaller/installer/javasrc.s60/com/nokia/mj/impl/installer/applicationregistrator/ApplicationRegistrator.java
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javamanager/javainstaller/installer/javasrc.s60/com/nokia/mj/impl/installer/applicationregistrator/ApplicationRegistrator.java	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,585 @@
+/*
+* Copyright (c) 2008-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:
+*
+*/
+
+
+package com.nokia.mj.impl.installer.applicationregistrator;
+
+import com.nokia.mj.impl.installer.utils.InstallerException;
+import com.nokia.mj.impl.installer.utils.FileRoots;
+import com.nokia.mj.impl.installer.utils.FileUtils;
+import com.nokia.mj.impl.installer.utils.Log;
+import com.nokia.mj.impl.installer.utils.PlatformUid;
+import com.nokia.mj.impl.utils.Uid;
+
+
+/**
+ * Registers (and unregisters) Java application to S60 platform.
+ * This version registers MIDlet to Symbian AppArc.
+ * startSession() must be called before the other methods of this
+ * class can be used.
+ *
+ * @author Nokia Corporation
+ * @version $Rev: 9041 $
+ */
+public final class ApplicationRegistrator
+{
+    // The OMJ default (svg) icon
+    private static final String DEFAULT_SVG_ICON_NAME = "java_app.mif";
+    private static final String DEFAULT_92_SVG_ICON_NAME = "java_app_92.mif";
+    private static final String DEFAULT_SVG_ICON_SUFFIX = ".mif";
+
+    /**
+     * Native session handle
+     */
+    private int iSessionHandle = 0;
+
+
+    /*** ----------------------------- PUBLIC ------------------------------ */
+
+    /**
+     * Starts application registration session.
+     * Before the new session is started rolls back any pending (un)registrations
+     * that are not committed (for example power off case). So do NOT start
+     * sessions from several instances of ApplicationRegistrator concurrently.
+     * The registrations and unregistrations are done only
+     * when commitSession is called.
+     * If you want to discard the registrations and unregistrations
+     * call rollbackSession.
+     * Does nothing if session has already been successfully started
+     * from this ApplicationRegistrator instance.
+     *
+     * @throws InstallerException if the session cannot created
+     * @see commitSession
+     * @see rollbackSession
+     */
+    public void startSession()
+    {
+        if (0 != iSessionHandle)
+        {
+            // session has already been created, do nothing
+            Log.logWarning("ApplicationRegistrator.startSession called although session is already open.");
+            return;
+        }
+
+        // native method writes error log and returns
+        // negative Symbian error code if it fails
+        int ret = _startSession();
+        if (ret < 0)
+        {
+            InstallerException.internalError("Creating session failed with code " + ret);
+        }
+
+        iSessionHandle = ret;
+    }
+
+    /**
+     * Registers one Java application to S60 AppArc.
+     *
+     * @param aAppRegInfo Information needed to register the application
+     * @throws InstallerException if registration cannot done or
+     *  startSession has not been called successfully
+     * @see startSession
+     * @see AppRegInfo
+     */
+    public void registerApplication(AppRegInfo aAppRegInfo)
+    {
+        if (0 == iSessionHandle)
+        {
+            InstallerException.internalError("No valid session.");
+        }
+
+        // check that aAppRegInfo.iTargetDrive is "A:" ... "Z:"
+        int err = 0;
+        aAppRegInfo.iTargetDrive = aAppRegInfo.iTargetDrive.toUpperCase();
+        if (aAppRegInfo.iTargetDrive.length() != 2)
+        {
+            err = 1;
+        }
+        else if (aAppRegInfo.iTargetDrive.charAt(1) != ':')
+        {
+            err = 1;
+        }
+        else if ((aAppRegInfo.iTargetDrive.charAt(0) < 'A') ||
+                 (aAppRegInfo.iTargetDrive.charAt(0) > 'Z'))
+        {
+            err = 1;
+        }
+        if (1 == err)
+        {
+            InstallerException.internalError(
+                "Invalid target drive " + aAppRegInfo.iTargetDrive);
+        }
+
+        // Symbian AppArc can store max 16 characters for group name.
+        String groupName = aAppRegInfo.iGroupName;
+        if (groupName.length() > 16)
+        {
+            groupName = aAppRegInfo.iGroupName.substring(0, 16);
+            Log.logWarning("ApplicationRegistrator.registerApplication: Application group name len > 16, cut to "
+                           + groupName);
+        }
+
+        Log.log("ApplicationRegistrator registerApplication called with  "
+                + aAppRegInfo.toString());
+
+        // Applications with name longer than 80 characters cannot be
+        // launched in Symbian.
+        String midletName = aAppRegInfo.iMIDletName;
+        if (midletName.length() > 80)
+        {
+            midletName = midletName.substring(0, 80);
+            Log.logWarning("ApplicationRegistrator.registerApplication: midlet name len > 80, cut to "
+                           + midletName);
+        }
+
+        try
+        {
+            err = _registerApplication(
+                      iSessionHandle,
+                      PlatformUid.getIntValue(aAppRegInfo.iUid),
+                      groupName,
+                      midletName,
+                      aAppRegInfo.iTargetDrive,
+                      aAppRegInfo.iIconFileName,
+                      aAppRegInfo.iJarFileName,
+                      aAppRegInfo.iHidden,
+                      aAppRegInfo.iBackground);
+        }
+        catch (Throwable t)
+        {
+            InstallerException.internalError("Registering application "
+                                             + "failed with unexpected throwable " + t.toString());
+        }
+
+        if (err < 0)
+        {
+            InstallerException.internalError("Registering application "
+                                             + aAppRegInfo.iUid.getStringValue() + " failed with code " + err);
+        }
+    }
+
+    /**
+     * Unregisters one Java application from S60 AppArc.
+     *
+     * @param aAppRegInfo Information needed to unregister the application,
+     *  only Uid is needed to unregister application in S60
+     * @throws InstallerException if unregistration cannot done or
+     *  startSession has not been called successfully
+     * @see startSession
+     * @see AppRegInfo
+     */
+    public void unregisterApplication(AppRegInfo aAppRegInfo)
+    {
+        if (0 == iSessionHandle)
+        {
+            InstallerException.internalError("No valid session.");
+        }
+
+        Log.log("Unregistering application " + aAppRegInfo.iUid.getStringValue());
+
+        int err = _unregisterApplication(iSessionHandle, PlatformUid.getIntValue(aAppRegInfo.iUid));
+        if (err < 0)
+        {
+            InstallerException.internalError("Unregistering application "
+                                             + aAppRegInfo.iUid.getStringValue() + " failed with code " + err);
+        }
+    }
+
+    /**
+     * Commits the registrations and unregistrations.
+     * Ends the current session if commit is successfull.
+     * If commit fails the session is kept open so that
+     * rollbackSession can be called.
+     *
+     * @param aSynchronous if true, makes synchronous commit
+     *
+     * @throws InstallerException if session cannot be committed
+     */
+    public void commitSession(boolean aSynchronous)
+    {
+        if (0 == iSessionHandle)
+        {
+            InstallerException.internalError("No valid session.");
+        }
+
+        int err = _commitSession(iSessionHandle, aSynchronous);
+        if (err < 0)
+        {
+            InstallerException.internalError("Commiting session failed with code " + err);
+        }
+
+        // Current session has been closed
+        iSessionHandle = 0;
+    }
+
+    /**
+     * Rolls back the registrations and unregistrations.
+     * Ends the current session.
+     *
+     * @throws InstallerException if session cannot be rolled back.
+     */
+    public void rollbackSession()
+    {
+        if (0 == iSessionHandle)
+        {
+            InstallerException.internalError("No valid session.");
+        }
+
+        int err = _rollbackSession(iSessionHandle);
+        // Session is closed always when rollback is called
+        iSessionHandle = 0;
+        if (err < 0)
+        {
+            InstallerException.internalError("Rolling back the session failed with code " + err);
+        }
+    }
+
+    /**
+     * Closes the current session if it still open.
+     * If registerApplication or unregisterApplication has been called,
+     * commitSession or rollbackSession must be called instead of this method.
+     */
+    public void closeSession()
+    {
+        if (0 == iSessionHandle)
+        {
+            return;
+        }
+
+        _closeSession(iSessionHandle);
+
+        // Current session has been closed
+        iSessionHandle = 0;
+    }
+
+    /**
+     * Checks whether the Uid is in use from S60 AppArc.
+     *
+     * @param aUid The Uid of the application.
+     * @return true if the Uid is already in use
+     * @throws InstallerException if checking cannot be done
+     */
+    public boolean uidInUse(Uid aUid)
+    {
+        if (0 == iSessionHandle)
+        {
+            InstallerException.internalError("No valid session.");
+        }
+
+        int ret;
+
+        PlatformUid s60Uid = (PlatformUid)PlatformUid.createUid(aUid.getStringValue());
+        if (null == s60Uid)
+        {
+            InstallerException.internalError("Illegal S60 Uid");
+        }
+
+        ret = _uidInUse(iSessionHandle, s60Uid.getIntValue());
+        if (0 == ret)
+        {
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    /**
+     * Returns the logical group name for an installed application.
+     *
+     * @param aUid The Uid of the application.
+     * @return the group name of the application. Can be empty string.
+     * @throws InstallerException if the group name cannot be returned
+     */
+    public String getGroupName(Uid aUid)
+    {
+        if (0 == iSessionHandle)
+        {
+            InstallerException.internalError("No valid session.");
+        }
+
+        int ret;
+
+        StringBuffer groupName = new StringBuffer("");
+        PlatformUid s60Uid = (PlatformUid)PlatformUid.createUid(aUid.getStringValue());
+        if (null == s60Uid)
+        {
+            InstallerException.internalError("Illegal S60 Uid");
+        }
+
+        ret = _getGroupName(iSessionHandle, s60Uid.getIntValue(), groupName);
+        if (-1 == ret)
+        {
+            // Symbian error code KErrNotFound means that there is no
+            // application with aUid, just log this error so that
+            // the installation / uninstallation operation currently on-going
+            // is not stopped.
+
+            Log.log("ApplicationRegistrator.getGroupName() failed. No app with such uid.");
+        }
+        else if (ret < -1)
+        {
+            InstallerException.internalError("Getting group name failed with code " + ret);
+        }
+
+        return groupName.toString();
+    }
+
+    /**
+     * Converts icon to platform specific format.
+     *
+     * @param aInputIconFilename file name for input icon file
+     * @param aOutputIconFilename file name for output icon file
+     * @param aJarFilename jar file name if aInputIconFilename specifies
+     *    file inside jar file,
+     *    or null if aInputIconFilename specifies file from disk
+     * @param 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
+     */
+    public boolean convertIcon(
+        String aInputIconFilename,
+        String aOutputIconFilename,
+        String aJarFilename,
+        StringBuffer aIconSuffix)
+    {
+        return _convertIcon(aInputIconFilename, aOutputIconFilename,
+                            aJarFilename, aIconSuffix);
+    }
+
+    /**
+     * Return path to the default icon (SVG icon in S60)
+     *
+     * @return full path name to the default icon.
+     */
+    public String getDefaultIconPath()
+    {
+        String iconPath;
+
+        if (_runningIn92Emulator())
+        {
+            // In real 9.2 devices the icon has the same name as in earlier
+            // devices. Only emulator is special case.
+            iconPath = FileRoots.getResourceDir() + DEFAULT_92_SVG_ICON_NAME;
+        }
+        else
+        {
+            iconPath = FileRoots.getResourceDir() + DEFAULT_SVG_ICON_NAME;
+        }
+
+        if (FileUtils.exists(iconPath))
+        {
+            return iconPath;
+        }
+
+        // Executing code is some special environment, icon is not in the same
+        // drive as installer itself.
+        String driveLetter = iconPath.substring(0,1).toLowerCase();
+        if (driveLetter.charAt(0) == 'z')
+        {
+            driveLetter = "C";
+        }
+        else
+        {
+            driveLetter = "Z";
+        }
+
+        // change drive letter
+        StringBuffer newIconPath = new StringBuffer(iconPath);
+        newIconPath.replace(0, 1, driveLetter);
+        return newIconPath.toString();
+    }
+
+    /**
+     * Return file suffix of the default icon
+     *
+     * @return file suffix of the default icon ('.mif' is S60)
+     */
+    public String getDefaultIconSuffix()
+    {
+        return DEFAULT_SVG_ICON_SUFFIX;
+    }
+
+    /**
+     * Returns true if the current device is touch screen
+     * device without physical LSK and RSK
+     *
+     * @return true if Installer should store the value of
+     *  Nokia-MIDlet-On-Screen-Keypad to Storage
+     */
+    public boolean isOnDeviceKeypadNeeded()
+    {
+        return _isOnDeviceKeypadNeeded();
+    }
+
+    /**
+     * Sends a process to process notification to the parent process
+     * of Java Installer telling that Installer is about to start
+     * displaying UI dialogs.
+     * The parent process reacts to the notification by hiding its
+     * installation related dialogs.
+     */
+    public void notifyLauncherThatUiIsReady()
+    {
+        _notifyLauncherThatUiIsReady();
+        return;
+    }
+
+    /*** ----------------------------- PACKAGE ---------------------------- */
+    /*** ----------------------------- PRIVATE ---------------------------- */
+    /*** ----------------------------- NATIVE ----------------------------- */
+
+    /**
+     * Starts native application registration session.
+     *
+     * @return native session handle or Symbian error code (negative number)
+     */
+    private static native int _startSession();
+
+    /**
+     * Registers Java Application to S60 AppArc
+     *
+     * @param aSessionHandle
+     * @param aUid The Uid of the application.
+     * @param aGroupName
+     * @param aMIDletName
+     * @param aTargetDrive Must be "C:", "E:", ..., "J:"
+     * @param aIconFileName the name of the icon file
+     * @param aJarFileName Full path name of the .jar file
+     * @param aHidden
+     * @param aBackground
+     * @return 0 if registration succeeded or Symbian error code
+     */
+    private static native int _registerApplication(
+        int aSessionHandle,
+        int aUid,
+        String aGroupName,
+        String aMIDletName,
+        String aTargetDrive,
+        String aIconFileName,
+        String aJarFileName,
+        boolean aHidden,
+        boolean aBackground);
+
+    /**
+     * Unregisters Java Application from S60 AppArc
+     *
+     * @param aSessionHandle
+     * @param aUid The Uid of the application to be unregistered..
+     * @return 0 if unregistration succeeded or Symbian error code
+     */
+    private static native int _unregisterApplication(
+        int aSessionHandle,
+        int aUid);
+
+    /**
+     * Commits native application registration session.
+     * If commit succeeds the native session is closed.
+     *
+     * @param aSessionHandle
+     * @param aSynchronous if true, makes synchronous commit
+     * @return 0 or Symbian error code (negative number)
+     */
+    private static native int _commitSession(int aSessionHandle, boolean aSynchronous);
+
+    /**
+     * Rolls back and closes native application registration session.
+     *
+     * @param aSessionHandle
+     * @return 0 or Symbian error code (negative number)
+     */
+    private static native int _rollbackSession(int aSessionHandle);
+
+    /**
+     * Tells whether the uid is in use in AppArc.
+     * Calls AppArc RApaLsSession::GetAppType
+     *
+     * @param aSessionHandle
+     * @param aUid
+     * @return 0 if the uid is not in use,
+     *  1 if the uid is in use
+     */
+    private static native int _uidInUse(
+        int aSessionHandle,
+        int aUid);
+
+    /**
+     * Returns the logical group name of the application.
+     * Calls AppArc RApaLsSession::GetAppCapability
+     *
+     * @param aSessionHandle
+     * @param aUid
+     * @param aGroupName should be "" when called, will contain group name
+     *  when function returns if call was successfull
+     * @return Symbian error code (negative number) if fails, otherwise 0
+     */
+    private static native int _getGroupName(
+        int aSessionHandle,
+        int aUid,
+        StringBuffer aGroupName);
+
+    /**
+     * Closes native application registration session.
+     *
+     * @param aSessionHandle the session to be closed
+     */
+    private static native void _closeSession(int aSessionHandle);
+
+    /**
+     * Converts icon to platform specific format.
+     *
+     * @param aInputIconFilename file name for input icon file
+     * @param aOutputIconFilename file name for output icon file
+     * @param aJarFilename jar file name if aInputIconFilename specifies
+     *     file inside jar file,
+     *     or null if aInputIconFilename specifies file from disk
+     * @param 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
+     */
+    private static native boolean _convertIcon(
+        String aInputIconFilename,
+        String aOutputIconFilename,
+        String aJarFilename,
+        StringBuffer aIconSuffix);
+
+    /**
+     * Returns true if the current device is touch screen
+     * device without physical LSK and RSK
+     *
+     * @return true if virtual on screen keypad is needed
+     */
+    private static native boolean _isOnDeviceKeypadNeeded();
+
+    /**
+     * Sends a process to process notification to the parent process
+     * of Java Installer telling that Installer is about to start
+     * displaying UI dialogs.
+     * The parent process reacts to the notification by hiding its
+     * installation related dialogs.
+     */
+    private static native void _notifyLauncherThatUiIsReady();
+
+    /**
+     * Returns true if the code is executed in Symbian 9.2
+     * emulator environment.
+     *
+     * @return true if Symbian 9.2 emulator environment
+     */
+    private static native boolean _runningIn92Emulator();
+}