diff --git a/toolkit/mozapps/extensions/AddonManager.jsm b/toolkit/mozapps/extensions/AddonManager.jsm index 528a85f2b7a..ac5e1511144 100644 --- a/toolkit/mozapps/extensions/AddonManager.jsm +++ b/toolkit/mozapps/extensions/AddonManager.jsm @@ -464,6 +464,7 @@ var gUpdateEnabled = true; var gAutoUpdateDefault = true; var gHotfixID = null; +var gUpdateCheckInProgress = false; /** * This is the real manager, kept here rather than in AddonManager to keep its * contents hidden from API users. @@ -479,7 +480,6 @@ var AddonManagerInternal = { // Store telemetry details per addon provider telemetryDetails: {}, - // A read-only wrapper around the types dictionary typesProxy: Proxy.create({ getOwnPropertyDescriptor: function typesProxy_getOwnPropertyDescriptor(aName) { @@ -1142,6 +1142,12 @@ var AddonManagerInternal = { throw Components.Exception("AddonManager is not initialized", Cr.NS_ERROR_NOT_INITIALIZED); + if (gUpdateCheckInProgress) { + throw Components.Exception("Background update check already in progress", + Cr.NS_ERROR_UNEXPECTED); + } + gUpdateCheckInProgress = true; + return Task.spawn(function* backgroundUpdateTask() { let hotfixID = this.hotfixID; @@ -1284,6 +1290,7 @@ var AddonManagerInternal = { } } + gUpdateCheckInProgress = false; Services.obs.notifyObservers(null, "addons-background-update-complete", null); diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index 89aa25d356a..5523867ecd0 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -3610,7 +3610,13 @@ this.XPIProvider = { * The AddonInstall to remove */ removeActiveInstall: function XPI_removeActiveInstall(aInstall) { - this.installs = this.installs.filter(function installFilter(i) i != aInstall); + let where = this.installs.indexOf(aInstall); + if (where == -1) { + logger.warn("removeActiveInstall: could not find active install for " + + aInstall.sourceURI.spec); + return; + } + this.installs.splice(where, 1); }, /** diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug557956.js b/toolkit/mozapps/extensions/test/browser/browser_bug557956.js index 581639aa5ca..a39fc7f1e4a 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_bug557956.js +++ b/toolkit/mozapps/extensions/test/browser/browser_bug557956.js @@ -75,7 +75,7 @@ function install_test_addons(aCallback) { // Switch to the test update URL Services.prefs.setCharPref(PREF_UPDATEURL, TESTROOT + "browser_bug557956.rdf"); - aCallback(); + executeSoon(aCallback); } } }; diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug562992.js b/toolkit/mozapps/extensions/test/browser/browser_bug562992.js index 10bf329f0a7..245edb8a5f2 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_bug562992.js +++ b/toolkit/mozapps/extensions/test/browser/browser_bug562992.js @@ -41,7 +41,7 @@ add_test(function () { gInstall = new MockInstall(undefined, undefined, addon); gInstall.addTestListener({ onNewInstall: function () { - run_next_test(); + executeSoon(run_next_test); } }); gProvider.addInstall(gInstall); @@ -65,7 +65,7 @@ add_test(function () { } } ok(false, "Item with correct name was not found"); - run_next_test(); + executeSoon(run_next_test); } }); gInstall.install(); diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug572561.js b/toolkit/mozapps/extensions/test/browser/browser_bug572561.js index 86dad46d886..97c602c11d4 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_bug572561.js +++ b/toolkit/mozapps/extensions/test/browser/browser_bug572561.js @@ -21,17 +21,18 @@ var gTestInstallListener = { onInstallEnded: function(aInstall) { check_hidden(false); - run_next_test(); + executeSoon(run_next_test); }, onInstallCancelled: function(aInstall) { ok(gExpectedCancel, "Should expect install cancel"); check_hidden(false); - run_next_test(); + executeSoon(run_next_test); }, onInstallFailed: function(aInstall) { ok(false, "Did not expect onInstallFailed"); + executeSoon(run_next_test); } }; diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug577990.js b/toolkit/mozapps/extensions/test/browser/browser_bug577990.js index 9b4ab3f8329..2c3c7ba5a62 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_bug577990.js +++ b/toolkit/mozapps/extensions/test/browser/browser_bug577990.js @@ -40,7 +40,7 @@ function install_locale(aCallback) { gInstall.addTestListener({ onInstallEnded: function(aInstall) { gInstall.removeTestListener(this); - aCallback(); + executeSoon(aCallback); } }); gInstall.install(); diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug591663.js b/toolkit/mozapps/extensions/test/browser/browser_bug591663.js index 0736aa39191..7a65cc4c553 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_bug591663.js +++ b/toolkit/mozapps/extensions/test/browser/browser_bug591663.js @@ -97,7 +97,7 @@ add_test(function() { }, onInstallEnded: function() { check_list(gItem); - run_next_test(); + executeSoon(run_next_test); } }); @@ -136,7 +136,7 @@ add_test(function() { onInstallEnded: function() { check_list(null); extension.cancel(); - run_next_test(); + executeSoon(run_next_test); } }); diff --git a/toolkit/mozapps/extensions/test/browser/browser_hotfix.js b/toolkit/mozapps/extensions/test/browser/browser_hotfix.js index ff288898306..77d3eb43014 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_hotfix.js +++ b/toolkit/mozapps/extensions/test/browser/browser_hotfix.js @@ -15,51 +15,56 @@ const PREF_APP_UPDATE_ENABLED = "app.update.enabled"; const HOTFIX_ID = "hotfix@tests.mozilla.org"; -var gNextTest; - -var SuccessfulInstallListener = { - onDownloadCancelled: function(aInstall) { - ok(false, "Should not have seen the download cancelled"); - is(aInstall.addon.id, HOTFIX_ID, "Should have seen the right add-on"); - - AddonManager.removeInstallListener(this); - gNextTest(); - }, - - onInstallEnded: function(aInstall) { - ok(true, "Should have seen the install complete"); - is(aInstall.addon.id, HOTFIX_ID, "Should have installed the right add-on"); - - AddonManager.removeInstallListener(this); - aInstall.addon.uninstall(); - Services.prefs.clearUserPref(PREF_EM_HOTFIX_LASTVERSION); - gNextTest(); - } +/* + * Register an addon install listener and return a promise that: + * resolves with the AddonInstall object if the install succeeds + * rejects with the AddonInstall if the install fails + */ +function promiseInstallListener() { + return new Promise((resolve, reject) => { + let listener = { + onInstallEnded: ai => { + AddonManager.removeInstallListener(listener); + resolve(ai); + }, + onDownloadCancelled: ai => { + AddonManager.removeInstallListener(listener); + reject(ai); + } + }; + AddonManager.addInstallListener(listener); + }); } -var FailedInstallListener = { - onDownloadCancelled: function(aInstall) { - ok(true, "Should have seen the download cancelled"); - is(aInstall.addon.id, HOTFIX_ID, "Should have seen the right add-on"); - - AddonManager.removeInstallListener(this); - gNextTest(); - }, - - onInstallEnded: function(aInstall) { - ok(false, "Should not have seen the install complete"); - is(aInstall.addon.id, HOTFIX_ID, "Should have installed the right add-on"); - - AddonManager.removeInstallListener(this); - aInstall.addon.uninstall(); - Services.prefs.clearUserPref(PREF_EM_HOTFIX_LASTVERSION); - gNextTest(); - } +function promiseSuccessfulInstall() { + return promiseInstallListener().then( + aInstall => { + ok(true, "Should have seen the install complete"); + is(aInstall.addon.id, HOTFIX_ID, "Should have installed the right add-on"); + aInstall.addon.uninstall(); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_LASTVERSION); + }, + aInstall => { + ok(false, "Should not have seen the download cancelled"); + is(aInstall.addon.id, HOTFIX_ID, "Should have seen the right add-on"); + }); } -function test() { - waitForExplicitFinish(); +function promiseFailedInstall() { + return promiseInstallListener().then( + aInstall => { + ok(false, "Should not have seen the install complete"); + is(aInstall.addon.id, HOTFIX_ID, "Should have installed the right add-on"); + aInstall.addon.uninstall(); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_LASTVERSION); + }, + aInstall => { + ok(true, "Should have seen the download cancelled"); + is(aInstall.addon.id, HOTFIX_ID, "Should have seen the right add-on"); + }); +} +add_task(function setup() { Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, true); Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false); Services.prefs.setBoolPref(PREF_UPDATE_REQUIREBUILTINCERTS, false); @@ -78,109 +83,85 @@ function test() { var prefs = Services.prefs.getChildList(PREF_EM_HOTFIX_CERTS); prefs.forEach(Services.prefs.clearUserPref); }); - - run_next_test(); -} - -function end_test() { - finish(); -} - -add_test(function check_no_cert_checks() { - Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, false); - AddonManager.addInstallListener(SuccessfulInstallListener); - - gNextTest = run_next_test; - - AddonManagerPrivate.backgroundUpdateCheck(); }); -add_test(function check_wrong_cert_fingerprint() { +add_task(function* check_no_cert_checks() { + Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, false); + yield Promise.all([ + promiseSuccessfulInstall(), + AddonManagerPrivate.backgroundUpdateCheck() + ]); +}); + +add_task(function* check_wrong_cert_fingerprint() { Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true); Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "foo"); - AddonManager.addInstallListener(FailedInstallListener); - - gNextTest = function() { - Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); - - run_next_test(); - }; - - AddonManagerPrivate.backgroundUpdateCheck(); + yield Promise.all([ + promiseFailedInstall(), + AddonManagerPrivate.backgroundUpdateCheck() + ]); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); }); -add_test(function check_right_cert_fingerprint() { +add_task(function* check_right_cert_fingerprint() { Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true); Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "3E:B9:4E:07:12:FE:3C:01:41:46:13:46:FC:84:52:1A:8C:BE:1D:A2"); - AddonManager.addInstallListener(SuccessfulInstallListener); + yield Promise.all([ + promiseSuccessfulInstall(), + AddonManagerPrivate.backgroundUpdateCheck() + ]); - gNextTest = function() { - Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); - - run_next_test(); - }; - - AddonManagerPrivate.backgroundUpdateCheck(); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); }); -add_test(function check_multi_cert_fingerprint_1() { +add_task(function* check_multi_cert_fingerprint_1() { Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true); Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "3E:B9:4E:07:12:FE:3C:01:41:46:13:46:FC:84:52:1A:8C:BE:1D:A2"); Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint", "foo"); - AddonManager.addInstallListener(SuccessfulInstallListener); + yield Promise.all([ + promiseSuccessfulInstall(), + AddonManagerPrivate.backgroundUpdateCheck() + ]); - gNextTest = function() { - Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); - Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint"); - - run_next_test(); - }; - - AddonManagerPrivate.backgroundUpdateCheck(); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint"); }); -add_test(function check_multi_cert_fingerprint_2() { +add_task(function* check_multi_cert_fingerprint_2() { Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true); Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "foo"); Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint", "3E:B9:4E:07:12:FE:3C:01:41:46:13:46:FC:84:52:1A:8C:BE:1D:A2"); - AddonManager.addInstallListener(SuccessfulInstallListener); + yield Promise.all([ + promiseSuccessfulInstall(), + AddonManagerPrivate.backgroundUpdateCheck() + ]); - gNextTest = function() { - Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); - Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint"); - - run_next_test(); - }; - - AddonManagerPrivate.backgroundUpdateCheck(); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint"); }); -add_test(function check_no_cert_no_checks() { +add_task(function* check_no_cert_no_checks() { Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, false); Services.prefs.setCharPref(PREF_EM_HOTFIX_URL, TESTROOT + "unsigned_hotfix.rdf"); - AddonManager.addInstallListener(SuccessfulInstallListener); - - gNextTest = run_next_test; - - AddonManagerPrivate.backgroundUpdateCheck(); + yield Promise.all([ + promiseSuccessfulInstall(), + AddonManagerPrivate.backgroundUpdateCheck() + ]); }); -add_test(function check_no_cert_cert_fingerprint_check() { +add_task(function* check_no_cert_cert_fingerprint_check() { Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true); Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "3E:B9:4E:07:12:FE:3C:01:41:46:13:46:FC:84:52:1A:8C:BE:1D:A2"); - AddonManager.addInstallListener(FailedInstallListener); + yield Promise.all([ + promiseFailedInstall(), + AddonManagerPrivate.backgroundUpdateCheck() + ]); - gNextTest = function() { - Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); - - run_next_test(); - }; - - AddonManagerPrivate.backgroundUpdateCheck(); + Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint"); }); diff --git a/toolkit/mozapps/extensions/test/browser/browser_manualupdates.js b/toolkit/mozapps/extensions/test/browser/browser_manualupdates.js index 27a4a6cd801..3c0de42bc28 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_manualupdates.js +++ b/toolkit/mozapps/extensions/test/browser/browser_manualupdates.js @@ -184,7 +184,7 @@ add_test(function() { is_element_hidden(item._installStatus, "Install progress widget should be hidden"); if (badgeUpdated) - run_next_test(); + executeSoon(run_next_test); else installCompleted = true; } diff --git a/toolkit/mozapps/extensions/test/browser/browser_searching.js b/toolkit/mozapps/extensions/test/browser/browser_searching.js index 9e03e82973d..7c29ff0fc19 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_searching.js +++ b/toolkit/mozapps/extensions/test/browser/browser_searching.js @@ -566,7 +566,7 @@ add_test(function() { is(installBtn.hidden, true, "Install button should be hidden after install ended"); check_filtered_results(QUERY, "relevancescore", false); - run_next_test(); + executeSoon(run_next_test); } } diff --git a/toolkit/mozapps/extensions/test/browser/browser_select_compatoverrides.js b/toolkit/mozapps/extensions/test/browser/browser_select_compatoverrides.js index 7735f109067..747811e6372 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_select_compatoverrides.js +++ b/toolkit/mozapps/extensions/test/browser/browser_select_compatoverrides.js @@ -30,7 +30,7 @@ function install_test_addon(aCallback) { onInstallEnded: function() { AddonManager.getAddonByID("addon1@tests.mozilla.org", function(addon) { gTestAddon = addon; - aCallback(); + executeSoon(aCallback); }); } };