|
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.midp2.install.steps; |
|
20 |
|
21 |
|
22 import com.nokia.mj.impl.installer.applicationregistrator.ApplicationRegistrator; |
|
23 import com.nokia.mj.impl.installer.exetable.ExeBall; |
|
24 import com.nokia.mj.impl.installer.exetable.ExeStep; |
|
25 import com.nokia.mj.impl.installer.storagehandler.ApplicationInfo; |
|
26 import com.nokia.mj.impl.installer.storagehandler.SuiteInfo; |
|
27 import com.nokia.mj.impl.installer.utils.FileUtils; |
|
28 import com.nokia.mj.impl.installer.utils.InstallerException; |
|
29 |
|
30 import com.nokia.mj.impl.utils.Uid; |
|
31 |
|
32 import java.util.Vector; |
|
33 |
|
34 /** |
|
35 * MIDP installation step ConvertIcons. |
|
36 * |
|
37 * This step is called two times. |
|
38 * |
|
39 * First call happens after the confirmation UI dialog |
|
40 * is shown to the user. If .jar file is already available (local installation), |
|
41 * converts the suite icon and the application icons and stores them to temp |
|
42 * place inside Integrity Server session. If .jar is not yet present, |
|
43 * sets the path to the default icon (either .svg or if the device does not |
|
44 * support .svg, then .mbm in S60, .png in Linux) to suite icon and |
|
45 * application icons. |
|
46 * |
|
47 * Second call happens before AuthenticateJar step. |
|
48 * If new .jar file was downloaded after first call and contains icons |
|
49 * used as application icons, converts the icons and stores them to temp |
|
50 * place inside Integrity Server session. |
|
51 * Otherwise if default icons are used copies the default icons |
|
52 * to temp place with an unique name inside Integrity Server session and |
|
53 * sets path to the converted and renamed icon to suite and application |
|
54 * icons. [This must be done in S60 because icon cannot be registered |
|
55 * into AppArc unless it can be opened in write mode and it has unique name.] |
|
56 * |
|
57 * @author Nokia Corporation |
|
58 * @version $Rev: 2259 $ $Date: 2008-09-19 12:27:49 +0300 (Fri, 19 Sep 2008) $ |
|
59 */ |
|
60 public class ConvertIcons extends ExeStep |
|
61 { |
|
62 private boolean iSecondCall = false; |
|
63 |
|
64 public void execute(ExeBall aBall) |
|
65 { |
|
66 InstallBall ball = (InstallBall)aBall; |
|
67 boolean fileOpResult = true; |
|
68 |
|
69 if (iSecondCall) |
|
70 { |
|
71 ball.log("Finalising icon information ..."); |
|
72 |
|
73 // If .jar file has been downloaded since the first call |
|
74 // of this method OR |
|
75 // if this installation is silent installation, |
|
76 // convert the icons in the .jar now |
|
77 if (ball.iDownloadSucceeded || ball.isSilent()) |
|
78 { |
|
79 convertIconsInJar(ball); |
|
80 } |
|
81 |
|
82 // In any case, all default application icons |
|
83 // must be copied to uniquely named files so that |
|
84 // they can be registered in S60 and uninstalling one |
|
85 // application does not remove icons from all applications |
|
86 // using the default icon |
|
87 String defaultIcon = ball.iApplicationRegistrator.getDefaultIconPath(); |
|
88 String newName; |
|
89 Vector newApps = ball.iSuite.getApplications(); |
|
90 |
|
91 // Handle application icons |
|
92 for (int i = 0; i < newApps.size(); i++) |
|
93 { |
|
94 ApplicationInfo newApp = (ApplicationInfo)newApps.elementAt(i); |
|
95 |
|
96 if (newApp.getConvertedIconPath().equals(defaultIcon)) |
|
97 { |
|
98 // also the suffix of the file must be set to correct |
|
99 newName = |
|
100 FileUtils.getIntegrityServiceRoot() + |
|
101 newApp.getUid().getStringValue() + |
|
102 "_icon" + |
|
103 ball.iApplicationRegistrator.getDefaultIconSuffix(); |
|
104 |
|
105 fileOpResult = ball.iIntegrityService.copy(defaultIcon, newName); |
|
106 if (!fileOpResult) |
|
107 { |
|
108 InstallerException.internalError( |
|
109 "Copying file " + defaultIcon + " to " + newName + " failed."); |
|
110 } |
|
111 |
|
112 newApp.setConvertedIconPath(newName); |
|
113 } |
|
114 } |
|
115 } |
|
116 else |
|
117 { |
|
118 ball.log("Setting preliminary icon information ..."); |
|
119 |
|
120 if (ball.isSilent()) |
|
121 { |
|
122 // No icons will to be shown to the user, |
|
123 // no need to do anything yet |
|
124 iSecondCall = true; |
|
125 return; |
|
126 } |
|
127 |
|
128 // Ask javainstalllauncher to stop displaying |
|
129 // 'Preparing installation' dialog. |
|
130 ball.iApplicationRegistrator.notifyLauncherThatUiIsReady(); |
|
131 |
|
132 convertIconsInJar(ball); |
|
133 |
|
134 iSecondCall = true; |
|
135 } |
|
136 |
|
137 } // end of execute method |
|
138 |
|
139 |
|
140 public void cancel(ExeBall aBall) |
|
141 { |
|
142 // nop |
|
143 } |
|
144 |
|
145 /** |
|
146 * Convert the icons in the .jar file if any. |
|
147 * Otherwise set default icon to suite icon and |
|
148 * application icons. |
|
149 * |
|
150 * @throws InstallerException if the icon file cannot be |
|
151 * renamed so that it would have correct suffix |
|
152 */ |
|
153 protected void convertIconsInJar(InstallBall ball) |
|
154 { |
|
155 String defaultIcon = ball.iApplicationRegistrator.getDefaultIconPath(); |
|
156 Vector newApps = ball.iSuite.getApplications(); |
|
157 boolean fileOpResult = true; |
|
158 |
|
159 // If .jar file is not available, use default icon. |
|
160 if (ball.iJarFilename == null) |
|
161 { |
|
162 // Set suite icon |
|
163 ball.iSuite.setConvertedIconPath(defaultIcon); |
|
164 |
|
165 // Set application icons |
|
166 for (int i = 0; i < newApps.size(); i++) |
|
167 { |
|
168 ((ApplicationInfo)newApps.elementAt(i)).setConvertedIconPath( |
|
169 defaultIcon); |
|
170 } |
|
171 } |
|
172 else |
|
173 { |
|
174 // Check icon attributes and convert icons if they are in .jar. |
|
175 // If no icon attributes defined or icons are not in .jar or |
|
176 // they cannot be converted, use default icon |
|
177 |
|
178 // The icon of the suite can be specified in two attributes. |
|
179 // The priority order of the attributes is: |
|
180 // 1. Nokia-Scalable-Icon |
|
181 // 2. MIDlet-Icon |
|
182 // 3. Use default icon if neither of the attributes has been defined |
|
183 String suiteIconName = ball.getAttributeValue("Nokia-Scalable-Icon"); |
|
184 if (null == suiteIconName) |
|
185 { |
|
186 // no scalable suite icon defined |
|
187 suiteIconName = ball.getAttributeValue("MIDlet-Icon"); |
|
188 if (null == suiteIconName) |
|
189 { |
|
190 // no suite icon defined, use default icon |
|
191 suiteIconName = ""; |
|
192 } |
|
193 } |
|
194 |
|
195 StringBuffer suiteIconSuffix = new StringBuffer(); |
|
196 String suiteIconFile = ""; |
|
197 if (suiteIconName.length() > 0) |
|
198 { |
|
199 suiteIconFile = |
|
200 ball.iIntegrityService.createTempFile(-1); |
|
201 if (ball.iApplicationRegistrator.convertIcon( |
|
202 suiteIconName, suiteIconFile, ball.iJarFilename, suiteIconSuffix)) |
|
203 { |
|
204 // Conversion succeeded, icon is now in place specified |
|
205 // by suiteIconFile |
|
206 |
|
207 // Must rename the temp file to have the correct suffix |
|
208 // so that the device OS recognizes the icon type correctly |
|
209 if (suiteIconSuffix.length() > 0) |
|
210 { |
|
211 fileOpResult = ball.iIntegrityService.move( |
|
212 suiteIconFile, suiteIconFile + suiteIconSuffix.toString()); |
|
213 if (!fileOpResult) |
|
214 { |
|
215 InstallerException.internalError( |
|
216 "Renaming file " + suiteIconFile + " to " + |
|
217 suiteIconFile + suiteIconSuffix.toString() + " failed."); |
|
218 } |
|
219 suiteIconFile += suiteIconSuffix.toString(); |
|
220 } |
|
221 |
|
222 ball.iSuite.setConvertedIconPath(suiteIconFile); |
|
223 } |
|
224 else |
|
225 { |
|
226 ball.iSuite.setConvertedIconPath(defaultIcon); |
|
227 // Cannot use suite icon file |
|
228 suiteIconFile = ""; |
|
229 } |
|
230 } |
|
231 else |
|
232 { |
|
233 ball.iSuite.setConvertedIconPath(defaultIcon); |
|
234 } |
|
235 |
|
236 // The icon of the application can be specified in two attributes. |
|
237 // The priority order of the attributes is: |
|
238 // 1. Nokia-Scalable-Icon-MIDlet-<N> |
|
239 // 2. MIDlet-<N> |
|
240 // 3. Use suite icon |
|
241 // 4. Use default icon |
|
242 StringBuffer iconSuffix = new StringBuffer(); |
|
243 String iconName; |
|
244 for (int i = 0; i < newApps.size(); i++) |
|
245 { |
|
246 // clean up old suffix |
|
247 iconSuffix.setLength(0); |
|
248 ApplicationInfo newApp = (ApplicationInfo)newApps.elementAt(i); |
|
249 |
|
250 // loop variable i goes from 0..(N-1) but in jad/jar attributes |
|
251 // numbering is 1..N |
|
252 iconName = |
|
253 ball.getAttributeValue("Nokia-Scalable-Icon-MIDlet-" + (i+1)); |
|
254 if (null == iconName) |
|
255 { |
|
256 // The ApplicationInfo object contains the value of |
|
257 // the attribute MIDlet-<N> |
|
258 iconName = newApp.getIconPath(); |
|
259 } |
|
260 if (iconName.length() == 0) |
|
261 { |
|
262 // No MIDlet icon defined, use already converted suite |
|
263 // icon if it exists |
|
264 if (suiteIconFile.length() > 0) |
|
265 { |
|
266 // Must make separate copy of the suite icon for each |
|
267 // midlet. Otherwise removing one of the midlets that |
|
268 // have suite icon removes the icon also from the |
|
269 // other midlets that have the suite icon. |
|
270 String newName = |
|
271 FileUtils.getIntegrityServiceRoot() + |
|
272 newApp.getUid().getStringValue() + |
|
273 "_icon" + |
|
274 suiteIconSuffix.toString(); |
|
275 fileOpResult = ball.iIntegrityService.copy( |
|
276 suiteIconFile, |
|
277 newName); |
|
278 if (!fileOpResult) |
|
279 { |
|
280 InstallerException.internalError( |
|
281 "Copying file " + suiteIconFile + " to " + |
|
282 newName + " failed."); |
|
283 } |
|
284 |
|
285 newApp.setConvertedIconPath(newName); |
|
286 continue; |
|
287 } |
|
288 else |
|
289 { |
|
290 // use default icon |
|
291 newApp.setConvertedIconPath(defaultIcon); |
|
292 } |
|
293 } |
|
294 else |
|
295 { |
|
296 // Convert icon. It is inside .jar file. |
|
297 String iconFile = ball.iIntegrityService.createTempFile(-1); |
|
298 String finalIconFile; |
|
299 |
|
300 if (ball.iApplicationRegistrator.convertIcon( |
|
301 iconName, iconFile, ball.iJarFilename, iconSuffix)) |
|
302 { |
|
303 // Conversion succeeded, icon is now in place |
|
304 // specified by iconFile. |
|
305 |
|
306 // Must rename the temp file to have the correct suffix |
|
307 // so that the device OS recognizes the icon type correctly. |
|
308 // Form the final name based on the Uid of the application |
|
309 // so that the name of the icon file stays the same when |
|
310 // the application upgraded (prevents problems with device UI) |
|
311 finalIconFile = |
|
312 FileUtils.getIntegrityServiceRoot() + |
|
313 newApp.getUid().getStringValue() + |
|
314 "_icon" + |
|
315 iconSuffix.toString(); |
|
316 fileOpResult = ball.iIntegrityService.move( |
|
317 iconFile, |
|
318 finalIconFile); |
|
319 if (!fileOpResult) |
|
320 { |
|
321 InstallerException.internalError( |
|
322 "Renaming file " + iconFile + " to " + |
|
323 finalIconFile + " failed."); |
|
324 } |
|
325 |
|
326 newApp.setConvertedIconPath(finalIconFile); |
|
327 } |
|
328 else |
|
329 { |
|
330 ball.log("Warning: Converting icon " + iconName + " inside .jar file " |
|
331 + ball.iJarFilename + " failed."); |
|
332 |
|
333 // MIDlet icon cannot be used, use already converted suite |
|
334 // icon if it exists |
|
335 if (suiteIconFile.length() > 0) |
|
336 { |
|
337 // Must make separate copy of the suite icon for each |
|
338 // midlet. Otherwise removing one of the midlets that |
|
339 // have suite icon removes the icon also from the |
|
340 // other midlets that have the suite icon. |
|
341 String newName = |
|
342 FileUtils.getIntegrityServiceRoot() + |
|
343 newApp.getUid().getStringValue() + |
|
344 "_icon" + |
|
345 suiteIconSuffix.toString(); |
|
346 fileOpResult = ball.iIntegrityService.copy( |
|
347 suiteIconFile, |
|
348 newName); |
|
349 if (!fileOpResult) |
|
350 { |
|
351 InstallerException.internalError( |
|
352 "Copying file " + suiteIconFile + " to " + |
|
353 newName + " failed."); |
|
354 } |
|
355 |
|
356 ball.log("Using suite icon for midlet number " + (i+1)); |
|
357 newApp.setConvertedIconPath(newName); |
|
358 continue; |
|
359 } |
|
360 else |
|
361 { |
|
362 // use default icon |
|
363 ball.log("Using default icon for midlet number " + (i+1)); |
|
364 newApp.setConvertedIconPath(defaultIcon); |
|
365 } |
|
366 } |
|
367 } |
|
368 } // for loop |
|
369 } // else, .jar file was available |
|
370 } // end of convertIconsInJar |
|
371 |
|
372 } |