FileDocCategorySizeDatePackage
GraphicalInstaller.javaAPI DocphoneME MR2 API (J2ME)66477Wed May 02 18:00:02 BST 2007com.sun.midp.installer

GraphicalInstaller

public class GraphicalInstaller extends MIDlet implements CommandListener
The Graphical MIDlet suite installer.

The graphical installer is implements the installer requirements of the MIDP OTA specification.

If the Content Handler API (CHAPI) is present the GraphicalInstaller will dequeue a single Invocation and install from the URL contained in the request. If there is no Invocation present then the arguments below will be used.

The MIDlet uses certain application properties as arguments:

  1. arg-0: "U" for update "I" or anything else for install
  2. arg-1: Suite ID for updating, URL for installing
  3. arg-2: For installing a name to put in the title bar when installing
see
CHManagerImpl
see
CHManager

Fields Summary
public static final int
ALERT_TIMEOUT
Standard timeout for alerts.
public static final String
SETTINGS_STORE
settings database
public static final int
URL_RECORD_ID
record id of selected midlet
public static final int
SELECTED_MIDLET_RECORD_ID
record is of the last installed midlet
private Installer
installer
The installer that is being used to install or update a suite.
private Display
display
Display for this MIDlet.
private Form
passwordForm
Form obtain a password and a username.
private TextField
usernameField
Contains the username for installing.
private TextField
passwordField
Contains the password for installing.
private BackgroundInstaller
backgroundInstaller
Background installer that holds state for the current install.
private Form
progressForm
Displays the progress of the install.
private int
progressGaugeIndex
Gauge for progress form index.
private int
progressUrlIndex
URL for progress form index.
private long
lastDisplayChange
Keeps track of when the display last changed, in milliseconds.
private String
cancelledMessage
What to display to the user when the current action is cancelled.
private String
finishingMessage
What to display to the user when the current action is finishing.
private int
storageId
ID of the storage where the new midlet suite will be installed.
com.sun.midp.content.CHManager
chmanager
Content handler specific install functions.
private Command
stopCmd
Command object for "Stop" command for progress form.
private Command
cancelCmd
Command object for "Cancel" command for the confirm form.
private Command
continueCmd
Command object for "Install" command for the confirm download form.
private Command
nextCmd
Command object for "Next" command for password form.
private Command
okCmd
Command object for "continue" command for warning form.
private Command
exceptionCmd
Command object for "OK" command for exception form.
private Command
keepRMSCmd
Command object for "Yes" command for keep RMS form.
private Command
removeRMSCmd
Command object for "No" command for keep RMS form.
Constructors Summary
public GraphicalInstaller()
Create and initialize a new graphical installer MIDlet.

If a ContentHandler request to install a suite is found, then that URL will be installed. In this case the command arguments are ignored.

The Display is retrieved and the list of MIDlet will be retrieved or update a currently installed suite.

        int    suiteId;
        String arg0;
        String label;
        String url;

        installer = new HttpInstaller();
        display = Display.getDisplay(this);

        initSettings();

        // Establish Content handler installer context
        chmanager = CHManager.getManager(null);

        // Get the URL, if any, provided from the invocation mechanism.
        url = chmanager.getInstallURL(this);
        if (url != null) {
            label = Resource.getString(ResourceConstants.APPLICATION);
            installSuite(label, url);
            return;
        }

        arg0 = getAppProperty("arg-0");
        if (arg0 == null) {
            // goto back to the discovery midlet
            exit(false);
            return;
        }

        if ("U".equals(arg0)) {
            String strSuiteID = getAppProperty("arg-1");
            suiteId = MIDletSuite.UNUSED_SUITE_ID;

            if (strSuiteID != null) {
              try {
                  suiteId = Integer.parseInt(strSuiteID);
              } catch (NumberFormatException nfe) {
                  // Intentionally ignored
              }
            }

            if (suiteId == MIDletSuite.UNUSED_SUITE_ID) {
                // goto back to the discovery midlet
                exit(false);
                return;
            }

            updateSuite(suiteId);
            return;
        }

        url = getAppProperty("arg-1");
        if (url == null) {
            // goto back to the discovery midlet
            exit(false);
            return;
        }

        label = getAppProperty("arg-2");
        if (label == null || label.length() == 0) {
            label = Resource.getString(ResourceConstants.APPLICATION);
        }

        installSuite(label, url);
    
Methods Summary
private voidcancelBackgroundInstall()
Cancel an install (if there is one) waiting for user input.

        if (backgroundInstaller != null) {
            backgroundInstaller.continueInstall = false;

            synchronized (backgroundInstaller) {
                backgroundInstaller.notify();
            }
        }
    
public voidcommandAction(Command c, Displayable s)
Respond to a command issued on any Screen.

