From a2a7ef293feb89263966bfb882c08f05270ac1da Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Mon, 7 May 2018 10:05:56 -0400 Subject: [PATCH] Bug 1459298 - Stop spinning event loop when window closes; r=esawin If our window closes while we're spinning the event loop, stop spinning as soon as possible so we can continue with cleaning up the window. MozReview-Commit-ID: ByS0c6R0cM8 --HG-- extra : rebase_source : 6d32f1e8c6d6119eaaacb6a3ef5d9319c884e642 --- .../geckoview/GeckoViewNavigationContent.js | 4 ++-- .../geckoview/GeckoViewPermission.js | 2 +- .../components/geckoview/GeckoViewPrompt.js | 8 +++++--- .../modules/geckoview/GeckoViewNavigation.jsm | 18 ++++++++++-------- .../modules/geckoview/GeckoViewUtils.jsm | 15 ++++++++------- .../modules/geckoview/LoadURIDelegate.jsm | 11 ++++++++--- 6 files changed, 34 insertions(+), 24 deletions(-) diff --git a/mobile/android/chrome/geckoview/GeckoViewNavigationContent.js b/mobile/android/chrome/geckoview/GeckoViewNavigationContent.js index 2ae2ffdf03ef..f0deb8399457 100644 --- a/mobile/android/chrome/geckoview/GeckoViewNavigationContent.js +++ b/mobile/android/chrome/geckoview/GeckoViewNavigationContent.js @@ -39,8 +39,8 @@ class GeckoViewNavigationContent extends GeckoViewContentModule { addEventListener("click", ErrorPageEventHandler, true); } - return LoadURIDelegate.load(this.eventDispatcher, aUri, aWhere, aFlags, - aTriggeringPrincipal); + return LoadURIDelegate.load(content, this.eventDispatcher, + aUri, aWhere, aFlags); } } diff --git a/mobile/android/components/geckoview/GeckoViewPermission.js b/mobile/android/components/geckoview/GeckoViewPermission.js index 748d2599071b..7c845157d7eb 100644 --- a/mobile/android/components/geckoview/GeckoViewPermission.js +++ b/mobile/android/components/geckoview/GeckoViewPermission.js @@ -55,7 +55,7 @@ GeckoViewPermission.prototype = { perms.push(PERM_RECORD_AUDIO); } - let dispatcher = GeckoViewUtils.getActiveDispatcher(); + let [dispatcher] = GeckoViewUtils.getActiveDispatcherAndWindow(); let callback = _ => { Services.obs.notifyObservers(aCallback, "getUserMedia:got-device-permission"); }; diff --git a/mobile/android/components/geckoview/GeckoViewPrompt.js b/mobile/android/components/geckoview/GeckoViewPrompt.js index e54fcf2be19f..dd1ba385778a 100644 --- a/mobile/android/components/geckoview/GeckoViewPrompt.js +++ b/mobile/android/components/geckoview/GeckoViewPrompt.js @@ -344,7 +344,8 @@ function PromptDelegate(aDomWin) { } if (!this._dispatcher) { - this._dispatcher = GeckoViewUtils.getActiveDispatcher(); + [this._dispatcher, this._domWin] = + GeckoViewUtils.getActiveDispatcherAndWindow(); } } @@ -392,14 +393,15 @@ PromptDelegate.prototype = { */ _showPrompt: function(aMsg) { let result = undefined; - if (!this._changeModalState(/* aEntering */ true)) { + if (!this._domWin || !this._changeModalState(/* aEntering */ true)) { return; } try { this.asyncShowPrompt(aMsg, res => result = res); // Spin this thread while we wait for a result - Services.tm.spinEventLoopUntil(() => result !== undefined); + Services.tm.spinEventLoopUntil(() => + this._domWin.closed || result !== undefined); } finally { this._changeModalState(/* aEntering */ false); } diff --git a/mobile/android/modules/geckoview/GeckoViewNavigation.jsm b/mobile/android/modules/geckoview/GeckoViewNavigation.jsm index ef1a544004a9..1bf66252f062 100644 --- a/mobile/android/modules/geckoview/GeckoViewNavigation.jsm +++ b/mobile/android/modules/geckoview/GeckoViewNavigation.jsm @@ -139,14 +139,15 @@ class GeckoViewNavigation extends GeckoViewModule { nextTabParentId: aNextTabParentId }); }).then(window => { - browser = (window && window.browser); + browser = (window && window.browser) || null; }, () => { browser = null; }); // Wait indefinitely for app to respond with a browser or null - Services.tm.spinEventLoopUntil(() => browser !== undefined); - return browser; + Services.tm.spinEventLoopUntil(() => + this.window.closed || browser !== undefined); + return browser || null; } // nsIBrowserDOMWindow. @@ -154,8 +155,8 @@ class GeckoViewNavigation extends GeckoViewModule { debug `createContentWindow: uri=${aUri && aUri.spec} where=${aWhere} flags=${aFlags}`; - if (LoadURIDelegate.load(this.eventDispatcher, aUri, aWhere, aFlags, - aTriggeringPrincipal)) { + if (LoadURIDelegate.load(this.window, this.eventDispatcher, + aUri, aWhere, aFlags)) { // The app has handled the load, abort open-window handling. Components.returnCode = Cr.NS_ERROR_ABORT; return null; @@ -179,7 +180,8 @@ class GeckoViewNavigation extends GeckoViewModule { nextTabParentId=${aNextTabParentId} name=${aName}`; - if (LoadURIDelegate.load(this.eventDispatcher, aUri, aWhere, aFlags, null)) { + if (LoadURIDelegate.load(this.window, this.eventDispatcher, + aUri, aWhere, aFlags)) { // The app has handled the load, abort open-window handling. Components.returnCode = Cr.NS_ERROR_ABORT; return null; @@ -199,8 +201,8 @@ class GeckoViewNavigation extends GeckoViewModule { debug `handleOpenUri: uri=${aUri && aUri.spec} where=${aWhere} flags=${aFlags}`; - if (LoadURIDelegate.load(this.eventDispatcher, aUri, aWhere, aFlags, - aTriggeringPrincipal)) { + if (LoadURIDelegate.load(this.window, this.eventDispatcher, + aUri, aWhere, aFlags)) { return null; } diff --git a/mobile/android/modules/geckoview/GeckoViewUtils.jsm b/mobile/android/modules/geckoview/GeckoViewUtils.jsm index a7e7fd804a54..e1aea83425c9 100644 --- a/mobile/android/modules/geckoview/GeckoViewUtils.jsm +++ b/mobile/android/modules/geckoview/GeckoViewUtils.jsm @@ -289,21 +289,22 @@ var GeckoViewUtils = { return null; }, - getActiveDispatcher: function() { - let dispatcher = this.getDispatcherForWindow(Services.focus.activeWindow); + getActiveDispatcherAndWindow: function() { + let win = Services.focus.activeWindow; + let dispatcher = this.getDispatcherForWindow(win); if (dispatcher) { - return dispatcher; + return [dispatcher, win]; } let iter = Services.wm.getEnumerator(/* windowType */ null); while (iter.hasMoreElements()) { - dispatcher = this.getDispatcherForWindow( - iter.getNext().QueryInterface(Ci.nsIDOMWindow)); + win = iter.getNext().QueryInterface(Ci.nsIDOMWindow); + dispatcher = this.getDispatcherForWindow(win); if (dispatcher) { - return dispatcher; + return [dispatcher, win]; } } - return null; + return [null, null]; }, /** diff --git a/mobile/android/modules/geckoview/LoadURIDelegate.jsm b/mobile/android/modules/geckoview/LoadURIDelegate.jsm index d0d6097457dd..cdcec1e8f482 100644 --- a/mobile/android/modules/geckoview/LoadURIDelegate.jsm +++ b/mobile/android/modules/geckoview/LoadURIDelegate.jsm @@ -15,7 +15,11 @@ XPCOMUtils.defineLazyModuleGetters(this, { var LoadURIDelegate = { // Delegate URI loading to the app. // Return whether the loading has been handled. - load: function(aEventDispatcher, aUri, aWhere, aFlags, aTriggeringPrincipal) { + load: function(aWindow, aEventDispatcher, aUri, aWhere, aFlags) { + if (!aWindow) { + return false; + } + const message = { type: "GeckoView:OnLoadRequest", uri: aUri ? aUri.displaySpec : "", @@ -31,8 +35,9 @@ var LoadURIDelegate = { // treat as unhandled. handled = false; }); - Services.tm.spinEventLoopUntil(() => handled !== undefined); + Services.tm.spinEventLoopUntil(() => + aWindow.closed || handled !== undefined); - return handled; + return handled || false; } };