From 6b1641fe8994916821eda0a246d7403cfb3f8a49 Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Thu, 1 Jun 2017 15:07:16 -0400 Subject: [PATCH] Bug 1367081 - Make PromptService usable from GeckoView custom tabs; r=droeh Make PromptService and Prompt.jsm not depend as much on BrowserApp and the main Fennec window, so it can be used from a GeckoView-based custom tabs Activity. This approach is used because it involves a lot less work than trying to implement a PromptDelegate for Fennec. MozReview-Commit-ID: AEH0HgAOx2S --- .../base/java/org/mozilla/gecko/GeckoApp.java | 2 +- .../mozilla/gecko/prompts/PromptService.java | 16 ++++----- mobile/android/modules/Prompt.jsm | 34 ++++++++++++++++--- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java index 64c8803b740b..92d9fcc0637a 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java @@ -1841,7 +1841,7 @@ public abstract class GeckoApp extends GeckoActivity startActivity(settingsIntent); } - mPromptService = new PromptService(this); + mPromptService = new PromptService(this, getAppEventDispatcher()); // Trigger the completion of the telemetry timer that wraps activity startup, // then grab the duration to give to FHR. diff --git a/mobile/android/base/java/org/mozilla/gecko/prompts/PromptService.java b/mobile/android/base/java/org/mozilla/gecko/prompts/PromptService.java index 827713194303..923f5f131fb4 100644 --- a/mobile/android/base/java/org/mozilla/gecko/prompts/PromptService.java +++ b/mobile/android/base/java/org/mozilla/gecko/prompts/PromptService.java @@ -6,8 +6,6 @@ package org.mozilla.gecko.prompts; import org.mozilla.gecko.EventDispatcher; -import org.mozilla.gecko.GeckoApp; -import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.util.BundleEventListener; import org.mozilla.gecko.util.EventCallback; import org.mozilla.gecko.util.GeckoBundle; @@ -19,17 +17,19 @@ import android.util.Log; public class PromptService implements BundleEventListener { private static final String LOGTAG = "GeckoPromptService"; - private final GeckoApp mGeckoApp; + private final Context mContext; + private final EventDispatcher mDispatcher; - public PromptService(GeckoApp geckoApp) { - mGeckoApp = geckoApp; - mGeckoApp.getAppEventDispatcher().registerUiThreadListener(this, + public PromptService(final Context context, final EventDispatcher dispatcher) { + mContext = context; + mDispatcher = dispatcher; + mDispatcher.registerUiThreadListener(this, "Prompt:Show", "Prompt:ShowTop"); } public void destroy() { - mGeckoApp.getAppEventDispatcher().unregisterUiThreadListener(this, + mDispatcher.unregisterUiThreadListener(this, "Prompt:Show", "Prompt:ShowTop"); } @@ -39,7 +39,7 @@ public class PromptService implements BundleEventListener { public void handleMessage(final String event, final GeckoBundle message, final EventCallback callback) { Prompt p; - p = new Prompt(mGeckoApp, new Prompt.PromptCallback() { + p = new Prompt(mContext, new Prompt.PromptCallback() { @Override public void onPromptFinished(final GeckoBundle result) { callback.sendSuccess(result); diff --git a/mobile/android/modules/Prompt.jsm b/mobile/android/modules/Prompt.jsm index c28a71c31298..1295e903f1c5 100644 --- a/mobile/android/modules/Prompt.jsm +++ b/mobile/android/modules/Prompt.jsm @@ -7,6 +7,7 @@ var Cc = Components.classes; var Ci = Components.interfaces; +Components.utils.import("resource://gre/modules/Messaging.jsm"); Components.utils.import("resource://gre/modules/Services.jsm"); this.EXPORTED_SYMBOLS = ["Prompt"]; @@ -15,14 +16,24 @@ function log(msg) { Services.console.logStringMessage(msg); } +function getRootWindow(win) { + // Get the root xul window. + return win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDocShell).QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); +} + function Prompt(aOptions) { this.window = "window" in aOptions ? aOptions.window : null; this.msg = { async: true }; if (this.window) { - let window = Services.wm.getMostRecentWindow("navigator:browser"); - var tab = window.BrowserApp.getTabForWindow(this.window); + let window = getRootWindow(this.window); + var tab = window && + window.BrowserApp && + window.BrowserApp.getTabForWindow(this.window); if (tab) { this.msg.tabId = tab.id; } @@ -174,11 +185,24 @@ Prompt.prototype = { this._innerShow(); }, + _getDispatcher: function(win) { + let root = win && getRootWindow(win); + try { + return root && (root.WindowEventDispatcher || EventDispatcher.for(root)); + } catch (e) { + // No EventDispatcher for this window. + return null; + } + }, + _innerShow: function() { - let window = Services.wm.getMostRecentWindow("navigator:browser"); - window.WindowEventDispatcher.sendRequestForResult(this.msg).then((data) => { - if (this.callback) + let dispatcher = + this._getDispatcher(this.window) || + this._getDispatcher(Services.wm.getMostRecentWindow("navigator:browser")); + dispatcher.sendRequestForResult(this.msg).then((data) => { + if (this.callback) { this.callback(data); + } }); },