diff -r f5050f1da672 -r 04becd199f91 javamanager/javainstaller/installer/javasrc.s60/com/nokia/mj/impl/installer/applicationregistrator/ApplicationRegistrator.java --- /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(); +}