FileDocCategorySizeDatePackage
MIDletState.javaAPI DocJ2ME MIDP 2.018578Thu Nov 07 12:02:22 GMT 2002com.sun.midp.midlet

MIDletState

public abstract class MIDletState extends Object
MIDletState holds the current state of the MIDlet and forwards updates to it. It holds the reference to the MIDlet itself and the Display object used to communicate with the MIDlet's Display.

When each MIDlet is constructed it creates a MIDletProxy object (subclassed from MIDletState). The MIDletProxy is in the javax.microedition.midlet package so that it can invoke the control methods of MIDlets (startApp, destroyApp, pauseApp). Invocations from the Scheduler to the MIDlet are forwarded using corresponding methods.

All state changes are synchronized using the mutex retrieved from the Scheduler. NotifyPaused, ResumeRequest, and NotifyDestroyed methods invoked on the MIDlet cause the appropriate state change. The Scheduler is aware of changes by waiting on the mutex.

The getAppProperty method from the MIDlet is sent here and relayed to the Scheduler.

Fields Summary
static final int
PAUSED
State of the MIDlet is Paused; it should be quiescent
static final int
ACTIVE
State of the MIDlet is Active
static final int
PAUSED_RESUME
State of the MIDlet is Paused but Resume has been requested
static final int
ACTIVE_PENDING
State of the MIDlet when resumed by the display manager
static final int
PAUSE_PENDING
State of the MIDlet when paused by the display manager
static final int
DESTROY_PENDING
State of the MIDlet with destroy pending
static final int
DESTROYED
State of the MIDlet is Destroyed
private static com.sun.midp.security.SecurityToken
classSecurityToken
This class has a different security domain than the application.
private static Object
createMIDletLock
Lock for creating a MIDlet.
private static boolean
allowedToCreateMIDlet
Lock for creating a MIDlet, default to false.
private int
state
The applications current state.
private Object
mutex
The lock for changes to the state.
private Scheduler
scheduler
The controller of MIDlets.
protected javax.microedition.midlet.MIDlet
midlet
The MIDlet for which this is the state.
protected javax.microedition.lcdui.Display
display
The Display for this MIDlet.
protected com.sun.midp.lcdui.DisplayManager
displayManager
The controller of Displays.
Constructors Summary
protected MIDletState(javax.microedition.midlet.MIDlet m)
Protected constructor for subclasses. If any MIDlet is constructed it should be registered with Scheduler. That allows them to be managed even if an application creates one itself.

param
m the MIDlet this is the state for; Must not be null.
exception
SecurityException if is constructor is not being called in the context of createMIDlet and the suite does not have the AMS permission.

        DisplayAccess accessor;

	midlet = m;
	state = PAUSED_RESUME;	// So it will be made active soon
	scheduler = Scheduler.getScheduler();
	mutex = scheduler.getMutex();

        synchronized (createMIDletLock) {
            if (!allowedToCreateMIDlet) {
                MIDletSuite suite = scheduler.getMIDletSuite();

                if (suite != null) {
                    suite.checkIfPermissionAllowed(Permissions.AMS);
                }
            }
        }

	// Force the creation of the Display
        displayManager = DisplayManagerFactory.getDisplayManager();
        accessor = displayManager.createDisplay(classSecurityToken, midlet);
        display = accessor.getDisplay();

        if (scheduler.getMIDletSuite().isTrusted()) {
            accessor.setTrustedIcon(classSecurityToken, true);
        }
    
Methods Summary
public intcheckPermission(java.lang.String permission)
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

        return getMIDletSuite().checkPermission(permission);
    
static javax.microedition.midlet.MIDletcreateMIDlet(java.lang.String classname)
Create a MIDlet without throwing a security exception.

param
classname name of MIDlet class
return
newly created MIDlet
exception
ClassNotFoundException is thrown, if the MIDlet main class is not found
exception
InstantiationException is thrown, if the MIDlet can not be created
exception
IllegalAccessException is thrown, if the MIDlet is not permitted to perform a specific operation

        Class midletClass;
        Object midlet;

        synchronized (createMIDletLock) {
            try {
                allowedToCreateMIDlet = true;

                midletClass = Class.forName(classname);
                midlet = midletClass.newInstance();
                if (midlet instanceof MIDlet) {
                    return (MIDlet)midlet;
                }

                throw new InstantiationException("Class not a MIDlet");
            } finally {
                allowedToCreateMIDlet = false;
            }
        }
    
protected abstract voiddestroyApp(boolean unconditional)
Signals the MIDlet to terminate and enter the DESTROYED state. In the destroyed state the MIDlet must release all resources and save any persistent state. This method may be called from the PAUSED or ACTIVE states.

MIDlets should perform any operations required before being terminated, such as releasing resources or saving preferences or state.

NOTE: The MIDlet can request that it not enter the DESTROYED state by throwing an MIDletStateChangeException. This is only a valid response if the unconditional flag is set to false. If it is true the MIDlet is assumed to be in the DESTROYED state regardless of how this method terminates. If it is not an unconditional request, the MIDlet can signify that it wishes to stay in its current state by throwing the MIDletStateChangeException. This request may be honored and the destroy() method called again at a later time.