param
c command activated by the user
param
s the Displayable the command was on.

        if (c == nextCmd) {
            // the user has entered a username and password
            resumeInstallWithPassword();
        } else if (c == okCmd) {
            resumeInstallAfterWarning();
        } else if (c == continueCmd) {
            startJarDownload();
        } else if (c == keepRMSCmd) {
            setKeepRMSAnswer(true);
        } else if (c == removeRMSCmd) {
            setKeepRMSAnswer(false);
        } else if (c == stopCmd) {
            if (installer != null) {
                /*
                 * BackgroundInstaller may be displaying
                 * the "Finishing" message
                 *
                 * also we need to prevent the BackgroundInstaller from
                 * re-displaying the list before the cancelled message is
                 * displayed
                 */
                synchronized (this) {
                    if (installer.stopInstalling()) {
                        displayCancelledMessage(cancelledMessage);
                    }
                }
            } else {
                // goto back to the manager midlet
                exit(false);
            }
        } else if (c == cancelCmd) {
            displayCancelledMessage(cancelledMessage);
            cancelBackgroundInstall();
        } else if (c == Alert.DISMISS_COMMAND) {
            // goto back to the manager midlet
            exit(false);
        }
    
private voidcreateProgressForm(java.lang.String action, java.lang.String name, java.lang.String url, int size, java.lang.String gaugeLabel)
Create and display the progress form to the user with the stop action.

param
action action to put in the form's title
param
name name to in the form's title
param
url URL of a JAD
param
size 0 if unknown, else size of object to download in K bytes
param
gaugeLabel label for progress gauge

        Form installForm;

        // display the JAR progress form
        installForm = displayProgressForm(action, name, url, size,
                                            gaugeLabel);
        installForm.addCommand(stopCmd);
        installForm.setCommandListener(this);
    
public voiddestroyApp(boolean unconditional)
Destroy cleans up.

param
unconditional is ignored; this object always destroys itself when requested.

        if (installer != null) {
            installer.stopInstalling();
        }

        /* The backgroundInstaller could be waiting for the user. */
        cancelBackgroundInstall();
    
private voiddisplayAlert(java.lang.String title, java.lang.String message, AlertType type)
Display an alert to the user, with a done command.

param
title alert's title
param
message alert message
param
type severity of the alert message


        Alert a = new Alert(title, message, null, type);

        a.setTimeout(Alert.FOREVER);
        a.setCommandListener(this);

        display.setCurrent(a, new Form(""));
          // this Form is never displayed
    
private voiddisplayAuthPathConfirmation(InstallState state)
Confirm the authorization path with the user.

param
state current state of the install.

        Form infoForm;
        String name;
        String values[] = new String[1];
        StringItem item;
        String authPath[];
        String temp;
        StringBuffer label = new StringBuffer(40);
        StringBuffer value = new StringBuffer(40);

        name = state.getAppProperty(MIDletSuite.SUITE_NAME_PROP);

        try {
            infoForm = new Form(Resource.getString(
                          ResourceConstants.AMS_AUTHORIZATION_INFO));

            infoForm.append(new ImageItem(null, TrustedMIDletIcon.getIcon(),
                ImageItem.LAYOUT_NEWLINE_BEFORE |
                ImageItem.LAYOUT_CENTER |
                ImageItem.LAYOUT_NEWLINE_AFTER, null));

            values[0] = name;
            label.setLength(0);
            label.append(Resource.getString(
                ResourceConstants.AMS_GRA_INTLR_TRUSTED, values));
            label.append(": ");

            authPath = state.getAuthPath();
            temp = label.toString();
            for (int i = 0; i < authPath.length; i++) {
                item = new StringItem(temp, authPath[i]);
                item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
                infoForm.append(item);
                temp = " -> ";
            }

            infoForm.addCommand(continueCmd);
            infoForm.addCommand(cancelCmd);
            infoForm.setCommandListener(this);

            // We need to prevent "flashing" on fast development platforms.
            preventScreenFlash();

            display.setCurrent(infoForm);
        } catch (Exception ex) {
            StringBuffer sb = new StringBuffer();

            sb.append(Resource.getString(ResourceConstants.EXCEPTION));
            sb.append(": ");
            sb.append(ex.toString());
            displayException(Resource.getString
                             (ResourceConstants.AMS_CANT_ACCESS),
                             sb.toString());
        }
    
private voiddisplayCancelledMessage(java.lang.String message)
Alert the user that an action was canceled. The backgroundInstaller will hide the message.

param
message message to display to user

        Form form;
        Image icon;

        form = new Form(null);

        icon = getImageFromInternalStorage("_ack8");
        form.append(new ImageItem(null, icon, ImageItem.LAYOUT_CENTER +
                                     ImageItem.LAYOUT_NEWLINE_BEFORE +
                                     ImageItem.LAYOUT_NEWLINE_AFTER, null));

        form.append(message);

        display.setCurrent(form);
        lastDisplayChange = System.currentTimeMillis();
    
private voiddisplayDownloadConfirmation(InstallState state)
Confirm the JAR download with the user.

