gecko-dev/remote/sessions/ContentProcessSession.jsm
Andreas Tolfsen da5a13b347 bug 1537775: remote: clarify method/domain/command terminology; r=ochameau
The remote agent currently uses "method" interchangably for the
full method string as extracted from JSON input as well as for the
function part following the first dot after the method has been split.

To avoid namespace clashes, this patch makes a distinction between
method, being the input JSON field; the first substring prior to the
dot being the domain; and the rest that follows being called the command:

	method = "<domain>.<command>"

This naming seems to be supported by chrome-remote-interface:

	https://github.com/cyrus-and/chrome-remote-interface/blob/master/lib/api.js#L32

Differential Revision: https://phabricator.services.mozilla.com/D25946

--HG--
extra : moz-landing-system : lando
2019-04-04 11:35:24 +00:00

92 lines
2.7 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = ["ContentProcessSession"];
const {ContentProcessDomains} = ChromeUtils.import("chrome://remote/content/domains/ContentProcessDomains.jsm");
const {Domains} = ChromeUtils.import("chrome://remote/content/domains/Domains.jsm");
class ContentProcessSession {
constructor(messageManager, browsingContext, content, docShell) {
this.messageManager = messageManager;
this.browsingContext = browsingContext;
this.content = content;
this.docShell = docShell;
this.domains = new Domains(this, ContentProcessDomains);
this.messageManager.addMessageListener("remote:request", this);
this.messageManager.addMessageListener("remote:destroy", this);
}
destroy() {
this.messageManager.removeMessageListener("remote:request", this);
this.messageManager.removeMessageListener("remote:destroy", this);
}
// Domain event listener
onEvent(eventName, params) {
this.messageManager.sendAsyncMessage("remote:event", {
browsingContextId: this.browsingContext.id,
event: {
eventName,
params,
},
});
}
// nsIMessageListener
async receiveMessage({name, data}) {
const {browsingContextId} = data;
// We may have more than one tab loaded in the same process,
// and debug the two at the same time. We want to ensure not
// mixing up the requests made against two such tabs.
// Each tab is going to have its own frame script instance
// and two communication channels are going to be set up via
// the two message managers.
if (browsingContextId != this.browsingContext.id) {
return;
}
switch (name) {
case "remote:request":
try {
const {id, domain, command, params} = data.request;
const inst = this.domains.get(domain);
const func = inst[command];
if (!func || typeof func != "function") {
throw new Error(`Implementation missing: ${domain}.${command}`);
}
const result = await func.call(inst, params);
this.messageManager.sendAsyncMessage("remote:result", {
browsingContextId,
id,
result,
});
} catch (e) {
this.messageManager.sendAsyncMessage("remote:error", {
browsingContextId,
id: data.request.id,
error: {
name: e.name || "exception",
message: e.message || String(e),
stack: e.stack,
},
});
}
break;
case "remote:destroy":
this.destroy();
break;
}
}
}