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

OtaNotifier

public final class OtaNotifier extends Object
This class handles sending installation and deletion notifications as specified by the OTA section of the MIDP 2.0 specification. The delete notifications are only sent when an install notification is sent. The installer will call this class to send the initial install notification, if the notification fails and is a success notification, the notification will be queued, so that the next time a MIDlet from the suite is run, that suite's notification will be retried. The MIDlet state handler will call this class to process install notification retries.

Fields Summary
static final int
RETRY_DELAY
Retry delay.
public static final String
NOTIFY_PROP
MIDlet property for the install notify URL.
public static final String
SUCCESS_MSG
Success message for the suite provider.
public static final String
INSUFFICIENT_MEM_MSG
Error message for the suite provider.
public static final String
USER_CANCELLED_MSG
Error message for the suite provider.
public static final String
JAR_SIZE_MISMATCH_MSG
Error message for the suite provider.
public static final String
ATTRIBUTE_MISMATCH_MSG
Error message for the suite provider.
public static final String
INVALID_JAD_MSG
Error message for the suite provider.
public static final String
INVALID_JAR_MSG
Error message for the suite provider.
public static final String
INCOMPATIBLE_MSG
Error message for the suite provider.
public static final String
AUTHENTICATION_FAILURE_MSG
Error message for authentication failure.
public static final String
AUTHORIZATION_FAILURE_MSG
Error message for authorization failure.
public static final String
PUSH_REG_FAILURE_MSG
Error message for push registration failure.
public static final String
DELETE_NOTIFICATION_MSG
Error message for push registration failure.
public static final String
CONTENT_HANDLER_CONFLICT
Message to send when a content handler install fails.
public static final String
INVALID_CONTENT_HANDLER
Message to send when a content handler install fails.
Constructors Summary
Methods Summary
private static native voidaddInstallNotification(int suiteId, java.lang.String url)
Adds an element to the install notification list.

param
suiteId suite the notification belongs to
param
url url to send the notification to

private static native voidfillDeleteNotificationListForRetry(com.sun.midp.installer.PendingNotification[] list)
Retrieves the queued delete notification list from storage and increments the retry count of every member of the list.

param
list empty delete notification list to fill

private static java.lang.StringformatAuthCredentials(java.lang.String username, java.lang.String password)
Formats the username and password for HTTP basic authentication according RFC 2617.

param
username for HTTP authentication
param
password for HTTP authentication
return
properly formated basic authentication credential

        byte[] data = new byte[username.length() + password.length() + 1];
        int j = 0;

        for (int i = 0; i < username.length(); i++, j++) {
            data[j] = (byte)username.charAt(i);
        }

        data[j] = (byte)':";
        j++;

        for (int i = 0; i < password.length(); i++, j++) {
            data[j] = (byte)password.charAt(i);
        }

        return "Basic " + Base64.encode(data, 0, data.length);
    
private static synchronized com.sun.midp.installer.PendingNotification[]getDeleteNotifications()
Retrieves the queued delete notification list. Each element in the array is a URL to send a delete notification to.

return
the delete notification list

        PendingNotification[] array =
            new PendingNotification[getNumberOfDeleteNotifications()];

        if (array.length > 0) {
            for (int i = 0; i < array.length; i++) {
                array[i] = new PendingNotification();
            }

            fillDeleteNotificationListForRetry(array);
        }

        return array;
    
private static native booleangetInstallNotificationForRetry(int suiteId, com.sun.midp.installer.PendingNotification dest)
Retrieves the URL of suite's install notification from storage and increments the retry count of element.

param
suiteId suite ID of the notification
param
dest where to put the notification
return
true if the notification is found

private static native intgetNumberOfDeleteNotifications()
Retrieves the number of URLs queued delete in the notification list.

return
the number of URLs in the delete notification list

public static voidpostInstallMsgBackToProvider(java.lang.String message, com.sun.midp.midlet.MIDletSuite suite, java.lang.String proxyUsername, java.lang.String proxyPassword)
Posts a status message back to the provider's URL in JAD. This method will also retry ALL pending delete notifications.

param
message status message to post
param
suite MIDlet suite object
param
proxyUsername if not null, it will be put in the post
param
proxyPassword if not null, it will be put in the post


                                                                
        
                  
        String url;
        MIDletSuite callingMidletSuite =
            MIDletStateHandler.getMidletStateHandler().getMIDletSuite();

        if (callingMidletSuite == null) {
            throw new IllegalStateException("This method can't be called " +
                "before a suite is started.");
        }

        callingMidletSuite.checkIfPermissionAllowed(Permissions.AMS);

        // Now, send out install notifications
        url = suite.getProperty(NOTIFY_PROP);
        try {
            postMsgBackToProvider(message, url, proxyUsername, proxyPassword);
        } catch (Throwable t) {
            if (message == SUCCESS_MSG) {
                // Only queue successful install notifications for retry
                addInstallNotification(suite.getID(), url);
            }
        }
    