param
state current state of the install.

        Form infoForm;
        StringItem item;
        String name;
        String desc;
        StringBuffer label = new StringBuffer(40);
        StringBuffer value = new StringBuffer(40);
        String[] values = new String[1];

        name = state.getSuiteName();

        try {
            infoForm = new Form(null);

            infoForm.setTitle(Resource.getString
                              (ResourceConstants.AMS_CONFIRMATION));

            values[0] = name;
            item = new StringItem(null, Resource.getString
                      (ResourceConstants.AMS_GRA_INTLR_WANT_INSTALL,
                       values));
            item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
            infoForm.append(item);

            if (!installer.isJadSigned()) {
                // The MIDlet suite is not signed, therefore will be untrusted
                item = new StringItem(
                          Resource.getString(ResourceConstants.WARNING) + ":",
                          Resource.getString
                          (ResourceConstants.AMS_GRA_INTLR_UNTRUSTED_WARN));
                item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
                infoForm.append(item);
            }

            // round up the size to a Kilobyte
            label.append(Resource.getString(ResourceConstants.AMS_SIZE));
            label.append(": ");
            value.setLength(0);
            value.append(state.getJarSize());
            value.append(" K");
            item = new StringItem(label.toString(), value.toString());
            item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
            infoForm.append(item);

            label.setLength(0);
            label.append(Resource.getString(ResourceConstants.AMS_VERSION));
            label.append(": ");
            value.setLength(0);
            item = new StringItem(label.toString(),
                       state.getAppProperty(MIDletSuite.VERSION_PROP));
            item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
            infoForm.append(item);

            label.setLength(0);
            label.append(Resource.getString(ResourceConstants.AMS_VENDOR));
            label.append(": ");
            item = new StringItem(label.toString(),
                      state.getAppProperty(MIDletSuite.VENDOR_PROP));
            item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
            infoForm.append(item);

            desc = state.getAppProperty(MIDletSuite.DESC_PROP);
            if (desc != null) {
                label.setLength(0);
                label.append(Resource.getString
                             (ResourceConstants.AMS_DESCRIPTION));
                label.append(": ");
                item = new StringItem(label.toString(), desc);
                item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
                infoForm.append(item);
            }

            label.setLength(0);
            label.append(Resource.getString(ResourceConstants.AMS_WEBSITE));
            label.append(": ");
            infoForm.append(new StringItem(label.toString(),
                                           state.getJarUrl()));

            infoForm.addCommand(continueCmd);
            infoForm.addCommand(cancelCmd);
            infoForm.setCommandListener(this);

            // We need to prevent "flashing" on fast development platforms.
            preventScreenFlash();

            display.setCurrent(infoForm);
        } catch (Exception ex) {
            StringBuffer sb = new StringBuffer();

            sb.append(name);
            sb.append("\n");
            sb.append(Resource.getString(ResourceConstants.EXCEPTION));
            sb.append(": ");
            sb.append(ex.toString());
            displayException(Resource.getString
                             (ResourceConstants.AMS_CANT_ACCESS),
                             sb.toString());
        }
    
private voiddisplayException(java.lang.String title, java.lang.String message)
Display an exception to the user, with a done command.

param
title exception form's title
param
message exception message

        displayAlert(title, message, AlertType.ERROR);
    
private voiddisplayJarOnlyDownloadConfirmation()
Confirm the JAR only download with the user.

        Form infoForm;
        StringItem item;
        StringBuffer label = new StringBuffer(40);
        StringBuffer value = new StringBuffer(40);
        String[] values = new String[1];

        try {
            infoForm = new Form(null);

            infoForm.setTitle(Resource.getString
                              (ResourceConstants.AMS_CONFIRMATION));

            values[0] = backgroundInstaller.name;
            item = new StringItem(null, Resource.getString(
                                  ResourceConstants.AMS_GRA_INTLR_WANT_INSTALL,
                                  values));
            item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
            infoForm.append(item);

            label.append(Resource.getString(ResourceConstants.AMS_WEBSITE));
            label.append(": ");
            item = new StringItem(label.toString(), backgroundInstaller.url);
            item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
            infoForm.append(item);

            value.append(" \n");
            value.append(Resource.getString
                         (ResourceConstants.AMS_GRA_INTLR_NO_INFO));
            infoForm.append(new StringItem(null, value.toString()));

            infoForm.addCommand(continueCmd);
            infoForm.addCommand(cancelCmd);
            infoForm.setCommandListener(this);

            // We need to prevent "flashing" on fast development platforms.
            preventScreenFlash();

            display.setCurrent(infoForm);
        } catch (Exception ex) {
            StringBuffer sb = new StringBuffer();

            sb.append(backgroundInstaller.name);
            sb.append("\n");
            sb.append(Resource.getString(ResourceConstants.EXCEPTION));
            sb.append(": ");
            sb.append(ex.toString());
            displayException(Resource.getString
                             (ResourceConstants.AMS_CANT_ACCESS),
                             sb.toString());
        }
    
private voiddisplayKeepRMSForm(InstallState state)
Ask the user during an update if they want to keep the old RMS data.

param
state current state of the install.

        Form infoForm;
        String name;
        String desc;
        StringBuffer label = new StringBuffer(40);
        StringBuffer value = new StringBuffer(40);
        String[] values = new String[1];

        name = state.getAppProperty(MIDletSuite.SUITE_NAME_PROP);

        try {
            infoForm = new Form(null);

            infoForm.setTitle(Resource.getString
                              (ResourceConstants.AMS_CONFIRMATION));

            values[0] = name;
            value.append(Resource.getString
                         (ResourceConstants.AMS_GRA_INTLR_NEW_OLD_VERSION,
                          values));
            infoForm.append(value.toString());

            infoForm.addCommand(keepRMSCmd);
            infoForm.addCommand(removeRMSCmd);
            infoForm.setCommandListener(this);

            // We need to prevent "flashing" on fast development platforms.
            preventScreenFlash();

            display.setCurrent(infoForm);
        } catch (Exception ex) {
            StringBuffer sb = new StringBuffer();

            sb.append(name);
            sb.append("\n");
            sb.append(Resource.getString(ResourceConstants.EXCEPTION));
            sb.append(": ");
            sb.append(ex.toString());
            displayException(Resource.getString
                             (ResourceConstants.AMS_CANT_ACCESS),
                             sb.toString());
        }
    
