diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index bae6e2de6f..acc4b9cd80 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -1,2 +1,2 @@ -1185 -Changed: lushnikov@chromium.org Wed Oct 7 08:45:05 PDT 2020 +1186 +Changed: lushnikov@chromium.org Wed Oct 7 09:26:45 PDT 2020 diff --git a/browser_patches/firefox/juggler/protocol/BrowserHandler.js b/browser_patches/firefox/juggler/protocol/BrowserHandler.js index cce64d5561..e99a9c4fd5 100644 --- a/browser_patches/firefox/juggler/protocol/BrowserHandler.js +++ b/browser_patches/firefox/juggler/protocol/BrowserHandler.js @@ -4,6 +4,7 @@ "use strict"; +const {AddonManager} = ChromeUtils.import("resource://gre/modules/AddonManager.jsm"); const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js"); const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js'); @@ -45,6 +46,18 @@ class BrowserHandler { for (const target of this._targetRegistry.targets()) this._onTargetCreated(target); + + // Wait to complete initialization of addon manager and search + // service before returning from this method. Failing to do so will result + // in a broken shutdown sequence and multiple errors in browser STDERR log. + // + // NOTE: we have to put this here instead of in the `Browser.close` handler + // since browser shutdown can be initiated when the last tab is closed, e.g. + // with persistent context. + await Promise.all([ + waitForAddonManager(), + waitForSearchService(), + ]); } async ['Browser.createBrowserContext']({removeOnDetach}) { @@ -243,6 +256,26 @@ class BrowserHandler { } } +async function waitForSearchService() { + const searchService = Components.classes["@mozilla.org/browser/search-service;1"].getService(Components.interfaces.nsISearchService); + await searchService.init(); +} + +async function waitForAddonManager() { + if (AddonManager.isReady) + return; + await new Promise(resolve => { + let listener = { + onStartup() { + AddonManager.removeManagerListener(listener); + resolve(); + }, + onShutdown() { }, + }; + AddonManager.addManagerListener(listener); + }); +} + function nullToUndefined(value) { return value === null ? undefined : value; }