javamanager/javainstaller/installer/javasrc/com/nokia/mj/impl/installer/InstallationNotifier.java
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 14:23:59 +0300
branchRCL_3
changeset 83 26b2b12093af
parent 77 7cee158cb8cd
permissions -rw-r--r--
Revision: v2.2.17 Kit: 201041

/*
* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/


package com.nokia.mj.impl.installer;

import com.nokia.mj.impl.installer.applicationregistrator.SifNotifier;
import com.nokia.mj.impl.installer.exetable.ExeProgressListener;
import com.nokia.mj.impl.installer.ui.InstallerUi;
import com.nokia.mj.impl.installer.utils.InstallerException;
import com.nokia.mj.impl.installer.utils.Log;
import com.nokia.mj.impl.installer.utils.SysUtil;
import com.nokia.mj.impl.utils.InstallerDetailedErrorMessage;
import com.nokia.mj.impl.utils.InstallerErrorMessage;
import com.nokia.mj.impl.utils.OtaStatusCode;
import com.nokia.mj.impl.utils.Uid;
import com.nokia.mj.impl.utils.exception.InstallerExceptionBase;

/**
 * InstallationNotifier notifies interested parties about Java
 * application installation progress.
 */
public class InstallationNotifier implements ExeProgressListener
{
    // Installation states
    public static final int INSTALLING = 0x100;
    public static final int INSTALL_OK = 0x101;
    public static final int INSTALL_FAIL = 0x102;
    public static final int UNINSTALLING = 0x200;
    public static final int UNINSTALL_OK = 0x201;
    public static final int UNINSTALL_FAIL = 0x202;

    // Maximum number of progress updates to SysUtil.setProperty().
    private static final int MAX_PROPERTY_PROGRESS_UPDATES = 5;
    // Maximum number of progress updates to UI.
    private static final int MAX_UI_PROGRESS_UPDATES = 20;

    // Flag telling if the properties are already defined.
    private static boolean iPropertiesDefined = false;

    // InstallerUI instance.
    private InstallerUi iInstallerUi = null;
    // SifNotifier instance.
    private SifNotifier iSifNotifier = null;

    // Maximum progress value.
    private int iMaxValue = 1;
    // Tells how often property progress should be updated.
    private int iPropertyProgressStep = 1;
    // Tells how often UI progress should be updated.
    private int iUiProgressStep = 1;
    // Point between 0 and iMaxValue where the last property
    // update has been made.
    private int iLastPropertyUpdate = 0;
    // Point between 0 and iMaxValue where the last UI update
    // has been made.
    private int iLastUiUpdate = 0;
    // Flag telling if the started() method has been called.
    private boolean iStarted = false;
    // Flag telling if the progress maximum value has been reached.
    private boolean iMaxValueReached = false;

    /**
     * Set InstallerUi to be used.
     */
    public void setInstallerUi(InstallerUi aUi)
    {
        iInstallerUi = aUi;
        if (iStarted && iInstallerUi != null)
        {
            // Notify InstallerUi that execution has been started.
            try
            {
                iInstallerUi.started();
            }
            catch (Throwable t)
            {
                Log.logError(
                    "InstallationNotifier: InstallerUi.started threw exception", t);
            }
        }
    }

    /**
     * Set SifNotifier to be used.
     */
    public void setSifNotifier(SifNotifier aSifNotifier)
    {
        iSifNotifier = aSifNotifier;
    }

    /**
     * Execution engine calls started() method to tell that
     * engine has been started.
     */
    public void started()
    {
        Log.log("InstallationNotifier.started");
        iStarted = true;
        if (iInstallerUi != null)
        {
            // Call setInstallerUi() which calls InstallerUi.started().
            setInstallerUi(iInstallerUi);
        }
    }

    /**
     * Execution engine calls ended() method to tell that
     * engine execution has ended.
     */
    public void ended()
    {
        Log.log("InstallationNotifier.ended");
        if (iInstallerUi != null)
        {
            try
            {
                iInstallerUi.ended();
            }
            catch (Throwable t)
            {
                Log.logError(
                    "InstallationNotifier: InstallerUi.ended threw exception", t);
            }
        }
        if (iSifNotifier != null)
        {
            // After this SifNotifier is no longer used, destroy it.
            try
            {
                iSifNotifier.destroy();
                iSifNotifier = null;
            }
            catch (Throwable t)
            {
                Log.logError("InstallationNotifier: SifNotifier.destroy failed", t);
            }
        }
    }

    /**
     * Execution engine calls error() method to tell that
     * an exception has been thrown during engine execution.
     * Even if error() gets called, the engine will still call
     * ended() in the end.
     */
    public void error(Exception aException)
    {
        Log.log("InstallationNotifier.error: " + aException);
        InstallerExceptionBase installerException = null;
        if (aException instanceof InstallerExceptionBase)
        {
            installerException = (InstallerExceptionBase)aException;
        }
        else
        {
            Log.logError(
                "InstallationNotifier.error: Unexpected exception type",
                aException);
            installerException = InstallerException.getInternalErrorException(
                                     aException.toString(), aException);
        }
        if (iInstallerUi != null && installerException != null)
        {
            try
            {
                iInstallerUi.error(installerException);
            }
            catch (Throwable t)
            {
                Log.logError(
                    "InstallationNotifier: InstallerUi.error threw exception", t);
            }
        }
    }

    /**
     * Execution engine calls setMax() method to tell what is the
     * maximum progress indicator value. This method is called once
     * before execution steps are executed. Between each execution
     * step set() method gets called to indicate execution progress.
     * @param maxValue maximum progress indicator value
     */
    public void setMax(int aMaxValue)
    {
        iMaxValue = aMaxValue;
        iPropertyProgressStep = iMaxValue / MAX_PROPERTY_PROGRESS_UPDATES;
        if (iPropertyProgressStep == 0)
        {
            iPropertyProgressStep = 1;
        }
        iUiProgressStep = iMaxValue / MAX_UI_PROGRESS_UPDATES;
        if (iUiProgressStep == 0)
        {
            iUiProgressStep = 1;
        }
    }

