/* * * * Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */ package javax.microedition.midlet; import com.sun.midp.midlet.MIDletPeer; import com.sun.midp.midlet.MIDletStateHandler; import com.sun.midp.security.SecurityToken; import com.sun.midp.security.SecurityInitializer; import com.sun.midp.security.ImplicitlyTrustedClass; import javax.microedition.lcdui.Display; /** * A <code>MIDlet</code> is a MID Profile application. * The application must extend this class to allow the * application management software to control the MIDlet and to be * able to retrieve properties from the application descriptor * and notify and request state changes. * The methods of this class allow the application management software * to create, start, pause, and destroy a MIDlet. * A <code>MIDlet</code> is a set of classes designed to be run and * controlled by the application management software via this interface. * The states allow the application management software to manage * the activities of multiple <CODE>MIDlets</CODE> within * a runtime environment. * It can select which <code>MIDlet</code>s are active at a given time * by starting and pausing them individually. * The application management software maintains the state of the * <code>MIDlet</code> and * invokes methods on the <code>MIDlet</code> to notify the MIDlet of * change states. * The <code>MIDlet</code> * implements these methods to update its internal activities and * resource usage as directed by the application management software. * The <code>MIDlet</code> can initiate some state changes itself and * notifies the application management software of those state changes * by invoking the appropriate methods.<p> * * <strong>Note:</strong> The methods on this interface signal state * changes. The state change is not considered complete until the state * change method has returned. It is intended that these methods return * quickly.<p> */ public abstract class MIDlet { /** * Inner class to request security token from SecurityInitializer. * SecurityInitializer should be able to check this inner class name. */ static private class SecurityTrusted implements ImplicitlyTrustedClass {} /** Security token to allow access to implementation APIs */ private static SecurityToken classSecurityToken = SecurityInitializer.requestToken(new SecurityTrusted()); /** Internal peer of this MIDlet */ private MIDletPeer peer; /** * Static initializer to set MIDletTunnel implementation * in MIDletPeer class. */ static { MIDletPeer.setMIDletTunnel(classSecurityToken, new MIDletTunnelImpl()); } /** * Gets the MIDletPeer instance for this MIDlet. * * @return MIDletPeer instance for this midlet. */ MIDletPeer getMIDletPeer() { return peer; } /** * Protected constructor for subclasses. * The application management software is responsible * for creating MIDlets and creation of MIDlets is restricted. * MIDlets should not attempt to create other MIDlets. * * @exception java.lang.SecurityException unless the application * management software is creating the MIDlet. */ protected MIDlet() { peer = MIDletStateHandler.newMIDletPeer(classSecurityToken, this); // Ensure that a display for this midlet is created Display d = Display.getDisplay(this); } /** * Signals the <code>MIDlet</code> that it has entered the * <em>Active</em> state. * In the <em>Active</EM> state the <code>MIDlet</code> may * hold resources. * The method will only be called when * the <code>MIDlet</code> is in the <em>Paused</em> state. * <p> * Two kinds of failures can prevent the service from starting, * transient and non-transient. For transient failures the * <code>MIDletStateChangeException</code> exception should be thrown. * For non-transient failures the <code>notifyDestroyed</code> * method should be called. * <p> * If a Runtime exception occurs during <code>startApp</code> the * MIDlet will be * destroyed immediately. Its <code>destroyApp</code> will be * called allowing * the MIDlet to cleanup. * * @exception MIDletStateChangeException is thrown * if the <code>MIDlet</code> * cannot start now but might be able to start at a * later time. */ protected abstract void startApp() throws MIDletStateChangeException; /** * * Signals the <code>MIDlet</code> to enter * the <em>Paused</em> state. * In the <em>Paused</em> state the <code>MIDlet</code> must * release shared resources * and become quiescent. This method will only be called * called when the <code>MIDlet</code> is in the <em>Active</em> state. <p> * <p> * If a Runtime exception occurs during <code>pauseApp</code> the * MIDlet will be destroyed immediately. Its * <code>destroyApp</code> will be called allowing * the MIDlet to cleanup. */ protected abstract void pauseApp(); /** * Signals the <code>MIDlet</code> to terminate and enter the * <em>Destroyed</em> state. * In the destroyed state the <code>MIDlet</code> must release * all resources and save any persistent state. This method may * be called from the <em>Paused</em> or * <em>Active</em> states. <p> * <code>MIDlet</code>s should * perform any operations required before being terminated, such as * releasing resources or saving preferences or * state. <p> * * <strong>Note:</strong> The <code>MIDlet</code> can request that * it not enter the <em>Destroyed</em> * state by throwing an <code>MIDletStateChangeException</code>. This * is only a valid response if the <code>unconditional</code> * flag is set to <code>false</code>. If it is <code>true</code> * the <code>MIDlet</code> is assumed to be in the <em>Destroyed</em> state * regardless of how this method terminates. If it is not an * unconditional request, the <code>MIDlet</code> can signify that it * wishes to stay in its current state by throwing the * <code>MIDletStateChangeException</code>. * This request may be honored and the <code>destroy()</code> * method called again at a later time. * * <p>If a Runtime exception occurs during <code>destroyApp</code> then * they are ignored and the MIDlet is put into the <em>Destroyed</em> * state. * * @param unconditional If true when this method is called, the * <code>MIDlet</code> must cleanup and release all resources. If * false the <code>MIDlet</code> may throw * <CODE>MIDletStateChangeException</CODE> to indicate it does not * want to be destroyed at this time. * * @exception MIDletStateChangeException is thrown * if the <code>MIDlet</code> wishes to continue to * execute (Not enter the <em>Destroyed</em> state). * This exception is ignored if <code>unconditional</code> * is equal to <code>true</code>. */ protected abstract void destroyApp(boolean unconditional) throws MIDletStateChangeException; /** * * Used by an <code>MIDlet</code> to notify the application * management software that it has entered into the * <em>Destroyed</em> state. The application management software * will not call the MIDlet's <code>destroyApp</code> method, * and all resources * held by the <code>MIDlet</code> will be considered eligible for * reclamation. * The <code>MIDlet</code> must have performed the same operations * (clean up, releasing of resources etc.) it would have if the * <code>MIDlet.destroyApp()</code> had been called. * */ public final void notifyDestroyed() { peer.notifyDestroyed(); } /** * Notifies the application management software that the MIDlet * does not want to be active and has * entered the <em>Paused</em> state. Invoking this method will * have no effect if the <code>MIDlet</code> is destroyed, or if * it has not yet been started. <p> * It may be invoked by the <code>MIDlet</code> when it is * in the <em>Active</em> state. <p> * * If a <code>MIDlet</code> calls <code>notifyPaused()</code>, in the * future its <code>startApp()</code> method may be called make * it active again, or its <code>destroyApp()</code> method may be * called to request it to destroy itself. <p> * * If the application pauses itself it will need to call * <code>resumeRequest</code> to request to reenter the * <code>active</code> state. */ public final void notifyPaused() { peer.notifyPaused(); } /** * Provides a <code>MIDlet</code> with a mechanism to retrieve named * properties from the application management software. * The properties are retrieved from the combination of * the application descriptor file and the manifest. * For trusted applications the values in the manifest MUST NOT * be overridden by those in the application descriptor. If they * differ, the MIDlet will not be installed on the device. * For untrusted applications, if an attribute * in the descriptor has the same name as an attribute in the * manifest the value from the descriptor is used and the value * from the manifest is ignored. * * @param key the name of the property * @return A string with the value of the property. * <code>null</code> is returned if no value is available for the * key. * @exception NullPointerException is thrown * if key is <code>null</code>. */ public final String getAppProperty(String key) { return peer.getMIDletSuite().getProperty(key); } /** * Provides a <code>MIDlet</code> with a mechanism to indicate * that it is interested in entering the <em>Active</em> * state. Calls to this method can be used by the application * management software to determine which applications to move to * the <em>Active</em> state. <p> When the application management * software decides to activate this application it will call the * <code>startApp</code> method. <p> The application is generally * in the <em>Paused</em> state when this is called. Even in the * paused state the application may handle asynchronous events * such as timers or callbacks. */ public final void resumeRequest() { peer.resumeRequest(); } /** * <p>Requests that the device handle (for example, display or * install) the indicated URL.</p> * * <p>If the platform has the appropriate capabilities and * resources available, it SHOULD bring the appropriate * application to the foreground and let the user interact with * the content, while keeping the MIDlet suite running in the * background. If the platform does not have appropriate * capabilities or resources available, it MAY wait to handle the * URL request until after the MIDlet suite exits. In this case, * when the requesting MIDlet suite exits, the platform MUST then * bring the appropriate application (if one exists) to the * foreground to let the user interact with the content.</p> * * <p>This is a non-blocking method. In addition, this method does * NOT queue multiple requests. On platforms where the MIDlet * suite must exit before the request is handled, the platform * MUST handle only the last request made. On platforms where the * MIDlet suite and the request can be handled concurrently, each * request that the MIDlet suite makes MUST be passed to the * platform software for handling in a timely fashion.</p> * * <p>If the URL specified refers to a MIDlet suite (either an * Application Descriptor or a JAR file), the application handling * the request MUST interpret it as a request to install the named * package. In this case, the platform's normal MIDlet suite * installation process SHOULD be used, and the user MUST be * allowed to control the process (including cancelling the * download and/or installation). If the MIDlet suite being * installed is an <em>update</em> of the currently running MIDlet * suite, the platform MUST first stop the currently running * MIDlet suite before performing the update. On some platforms, * the currently running MIDlet suite MAY need to be stopped * before any installations can occur.</p> * * <p>If the URL specified is of the form * <code>tel:<number></code>, as specified in <a * href="http://www.ietf.org/rfc/rfc2806.txt">RFC2806</a>, then the * platform MUST interpret this as a request to initiate a voice * call. The request MUST be passed to the "phone" * application to handle if one is present in the platform. The * "phone" application, if present, MUST be able to set * up local and global phone calls and also perform DTMF post * dialing. Not all elements of RFC2806 need be implemented, * especially the area-specifier or any other requirement on the * terminal to know its context. The isdn-subaddress, * service-provider and future-extension may also be * ignored. Pauses during dialing are not relevant in some * telephony services.</p> * * <p>Devices MAY choose to support additional URL schemes beyond * the requirements listed above.</p> * * <p>Many of the ways this method will be used could have a * financial impact to the user (e.g. transferring data through a * wireless network, or initiating a voice call). Therefore the * platform MUST ask the user to explicitly acknowledge each * request before the action is taken. Implementation freedoms are * possible so that a pleasant user experience is retained. For * example, some platforms may put up a dialog for each request * asking the user for permission, while other platforms may * launch the appropriate application and populate the URL or * phone number fields, but not take the action until the user * explicitly clicks the load or dial buttons.</p> * * @return true if the MIDlet suite MUST first exit before the * content can be fetched. * * @param URL The URL for the platform to load. An empty string * (not null) cancels any pending requests. * * @exception javax.microedition.io.ConnectionNotFoundException if * the platform cannot handle the URL requested. * */ public final boolean platformRequest(String URL) throws javax.microedition.io.ConnectionNotFoundException { return peer.platformRequest(URL); } /** * Get the status of the specified permission. * If no API on the device defines the specific permission * requested then it must be reported as denied. * If the status of the permission is not known because it might * require a user interaction then it should be reported as unknown. * * @param permission to check if denied, allowed, or unknown. * @return 0 if the permission is denied; 1 if the permission is allowed; * -1 if the status is unknown * */ public final int checkPermission(String permission) { return peer.checkPermission(permission); } }