|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 package com.nokia.mj.impl.installer; |
|
20 |
|
21 import com.nokia.mj.impl.installer.applicationregistrator.SifNotifier; |
|
22 import com.nokia.mj.impl.installer.exetable.ExeProgressListener; |
|
23 import com.nokia.mj.impl.installer.ui.InstallerUi; |
|
24 import com.nokia.mj.impl.installer.utils.InstallerException; |
|
25 import com.nokia.mj.impl.installer.utils.Log; |
|
26 import com.nokia.mj.impl.installer.utils.SysUtil; |
|
27 import com.nokia.mj.impl.utils.InstallerDetailedErrorMessage; |
|
28 import com.nokia.mj.impl.utils.InstallerErrorMessage; |
|
29 import com.nokia.mj.impl.utils.OtaStatusCode; |
|
30 import com.nokia.mj.impl.utils.Uid; |
|
31 import com.nokia.mj.impl.utils.exception.InstallerExceptionBase; |
|
32 |
|
33 /** |
|
34 * InstallationNotifier notifies interested parties about Java |
|
35 * application installation progress. |
|
36 */ |
|
37 public class InstallationNotifier implements ExeProgressListener |
|
38 { |
|
39 // Installation states |
|
40 public static final int INSTALLING = 0x100; |
|
41 public static final int INSTALL_OK = 0x101; |
|
42 public static final int INSTALL_FAIL = 0x102; |
|
43 public static final int UNINSTALLING = 0x200; |
|
44 public static final int UNINSTALL_OK = 0x201; |
|
45 public static final int UNINSTALL_FAIL = 0x202; |
|
46 |
|
47 // Maximum number of progress updates to SysUtil.setProperty(). |
|
48 private static final int MAX_PROPERTY_PROGRESS_UPDATES = 5; |
|
49 // Maximum number of progress updates to UI. |
|
50 private static final int MAX_UI_PROGRESS_UPDATES = 20; |
|
51 |
|
52 // Flag telling if the properties are already defined. |
|
53 private static boolean iPropertiesDefined = false; |
|
54 |
|
55 // InstallerUI instance. |
|
56 private InstallerUi iInstallerUi = null; |
|
57 // SifNotifier instance. |
|
58 private SifNotifier iSifNotifier = null; |
|
59 |
|
60 // Maximum progress value. |
|
61 private int iMaxValue = 1; |
|
62 // Tells how often property progress should be updated. |
|
63 private int iPropertyProgressStep = 1; |
|
64 // Tells how often UI progress should be updated. |
|
65 private int iUiProgressStep = 1; |
|
66 // Point between 0 and iMaxValue where the last property |
|
67 // update has been made. |
|
68 private int iLastPropertyUpdate = 0; |
|
69 // Point between 0 and iMaxValue where the last UI update |
|
70 // has been made. |
|
71 private int iLastUiUpdate = 0; |
|
72 // Flag telling if the started() method has been called. |
|
73 private boolean iStarted = false; |
|
74 // Flag telling if the progress maximum value has been reached. |
|
75 private boolean iMaxValueReached = false; |
|
76 |
|
77 /** |
|
78 * Set InstallerUi to be used. |
|
79 */ |
|
80 public void setInstallerUi(InstallerUi aUi) |
|
81 { |
|
82 iInstallerUi = aUi; |
|
83 if (iStarted && iInstallerUi != null) |
|
84 { |
|
85 // Notify InstallerUi that execution has been started. |
|
86 try |
|
87 { |
|
88 iInstallerUi.started(); |
|
89 } |
|
90 catch (Throwable t) |
|
91 { |
|
92 Log.logError("InstallerUi.started threw exception", t); |
|
93 } |
|
94 } |
|
95 } |
|
96 |
|
97 /** |
|
98 * Set SifNotifier to be used. |
|
99 */ |
|
100 public void setSifNotifier(SifNotifier aSifNotifier) |
|
101 { |
|
102 iSifNotifier = aSifNotifier; |
|
103 } |
|
104 |
|
105 /** |
|
106 * Execution engine calls started() method to tell that |
|
107 * engine has been started. |
|
108 */ |
|
109 public void started() |
|
110 { |
|
111 Log.log("InstallationNotifier.started"); |
|
112 iStarted = true; |
|
113 if (iInstallerUi != null) |
|
114 { |
|
115 // Call setInstallerUi() which calls InstallerUi.started(). |
|
116 setInstallerUi(iInstallerUi); |
|
117 } |
|
118 } |
|
119 |
|
120 /** |
|
121 * Execution engine calls ended() method to tell that |
|
122 * engine execution has ended. |
|
123 */ |
|
124 public void ended() |
|
125 { |
|
126 Log.log("InstallationNotifier.ended"); |
|
127 if (iInstallerUi != null) |
|
128 { |
|
129 try |
|
130 { |
|
131 iInstallerUi.ended(); |
|
132 } |
|
133 catch (Throwable t) |
|
134 { |
|
135 Log.logError("InstallerUi.ended threw exception", t); |
|
136 } |
|
137 } |
|
138 if (iSifNotifier != null) |
|
139 { |
|
140 // After this SifNotifier is no longer used, destroy it. |
|
141 try |
|
142 { |
|
143 iSifNotifier.destroy(); |
|
144 iSifNotifier = null; |
|
145 } |
|
146 catch (Throwable t) |
|
147 { |
|
148 Log.logError("InstallationNotifier: SifNotifier.destroy failed", t); |
|
149 } |
|
150 } |
|
151 } |
|
152 |
|
153 /** |
|
154 * Execution engine calls error() method to tell that |
|
155 * an exception has been thrown during engine execution. |
|
156 * Even if error() gets called, the engine will still call |
|
157 * ended() in the end. |
|
158 */ |
|
159 public void error(Exception aException) |
|
160 { |
|
161 Log.log("InstallationNotifier.error: " + aException); |
|
162 InstallerExceptionBase installerException = null; |
|
163 if (aException instanceof InstallerExceptionBase) |
|
164 { |
|
165 installerException = (InstallerExceptionBase)aException; |
|
166 } |
|
167 else |
|
168 { |
|
169 Log.logError( |
|
170 "InstallationNotifier.error: Unexpected exception type", |
|
171 aException); |
|
172 installerException = InstallerException.getInternalErrorException( |
|
173 aException.toString(), aException); |
|
174 } |
|
175 if (iInstallerUi != null && installerException != null) |
|
176 { |
|
177 try |
|
178 { |
|
179 iInstallerUi.error(installerException); |
|
180 } |
|
181 catch (Throwable t) |
|
182 { |
|
183 Log.logError("InstallerUi.error threw exception", t); |
|
184 } |
|
185 } |
|
186 } |
|
187 |
|
188 /** |
|
189 * Execution engine calls setMax() method to tell what is the |
|
190 * maximum progress indicator value. This method is called once |
|
191 * before execution steps are executed. Between each execution |
|
192 * step set() method gets called to indicate execution progress. |
|
193 * @param maxValue maximum progress indicator value |
|
194 */ |
|
195 public void setMax(int aMaxValue) |
|
196 { |
|
197 iMaxValue = aMaxValue; |
|
198 iPropertyProgressStep = iMaxValue / MAX_PROPERTY_PROGRESS_UPDATES; |
|
199 if (iPropertyProgressStep == 0) |
|
200 { |
|
201 iPropertyProgressStep = 1; |
|
202 } |
|
203 iUiProgressStep = iMaxValue / MAX_UI_PROGRESS_UPDATES; |
|
204 if (iUiProgressStep == 0) |
|
205 { |
|
206 iUiProgressStep = 1; |
|
207 } |
|
208 } |
|
209 |
|
210 /** |
|
211 * Returns maximum progress indicator value. |
|
212 */ |
|
213 public int getMax() |
|
214 { |
|
215 return iMaxValue; |
|
216 } |
|
217 |
|
218 /** |
|
219 * Execution engine calls set() method between each execution |
|
220 * step to indicate execution progress. When all steps are |
|
221 * execeuted progress value increases to limit told with |
|
222 * setMax() method. |
|
223 * @param currentValue current progress indicator value |
|
224 */ |
|
225 public void set(int aCurrentValue) |
|
226 { |
|
227 if (iMaxValueReached) |
|
228 { |
|
229 // Ignore possible calls that are made after progress has |
|
230 // reached maximum value. |
|
231 return; |
|
232 } |
|
233 if (aCurrentValue >= iMaxValue) |
|
234 { |
|
235 iMaxValueReached = true; |
|
236 } |
|
237 int currentPercentage = (aCurrentValue * 100) / iMaxValue; |
|
238 Log.log("InstallationNotifier.set: progress " + currentPercentage); |
|
239 defineProperties(); |
|
240 |
|
241 if (aCurrentValue == 0 || |
|
242 aCurrentValue == iMaxValue || |
|
243 aCurrentValue >= iLastPropertyUpdate + iPropertyProgressStep || |
|
244 aCurrentValue <= iLastPropertyUpdate - iPropertyProgressStep) |
|
245 { |
|
246 iLastPropertyUpdate = aCurrentValue; |
|
247 Log.log("InstallationNotifier.set: update property to " + |
|
248 currentPercentage); |
|
249 // Update property values: progress. |
|
250 SysUtil.setPropertyValue |
|
251 (SysUtil.PROP_CATEGORY_SYSTEM, |
|
252 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_PROGRESS, |
|
253 currentPercentage); |
|
254 } |
|
255 |
|
256 if (aCurrentValue == 0 || |
|
257 aCurrentValue == iMaxValue || |
|
258 aCurrentValue >= iLastUiUpdate + iUiProgressStep || |
|
259 aCurrentValue <= iLastUiUpdate - iUiProgressStep) |
|
260 { |
|
261 iLastUiUpdate = aCurrentValue; |
|
262 if (iInstallerUi != null) |
|
263 { |
|
264 Log.log("InstallationNotifier.set: update ui to " + |
|
265 currentPercentage); |
|
266 try |
|
267 { |
|
268 iInstallerUi.updateProgress(currentPercentage); |
|
269 } |
|
270 catch (Throwable t) |
|
271 { |
|
272 Log.logError("InstallerUi.updateProgress threw exception", t); |
|
273 } |
|
274 } |
|
275 if (iSifNotifier != null) |
|
276 { |
|
277 Log.log("InstallationNotifier.set: update SifNotifier to " + |
|
278 currentPercentage); |
|
279 try |
|
280 { |
|
281 iSifNotifier.notifyProgress( |
|
282 iSifNotifier.SUB_OP_NO, currentPercentage, 100); |
|
283 } |
|
284 catch (Throwable t) |
|
285 { |
|
286 Log.logError("SifNotifier.notifyProgress threw exception", t); |
|
287 } |
|
288 } |
|
289 } |
|
290 } |
|
291 |
|
292 /** |
|
293 * This method is called from execution steps to notify |
|
294 * that installation or uninstallation |
|
295 * is about to start. |
|
296 * @param aState installation/uninstallation state |
|
297 */ |
|
298 public void start(int aState) |
|
299 { |
|
300 Log.log("InstallationNotifier.start: state=" + aState); |
|
301 defineProperties(); |
|
302 |
|
303 // Update property values: uid=0, state. |
|
304 SysUtil.setPropertyValue(SysUtil.PROP_CATEGORY_SYSTEM, |
|
305 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION, 0); |
|
306 SysUtil.setPropertyValue(SysUtil.PROP_CATEGORY_SYSTEM, |
|
307 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_STATE, aState); |
|
308 } |
|
309 |
|
310 /** |
|
311 * This method is called from execution steps to notify |
|
312 * that installation or uninstallation is finished. |
|
313 * @param aUid uid of the installed/uinstalled application suite |
|
314 * @param aState installation/uninstallation state |
|
315 */ |
|
316 public void finish(Uid aUid, int aState) |
|
317 { |
|
318 Log.log("InstallationNotifier.finish: uid=" + aUid + |
|
319 ", state=" + aState); |
|
320 |
|
321 // Update property values: uid, state. |
|
322 SysUtil.setPropertyValue(SysUtil.PROP_CATEGORY_SYSTEM, |
|
323 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION, aUid); |
|
324 SysUtil.setPropertyValue(SysUtil.PROP_CATEGORY_SYSTEM, |
|
325 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_STATE, aState); |
|
326 } |
|
327 |
|
328 /** |
|
329 * Define the properties InstallationNotifier updates. |
|
330 * This method does not define properties again if this |
|
331 * JavaInstaller instance has already defined them. |
|
332 */ |
|
333 static void defineProperties() |
|
334 { |
|
335 if (!iPropertiesDefined) |
|
336 { |
|
337 // Define properties to be updated. |
|
338 SysUtil.defineProperty(SysUtil.PROP_CATEGORY_SYSTEM, |
|
339 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION); |
|
340 SysUtil.defineProperty(SysUtil.PROP_CATEGORY_SYSTEM, |
|
341 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_PROGRESS); |
|
342 SysUtil.defineProperty(SysUtil.PROP_CATEGORY_SYSTEM, |
|
343 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_STATE); |
|
344 iPropertiesDefined = true; |
|
345 Log.log("InstallationNotifier: properties defined"); |
|
346 } |
|
347 } |
|
348 |
|
349 /** |
|
350 * Delete the properties InstallationNotifier updates. |
|
351 */ |
|
352 static void deleteProperties() |
|
353 { |
|
354 deleteProperty(SysUtil.PROP_CATEGORY_SYSTEM, |
|
355 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION); |
|
356 deleteProperty(SysUtil.PROP_CATEGORY_SYSTEM, |
|
357 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_PROGRESS); |
|
358 deleteProperty(SysUtil.PROP_CATEGORY_SYSTEM, |
|
359 SysUtil.PROP_KEY_JAVA_LATEST_INSTALLATION_STATE); |
|
360 Log.log("InstallationNotifier: properties deleted"); |
|
361 } |
|
362 |
|
363 /** |
|
364 * Unregisters specified property. |
|
365 */ |
|
366 private static void deleteProperty(Uid aCategory, long aKey) |
|
367 { |
|
368 try |
|
369 { |
|
370 SysUtil.deleteProperty(aCategory, aKey); |
|
371 Log.log("Deleted property: Uid: " + aCategory + |
|
372 ", key: 0x" + Long.toString(aKey, 16)); |
|
373 } |
|
374 catch (Exception ex) |
|
375 { |
|
376 Log.logError("Deleting property failed", ex); |
|
377 } |
|
378 } |
|
379 } |