private FormdisplayProgressForm(java.lang.String action, java.lang.String name, java.lang.String url, int size, java.lang.String gaugeLabel)
Display the connecting form to the user, let call set actions.

param
action action to put in the form's title
param
name name to in the form's title
param
url URL of a JAD
param
size 0 if unknown, else size of object to download in K bytes
param
gaugeLabel label for progress gauge
return
displayed form

        Gauge progressGauge;
        StringItem urlItem;

        progressForm = new Form(null);

        progressForm.setTitle(action + " " + name);

        if (size <= 0) {
            progressGauge = new Gauge(gaugeLabel,
                                      false, Gauge.INDEFINITE,
                                      Gauge.CONTINUOUS_RUNNING);
        } else {
            progressGauge = new Gauge(gaugeLabel,
                                      false, size, 0);
        }

        progressGaugeIndex = progressForm.append(progressGauge);

        if (url == null) {
            urlItem = new StringItem("", "");
        } else {
            urlItem =
                new StringItem(Resource.getString
                               (ResourceConstants.AMS_WEBSITE) + ": ", url);
        }

        progressUrlIndex = progressForm.append(urlItem);

        display.setCurrent(progressForm);
        lastDisplayChange = System.currentTimeMillis();

        return progressForm;
    
private voiddisplaySuccessMessage(java.lang.String successMessage)
Alert the user that an action was successful.

param
successMessage message to display to user

        Image icon;
        Alert successAlert;

        icon = getImageFromInternalStorage("_dukeok8");

        successAlert = new Alert(null, successMessage, icon, null);

        successAlert.setTimeout(Alert.FOREVER);

        // Provide a listener to disable the advance-to-next-displayable
        // feature of Alert.
        successAlert.setCommandListener(
            new CommandListener() {
                public void commandAction(Command c, Displayable d) { }
            }
        );

        // We need to prevent "flashing" on fast development platforms.
        preventScreenFlash();

        lastDisplayChange = System.currentTimeMillis();
        display.setCurrent(successAlert, new Form(""));
            // this Form is never displayed
    
private voiddisplayWarning(java.lang.String title, java.lang.String message)
Display an warning to the user, with a done command.

param
title warnings form's title
param
message warning message

        displayAlert(title, message, AlertType.WARNING);
    
voidexit(boolean success)
Exit the GraphicalInstaller with the status supplied. It will perform any remaining cleanup and call notifyDestroyed.

param
success true if the install was a success, false otherwise.

        chmanager.installDone(success);

        notifyDestroyed();
    
private static byte[]getImageFileBytes(java.lang.String imageFileName)
Read image data from storage file to byte array.

param
imageFileName name of the file with icon data
return
byte array with icon data, or null if file not found


                                       
         
        byte[] imageBytes;
        RandomAccessStream stream;
        stream = new RandomAccessStream();
        try {
            stream.connect(imageFileName, Connector.READ);
            imageBytes = new byte[stream.getSizeOf()];
            stream.readBytes(imageBytes, 0, imageBytes.length);
            stream.disconnect();
            return imageBytes;
        } catch (java.io.IOException noIcon) {}
        return null;
    
public static ImagegetImageFromInternalStorage(java.lang.String imageName)
Gets an image from the internal storage. IMPL_NOTE: this method should be moved somewhere.

param
imageName image file name without a path and extension
return
Image loaded from storage, or null if not found

        String imageFileName;
        byte[] imageBytes;

        MIDletStateHandler midletStateHandler =
            MIDletStateHandler.getMidletStateHandler();
        MIDletSuite midletSuite = midletStateHandler.getMIDletSuite();
        midletSuite.checkIfPermissionAllowed(Permissions.AMS);

        imageFileName = File.getStorageRoot(Constants.INTERNAL_STORAGE_ID) +
            imageName;
        imageBytes = getImageFileBytes(imageFileName + ".raw");
        if (imageBytes == null) {
            imageBytes = getImageFileBytes(imageFileName + ".png");
        }
        if (imageBytes != null) {
            return Image.createImage(imageBytes, 0, imageBytes.length);
        }
        return null;
    
private voidgetProxyUsernameAndPassword()
Ask for proxy username and password.

        getUsernameAndPasswordCommon(
              Resource.getString(
              ResourceConstants.AMS_GRA_INTLR_PASSWORD_FORM_FIREWALL_TITLE));
    
private voidgetUsernameAndPassword()
Ask for a username and password.

        getUsernameAndPasswordCommon("");
    
private voidgetUsernameAndPasswordCommon(java.lang.String title)
Ask a username and password.