    /**
     * Returns maximum progress indicator value.
     */
    public int getMax()
    {
        return iMaxValue;
    }

    /**
     * Execution engine calls set() method between each execution
     * step to indicate execution progress. When all steps are
     * execeuted progress value increases to limit told with
     * setMax() method.
     * @param currentValue current progress indicator value
     */
    public void set(int aCurrentValue)
    {
        if (iMaxValueReached)
        {
            // Ignore possible calls that are made after progress has
            // reached maximum value.
            return;
        }
        if (aCurrentValue >= iMaxValue)
        {
            iMaxValueReached = true;
        }
        int currentPercentage = (aCurrentValue * 100) / iMaxValue;
        Log.log("InstallationNotifier.set: progress " + currentPercentage);
        defineProperties();

        if (aCurrentValue == 0 ||
                aCurrentValue == iMaxValue ||
                aCurrentValue >= iLastPropertyUpdate + iPropertyProgressStep ||
                aCurrentValue <= iLastPropertyUpdate - iPropertyProgressStep)
        {
            iLastPropertyUpdate = aCurrentValue;
            Log.log("InstallationNotifier.set: update property to " +
                    currentPercentage);
            // Update property values: progress.
            SysUtil.setPropertyValue
            (SysUtil.PROP_CATEGORY_SYSTEM,
             SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_PROGRESS,
             currentPercentage);
        }

        if (aCurrentValue == 0 ||
                aCurrentValue == iMaxValue ||
                aCurrentValue >= iLastUiUpdate + iUiProgressStep ||
                aCurrentValue <= iLastUiUpdate - iUiProgressStep)
        {
            iLastUiUpdate = aCurrentValue;
            if (iInstallerUi != null)
            {
                Log.log("InstallationNotifier.set: update ui to " +
                        currentPercentage);
                try
                {
                    iInstallerUi.updateProgress(currentPercentage);
                }
                catch (Throwable t)
                {
                    Log.logError(
                        "InstallationNotifier: InstallerUi.updateProgress threw exception", t);
                }
            }
            if (iSifNotifier != null)
            {
                Log.log("InstallationNotifier.set: update SifNotifier to " +
                        currentPercentage);
                try
                {
                    iSifNotifier.notifyProgress(
                        iSifNotifier.SUB_OP_NO, currentPercentage, 100);
                }
                catch (Throwable t)
                {
                    Log.logError(
                        "InstallationNotifier: SifNotifier.notifyProgress threw exception", t);
                }
            }
        }
    }

    /**
     * This method is called from execution steps to notify
     * that installation or uninstallation
     * is about to start.
     * @param aState installation/uninstallation state
     */
    public void start(int aState)
    {
        Log.log("InstallationNotifier.start: state=" + aState);
        defineProperties();

        // Update property values: uid=0, state.
        SysUtil.setPropertyValue(SysUtil.PROP_CATEGORY_SYSTEM,
                                 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION, 0);
        SysUtil.setPropertyValue(SysUtil.PROP_CATEGORY_SYSTEM,
                                 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_STATE, aState);
    }

    /**
     * This method is called from execution steps to notify
     * that installation or uninstallation is finished.
     * @param aUid uid of the installed/uinstalled application suite
     * @param aState installation/uninstallation state
     */
    public void finish(Uid aUid, int aState)
    {
        Log.log("InstallationNotifier.finish: uid=" + aUid +
                ", state=" + aState);

        // Update property values: uid, state.
        SysUtil.setPropertyValue(SysUtil.PROP_CATEGORY_SYSTEM,
                                 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION, aUid);
        SysUtil.setPropertyValue(SysUtil.PROP_CATEGORY_SYSTEM,
                                 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_STATE, aState);
    }

    /**
     * Define the properties InstallationNotifier updates.
     * This method does not define properties again if this
     * JavaInstaller instance has already defined them.
     */
    static void defineProperties()
    {
        if (!iPropertiesDefined)
        {
            // Define properties to be updated.
            SysUtil.defineProperty(SysUtil.PROP_CATEGORY_SYSTEM,
                                   SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION);
            SysUtil.defineProperty(SysUtil.PROP_CATEGORY_SYSTEM,
                                   SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_PROGRESS);
            SysUtil.defineProperty(SysUtil.PROP_CATEGORY_SYSTEM,
                                   SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_STATE);
            iPropertiesDefined = true;
            Log.log("InstallationNotifier: properties defined");
        }
    }

    /**
     * Delete the properties InstallationNotifier updates.
     */
    static void deleteProperties()
    {
        deleteProperty(SysUtil.PROP_CATEGORY_SYSTEM,
                       SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION);
        deleteProperty(SysUtil.PROP_CATEGORY_SYSTEM,
                       SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_PROGRESS);
        deleteProperty(SysUtil.PROP_CATEGORY_SYSTEM,
                       SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_STATE);
        Log.log("InstallationNotifier: properties deleted");
    }

    /**
     * Unregisters specified property.
     */
    private static void deleteProperty(Uid aCategory, long aKey)
    {
        try
        {
            SysUtil.deleteProperty(aCategory, aKey);
            Log.log("Deleted property: Uid: " + aCategory +
                    ", key: 0x" + Long.toString(aKey, 16));
        }
        catch (Exception ex)
        {
            Log.logError(
                "InstallationNotifier: Deleting property failed", ex);
        }
    }
}