javamanager/javainstaller/installer/javasrc.s60/com/nokia/mj/impl/installer/applicationregistrator/SifNotifier.java
branchRCL_3
changeset 77 7cee158cb8cd
parent 60 6c158198356e
child 83 26b2b12093af
--- a/javamanager/javainstaller/installer/javasrc.s60/com/nokia/mj/impl/installer/applicationregistrator/SifNotifier.java	Tue Sep 14 21:06:50 2010 +0300
+++ b/javamanager/javainstaller/installer/javasrc.s60/com/nokia/mj/impl/installer/applicationregistrator/SifNotifier.java	Wed Sep 15 12:05:25 2010 +0300
@@ -18,8 +18,11 @@
 
 package com.nokia.mj.impl.installer.applicationregistrator;
 
+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.PropertyListener;
+import com.nokia.mj.impl.installer.utils.PropertyProvider;
 
 /**
  * Sends installation and uninstallation progress notifications
@@ -28,24 +31,26 @@
 public final class SifNotifier
 {
     /** Install operation. */
-    public static final int OP_INSTALL = 1;
+    public static final int OP_INSTALL = 1; // TSifOperationPhase::EInstalling
     /** Uninstall operation. */
-    public static final int OP_UNINSTALL = 2;
+    public static final int OP_UNINSTALL = 2; // TSifOperationPhase::EUninstalling
     /** Update operation. */
-    public static final int OP_UPDATE = 3;
+    public static final int OP_UPDATE = 3; // TSifOperationPhase::EUpgrading
 
-    /** Indicates installaion or uninstallation without
+    /** Indicates installation or uninstallation without
         specific suboperation. */
-    public static final int SUB_OP_NO = 1;
+    public static final int SUB_OP_NO = 1; // TSifOperationSubPhase::ENoSubPhase
     /** OCSP phase during installation. */
-    public static final int SUB_OP_OCSP = 2;
+    public static final int SUB_OP_OCSP = 2; // TSifOperationSubPhase::EOCSPCheck
     /** Download phase during installation. */
-    public static final int SUB_OP_DOWNLOAD = 3;
+    public static final int SUB_OP_DOWNLOAD = 3; // TSifOperationSubPhase::EDownload
     /** Maximum progress notification value. */
     private static final int MAX_PROGRESS = 100;
 
     /** Operation being notified. */
     private int iOperation = 0;
+    /** Suboperation during installation. */
+    private int iSubOperation = 0;
     /** Global component id for the application. */
     private String iGlobalComponentId = null;
     /** Component name (i.e. suite name). */
@@ -64,11 +69,26 @@
     /** Sending progress notifications is only allowed between start
      *  and end notifications. */
     private boolean iNotifyProgressAllowed = false;
-    /** Value of the last progress notification that has been sent. */
+    /**
+     * Value of the last progress notification that has been sent with
+     * SUB_OP_NO suboperation.
+     */
     private int iLastProgressSent = 0;
+    /** Current value of the last progress notification that has been sent. */
+    private int iCurrentValue = 0;
+    /** total value of the last progress notification that has been sent. */
+    private int iTotalValue = 0;
 
-    /** Native object handle. */
+    /** Native notifier object handle. */
     private int iHandle = 0;
+    /** Native indicator object handle. */
+    private int iIndicatorHandle = 0;
+    /** InstallerUi handle. */
+    private InstallerUi iInstallerUi = null;
+    /** Provider for indicator status events. */
+    private PropertyProvider iIndicatorStatusProvider = null;
+    /** Indicator state. */
+    private int iIndicatorState = -1;
 
     /*** ----------------------------- PUBLIC ------------------------------ */
 