param
title title of the password form

        if (passwordForm == null) {
            passwordForm = new Form(null);

            usernameField = new TextField(
                            Resource.getString(ResourceConstants.
                                               AMS_GRA_INTLR_ENTER_ID),
                            null, 40,
                            TextField.ANY);
            passwordForm.append(usernameField);

            passwordField = new TextField(
                            Resource.getString(ResourceConstants.
                                               AMS_GRA_INTLR_PASSWORD),
                            null, 40,
                            TextField.PASSWORD);
            passwordForm.append(passwordField);
            passwordForm.addCommand(cancelCmd);
            passwordForm.addCommand(nextCmd);
            passwordForm.setCommandListener(this);
        }

        passwordForm.setTitle(title);
        passwordField.setString("");
        display.setCurrent(passwordForm);
    
public static voidinitSettings()
Initialize the settings database if it doesn't exist. This may create two entries. The first will be for the download url, the second will be for storing the storagename of the currently selected midlet

        MIDletStateHandler midletStateHandler =
            MIDletStateHandler.getMidletStateHandler();
        MIDletSuite midletSuite = midletStateHandler.getMIDletSuite();

        midletSuite.checkIfPermissionAllowed(Permissions.AMS);

        try {
            RecordStore settings = RecordStore.
                                   openRecordStore(SETTINGS_STORE, true);

            try {
                if (settings.getNumRecords() == 0) {
                    // space for a URL
                    settings.addRecord(null, 0, 0);

                    // space for current MIDlet Suite name
                    settings.addRecord(null, 0, 0);
                }
            } finally {
                settings.closeRecordStore();
            }

        } catch (Exception e) {
            if (Logging.REPORT_LEVEL <= Logging.WARNING) {
                Logging.report(Logging.WARNING, LogChannels.LC_AMS,
                               "initSettings  throw an Exception");
            }
        }
    
private voidinstallSuite(java.lang.String label, java.lang.String url)
Install a suite from URL.

param
label label of the URL link
param
url HTTP/S URL of the suite to update

        cancelledMessage =
            Resource.getString(ResourceConstants.AMS_GRA_INTLR_INST_CAN);
        finishingMessage =
            Resource.getString(ResourceConstants.AMS_GRA_INTLR_FIN_INST);
        installSuiteCommon(Resource.getString
                           (ResourceConstants.AMS_GRA_INTLR_INSTALLING),
                           label, url,
                           label + Resource.getString
                           (ResourceConstants.AMS_GRA_INTLR_SUCC_INSTALLED),
                           false);
    
private voidinstallSuiteCommon(java.lang.String action, java.lang.String name, java.lang.String url, java.lang.String successMessage, boolean updateFlag)
Common helper method to install or update a suite.

param
action action to put in the form's title
param
name name to in the form's title
param
url URL of a JAD
param
successMessage message to display to user upon success
param
updateFlag if true the current suite is being updated

        try {
            createProgressForm(action, name, url, 0,
                        Resource.getString(
                            ResourceConstants.AMS_GRA_INTLR_CONN_GAUGE_LABEL));
            backgroundInstaller = new BackgroundInstaller(this, url, name,
                                      successMessage, updateFlag);
            new Thread(backgroundInstaller).start();
        } catch (Exception ex) {
            StringBuffer sb = new StringBuffer();

            sb.append(name);
            sb.append("\n");
            sb.append(Resource.getString(ResourceConstants.ERROR));
            sb.append(": ");
            sb.append(ex.toString());
            displayException(Resource.getString
                             (ResourceConstants.AMS_CANT_ACCESS),
                             sb.toString());
        }
    
public voidpauseApp()
Pause; there are no resources that need to be released.

    
voidpreventScreenFlash()
Prevent screen flash on a fast systems.

        long waitTime = ALERT_TIMEOUT -
            (System.currentTimeMillis() - lastDisplayChange);

        if (waitTime <= 0) {
            return;

        }

        try {
            Thread.sleep(waitTime);
        } catch (InterruptedException ie) {
            // ignore
        }
    
private voidresumeInstallAfterWarning()
Resume the install after a the user overrides a warning.

        // redisplay the progress form
        display.setCurrent(progressForm);

        backgroundInstaller.continueInstall = true;
        synchronized (backgroundInstaller) {
            backgroundInstaller.notify();
        }
    
private voidresumeInstallWithPassword()
Resume the install of the suite with a password and username.

        String username;
        String password;


        username = usernameField.getString();
        password = passwordField.getString();
        if (username == null || username.length() == 0) {
            Alert a = new Alert(Resource.getString(ResourceConstants.ERROR),
                             Resource.getString(ResourceConstants.
                                                AMS_GRA_INTLR_ID_NOT_ENTERED),
                             null, AlertType.ERROR);
            a.setTimeout(ALERT_TIMEOUT);
            display.setCurrent(a, passwordForm);
            return;
        }

        if (password == null || password.length() == 0) {
            Alert a = new Alert(Resource.getString(ResourceConstants.ERROR),
                                Resource.getString(ResourceConstants.
                                            AMS_GRA_INTLR_PWD_NOT_ENTERED),
                                null, AlertType.ERROR);
            a.setTimeout(ALERT_TIMEOUT);
            display.setCurrent(a, passwordForm);
            return;
        }

        // redisplay the progress form
        display.setCurrent(progressForm);

        if (backgroundInstaller.proxyAuth) {
            backgroundInstaller.installState.setProxyUsername(username);
            backgroundInstaller.installState.setProxyPassword(password);
        } else {
            backgroundInstaller.installState.setUsername(username);
            backgroundInstaller.installState.setPassword(password);
        }

        backgroundInstaller.continueInstall = true;
        synchronized (backgroundInstaller) {
            backgroundInstaller.notify();
        }
    