private static voidpostMsgBackToProvider(java.lang.String message, java.lang.String url, java.lang.String proxyUsername, java.lang.String proxyPassword)
Posts a status message back to the provider's URL in JAD.

param
message status message to post
param
url target http url for the status message
param
proxyUsername if not null, it will be put in the post
param
proxyPassword if not null, it will be put in the post
exception
IOException is thrown if any error prevents the notification from being successful

        HttpConnection transaction;

        if (url == null) {
            return;
        }

        transaction = (HttpConnection)Connector.open(url, Connector.WRITE);

        postMsgBackToProvider(message, transaction, proxyUsername,
                              proxyPassword);
    
private static voidpostMsgBackToProvider(java.lang.String message, javax.microedition.io.HttpConnection transaction, java.lang.String proxyUsername, java.lang.String proxyPassword)
Posts a status message back to the provider's URL in JAD.

param
message status message to post
param
transaction http connection to use for posting the status message
param
proxyUsername if not null, it will be put in the post
param
proxyPassword if not null, it will be put in the post
exception
IOException is thrown if any error prevents the notification from being successful

        OutputStream out;

        try {
            transaction.setRequestMethod(HttpConnection.POST);

            if (proxyUsername != null && proxyPassword != null) {
                transaction.setRequestProperty("Proxy-Authorization",
                    formatAuthCredentials(proxyUsername, proxyPassword));
            }

            out = transaction.openOutputStream();

            try {
                int responseCode;

                out.write(message.getBytes());
                responseCode = transaction.getResponseCode();
                if (responseCode != HttpConnection.HTTP_OK) {
                    throw new IOException("Failed to notify " +
                        transaction.getURL() +
                        " HTTP response code: " + responseCode);
                }
            } finally {
                out.close();
            }
        } finally {
            transaction.close();
        }
    
public static voidpostQueuedDeleteMsgsBackToProvider(java.lang.String proxyUsername, java.lang.String proxyPassword)
Posts all queued delete notification messages

param
proxyUsername if not null, it will be put in the post
param
proxyPassword if not null, it will be put in the post

        PendingNotification[] deleteNotifyList;

        deleteNotifyList = getDeleteNotifications();

        for (int i = 0; i < deleteNotifyList.length; i++) {
            try {
                postMsgBackToProvider(DELETE_NOTIFICATION_MSG,
                                      deleteNotifyList[i].url,
                                      proxyUsername, proxyPassword);
                removeDeleteNotification(deleteNotifyList[i].suiteId);
            } catch (Throwable t) {
                if (deleteNotifyList[i].retries >=
                        Constants.MAX_INSTALL_DELETE_NOTIFICATION_RETRIES) {
                    removeDeleteNotification(deleteNotifyList[i].suiteId);
                }
            }
        }
    
private static native voidremoveDeleteNotification(int suiteId)
Removes the element from the delete notification list.

param
suiteId suite ID of the notification

private static native voidremoveInstallNotification(int suiteId)
Removes the element from the install notification list.

param
suiteId suite ID of the notification

public static voidretryInstallNotification(com.sun.midp.security.SecurityToken token, com.sun.midp.midlet.MIDletSuite suite)
Retry the pending install status message for this suite only. This method will also retry ALL pending delete notifications, if the install notification was retried.

param
token security token of the caller
param
suite MIDlet suite object

        /*
         * Delay any processing so that startup time is not effected.
         */
        new Thread(new InstallRetryHandler(token, suite)).start();
    
static voidretryInstallNotificationInternal(com.sun.midp.security.SecurityToken token, com.sun.midp.midlet.MIDletSuite suite)
Retry the pending install status message for this suite only. This method will also retry ALL pending delete notifications, if the install notification was retried.

param
token security token of the caller
param
suite MIDlet suite object

        PendingNotification notification = new PendingNotification();

        token.checkIfPermissionAllowed(Permissions.AMS);

        // Now, send out install notifications
        if (suite.getProperty(NOTIFY_PROP) == null) {
            return;
        }

        if (!getInstallNotificationForRetry(suite.getID(), notification)) {
            return;
        }

        try {
            Protocol httpConnection = new Protocol();

            httpConnection.openPrim(token, notification.url);
            postMsgBackToProvider(SUCCESS_MSG, httpConnection, null, null);
            removeInstallNotification(notification.suiteId);
        } catch (Throwable t) {
            if (notification.retries >=
                Constants.MAX_INSTALL_DELETE_NOTIFICATION_RETRIES) {
                removeInstallNotification(notification.suiteId);
            }
        }

        try {
            // Send out delete notifications that have been queued, first
            postQueuedDeleteMsgsBackToProvider(null, null);
        } catch (Throwable t) {
            // ignore
        }