@@ -81,6 +101,164 @@
     }
 
     /**
+     * Set InstallerUi used when handling indicator.
+     */
+    public void setInstallerUi(InstallerUi aInstallerUi)
+    {
+        iInstallerUi = aInstallerUi;
+    }
+
+    /**
+     * Activates and updates indicator which displays installation
+     * progress to user while installer UI is hidden. The notifyStart
+     * and notifyProgress methods must be called at least once before
+     * calling this method.
+     */
+    public void activateIndicator()
+    {
+        if (iInstallerUi == null)
+        {
+            return;
+        }
+
+        if (iIndicatorHandle == 0)
+        {
+            int ret = _initIndicator();
+            if (ret < 0)
+            {
+                Log.logError(
+                    "Initializing SifNotifier indicator failed with code " +
+                    ret);
+            }
+            else
+            {
+                Log.log("SifNotifier indicator created");
+            }
+            iIndicatorHandle = ret;
+        }
+
+        if (iIndicatorHandle == 0)
+        {
+            return;
+        }
+
+        int phase = 0;
+        switch (iSubOperation)
+        {
+        case SUB_OP_OCSP: phase = 2; break; // TInstallingPhase::ECheckingCerts
+        case SUB_OP_DOWNLOAD: phase = 1; break; // TInstallingPhase::EDownloading
+        default: phase = 0; // TInstallingPhase::EInstalling
+        }
+        int progress = (iTotalValue == 0? 0: iCurrentValue*100/iTotalValue);
+        updateIndicator(iComponentName, phase, progress);
+
+        if (iIndicatorStatusProvider == null)
+        {
+            // Create PropertyListener which listens indicator status events
+            // and unhides UI when necessary.
+            final int indicatorCategory = 0x20022FC5; // sifuiinstallindicatorplugin
+            final int indicatorKey = 0x2002E690; // /SifUiInstallIndicator/Status
+            iIndicatorStatusProvider = new PropertyProvider();
+            iIndicatorStatusProvider.subscribe(
+                indicatorCategory, indicatorKey, new PropertyListener()
+                {
+                    public void valueChanged(int aCategory, int aKey, int aValue)
+                    {
+                        Log.log("SifNotifier indicator status " + aValue +
+                                " (category=" + aCategory + ", key=" + aKey + ")");
+                        iIndicatorState = aValue;
+                        if (iIndicatorState == 0)
+                        {
+                            // Indicator has been closed, unhide the UI.
+                            iInstallerUi.hide(false);
+                        }
+                    }
+                });
+            Log.log("SifNotifier indicator status provider subscribed");
+        }
+    }
+
+    /**
+     * Updates indicator which displays installation progress to user
+     * while installer UI is hidden. The activateindicator method must
+     * be called before calling this method.
+     */
+    public void updateIndicator(String aName, int aPhase, int aProgress)
+    {
+        if (iInstallerUi == null || iIndicatorHandle == 0)
+        {
+            return;
+        }
+
+        final String name = aName;
+        final int phase = aPhase;
+        final int progress = aProgress;
+        iInstallerUi.syncExec(new Runnable()
+        {
+            // Indicator must be updated from UI thread.
+            public void run()
+            {
+                int ret = _updateIndicator(
+                    iIndicatorHandle, name, phase, progress);
+                if (ret < 0)
+                {
+                    Log.logError(
+                        "Updating SifNotifier indicator failed with code " +
+                        ret);
+                }
+                else
+                {
+                    Log.log("SifNotifier indicator updated: " + name +
+                            ", " + phase + ", " + progress + "%");
+                }
+            }
+        });
+    }
+
+    /**
+     * Deactivates indicator which displays installation
+     * progress to user while installer UI is hidden.
+     */
+    public void deactivateIndicator()
+    {
+        if (iIndicatorStatusProvider != null)
+        {
+            iIndicatorStatusProvider.unsubscribe();
+            iIndicatorStatusProvider = null;
+            Log.log("SifNotifier indicator status provider unsubscribed");
+        }
+
+        if (iInstallerUi == null)
+        {
+            return;
+        }
+
+        iInstallerUi.syncExec(new Runnable()
+        {
+            // Indicator must be deactivated from UI thread.
+            public void run()
+            {
+                if (iIndicatorHandle == 0)
+                {
+                    return;
+                }
+                int ret = _destroyIndicator(iIndicatorHandle, iIndicatorState);
+                if (ret < 0)
+                {
+                    Log.logError(
+                        "Destroying SifNotifier indicator failed with code " +
+                        ret);
+                }
+                else
+                {
+                    Log.log("SifNotifier indicator destroyed");
+                }
+                iIndicatorHandle = 0;
+            }
+        });
+    }
+
+    /**
      * Returns true if SIF progress notifications are enabled, false otherwise.
      */
     public static boolean enabled()
@@ -109,7 +287,7 @@
 
         checkHandle();
         int ret = _notifyStart(
-                      iHandle, aGlobalComponentId, aComponentName,
+                      iHandle, aOperation, aGlobalComponentId, aComponentName,
                       aApplicationNames, aApplicationIcons,
                       aComponentSize, aIconDir, aComponentIcon);
         if (ret < 0)
@@ -176,6 +354,16 @@
         {
             return;
         }
+
+        iSubOperation = aSubOperation;
+        iCurrentValue = aCurrent;
+        iTotalValue = aTotal;
+        if (iIndicatorHandle != 0)
+        {
+            // Call activateIndicator so that indicator gets updated.
+            activateIndicator();
+        }
+
         checkHandle();
         if (aSubOperation == SUB_OP_NO)
         {
@@ -209,6 +397,7 @@
      */
     public void destroy()
     {
+        deactivateIndicator();
         checkHandle();
         int ret = _destroy(iHandle);
         if (ret < 0)
@@ -309,6 +498,7 @@
      * Notifies SIF about installation/uinstallation start.
      *
      * @param aHandle
+     * @param aOperation
      * @param aGlobalComponentId
      * @param aComponentName
      * @param aApplicationNames
@@ -320,9 +510,10 @@
      * otherwise 0
      */
     private static native int _notifyStart(
-        int aHandle, String aGlobalComponentId, String aComponentName,
-        String[] aApplicationNames, String[] aApplicationIcons,
-        int aComponentSize, String aIconDir, String aComponentIcon);
+        int aHandle, int aOperation, String aGlobalComponentId,
+        String aComponentName, String[] aApplicationNames,
+        String[] aApplicationIcons, int aComponentSize,
+        String aIconDir, String aComponentIcon);
 
     /**
      * Notifies SIF about installation/uinstallation completion.
@@ -362,7 +553,7 @@
      * other methods are called.
      *
      * @return Symbian error code (negative number) if operation fails,
-     * otherwise handle to the natie side object
+     * otherwise handle to the native side object
      */
     private static native int _init();
 
@@ -376,4 +567,35 @@
      */
     private static native int _destroy(int aHandle);
 
+    /**
+     * Initializes SifNotifier indicator.
+     *
+     * @return Symbian error code (negative number) if operation fails,
+     * otherwise handle to the native side object
+     */
+    private static native int _initIndicator();
+
+    /**
+     * Updates SifNotifier indicator.
+     *
+     * @param aHandle handle to indicator object
+     * @param aName application name
+     * @param aPhase operation phase
+     * @param aProgress progress in percentage
+     * @return Symbian error code (negative number) if operation fails,
+     * otherwise handle to the native side object
+     */
+    private static native int _updateIndicator(
+        int aHandle, String aName, int aPhase, int aProgress);
+
+    /**
+     * Destroys SifNotifier indicator.
+     *
+     * @param aHandle handle to indicator object
+     * @param aState indicator state
+     * @return Symbian error code (negative number) if operation fails,
+     * otherwise 0
+     */
+    private static native int _destroyIndicator(int aHandle, int aState);
+
 }