public static java.lang.ExceptionsaveSettings(java.lang.String url, int curMidlet)
Save the settings the user entered.

param
url the url to save
param
curMidlet suiteId of the currently selected midlet
return
the Exception that may have been thrown, or null

        Exception ret = null;
        MIDletStateHandler midletStateHandler =
            MIDletStateHandler.getMidletStateHandler();
        MIDletSuite midletSuite = midletStateHandler.getMIDletSuite();

        midletSuite.checkIfPermissionAllowed(Permissions.AMS);

        try {
            String temp;
            ByteArrayOutputStream bas;
            DataOutputStream dos;
            byte[] data;
            RecordStore settings;

            bas = new ByteArrayOutputStream();
            dos = new DataOutputStream(bas);
            settings = RecordStore.openRecordStore(SETTINGS_STORE, false);

            if (url != null) {
                dos.writeUTF(url);
                data = bas.toByteArray();
                settings.setRecord(URL_RECORD_ID, data, 0, data.length);
            }

            // Save the current midlet even if its id is
            // MIDletSuite.UNUSED_SUITE_ID. Otherwise in SVM mode
            // the last installed midlet will be always highlighted
            // because its it is recorded in this RMS record.
            bas.reset();

            dos.writeInt(curMidlet);
            data = bas.toByteArray();
            settings.setRecord(SELECTED_MIDLET_RECORD_ID,
                               data, 0, data.length);

            settings.closeRecordStore();
            dos.close();
        } catch (Exception e) {
            ret = e;
        }

        return ret;
    
private voidsetKeepRMSAnswer(boolean keepRMS)
Tell the background installer to keep the RMS data.

param
keepRMS set to true to mean the user answered yes

        // redisplay the progress form
        display.setCurrent(progressForm);

        // We need to prevent "flashing" on fast development platforms.
        preventScreenFlash();

        backgroundInstaller.continueInstall = keepRMS;
        synchronized (backgroundInstaller) {
            backgroundInstaller.notify();
        }
    
public voidstartApp()
Start.

    
private voidstartJarDownload()
Resume the install to start the JAR download.

        updateProgressForm(backgroundInstaller.url, 0,
                 Resource.getString
                   (ResourceConstants.
                   AMS_GRA_INTLR_CONN_GAUGE_LABEL));
        // redisplay the progress form
        display.setCurrent(progressForm);

        backgroundInstaller.continueInstall = true;
        synchronized (backgroundInstaller) {
            backgroundInstaller.notify();
        }
    
private static java.lang.StringtranslateJadException(InvalidJadException exception, java.lang.String name, java.lang.String vendor, java.lang.String version, java.lang.String jadUrl)
Translate an InvalidJadException into a message for the user.

