/*
*
*
* 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 com.sun.j2me.content;
import javax.microedition.content.ContentHandlerException;
import javax.microedition.content.ContentHandlerServer;
import javax.microedition.content.Invocation;
import javax.microedition.content.Registry;
import com.sun.midp.security.SecurityInitializer;
import com.sun.midp.security.SecurityToken;
import com.sun.midp.security.ImplicitlyTrustedClass;
import javax.microedition.midlet.MIDlet;
import com.sun.midp.main.MIDletProxy;
import com.sun.midp.main.MIDletProxyList;
import com.sun.midp.main.MIDletProxyListListener;
import com.sun.midp.midlet.MIDletSuite;
import com.sun.midp.events.EventListener;
import com.sun.midp.events.EventQueue;
import com.sun.midp.events.Event;
import com.sun.midp.events.EventTypes;
/**
* Handle all of the details of installing ContentHandlers.
* Called at by the installer at the appropriate times to
* {@link #preInstall parse and verify the JAD/Manifest attributes} and
* {@link #install remove old content handlers and register new ones}.
* If the installation fails the old handlers are
* {@link #restore restored}.
* When a suite is to be removed the content handlers are
* {@link #uninstall uninstalled}.
*
*<p>
* Two versions of this file exist; one which is no-op used when
* MIDP stack is not built with CHAPI and the real implementation when
* MIDP stack is BUILT with CHAPI.
*/
public class CHManagerImpl extends com.sun.midp.content.CHManager
implements MIDletProxyListListener, EventListener {
/**
* Inner class to request security token from SecurityInitializer.
* SecurityInitializer should be able to check this inner class name.
*/
static private class SecurityTrusted implements ImplicitlyTrustedClass {};
static {
if( AppProxy.LOGGER != null ) AppProxy.LOGGER.println( "CHManagerImpl.<static initializer>" );
SecurityToken classSecurityToken =
SecurityInitializer.requestToken(new SecurityTrusted());
com.sun.midp.content.CHManager.setCHManager(classSecurityToken, new CHManagerImpl());
AppProxy.setSecurityToken(classSecurityToken);
// load Invocation class
Class cl = Invocation.class;
cl = cl.getClass();
}
/** Installed handlers accumulator. */
private RegistryInstaller regInstaller;
/** The Invocation in progress for an install. */
private Invocation installInvoc;
/** The ContentHandler for the Installer. */
ContentHandlerServer handler;
/**
* Creates a new instance of CHManagerImpl.
* Always initialize the Access to the Registry as if the
* GraphicalInstaller is running.
*/
private CHManagerImpl() {
super();
if( AppProxy.LOGGER != null ) AppProxy.LOGGER.println( "CHManagerImpl()" );
}
/**
* Install the content handlers found and verified by preinstall.
* Register any content handlers parsed from the JAD/Manifest
* attributes.
*/
public void install() {
if( AppProxy.LOGGER != null ) AppProxy.LOGGER.println( "CHManagerImpl.install" );
if (regInstaller != null) {
regInstaller.install();
regInstaller = null; // Let GC take it.
}
}
/**
* Uninstall the Content handler specific information for
* the specified suiteId.
* @param suiteId the suiteId
*/
public void uninstall(int suiteId) {
if( AppProxy.LOGGER != null ) AppProxy.LOGGER.println( "CHManagerImpl.uninstall()" );
RegistryInstaller.uninstallAll(suiteId, false);
}
/**
* The content handler registrations are restored to the previous
* state.
*/
public void restore() {
}
/**
* Get a URL to install from the Invocation mechanism, if one
* has been queued.
* @param midlet to check for an invocation
* @return the URL to install; <code>null</code> if none available.
* @see com.sun.midp.content.CHManagerImpl
*/
public String getInstallURL(MIDlet midlet) {
try {
handler = Registry.getServer(midlet.getClass().getName());
} catch (ContentHandlerException che) {
return null;
}
installInvoc = handler.getRequest(false);
if (installInvoc != null) {
String url = installInvoc.getURL();
if (url != null && url.length() > 0) {
return url;
}
}
return null;
}
/**
* Complete the installation of the URL provided by
* {@link #getInstallURL} with the success/failure status
* provided.
* @param success <code>true</code> if the install was a success
* @see com.sun.midp.content.CHManagerImpl
*/
public void installDone(boolean success) {
if( AppProxy.LOGGER != null ) AppProxy.LOGGER.println( "CHManagerImpl.installDone()" );
if (installInvoc != null) {
handler.finish(installInvoc,
success ? Invocation.OK : Invocation.CANCELLED);
installInvoc = null;
regInstaller = null; // Double-clean.
}
}
/**
* Setup to monitor for MIDlets starting and exiting and check
* for incompletely handled Invocation requests.
* Cleanup only occurs within the AMS Isolate.
* This method is only called from MIDletSuiteLoader in the AMS Isolate.
*
* @param midletProxyList reference to the MIDlet proxy list
* @param eventQueue reference to AMS isolate event queue
*/
public void init(MIDletProxyList midletProxyList, EventQueue eventQueue) {
midletProxyList.addListener(this);
eventQueue.registerEventListener(EventTypes.CHAPI_EVENT, this);
}
/**
* Notification that a MIDlet is about to be created.
* Set the cleanup flag on all invocations for the MIDlet.
*
* @param suiteId the storage name of the MIDlet suite
* @param classname the midlet classname
*/
public void midletInit(int suiteId, String classname) {
InvocationStore.setCleanup(new CLDCAppID(suiteId, classname), true);
}
/**
* The ContentHandler monitor ignores MIDlet added callbacks.
* The necessary initialization is done in the Isolate and
* MIDletState that instantiates the MIDlet.
* Called when a MIDlet is added to the list and only in the AMS
* Isolate.
*
* @param midlet The proxy of the MIDlet being added
*/
public void midletAdded(MIDletProxy midlet) {
AppProxy.midletIsAdded( midlet.getSuiteId(), midlet.getClassName() );
}
/**
* The ContentHandler monitor ignores MIDlet update callbacks.
* Called when the state of a MIDlet in the list is updated.
*
* @param midlet The proxy of the MIDlet that was updated
* @param fieldId code for which field of the proxy was updated
*/
public void midletUpdated(MIDletProxy midlet, int fieldId) {
}
/**
* The ContentHandler monitor uses the MIDlet removed callback
* to cleanup any Invocations in an incorrect state.
* Called (in the AMS Isolate) when a MIDlet is removed from the list.
*
* @param midlet The proxy of the removed MIDlet
*/
public void midletRemoved(MIDletProxy midlet) {
if( AppProxy.LOGGER != null )
AppProxy.LOGGER.println("midletRemoved: " + midlet.getClassName());
// Cleanup unprocessed Invocations
CLDCAppID appID = new CLDCAppID(midlet.getSuiteId(), midlet.getClassName());
RegistryImpl.cleanup(appID);
AppProxy.midletIsRemoved( appID.suiteID, appID.className );
// Check for and execute a pending MIDlet suite
InvocationStoreProxy.invokeNext();
}
/**
* Called when error occurred while starting a MIDlet object.
*
* @param externalAppId ID assigned by the external application manager
* @param suiteId Suite ID of the MIDlet
* @param className Class name of the MIDlet
* @param errorCode start error code
* @param errorDetails start error details
*/
public void midletStartError(int externalAppId, int suiteId, String className,
int errorCode, String errorDetails) {
// Cleanup unprocessed Invocations
CLDCAppID appID = new CLDCAppID(suiteId, className);
InvocationStore.setCleanup(appID, true);
RegistryImpl.cleanup(appID);
AppProxy.midletIsRemoved( suiteId, className );
// Check for and execute a pending MIDlet suite
InvocationStoreProxy.invokeNext();
}
/**
* Preprocess an event that is being posted to the event queue.
* This method will get called in the thread that posted the event.
*
* @param event event being posted
*
* @param waitingEvent previous event of this type waiting in the
* queue to be processed
*
* @return true to allow the post to continue, false to not post the
* event to the queue
*/
public boolean preprocess(Event event, Event waitingEvent) {
return true;
}
/**
* Process an event.
* This method will get called in the event queue processing thread.
*
* @param event event to process
*/
public void process(Event event) {
InvocationStoreProxy.invokeNext();
}
}