gecko-dev/remote/sessions/ContentProcessSession.jsm
Alexandre Poirot 370bc3f1f2 Bug 1563692 - Move all CDP's JSON packet handling to Connection. r=remote-protocol-reviewers,jdescottes,ato
This helps sharing a single implementation of how the JSON objects
are read and written from/to the WebSocket connection.
Also, by delegating the command calls to the Session via `Session.execute`
and expecting a promise with a resolution or rejection, we make error
handling of command calls clearer and unified.

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

--HG--
extra : moz-landing-system : lando
2019-07-11 17:45:29 +00:00

95 lines
2.8 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;
// Most children or sibling classes are going to assume that docShell
// implements the following interface. So do the QI only once from here.
this.docShell.QueryInterface(Ci.nsIWebNavigation);
this.domains = new Domains(this, ContentProcessDomains);
this.messageManager.addMessageListener("remote:request", this);
this.messageManager.addMessageListener("remote:destroy", this);
}
destructor() {
this.messageManager.removeMessageListener("remote:request", this);
this.messageManager.removeMessageListener("remote:destroy", this);
this.domains.clear();
}
// 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 result = await this.domains.execute(domain, command, 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.destructor();
break;
}
}
}