param
exception exception to translate
param
name name of the MIDlet suite to insert into the message
param
vendor vendor of the MIDlet suite to insert into the message, can be null
param
version version of the MIDlet suite to insert into the message, can be null
param
jadUrl URL of a JAD, can be null
return
message to display to the user

        String[] values = {name, vendor, version, jadUrl,
                           exception.getExtraData()};
        int key;

        switch (exception.getReason()) {
        case InvalidJadException.OLD_VERSION:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_OLD_VERSION;
            break;

        case InvalidJadException.ALREADY_INSTALLED:
            key =
                ResourceConstants.
                  AMS_GRA_INTLR_INVALIDJADEXCEPTION_ALREADY_INSTALLED;
            break;

        case InvalidJadException.NEW_VERSION:
            key = ResourceConstants.
                      AMS_GRA_INTLR_INVALIDJADEXCEPTION_NEW_VERSION;
            break;

        case InvalidJadException.JAD_SERVER_NOT_FOUND:
        case InvalidJadException.JAD_NOT_FOUND:
        case InvalidJadException.INVALID_JAD_URL:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_INVALID_JAD_URL;
            break;

        case InvalidJadException.INVALID_JAD_TYPE:
            key = ResourceConstants.
                 AMS_GRA_INTLR_INVALIDJADEXCEPTION_INVALID_JAD_TYPE;
            break;

        case InvalidJadException.MISSING_PROVIDER_CERT:
        case InvalidJadException.MISSING_SUITE_NAME:
        case InvalidJadException.MISSING_VENDOR:
        case InvalidJadException.MISSING_VERSION:
        case InvalidJadException.MISSING_JAR_URL:
        case InvalidJadException.MISSING_JAR_SIZE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_MISSING_JAD_INFO;
            break;

        case InvalidJadException.MISSING_CONFIGURATION:
        case InvalidJadException.MISSING_PROFILE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_MISSING_JAR_INFO;
            break;

        case InvalidJadException.INVALID_KEY:
        case InvalidJadException.INVALID_VALUE:
        case InvalidJadException.INVALID_VERSION:
        case InvalidJadException.PUSH_FORMAT_FAILURE:
        case InvalidJadException.PUSH_CLASS_FAILURE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_INVALID_FORMAT;
            break;

        case InvalidJadException.DEVICE_INCOMPATIBLE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_DEVICE_INCOMPATIBLE;
            break;

        case InvalidJadException.JAD_MOVED:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_JAD_MOVED;
            break;

        case InvalidJadException.INSUFFICIENT_STORAGE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_INSUFFICIENT_STORAGE;
            break;

        case InvalidJadException.JAR_SERVER_NOT_FOUND:
        case InvalidJadException.JAR_NOT_FOUND:
        case InvalidJadException.INVALID_JAR_URL:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_JAR_NOT_FOUND;
            break;

        case InvalidJadException.INVALID_JAR_TYPE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_INVALID_JAR_TYPE;
            break;

        case InvalidJadException.SUITE_NAME_MISMATCH:
        case InvalidJadException.VERSION_MISMATCH:
        case InvalidJadException.VENDOR_MISMATCH:
        case InvalidJadException.JAR_SIZE_MISMATCH:
        case InvalidJadException.ATTRIBUTE_MISMATCH:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_ATTRIBUTE_MISMATCH;
            break;

        case InvalidJadException.CORRUPT_JAR:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_CORRUPT_JAR;
            break;

        case InvalidJadException.CANNOT_AUTH:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_CANNOT_AUTH;
            break;

        case InvalidJadException.CORRUPT_PROVIDER_CERT:
        case InvalidJadException.INVALID_PROVIDER_CERT:
        case InvalidJadException.CORRUPT_SIGNATURE:
        case InvalidJadException.INVALID_SIGNATURE:
        case InvalidJadException.UNSUPPORTED_CERT:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_INVALID_SIGNATURE;
            break;

        case InvalidJadException.UNKNOWN_CA:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_UNKNOWN_CA;
            break;

        case InvalidJadException.EXPIRED_PROVIDER_CERT:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_EXPIRED_PROVIDER_CERT;
            break;

        case InvalidJadException.EXPIRED_CA_KEY:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_EXPIRED_CA_KEY;
            break;

        case InvalidJadException.AUTHORIZATION_FAILURE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_AUTHORIZATION_FAILURE;
            break;

        case InvalidJadException.CA_DISABLED:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_CA_DISABLED;
            break;

        case InvalidJadException.PUSH_DUP_FAILURE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_PUSH_DUP_FAILURE;
            break;

        case InvalidJadException.PUSH_PROTO_FAILURE:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_PUSH_PROTO_FAILURE;
            break;

        case InvalidJadException.TRUSTED_OVERWRITE_FAILURE:
            if (exception.getExtraData() != null) {
                key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_TRUSTED_OVERWRITE_FAILURE;
            } else {
                key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_TRUSTED_OVERWRITE_FAILURE_2;
            }

            break;

        case InvalidJadException.TOO_MANY_PROPS:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_APP_TOO_BIG;
            break;

        case InvalidJadException.INVALID_CONTENT_HANDLER:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_INVALID_CONTENT_HANDLER;
            break;

        case InvalidJadException.CONTENT_HANDLER_CONFLICT:
            key = ResourceConstants.
            AMS_GRA_INTLR_INVALIDJADEXCEPTION_CONTENT_HANDLER_CONFLICT;
            break;

        case InvalidJadException.JAR_CLASSES_VERIFICATION_FAILED:
            // This constant is shared between graphical installer
            // and standalone class verifier MIDlet used for SVM mode
            key = ResourceConstants.AMS_CLASS_VERIFIER_FAILURE;
            break;

        case InvalidJadException.UNSUPPORTED_CHAR_ENCODING:
            key = ResourceConstants.
                AMS_GRA_INTLR_INVALIDJADEXCEPTION_UNSUPPORTED_CHAR_ENCODING;
            break;

        default:
            return exception.getMessage();
        }

        return Resource.getString(key, values);
    
private voidupdateProgressForm(java.lang.String url, int size, java.lang.String gaugeLabel)
Update URL and gauge of the progress form.

param
url new URL, null to remove, "" to not change
param
size 0 if unknown, else size of object to download in K bytes
param
gaugeLabel label for progress gauge

        Gauge oldProgressGauge;
        Gauge progressGauge;
        StringItem urlItem;

        // We need to prevent "flashing" on fast development platforms.
        preventScreenFlash();

        if (size <= 0) {
            progressGauge = new Gauge(gaugeLabel,
                                      false, Gauge.INDEFINITE,
                                      Gauge.CONTINUOUS_RUNNING);
        } else {
            progressGauge = new Gauge(gaugeLabel,
                                      false, size, 0);
        }

        oldProgressGauge = (Gauge)progressForm.get(progressGaugeIndex);
        progressForm.set(progressGaugeIndex, progressGauge);

        // this ends the background thread of gauge.
        oldProgressGauge.setValue(Gauge.CONTINUOUS_IDLE);

        if (url == null) {
            urlItem = new StringItem("", "");
            progressForm.set(progressUrlIndex, urlItem);
        } else if (url.length() != 0) {
            urlItem =
                new StringItem(Resource.getString
                               (ResourceConstants.AMS_WEBSITE) + ": ", url);
            progressForm.set(progressUrlIndex, urlItem);
        }

        lastDisplayChange = System.currentTimeMillis();
    
private voidupdateStatus(int status, InstallState state)
Update the status form.

