Bug 1756049 - Migrate GeckoViewPrompter.jsm to actor. r=ohall,owlish

Differential Revision: https://phabricator.services.mozilla.com/D141973
This commit is contained in:
Agi Sferro 2022-05-17 01:34:42 +00:00
Родитель a2706c8d0a
Коммит 8a9ef6fe70
5 изменённых файлов: 51 добавлений и 73 удалений

Просмотреть файл

@ -16,12 +16,12 @@ class GeckoViewPrompterChild extends GeckoViewActorChild {
this._prompts = new Map();
}
registerPrompt(prompt) {
this._prompts.set(prompt.id, prompt);
this.sendAsyncMessage("RegisterPrompt", {
dismissPrompt(prompt) {
this.eventDispatcher.sendRequest({
type: "GeckoView:Prompt:Dismiss",
id: prompt.id,
promptType: prompt.getPromptType(),
});
this.unregisterPrompt(prompt);
}
unregisterPrompt(prompt) {
@ -31,10 +31,23 @@ class GeckoViewPrompterChild extends GeckoViewActorChild {
});
}
notifyPromptShow(prompt) {
prompt(prompt, message) {
this._prompts.set(prompt.id, prompt);
this.sendAsyncMessage("RegisterPrompt", {
id: prompt.id,
promptType: prompt.getPromptType(),
});
// We intentionally do not await here as we want to fire NotifyPromptShow
// immediately rather than waiting until the user accepts/dismisses the
// prompt.
const result = this.eventDispatcher.sendRequestForResult({
type: "GeckoView:Prompt",
prompt: message,
});
this.sendAsyncMessage("NotifyPromptShow", {
id: prompt.id,
});
return result;
}
/**
@ -76,3 +89,5 @@ class GeckoViewPrompterChild extends GeckoViewActorChild {
}
}
}
const { debug, warn } = GeckoViewPrompterChild.initLogging("Prompter");

Просмотреть файл

@ -34,15 +34,8 @@ class GeckoViewPrompter {
}
}
if (this._domWin) {
this._dispatcher = GeckoViewUtils.getDispatcherForWindow(this._domWin);
}
if (!this._dispatcher) {
[
this._dispatcher,
this._domWin,
] = GeckoViewUtils.getActiveDispatcherAndWindow();
if (!this._domWin) {
this._domWin = Services.wm.getMostRecentWindow("navigator:geckoview");
}
this._innerWindowId = this._domWin?.browsingContext.currentWindowContext.innerWindowId;
@ -88,8 +81,7 @@ class GeckoViewPrompter {
}
_dismissUi() {
this.prompterActor?.unregisterPrompt(this);
this._dispatcher.dispatch("GeckoView:Prompt:Dismiss", { id: this.id });
this.prompterActor?.dismissPrompt(this);
}
accept(aInputText = this.inputText) {
@ -186,46 +178,35 @@ class GeckoViewPrompter {
});
}
asyncShowPrompt(aMsg, aCallback) {
let handled = false;
async asyncShowPrompt(aMsg, aCallback) {
this.message = aMsg;
this.inputText = aMsg.value;
this.callback = aCallback;
this.prompterActor?.registerPrompt(this);
const onResponse = response => {
if (handled) {
return;
}
if (!this.checkInnerWindow()) {
// Page has navigated away, let's dismiss the prompt
aCallback(null);
} else {
aCallback(response);
}
// This callback object is tied to the Java garbage collector because
// it is invoked from Java. Manually release the target callback
// here; otherwise we may hold onto resources for too long, because
// we would be relying on both the Java and the JS garbage collectors
// to run.
aMsg = undefined;
aCallback = undefined;
handled = true;
};
if (!this._dispatcher || !this.checkInnerWindow()) {
onResponse(null);
return;
}
aMsg.id = this.id;
this._dispatcher.dispatch("GeckoView:Prompt", aMsg, {
onSuccess: onResponse,
onError: error => {
Cu.reportError("Prompt error: " + error);
onResponse(null);
},
});
this.prompterActor?.notifyPromptShow(this);
let response = null;
try {
if (this.checkInnerWindow()) {
response = await this.prompterActor.prompt(this, aMsg);
}
} catch (error) {
// Nothing we can do really, we will treat this as a dismiss.
warn`Error while prompting: ${error}`;
}
if (!this.checkInnerWindow()) {
// Page has navigated away, let's dismiss the prompt
aCallback(null);
} else {
aCallback(response);
}
// This callback object is tied to the Java garbage collector because
// it is invoked from Java. Manually release the target callback
// here; otherwise we may hold onto resources for too long, because
// we would be relying on both the Java and the JS garbage collectors
// to run.
aMsg = undefined;
aCallback = undefined;
}
}

Просмотреть файл

@ -1319,14 +1319,12 @@ public class GeckoSession {
@Override
public void handleMessage(
final String event, final GeckoBundle message, final EventCallback callback) {
if (DEBUG) {
Log.d(LOGTAG, "handleMessage: event = " + event);
}
Log.d(LOGTAG, "handleMessage " + event);
if ("GeckoView:PinOnScreen".equals(event)) {
GeckoSession.this.setShouldPinOnScreen(message.getBoolean("pinned"));
} else if ("GeckoView:Prompt".equals(event)) {
mPromptController.handleEvent(GeckoSession.this, message, callback);
mPromptController.handleEvent(GeckoSession.this, message.getBundle("prompt"), callback);
} else if ("GeckoView:Prompt:Dismiss".equals(event)) {
mPromptController.dismissPrompt(message.getString("id"));
}

Просмотреть файл

@ -79,6 +79,7 @@ import org.mozilla.geckoview.GeckoSession.PromptDelegate.TextPrompt;
public void handleEvent(
final GeckoSession session, final GeckoBundle message, final EventCallback callback) {
Log.d(LOGTAG, "handleEvent " + message.getString("type"));
final PromptDelegate delegate = session.getPromptDelegate();
if (delegate == null) {
// Default behavior is same as calling dismiss() on callback.

Просмотреть файл

@ -365,23 +365,6 @@ var GeckoViewUtils = {
return null;
},
getActiveDispatcherAndWindow() {
const bc = Services.focus.activeBrowsingContext;
const win = bc ? bc.window : null; // WON'T WORK FOR OOP IFRAMES!
let dispatcher = this.getDispatcherForWindow(win);
if (dispatcher) {
return [dispatcher, win];
}
for (const win of Services.wm.getEnumerator(/* windowType */ null)) {
dispatcher = this.getDispatcherForWindow(win);
if (dispatcher) {
return [dispatcher, win];
}
}
return [null, null];
},
/**
* Add logging functions to the specified scope that forward to the given
* Log.jsm logger. Currently "debug" and "warn" functions are supported. To