FileDocCategorySizeDatePackage
AppProxy.javaAPI DocphoneME MR2 API (J2ME)23261Wed May 02 18:00:44 BST 2007com.sun.midp.content

AppProxy

public class AppProxy extends Object
Each AppProxy instance provides access to the AMS information and functions for a running or installed application. This class must be replaced for each platform/profile combination and be integrated with the appropriate Applicaiton Management Software.

The AppProxy class is *only* available within this package for security purposes. An instance exists for the current application and can be retrieved for any installed application. The following methods provide functions needed by CHAPI:

  • {@link #getCurrent} - the current application and the main class within it.
  • {@link #forApp} - the AppProxy for a named Jar ID and classname. For MIDP, they are the suiteID of the storage and MIDlet within the JAR.
  • {@link #getStorageID} - the storage ID for this AppProxy.
  • {@link #getClassname} - the classname for this AppProxy.
  • {@link #getApplicationID} - the CHAPI defined unique identifier for the application
  • {@link #getApplicationName} = a user friendly name for this application.
  • {@link #getAuthority} - the authority under which the application is granted permissions. For MIDP, the subject field of the signing certificate.
  • {@link #getProperty} - access to the properties in the manifest or application descriptor.
  • {@link #getVersion} - the version number of this application.
  • {@link #getDefaultID} - the default applicationID if none is provided in the manifest or application descriptor.
  • {@link #checkRegisterPermission} - method to check if the caller is allowed to register or unregister handlers.
  • {@link #checkAPIPermission} - method to check if the caller has permission to use internal APIs. Caller must have an appropriate security token (depending on the platform)
  • {@link #isRegistered} - used to check if the application is registered as appropriate for the platform. For MIDP, there is a MIDlet-n attribute in manifest or JAD.
  • {@link #verifyApplication} - Verify that a named class is the correct type and access to be launched as an application in the profile. For MIDP, the class must extend MIDlet.
  • {@link #launch} - Request this application be launched if it is not already running. Return a boolean indicating if the current application MUST voluntarily exit before the launched app can run.
  • {@link #requestForeground} - ask the "window manager" to give the foreground to the requested application. <

Fields Summary
private static com.sun.midp.security.SecurityToken
classSecurityToken
This class has a different security domain than the MIDlet suite
private static AppProxy
currentApp
The current AppProxy.
static final boolean
LOG_INFO
The log flag to enable informational messages.
private static boolean
oneExecute
This global state is true if an application has been executed and this application should be exiting to let it run. For SVM, this is set true by {@link #launch } and stays that way. For MVM, it is cleared if the VM allows the execute to occur. At MIDlet exit, {@link InvocationImpl#invokeNext} checks to see if another application Invoction is pending and invokes it. If this application has NOT invoked anything then the chosen app will be invoked.
protected Hashtable
appmap
The known AppProxy instances. Key is classname.
protected static final Object
mutex
The mutex used to avoid corruption between threads.
protected final com.sun.midp.midlet.MIDletSuite
msuite
The MIDlet suite for this app.
protected final int
storageId
The storageId (suiteId) for this application.
protected String
classname
The classname of the application.
private String
applicationName
The application name.
private String
applicationID
The ApplicationID, (same a suiteId).
private boolean
isRegistered
The application is registered.
static final String
VERSION_PROP
MIDlet property for the suite version.
static final String
VENDOR_PROP
MIDlet property for the suite vendor.
Constructors Summary
protected AppProxy(com.sun.midp.midlet.MIDletSuite msuite, String classname, Hashtable appmap)
Construct an AppProxy with the specified MIDletSuite.

param
msuite the MIDletSuite to initialize.
param
classname the classname of a copackaged application.
param
appmap a Hashtable to keep track of instances; may be null
exception
ClassNotFoundException if the classname is not present
exception
IllegalArgumentException if classname is not a valid application

        if (appmap == null) {
            // Allocate a Hashtable if needed
            appmap = new Hashtable();
        }

        this.msuite = msuite;
        this.storageId = msuite.getID();
        this.classname = classname;
        this.appmap = appmap;
        if (classname != null) {
            verifyApplication(classname);
            initAppInfo();
            appmap.put(classname, this);
            if (LOG_INFO) {
                logInfo("AppProxy created: " + classname);
            }
        }
    
protected AppProxy(int storageId, String classname)
Construct an AppProxy with the specified suiteId, classname. This is just a placeholder to make launch work.

param
storageId the suiteId
param
classname the classname

        this.storageId = storageId;
        this.classname = classname;
        MIDletSuite midletSuite = null;

        /* trying to initialize fields from suite info */
        try {
            midletSuite = MIDletSuiteStorage.
                    getMIDletSuiteStorage(classSecurityToken).
                    getMIDletSuite(storageId, false);
        } catch (MIDletSuiteLockedException msle) {
            if (LOG_INFO) {
                logException("AppProxy creation fails", msle);
            }
        } catch (MIDletSuiteCorruptedException msce) {
            if (LOG_INFO) {
                logException("AppProxy creation fails", msce);
            }
        }
        msuite = midletSuite;

        if (msuite != null) {
            initAppInfo();
        }

        if (LOG_INFO) {
            logInfo("AppProxy created: " + classname);
        }
    
Methods Summary
static final voidcheckAPIPermission(java.lang.Object securityToken)
Check if the internal API use is allowed.

param
securityToken a generic security token
exception
SecurityException thrown if internal API use not allowed

        if (securityToken != null) {
            ((SecurityToken)securityToken).
                checkIfPermissionAllowed(Permissions.MIDP);
        } else {
            MIDletSuite msuite =
                MIDletStateHandler.getMidletStateHandler().getMIDletSuite();
            if (msuite != null) {
                msuite.checkIfPermissionAllowed(Permissions.AMS);
            }
        }
    
final voidcheckRegisterPermission(java.lang.String reason)
Check the permission to register or unregister.

param
reason the reason for the permission check
exception
SecurityException if not allowed

        try {
            msuite.checkForPermission(Permissions.CHAPI_REGISTER,
                                      getApplicationName(), reason);
        } catch (InterruptedException ie) {
            throw new SecurityException("interrupted");
        }
    
com.sun.midp.content.AppProxyforApp(int storageId, java.lang.String classname)
Gets the AppProxy for an storageID and classname.

param
storageId the storageId (suiteId)
param
classname the name of the application class
return
the AppProxy for suiteId, classname; null if not a valid application (MIDlet)
exception
ClassNotFoundException if the classname is not present
exception
IllegalArgumentException if classname is not a valid application

        // Check in the current suite
        if (storageId == this.storageId) {
            return forClass(classname);
        }

        // Create a new instance
        AppProxy curr = new AppProxy(storageId, classname);

        return curr;
    
com.sun.midp.content.AppProxyforClass(java.lang.String classname)
Gets the AppProxy for an application class in the current bundle.

param
classname the name of the application class
return
the AppProxy for classname; null if not a valid application (MIDlet)
exception
ClassNotFoundException if the classname is not present
exception
IllegalArgumentException if classname is not a valid application

        AppProxy curr = null;
        synchronized (mutex) {
            // Check if class already has a AppProxy
            curr = (AppProxy)appmap.get(classname);
            if (curr == null) {
                // Create a new instance
                // throws ClassNotFoundException and IllegalArgumentException
                curr = new AppProxy(msuite, classname, appmap);
            }
        }
        return curr;
    
java.lang.StringgetApplicationID()
Gets the CHAPI application ID for this application.

return
the CHAPI application ID.

        return applicationID;
    
java.lang.StringgetApplicationName()
Gets the user friendly application name.

return
the user friendly application name

        return applicationName;
    
java.lang.StringgetAuthority()
Gets the Trusted authority that authenticated this application.

For MIDP, this is the CA of the signer. If exception is thrown during getting authorization this methods ignores it and returns null.

return
the authority.

        String auth = null;
        try {
            auth = ((MIDletSuiteImpl)msuite).getInstallInfo().getCA();
        } catch (RuntimeException e) {
        }
        return auth;
    
java.lang.StringgetClassname()
Gets the classname of this application.

return
the classname

        return classname;
    
static com.sun.midp.content.AppProxygetCurrent()
Gets the AppProxy for the currently running application.

return
the current application.

        synchronized (mutex) {
            if (currentApp == null) {
                MIDletStateHandler mh =
                    MIDletStateHandler.getMidletStateHandler();
                MIDletSuite msuite = mh.getMIDletSuite();
                try {
                    currentApp = (msuite != null) ?
                        new AppProxy(msuite,
                                     mh.getFirstRunningMidlet(),
                                     null) :
                        new AppProxy(MIDletSuite.INTERNAL_SUITE_ID, "");
                } catch (ClassNotFoundException cnfe) {
                    return null;
                }
            }
        }
        return currentApp;
    
java.lang.StringgetDefaultID()
Gets the content handler ID for the current application. The ID uniquely identifies the application which contains the content handler. The application ID is assigned when the application is installed.

All installed applications have vendor and name;

return
the ID; MUST NOT be null

        StringBuffer sb = new StringBuffer(80);
        String s = msuite.getProperty(VENDOR_PROP);
        sb.append((s != null) ? s : "internal");
        sb.append('-");
        s = msuite.getProperty(MIDletSuiteImpl.SUITE_NAME_PROP);
        sb.append((s != null) ? s : "system");
        sb.append('-");
        sb.append(classname);
        return sb.toString().replace(' ", '_");
    
private static java.lang.String[]getMIDletInfo(com.sun.midp.midlet.MIDletSuite suite, java.lang.String classname)
Get the MIDletInfo for the named MIDlet.

param
suite the MIDlet suite to look in for the midlet
param
classname the class name to look for
return
an array of Strings, name, icon, ID null if there is no matching MIDlet-n.

        for (int i = 1; ; i++) {
            String midletn = "MIDlet-".concat(Integer.toString(i));
            String attr = suite.getProperty(midletn);
            if (attr == null) {
                break; // break out of loop, not found
            }

            Vector args = Util.getCommaSeparatedValues(attr);
            if (args.size() < 3) {
                // Not enough args to be legit
                continue;
            }

            if (!classname.equals(args.elementAt(2))) {
                continue;
            }
            String[] values = new String[args.size()];
            args.copyInto(values);

            String ID = suite.getProperty(midletn.concat("-ID"));
            values[2] = ID;

            return values;
        }
        return null;
    
java.lang.StringgetProperty(java.lang.String key)
Gets a property from the manifest or application descriptor.

param
key the name of the property to retrieve
return
the value of the property or null

        return msuite.getProperty(key);
    
intgetStorageId()
Gets the storage ID of this application. The ID uniquely identifies the package/application bundle.

return
the application ID.

        return storageId;
    
java.lang.StringgetVersion()
Gets the version string for the application.

return
the version

        return msuite == null? null: msuite.getProperty(VERSION_PROP);
    
protected voidinitAppInfo()
Initialize application name and application ID from the attributes.

        // Check if it is an internal MIDlet
        if (storageId == MIDletSuite.INTERNAL_SUITE_ID) {
            applicationName = classname.substring(classname.lastIndexOf('.") + 1);
            applicationID = "system";
            isRegistered = true;
            return;
        }

        // Check if a registered MIDlet
        String[] minfo = getMIDletInfo(msuite, classname);

        // if a MIDlet, set the application name and application ID
        if (minfo != null) {
            applicationName = minfo[0];
            applicationID = minfo[2];
            isRegistered = true;
        }

        // Fill in defaults for appName and applicationID
        if (applicationName == null || applicationName.length() == 0) {
            applicationName = msuite.getProperty(
                                        MIDletSuiteImpl.SUITE_NAME_PROP);
        }

        if (applicationID == null || applicationID.length() == 0) {
            applicationID = getDefaultID();
        }
    
booleanisRegistered()
Gets true if the application is a registered application.

for MIDP, this means there was a MIDlet-n attribute.

return
true if this application is registered

        return isRegistered;
    
booleanlaunch(java.lang.String displayName)
Launch this application. Don't launch another application unless the execute allows this application to continue after the launch.

In SVM, (sequential applications) only the first execute matters; later ones should not override the first. All pending Invocations are queued in InvocationStore so they will not be lost. When MIDlets exit, another application will be selected from those pending.

param
displayName name to show to the user of what to launch
return
true if the application must exist before the target application can proceed.

        /*
         * If an execute has been queued already; don't queue another
         */
        if (oneExecute) {
            // launched something previously and app should exit.
            if (LOG_INFO) {
                logInfo("Launch skipped: " + classname +
                        ", oneExecute: " + oneExecute);
            }
            return true;
        } else {
            /* Invoke the target application */
            oneExecute =
                MIDletSuiteUtils.execute(classSecurityToken,
                                          storageId,
                                          classname, displayName);
            if (LOG_INFO) {
                logInfo("Launch: " + classname +
                        ", oneExecute: " + oneExecute);
            }
            return oneExecute;
        }
    
voidlogException(java.lang.String msg, java.lang.Throwable t)
Log an information message to the system logger for this AppProxy.

param
msg a message to write to the log.
param
t Throwable to be logged

        if (LOG_INFO) {
            System.out.println("** " + threadID() + ": " + msg);
            t.printStackTrace();
        }
    
voidlogInfo(java.lang.String msg)
Log an information message to the system logger for this AppProxy.

param
msg a message to write to the log.

        if (LOG_INFO) {
            System.out.println(">> " + threadID() + ": " + msg);
        }
    
static voidrequestForeground(int invokingSuiteId, java.lang.String invokingClassname, int targetSuiteId, java.lang.String targetClassname)
Request the transition of the foreground to this application from the invoking application.

param
invokingSuiteId the invoking suiteId
param
invokingClassname the invoking classname
param
targetSuiteId the target suiteId
param
targetClassname the target classname

        NativeEvent event =
            new NativeEvent(EventTypes.FOREGROUND_TRANSFER_EVENT);
        event.intParam1 = invokingSuiteId;
        event.stringParam1 = invokingClassname;
        event.intParam2 = targetSuiteId;
        event.stringParam2 = targetClassname;

        int amsIsolateId = MIDletSuiteUtils.getAmsIsolateId();
        EventQueue eventQueue = EventQueue.getEventQueue(classSecurityToken);
        eventQueue.sendNativeEventToIsolate(event, amsIsolateId);
    
static voidrequestForeground(int targetSuiteId, java.lang.String targetClassname)
The stronger variant for request the transition of the foreground to this application.

param
targetSuiteId the target suiteId
param
targetClassname the target classname

        NativeEvent event =
            new NativeEvent(EventTypes.SET_FOREGROUND_BY_NAME_REQUEST);
        event.intParam1 = targetSuiteId;
        event.stringParam1 = targetClassname;

        int amsIsolateId = MIDletSuiteUtils.getAmsIsolateId();
        EventQueue eventQueue = EventQueue.getEventQueue(classSecurityToken);
        eventQueue.sendNativeEventToIsolate(event, amsIsolateId);
    
static voidsetSecurityToken(com.sun.midp.security.SecurityToken token)
Sets the security token used for priveleged operations. The token may only be set once.

param
token a Security token


                             
        
        if (classSecurityToken != null) {
            throw new SecurityException();
        }
        classSecurityToken = token;
    
private java.lang.StringthreadID()
Map a thread to an printable string.

return
a short string for the thread

        if (LOG_INFO) {
            Thread thread = Thread.currentThread();
            int i = thread.hashCode() & 0xff;
            return "T" + i;
        } else {
            return "";
        }
    
public java.lang.StringtoString()
Create a printable representation of this AppProxy.

return
a printable string

        if (LOG_INFO) {
            return"class: " + classname +
                ", suite: " + storageId +
                ", registered: " + isRegistered +
                ", name: " + applicationName +
                ", ID: " + applicationID;
        } else {
            return super.toString();
        }
    
protected voidverifyApplication(java.lang.String classname)
Verify that the classname is a valid application. It must extend MIDlet.

param
classname the application class
exception
ClassNotFoundException is thrown if the class cannot be found
exception
IllegalArgumentException if the classname is null or empty or does not implement the lifecycle of a MIDlet.

        /* check the classname for null and get the class */
        Class appClass = Class.forName(classname);
        Class midletClass = Class.forName("javax.microedition.midlet.MIDlet");
        if ((!midletClass.isAssignableFrom(appClass)) ||
            appClass == midletClass) {
            throw new IllegalArgumentException("not a MIDlet");
        }