param
status current status of the install.
param
state current state of the install.

        if (status == Installer.DOWNLOADING_JAD) {
            updateProgressForm("", 0,
                 Resource.getString
                   (ResourceConstants.
                   AMS_GRA_INTLR_DOWNLOADING_JAD_GAUGE_LABEL));
            return;
        }

        if (status == Installer.DOWNLOADING_JAR) {
            updateProgressForm(state.getJarUrl(), state.getJarSize(),
                 Resource.getString
                   (ResourceConstants.
                   AMS_GRA_INTLR_DOWNLOADING_JAR_GAUGE_LABEL));
            return;
        }

        if (status == Installer.DOWNLOADED_1K_OF_JAR &&
                state.getJarSize() > 0) {
            Gauge progressGauge = (Gauge)progressForm.get(progressGaugeIndex);
            progressGauge.setValue(progressGauge.getValue() + 1);
            return;
        }

        if (Constants.MONET_ENABLED) {
            if (status == Installer.GENERATING_APP_IMAGE) {
                updateProgressForm(null, 0,
                    Resource.getString
                      (ResourceConstants.
                      AMS_GRA_INTLR_GENERATING_APP_IMAGE_GAUGE_LABEL));
                return;
            }
        }

        if (Constants.VERIFY_ONCE) {
            if (status == Installer.VERIFYING_SUITE_CLASSES) {
                if (state.getLastException() != null) {
                    displayWarning(
                        Resource.getString(
                        ResourceConstants.AMS_GRA_INTLR_INSTALL_WARNING),
                        Resource.getString(
                        ResourceConstants.AMS_CLASS_VERIFIER_FAILURE));
                } else {
                    updateProgressForm(null, 0,
                        Resource.getString(
                        ResourceConstants.AMS_CLASS_VERIFIER_GAUGE_LABEL));
                    return;
                }
            }
        }

        if (status == Installer.VERIFYING_SUITE) {
            updateProgressForm(null, 0,
                 Resource.getString
                   (ResourceConstants.
                   AMS_GRA_INTLR_VERIFYING_SUITE_GAUGE_LABEL));
            return;
        }

        if (status == Installer.STORING_SUITE) {
            updateProgressForm(null, 0, finishingMessage);
            return;
        }

        if (status == Installer.CORRUPTED_SUITE) {
            if (Logging.REPORT_LEVEL <= Logging.WARNING) {
                Logging.report(Logging.WARNING, LogChannels.LC_AMS,
                               "Suite is corrupted");
            }
            return;
        }
    
private voidupdateSuite(int id)
Update a suite.

param
id ID of the suite to update

        MIDletSuiteImpl midletSuite = null;
        try {
            // Any runtime error will get caught by the installer
            midletSuite =
                MIDletSuiteStorage.getMIDletSuiteStorage()
                    .getMIDletSuite(id, false);
            InstallInfo installInfo = midletSuite.getInstallInfo();
            MIDletInfo midletInfo;
            String name;

            if (midletSuite.getNumberOfMIDlets() == 1) {
                midletInfo =
                    new MIDletInfo(midletSuite.getProperty("MIDlet-1"));
                name = midletInfo.name;
            } else {
                name = midletSuite.getProperty(MIDletSuite.SUITE_NAME_PROP);
            }

            cancelledMessage =
                Resource.getString(ResourceConstants.AMS_GRA_INTLR_UPD_CAN);
            finishingMessage =
                Resource.getString(ResourceConstants.AMS_GRA_INTLR_FIN_UPD);
            installSuiteCommon(Resource.getString
                               (ResourceConstants.AMS_GRA_INTLR_UPDATING),
                               name,
                               installInfo.getDownloadUrl(),
                               name + Resource.getString
                               (ResourceConstants.AMS_GRA_INTLR_SUCC_UPDATED),
                               true);
        } catch (MIDletSuiteLockedException e) {
            if (Logging.REPORT_LEVEL <= Logging.WARNING) {
                Logging.report(Logging.WARNING, LogChannels.LC_AMS,
                               "updateSuite threw MIDletSuiteLockedException");
            }
        } catch (MIDletSuiteCorruptedException e) {
            String msg = Resource.getString
                         (ResourceConstants.AMS_MIDLETSUITE_ID_CORRUPT_MSG)
                         + id;
            Alert a = new Alert(Resource.getString(ResourceConstants.ERROR),
                            msg, null, AlertType.ERROR);
            a.setTimeout(Alert.FOREVER);
            a.setCommandListener(this);
            display.setCurrent(a, new Form(""));
                // this Form is never displayed
        } finally {
            if (midletSuite != null) {
                midletSuite.close();
            }
        }
    
private voidwarnUser(java.lang.String name, java.lang.String vendor, java.lang.String version, java.lang.String jadUrl, InvalidJadException e)
Give the user a chance to act on warning during an installation.

param
name name of the MIDlet suite to insert into the message
param
vendor vendor of the MIDlet suite to insert into the message, can be null
param
version version of the MIDlet suite to insert into the message, can be null
param
jadUrl URL of a JAD, can be null
param
e last exception from the installer

        Form warningForm;

        warningForm = new Form(null);
        warningForm.setTitle(Resource.getString(ResourceConstants.WARNING));
        warningForm.append(translateJadException(e, name, vendor, version,
                                                 jadUrl));
        warningForm.addCommand(cancelCmd);
        warningForm.addCommand(okCmd);
        warningForm.setCommandListener(this);
        display.setCurrent(warningForm);