--- 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);
+
}