param
unconditional If true when this method is called, the MIDlet must cleanup and release all resources. If false the MIDlet may throw MIDletStateChangeException to indicate it does not want to be destroyed at this time.
exception
MIDletStateChangeException is thrown if the MIDlet wishes to continue to execute (Not enter the DESTROYED state). This exception is ignored if unconditional is equal to true.

public javax.microedition.lcdui.DisplaygetDisplay()
Get the Display for this MIDlet.

return
the Display of this MIDlet.

	return display;
    
public javax.microedition.midlet.MIDletgetMIDlet()
Get the MIDlet for which this holds the state.

return
the MIDlet; will not be null.

	return midlet;
    
public final MIDletSuitegetMIDletSuite()
Provides a MIDlet with a mechanism to retrieve MIDletSuite for this MIDlet.

return
MIDletSuite for this MIDlet

	return scheduler.getMIDletSuite();
    
intgetState()
Get the state.

return
current state of the MIDlet.

	synchronized (mutex) {
	    return state;
	}
    
public static voidinitSecurityToken(com.sun.midp.security.SecurityToken token)
Initializes the security token for this class, so it can perform actions that a normal MIDlet Suite cannot.

param
token security token for this class


                                  
         
        if (classSecurityToken != null) {
            return;
        }

        classSecurityToken = token;
    
public final voidnotifyDestroyed()
Used by a MIDlet to notify the application management software that it has entered into the DESTROYED state. The application management software will not call the MIDlet's destroyApp method, and all resources held by the MIDlet will be considered eligible for reclamation. The MIDlet must have performed the same operations (clean up, releasing of resources etc.) it would have if the MIDlet.destroyApp() had been called.

	synchronized (mutex) {
	    state = DESTROYED;
	    mutex.notify();
	}
    
public final voidnotifyPaused()
Used by a MIDlet to notify the application management software that it has entered into the PAUSED state. Invoking this method will have no effect if the MIDlet is destroyed, or if it has not yet been started.

It may be invoked by the MIDlet when it is in the ACTIVE state.

If a MIDlet calls notifyPaused(), in the future its startApp() method may be called make it active again, or its destroyApp() method may be called to request it to destroy itself.

        int oldState;

	synchronized (mutex) {
            oldState = state;

            // do not notify the scheduler, since there is nothing to do
            setStateWithoutNotify(PAUSED);
	}

        // do work outside of the mutex
        if (oldState == ACTIVE) {
            displayManager.deactivate(getMIDlet());
        }
    
protected abstract voidpauseApp()
Signals the MIDlet to stop and enter the PAUSED state. In the PAUSED state the MIDlet must release shared resources and become quiescent. This method will only be called called when the MIDlet is in the ACTIVE state.

public final native booleanplatformRequest(java.lang.String URL)
Requests that the device handle (e.g. display or install) the indicated URL.

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 to the foreground to let the user interact with the content.

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.

If the URL specified refers to a MIDlet suite (either an Application Descriptor or a JAR file), the request is interpreted 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 update 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.

If the URL specified is of the form tel:<number>, as specified in RFC2806, 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.

Devices MAY choose to support additional URL schemes beyond the requirements listed above.

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 acknowlege 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.

return
true if the MIDlet suite MUST first exit before the content can be fetched.
param
URL The URL for the platform to load.
exception
ConnectionNotFoundException if the platform cannot handle the URL requested.
since
MIDP 2.0

public final voidresumeRequest()
Used by a MIDlet to notify the application management software that it is interested in entering the ACTIVE state. Calls to this method can be used by the application management software to determine which applications to move to the ACTIVE state.

When the application management software decides to activate this application it will call the startApp method.

The application is generally in the PAUSED state when this is called. Even in the paused state the application may handle asynchronous events such as timers or callbacks.

        setState(PAUSED_RESUME);
    
voidsetState(int newState)
Change the state and notify. Check to make sure the new state makes sense. Changes to the status are protected by the mutex. Any change to the state notifies the mutex.

param
newState new state of the MIDlet

	synchronized (mutex) {
            setStateWithoutNotify(newState);
            mutex.notify();
	}
    
voidsetStateWithoutNotify(int newState)
Change the state without notifing the scheduler. Check to make sure the new state makes sense.

To be called only by the scheduler or MIDletState while holding the scheduler mutex.

param
newState new state of the MIDlet

        switch (state) {
        case DESTROYED:
            // can't set any thing else
            return;
        
        case DESTROY_PENDING:
            if (newState != DESTROYED) {
                // can only set DESTROYED
                return;
            }
            
            break;

        case PAUSED:
            if (newState == PAUSE_PENDING) {
                // already paused by app
                return;
            }

            break;

        case ACTIVE:
            if (newState == PAUSED_RESUME || newState == ACTIVE_PENDING) {
                // already active
                return;
            }
        }

        state = newState;
    
protected abstract voidstartApp()
Signals the MIDlet to start and enter the ACTIVE state. In the ACTIVE state the MIDlet may hold resources. The method will only be called when the MIDlet is in the PAUSED state.

Two kinds of failures can prevent the service from starting, transient and non-transient. For transient failures the MIDletStateChangeException exception should be thrown. For non-transient failures the notifyDestroyed method should be called.

exception
MIDletStateChangeException is thrown if the MIDlet cannot start now but might be able to start at a later time.