|
1 // -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 // This UI is only opened from the Extension Manager when the app is upgraded. |
|
8 |
|
9 "use strict"; |
|
10 |
|
11 const PREF_UPDATE_EXTENSIONS_ENABLED = "extensions.update.enabled"; |
|
12 const PREF_XPINSTALL_ENABLED = "xpinstall.enabled"; |
|
13 const PREF_EM_HOTFIX_ID = "extensions.hotfix.id"; |
|
14 |
|
15 // timeout (in milliseconds) to wait for response to the metadata ping |
|
16 const METADATA_TIMEOUT = 30000; |
|
17 |
|
18 Components.utils.import("resource://gre/modules/Services.jsm"); |
|
19 Components.utils.import("resource://gre/modules/AddonManager.jsm"); |
|
20 Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm"); |
|
21 |
|
22 Components.utils.import("resource://gre/modules/Log.jsm"); |
|
23 let logger = Log.repository.getLogger("addons.update-dialog"); |
|
24 |
|
25 var gUpdateWizard = { |
|
26 // When synchronizing app compatibility info this contains all installed |
|
27 // add-ons. When checking for compatible versions this contains only |
|
28 // incompatible add-ons. |
|
29 addons: [], |
|
30 // Contains a list of add-ons that were disabled prior to the application |
|
31 // upgrade. |
|
32 inactiveAddonIDs: [], |
|
33 // The add-ons that we found updates available for |
|
34 addonsToUpdate: [], |
|
35 shouldSuggestAutoChecking: false, |
|
36 shouldAutoCheck: false, |
|
37 xpinstallEnabled: true, |
|
38 xpinstallLocked: false, |
|
39 // cached AddonInstall entries for add-ons we might want to update, |
|
40 // keyed by add-on ID |
|
41 addonInstalls: new Map(), |
|
42 shuttingDown: false, |
|
43 // Count the add-ons disabled by this update, enabled/disabled by |
|
44 // metadata checks, and upgraded. |
|
45 disabled: 0, |
|
46 metadataEnabled: 0, |
|
47 metadataDisabled: 0, |
|
48 upgraded: 0, |
|
49 upgradeFailed: 0, |
|
50 upgradeDeclined: 0, |
|
51 |
|
52 init: function gUpdateWizard_init() |
|
53 { |
|
54 this.inactiveAddonIDs = window.arguments[0]; |
|
55 |
|
56 try { |
|
57 this.shouldSuggestAutoChecking = |
|
58 !Services.prefs.getBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED); |
|
59 } |
|
60 catch (e) { |
|
61 } |
|
62 |
|
63 try { |
|
64 this.xpinstallEnabled = Services.prefs.getBoolPref(PREF_XPINSTALL_ENABLED); |
|
65 this.xpinstallLocked = Services.prefs.prefIsLocked(PREF_XPINSTALL_ENABLED); |
|
66 } |
|
67 catch (e) { |
|
68 } |
|
69 |
|
70 if (Services.io.offline) |
|
71 document.documentElement.currentPage = document.getElementById("offline"); |
|
72 else |
|
73 document.documentElement.currentPage = document.getElementById("versioninfo"); |
|
74 }, |
|
75 |
|
76 onWizardFinish: function gUpdateWizard_onWizardFinish () |
|
77 { |
|
78 if (this.shouldSuggestAutoChecking) |
|
79 Services.prefs.setBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED, this.shouldAutoCheck); |
|
80 }, |
|
81 |
|
82 _setUpButton: function gUpdateWizard_setUpButton(aButtonID, aButtonKey, aDisabled) |
|
83 { |
|
84 var strings = document.getElementById("updateStrings"); |
|
85 var button = document.documentElement.getButton(aButtonID); |
|
86 if (aButtonKey) { |
|
87 button.label = strings.getString(aButtonKey); |
|
88 try { |
|
89 button.setAttribute("accesskey", strings.getString(aButtonKey + "Accesskey")); |
|
90 } |
|
91 catch (e) { |
|
92 } |
|
93 } |
|
94 button.disabled = aDisabled; |
|
95 }, |
|
96 |
|
97 setButtonLabels: function gUpdateWizard_setButtonLabels(aBackButton, aBackButtonIsDisabled, |
|
98 aNextButton, aNextButtonIsDisabled, |
|
99 aCancelButton, aCancelButtonIsDisabled) |
|
100 { |
|
101 this._setUpButton("back", aBackButton, aBackButtonIsDisabled); |
|
102 this._setUpButton("next", aNextButton, aNextButtonIsDisabled); |
|
103 this._setUpButton("cancel", aCancelButton, aCancelButtonIsDisabled); |
|
104 }, |
|
105 |
|
106 ///////////////////////////////////////////////////////////////////////////// |
|
107 // Update Errors |
|
108 errorItems: [], |
|
109 |
|
110 checkForErrors: function gUpdateWizard_checkForErrors(aElementIDToShow) |
|
111 { |
|
112 if (this.errorItems.length > 0) |
|
113 document.getElementById(aElementIDToShow).hidden = false; |
|
114 }, |
|
115 |
|
116 onWizardClose: function gUpdateWizard_onWizardClose(aEvent) |
|
117 { |
|
118 return this.onWizardCancel(); |
|
119 }, |
|
120 |
|
121 onWizardCancel: function gUpdateWizard_onWizardCancel() |
|
122 { |
|
123 gUpdateWizard.shuttingDown = true; |
|
124 // Allow add-ons to continue downloading and installing |
|
125 // in the background, though some may require a later restart |
|
126 // Pages that are waiting for user input go into the background |
|
127 // on cancel |
|
128 if (gMismatchPage.waiting) { |
|
129 logger.info("Dialog closed in mismatch page"); |
|
130 if (gUpdateWizard.addonInstalls.size > 0) { |
|
131 gInstallingPage.startInstalls([i for ([, i] of gUpdateWizard.addonInstalls)]); |
|
132 } |
|
133 return true; |
|
134 } |
|
135 |
|
136 // Pages that do asynchronous things will just keep running and check |
|
137 // gUpdateWizard.shuttingDown to trigger background behaviour |
|
138 if (!gInstallingPage.installing) { |
|
139 logger.info("Dialog closed while waiting for updated compatibility information"); |
|
140 } |
|
141 else { |
|
142 logger.info("Dialog closed while downloading and installing updates"); |
|
143 } |
|
144 return true; |
|
145 } |
|
146 }; |
|
147 |
|
148 var gOfflinePage = { |
|
149 onPageAdvanced: function gOfflinePage_onPageAdvanced() |
|
150 { |
|
151 Services.io.offline = false; |
|
152 return true; |
|
153 }, |
|
154 |
|
155 toggleOffline: function gOfflinePage_toggleOffline() |
|
156 { |
|
157 var nextbtn = document.documentElement.getButton("next"); |
|
158 nextbtn.disabled = !nextbtn.disabled; |
|
159 } |
|
160 } |
|
161 |
|
162 // Addon listener to count addons enabled/disabled by metadata checks |
|
163 let listener = { |
|
164 onDisabled: function listener_onDisabled(aAddon) { |
|
165 logger.debug("onDisabled for ${id}", aAddon); |
|
166 gUpdateWizard.metadataDisabled++; |
|
167 }, |
|
168 onEnabled: function listener_onEnabled(aAddon) { |
|
169 logger.debug("onEnabled for ${id}", aAddon); |
|
170 gUpdateWizard.metadataEnabled++; |
|
171 } |
|
172 }; |
|
173 |
|
174 var gVersionInfoPage = { |
|
175 _completeCount: 0, |
|
176 _totalCount: 0, |
|
177 _versionInfoDone: false, |
|
178 onPageShow: function gVersionInfoPage_onPageShow() |
|
179 { |
|
180 gUpdateWizard.setButtonLabels(null, true, |
|
181 "nextButtonText", true, |
|
182 "cancelButtonText", false); |
|
183 |
|
184 try { |
|
185 var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID); |
|
186 } |
|
187 catch (e) { } |
|
188 |
|
189 // Retrieve all add-ons in order to sync their app compatibility information |
|
190 AddonManager.getAllAddons(function gVersionInfoPage_getAllAddons(aAddons) { |
|
191 if (gUpdateWizard.shuttingDown) { |
|
192 logger.debug("getAllAddons completed after dialog closed"); |
|
193 } |
|
194 |
|
195 gUpdateWizard.addons = [a for (a of aAddons) |
|
196 if (a.type != "plugin" && a.id != hotfixID)]; |
|
197 |
|
198 gVersionInfoPage._totalCount = gUpdateWizard.addons.length; |
|
199 |
|
200 // Count the add-ons newly disabled by this application update |
|
201 for (let addon of gUpdateWizard.addons) { |
|
202 if (gUpdateWizard.inactiveAddonIDs.indexOf(addon.id) != -1) { |
|
203 gUpdateWizard.disabled++; |
|
204 } |
|
205 } |
|
206 |
|
207 // Ensure compatibility overrides are up to date before checking for |
|
208 // individual addon updates. |
|
209 let ids = [addon.id for (addon of gUpdateWizard.addons)]; |
|
210 |
|
211 // Do the metadata ping, listening for any newly enabled/disabled add-ons. |
|
212 AddonManager.addAddonListener(listener); |
|
213 AddonRepository.repopulateCache(ids, function gVersionInfoPage_repopulateCache() { |
|
214 |
|
215 if (gUpdateWizard.shuttingDown) { |
|
216 logger.debug("repopulateCache completed after dialog closed"); |
|
217 } |
|
218 |
|
219 for (let addon of gUpdateWizard.addons) { |
|
220 logger.debug("VersionInfo Finding updates for " + addon.id); |
|
221 addon.findUpdates(gVersionInfoPage, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED); |
|
222 } |
|
223 }, METADATA_TIMEOUT); |
|
224 }); |
|
225 }, |
|
226 |
|
227 onAllUpdatesFinished: function gVersionInfoPage_onAllUpdatesFinished() { |
|
228 AddonManager.removeAddonListener(listener); |
|
229 AddonManagerPrivate.recordSimpleMeasure("appUpdate_disabled", |
|
230 gUpdateWizard.disabled); |
|
231 AddonManagerPrivate.recordSimpleMeasure("appUpdate_metadata_enabled", |
|
232 gUpdateWizard.metadataEnabled); |
|
233 AddonManagerPrivate.recordSimpleMeasure("appUpdate_metadata_disabled", |
|
234 gUpdateWizard.metadataDisabled); |
|
235 // Record 0 for these here in case we exit early; values will be replaced |
|
236 // later if we actually upgrade any. |
|
237 AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgraded", 0); |
|
238 AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeFailed", 0); |
|
239 AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeDeclined", 0); |
|
240 // Filter out any add-ons that were disabled before the application was |
|
241 // upgraded or are already compatible |
|
242 logger.debug("VersionInfo updates finished: inactive " + |
|
243 gUpdateWizard.inactiveAddonIDs.toSource() + " found " + |
|
244 [addon.id + ":" + addon.appDisabled for (addon of gUpdateWizard.addons)].toSource()); |
|
245 let filteredAddons = []; |
|
246 for (let a of gUpdateWizard.addons) { |
|
247 if (a.appDisabled && gUpdateWizard.inactiveAddonIDs.indexOf(a.id) < 0) { |
|
248 logger.debug("Continuing with add-on " + a.id); |
|
249 filteredAddons.push(a); |
|
250 } |
|
251 else if (gUpdateWizard.addonInstalls.has(a.id)) { |
|
252 gUpdateWizard.addonInstalls.get(a.id).cancel(); |
|
253 gUpdateWizard.addonInstalls.delete(a.id); |
|
254 } |
|
255 } |
|
256 gUpdateWizard.addons = filteredAddons; |
|
257 |
|
258 if (gUpdateWizard.shuttingDown) { |
|
259 // jump directly to updating auto-update add-ons in the background |
|
260 if (gUpdateWizard.addonInstalls.size > 0) { |
|
261 gInstallingPage.startInstalls([i for ([, i] of gUpdateWizard.addonInstalls)]); |
|
262 } |
|
263 return; |
|
264 } |
|
265 |
|
266 if (filteredAddons.length > 0) { |
|
267 if (!gUpdateWizard.xpinstallEnabled && gUpdateWizard.xpinstallLocked) { |
|
268 document.documentElement.currentPage = document.getElementById("adminDisabled"); |
|
269 return; |
|
270 } |
|
271 document.documentElement.currentPage = document.getElementById("mismatch"); |
|
272 } |
|
273 else { |
|
274 logger.info("VersionInfo: No updates require further action"); |
|
275 // VersionInfo compatibility updates resolved all compatibility problems, |
|
276 // close this window and continue starting the application... |
|
277 //XXX Bug 314754 - We need to use setTimeout to close the window due to |
|
278 // the EM using xmlHttpRequest when checking for updates. |
|
279 setTimeout(close, 0); |
|
280 } |
|
281 }, |
|
282 |
|
283 ///////////////////////////////////////////////////////////////////////////// |
|
284 // UpdateListener |
|
285 onUpdateFinished: function gVersionInfoPage_onUpdateFinished(aAddon, status) { |
|
286 ++this._completeCount; |
|
287 |
|
288 if (status != AddonManager.UPDATE_STATUS_NO_ERROR) { |
|
289 logger.debug("VersionInfo update " + this._completeCount + " of " + this._totalCount + |
|
290 " failed for " + aAddon.id + ": " + status); |
|
291 gUpdateWizard.errorItems.push(aAddon); |
|
292 } |
|
293 else { |
|
294 logger.debug("VersionInfo update " + this._completeCount + " of " + this._totalCount + |
|
295 " finished for " + aAddon.id); |
|
296 } |
|
297 |
|
298 // If we're not in the background, just make a list of add-ons that have |
|
299 // updates available |
|
300 if (!gUpdateWizard.shuttingDown) { |
|
301 // If we're still in the update check window and the add-on is now active |
|
302 // then it won't have been disabled by startup |
|
303 if (aAddon.active) { |
|
304 AddonManagerPrivate.removeStartupChange("disabled", aAddon.id); |
|
305 gUpdateWizard.metadataEnabled++; |
|
306 } |
|
307 |
|
308 // Update the status text and progress bar |
|
309 var updateStrings = document.getElementById("updateStrings"); |
|
310 var statusElt = document.getElementById("versioninfo.status"); |
|
311 var statusString = updateStrings.getFormattedString("statusPrefix", [aAddon.name]); |
|
312 statusElt.setAttribute("value", statusString); |
|
313 |
|
314 // Update the status text and progress bar |
|
315 var progress = document.getElementById("versioninfo.progress"); |
|
316 progress.mode = "normal"; |
|
317 progress.value = Math.ceil((this._completeCount / this._totalCount) * 100); |
|
318 } |
|
319 |
|
320 if (this._completeCount == this._totalCount) |
|
321 this.onAllUpdatesFinished(); |
|
322 }, |
|
323 |
|
324 onUpdateAvailable: function gVersionInfoPage_onUpdateAvailable(aAddon, aInstall) { |
|
325 logger.debug("VersionInfo got an install for " + aAddon.id + ": " + aAddon.version); |
|
326 gUpdateWizard.addonInstalls.set(aAddon.id, aInstall); |
|
327 }, |
|
328 }; |
|
329 |
|
330 var gMismatchPage = { |
|
331 waiting: false, |
|
332 |
|
333 onPageShow: function gMismatchPage_onPageShow() |
|
334 { |
|
335 gMismatchPage.waiting = true; |
|
336 gUpdateWizard.setButtonLabels(null, true, |
|
337 "mismatchCheckNow", false, |
|
338 "mismatchDontCheck", false); |
|
339 document.documentElement.getButton("next").focus(); |
|
340 |
|
341 var incompatible = document.getElementById("mismatch.incompatible"); |
|
342 for (let addon of gUpdateWizard.addons) { |
|
343 var listitem = document.createElement("listitem"); |
|
344 listitem.setAttribute("label", addon.name + " " + addon.version); |
|
345 incompatible.appendChild(listitem); |
|
346 } |
|
347 } |
|
348 }; |
|
349 |
|
350 var gUpdatePage = { |
|
351 _totalCount: 0, |
|
352 _completeCount: 0, |
|
353 onPageShow: function gUpdatePage_onPageShow() |
|
354 { |
|
355 gMismatchPage.waiting = false; |
|
356 gUpdateWizard.setButtonLabels(null, true, |
|
357 "nextButtonText", true, |
|
358 "cancelButtonText", false); |
|
359 document.documentElement.getButton("next").focus(); |
|
360 |
|
361 gUpdateWizard.errorItems = []; |
|
362 |
|
363 this._totalCount = gUpdateWizard.addons.length; |
|
364 for (let addon of gUpdateWizard.addons) { |
|
365 logger.debug("UpdatePage requesting update for " + addon.id); |
|
366 // Redundant call to find updates again here when we already got them |
|
367 // in the VersionInfo page: https://bugzilla.mozilla.org/show_bug.cgi?id=960597 |
|
368 addon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED); |
|
369 } |
|
370 }, |
|
371 |
|
372 onAllUpdatesFinished: function gUpdatePage_onAllUpdatesFinished() { |
|
373 if (gUpdateWizard.shuttingDown) |
|
374 return; |
|
375 |
|
376 var nextPage = document.getElementById("noupdates"); |
|
377 if (gUpdateWizard.addonsToUpdate.length > 0) |
|
378 nextPage = document.getElementById("found"); |
|
379 document.documentElement.currentPage = nextPage; |
|
380 }, |
|
381 |
|
382 ///////////////////////////////////////////////////////////////////////////// |
|
383 // UpdateListener |
|
384 onUpdateAvailable: function gUpdatePage_onUpdateAvailable(aAddon, aInstall) { |
|
385 logger.debug("UpdatePage got an update for " + aAddon.id + ": " + aAddon.version); |
|
386 gUpdateWizard.addonsToUpdate.push(aInstall); |
|
387 }, |
|
388 |
|
389 onUpdateFinished: function gUpdatePage_onUpdateFinished(aAddon, status) { |
|
390 if (status != AddonManager.UPDATE_STATUS_NO_ERROR) |
|
391 gUpdateWizard.errorItems.push(aAddon); |
|
392 |
|
393 ++this._completeCount; |
|
394 |
|
395 if (!gUpdateWizard.shuttingDown) { |
|
396 // Update the status text and progress bar |
|
397 var updateStrings = document.getElementById("updateStrings"); |
|
398 var statusElt = document.getElementById("checking.status"); |
|
399 var statusString = updateStrings.getFormattedString("statusPrefix", [aAddon.name]); |
|
400 statusElt.setAttribute("value", statusString); |
|
401 |
|
402 var progress = document.getElementById("checking.progress"); |
|
403 progress.value = Math.ceil((this._completeCount / this._totalCount) * 100); |
|
404 } |
|
405 |
|
406 if (this._completeCount == this._totalCount) |
|
407 this.onAllUpdatesFinished() |
|
408 }, |
|
409 }; |
|
410 |
|
411 var gFoundPage = { |
|
412 onPageShow: function gFoundPage_onPageShow() |
|
413 { |
|
414 gUpdateWizard.setButtonLabels(null, true, |
|
415 "installButtonText", false, |
|
416 null, false); |
|
417 |
|
418 var foundUpdates = document.getElementById("found.updates"); |
|
419 var itemCount = gUpdateWizard.addonsToUpdate.length; |
|
420 for (let install of gUpdateWizard.addonsToUpdate) { |
|
421 let listItem = foundUpdates.appendItem(install.name + " " + install.version); |
|
422 listItem.setAttribute("type", "checkbox"); |
|
423 listItem.setAttribute("checked", "true"); |
|
424 listItem.install = install; |
|
425 } |
|
426 |
|
427 if (!gUpdateWizard.xpinstallEnabled) { |
|
428 document.getElementById("xpinstallDisabledAlert").hidden = false; |
|
429 document.getElementById("enableXPInstall").focus(); |
|
430 document.documentElement.getButton("next").disabled = true; |
|
431 } |
|
432 else { |
|
433 document.documentElement.getButton("next").focus(); |
|
434 document.documentElement.getButton("next").disabled = false; |
|
435 } |
|
436 }, |
|
437 |
|
438 toggleXPInstallEnable: function gFoundPage_toggleXPInstallEnable(aEvent) |
|
439 { |
|
440 var enabled = aEvent.target.checked; |
|
441 gUpdateWizard.xpinstallEnabled = enabled; |
|
442 var pref = Components.classes["@mozilla.org/preferences-service;1"] |
|
443 .getService(Components.interfaces.nsIPrefBranch); |
|
444 pref.setBoolPref(PREF_XPINSTALL_ENABLED, enabled); |
|
445 this.updateNextButton(); |
|
446 }, |
|
447 |
|
448 updateNextButton: function gFoundPage_updateNextButton() |
|
449 { |
|
450 if (!gUpdateWizard.xpinstallEnabled) { |
|
451 document.documentElement.getButton("next").disabled = true; |
|
452 return; |
|
453 } |
|
454 |
|
455 var oneChecked = false; |
|
456 var foundUpdates = document.getElementById("found.updates"); |
|
457 var updates = foundUpdates.getElementsByTagName("listitem"); |
|
458 for (let update of updates) { |
|
459 if (!update.checked) |
|
460 continue; |
|
461 oneChecked = true; |
|
462 break; |
|
463 } |
|
464 |
|
465 gUpdateWizard.setButtonLabels(null, true, |
|
466 "installButtonText", true, |
|
467 null, false); |
|
468 document.getElementById("found").setAttribute("next", "installing"); |
|
469 document.documentElement.getButton("next").disabled = !oneChecked; |
|
470 } |
|
471 }; |
|
472 |
|
473 var gInstallingPage = { |
|
474 _installs : [], |
|
475 _errors : [], |
|
476 _strings : null, |
|
477 _currentInstall : -1, |
|
478 _installing : false, |
|
479 |
|
480 // Initialize fields we need for installing and tracking progress, |
|
481 // and start iterating through the installations |
|
482 startInstalls: function gInstallingPage_startInstalls(aInstallList) { |
|
483 if (!gUpdateWizard.xpinstallEnabled) { |
|
484 return; |
|
485 } |
|
486 |
|
487 logger.debug("Start installs for " |
|
488 + [i.existingAddon.id for (i of aInstallList)].toSource()); |
|
489 this._errors = []; |
|
490 this._installs = aInstallList; |
|
491 this._installing = true; |
|
492 this.startNextInstall(); |
|
493 }, |
|
494 |
|
495 onPageShow: function gInstallingPage_onPageShow() |
|
496 { |
|
497 gUpdateWizard.setButtonLabels(null, true, |
|
498 "nextButtonText", true, |
|
499 null, true); |
|
500 |
|
501 var foundUpdates = document.getElementById("found.updates"); |
|
502 var updates = foundUpdates.getElementsByTagName("listitem"); |
|
503 let toInstall = []; |
|
504 for (let update of updates) { |
|
505 if (!update.checked) { |
|
506 logger.info("User chose to cancel update of " + update.label); |
|
507 gUpdateWizard.upgradeDeclined++; |
|
508 update.install.cancel(); |
|
509 continue; |
|
510 } |
|
511 toInstall.push(update.install); |
|
512 } |
|
513 this._strings = document.getElementById("updateStrings"); |
|
514 |
|
515 this.startInstalls(toInstall); |
|
516 }, |
|
517 |
|
518 startNextInstall: function gInstallingPage_startNextInstall() { |
|
519 if (this._currentInstall >= 0) { |
|
520 this._installs[this._currentInstall].removeListener(this); |
|
521 } |
|
522 |
|
523 this._currentInstall++; |
|
524 |
|
525 if (this._installs.length == this._currentInstall) { |
|
526 Services.obs.notifyObservers(null, "TEST:all-updates-done", null); |
|
527 AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgraded", |
|
528 gUpdateWizard.upgraded); |
|
529 AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeFailed", |
|
530 gUpdateWizard.upgradeFailed); |
|
531 AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeDeclined", |
|
532 gUpdateWizard.upgradeDeclined); |
|
533 this._installing = false; |
|
534 if (gUpdateWizard.shuttingDown) { |
|
535 return; |
|
536 } |
|
537 var nextPage = this._errors.length > 0 ? "installerrors" : "finished"; |
|
538 document.getElementById("installing").setAttribute("next", nextPage); |
|
539 document.documentElement.advance(); |
|
540 return; |
|
541 } |
|
542 |
|
543 let install = this._installs[this._currentInstall]; |
|
544 |
|
545 if (gUpdateWizard.shuttingDown && !AddonManager.shouldAutoUpdate(install.existingAddon)) { |
|
546 logger.debug("Don't update " + install.existingAddon.id + " in background"); |
|
547 gUpdateWizard.upgradeDeclined++; |
|
548 install.cancel(); |
|
549 this.startNextInstall(); |
|
550 return; |
|
551 } |
|
552 install.addListener(this); |
|
553 install.install(); |
|
554 }, |
|
555 |
|
556 ///////////////////////////////////////////////////////////////////////////// |
|
557 // InstallListener |
|
558 onDownloadStarted: function gInstallingPage_onDownloadStarted(aInstall) { |
|
559 if (gUpdateWizard.shuttingDown) { |
|
560 return; |
|
561 } |
|
562 var strings = document.getElementById("updateStrings"); |
|
563 var label = strings.getFormattedString("downloadingPrefix", [aInstall.name]); |
|
564 var actionItem = document.getElementById("actionItem"); |
|
565 actionItem.value = label; |
|
566 }, |
|
567 |
|
568 onDownloadProgress: function gInstallingPage_onDownloadProgress(aInstall) { |
|
569 if (gUpdateWizard.shuttingDown) { |
|
570 return; |
|
571 } |
|
572 var downloadProgress = document.getElementById("downloadProgress"); |
|
573 downloadProgress.value = Math.ceil(100 * aInstall.progress / aInstall.maxProgress); |
|
574 }, |
|
575 |
|
576 onDownloadEnded: function gInstallingPage_onDownloadEnded(aInstall) { |
|
577 }, |
|
578 |
|
579 onDownloadFailed: function gInstallingPage_onDownloadFailed(aInstall) { |
|
580 this._errors.push(aInstall); |
|
581 |
|
582 gUpdateWizard.upgradeFailed++; |
|
583 this.startNextInstall(); |
|
584 }, |
|
585 |
|
586 onInstallStarted: function gInstallingPage_onInstallStarted(aInstall) { |
|
587 if (gUpdateWizard.shuttingDown) { |
|
588 return; |
|
589 } |
|
590 var strings = document.getElementById("updateStrings"); |
|
591 var label = strings.getFormattedString("installingPrefix", [aInstall.name]); |
|
592 var actionItem = document.getElementById("actionItem"); |
|
593 actionItem.value = label; |
|
594 }, |
|
595 |
|
596 onInstallEnded: function gInstallingPage_onInstallEnded(aInstall, aAddon) { |
|
597 if (!gUpdateWizard.shuttingDown) { |
|
598 // Remember that this add-on was updated during startup |
|
599 AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED, |
|
600 aAddon.id); |
|
601 } |
|
602 |
|
603 gUpdateWizard.upgraded++; |
|
604 this.startNextInstall(); |
|
605 }, |
|
606 |
|
607 onInstallFailed: function gInstallingPage_onInstallFailed(aInstall) { |
|
608 this._errors.push(aInstall); |
|
609 |
|
610 gUpdateWizard.upgradeFailed++; |
|
611 this.startNextInstall(); |
|
612 } |
|
613 }; |
|
614 |
|
615 var gInstallErrorsPage = { |
|
616 onPageShow: function gInstallErrorsPage_onPageShow() |
|
617 { |
|
618 gUpdateWizard.setButtonLabels(null, true, null, true, null, true); |
|
619 document.documentElement.getButton("finish").focus(); |
|
620 }, |
|
621 }; |
|
622 |
|
623 // Displayed when there are incompatible add-ons and the xpinstall.enabled |
|
624 // pref is false and locked. |
|
625 var gAdminDisabledPage = { |
|
626 onPageShow: function gAdminDisabledPage_onPageShow() |
|
627 { |
|
628 gUpdateWizard.setButtonLabels(null, true, null, true, |
|
629 "cancelButtonText", true); |
|
630 document.documentElement.getButton("finish").focus(); |
|
631 } |
|
632 }; |
|
633 |
|
634 // Displayed when selected add-on updates have been installed without error. |
|
635 // There can still be add-ons that are not compatible and don't have an update. |
|
636 var gFinishedPage = { |
|
637 onPageShow: function gFinishedPage_onPageShow() |
|
638 { |
|
639 gUpdateWizard.setButtonLabels(null, true, null, true, null, true); |
|
640 document.documentElement.getButton("finish").focus(); |
|
641 |
|
642 if (gUpdateWizard.shouldSuggestAutoChecking) { |
|
643 document.getElementById("finishedCheckDisabled").hidden = false; |
|
644 gUpdateWizard.shouldAutoCheck = true; |
|
645 } |
|
646 else |
|
647 document.getElementById("finishedCheckEnabled").hidden = false; |
|
648 |
|
649 document.documentElement.getButton("finish").focus(); |
|
650 } |
|
651 }; |
|
652 |
|
653 // Displayed when there are incompatible add-ons and there are no available |
|
654 // updates. |
|
655 var gNoUpdatesPage = { |
|
656 onPageShow: function gNoUpdatesPage_onPageLoad(aEvent) |
|
657 { |
|
658 gUpdateWizard.setButtonLabels(null, true, null, true, null, true); |
|
659 if (gUpdateWizard.shouldSuggestAutoChecking) { |
|
660 document.getElementById("noupdatesCheckDisabled").hidden = false; |
|
661 gUpdateWizard.shouldAutoCheck = true; |
|
662 } |
|
663 else |
|
664 document.getElementById("noupdatesCheckEnabled").hidden = false; |
|
665 |
|
666 gUpdateWizard.checkForErrors("updateCheckErrorNotFound"); |
|
667 document.documentElement.getButton("finish").focus(); |
|
668 } |
|
669 }; |