Bug 1506549 - Return target fronts out of RootFront.getProcess and getMainProcess. r=yulia

MozReview-Commit-ID: EGWYEmAkbtr

Depends on D11693

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alexandre Poirot 2018-11-15 10:22:49 +00:00
parent bf45800c90
commit 1578b6da37
20 changed files with 103 additions and 74 deletions

View File

@ -28,12 +28,6 @@ function initDebuggerClient() {
return new DebuggerClient(transport);
}
async function attachThread(client, actor) {
let [response, targetFront] = await client.attachTarget(actor);
let [response2, threadClient] = await targetFront.attachThread(null);
return threadClient;
}
function onNewSource(event, packet) {
if (packet.source.url.startsWith("chrome:")) {
ok(true, "Received a new chrome source: " + packet.source.url);
@ -63,9 +57,10 @@ add_task(async function() {
const [type] = await gClient.connect();
is(type, "browser", "Root actor should identify itself as a browser.");
const response = await gClient.mainRoot.getMainProcess();
let actor = response.form.actor;
gThreadClient = await attachThread(gClient, actor);
const front = await gClient.mainRoot.getMainProcess();
await front.attach();
const [, threadClient] = await front.attachThread();
gThreadClient = threadClient;
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:mozilla");
// listen for a new source and global

View File

@ -29,8 +29,8 @@ function test() {
let client = new DebuggerClient(DebuggerServer.connectPipe());
yield connect(client);
let chrome = yield client.mainRoot.getMainProcess();
let [, targetFront] = yield attachTarget(client, chrome.form);
let targetFront = yield client.mainRoot.getMainProcess();
yield targetFront.attach();
yield targetFront.attachThread();
yield testGetAllocationStack(client, chrome.form, () => {

View File

@ -129,8 +129,8 @@ var onConnectionReady = async function([aType, aTraits]) {
a.onclick = function() {
if (gClient.mainRoot.traits.allowChromeProcess) {
gClient.mainRoot.getMainProcess()
.then(aResponse => {
openToolbox(aResponse.form, true);
.then(front => {
openToolbox(null, true, null, front);
});
} else if (globals.consoleActor) {
openToolbox(globals, true, "webconsole", false);
@ -222,11 +222,12 @@ function handleConnectionTimeout() {
* The user clicked on one of the buttons.
* Opens the toolbox.
*/
function openToolbox(form, chrome = false, tool = "webconsole") {
function openToolbox(form, chrome = false, tool = "webconsole", activeTab = null) {
const options = {
form: form,
form,
activeTab,
client: gClient,
chrome: chrome,
chrome,
};
TargetFactory.forRemoteTab(options).then((target) => {
const hostType = Toolbox.HostType.WINDOW;

View File

@ -318,10 +318,8 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
const client = new DebuggerClient(transport);
await client.connect();
const { form } = await client.mainRoot.getProcess(processId);
const front = await client.mainRoot.attachContentProcessTarget(form);
const front = await client.mainRoot.getProcess(processId);
const options = {
form,
activeTab: front,
client,
chrome: true,

View File

@ -51,7 +51,7 @@ exports.targetFromURL = async function targetFromURL(url) {
// (handy to debug chrome stuff in a content process)
let chrome = params.has("chrome");
let form;
let form, front;
if (type === "tab") {
// Fetch target for a remote tab
id = parseInt(id, 10);
@ -75,8 +75,7 @@ exports.targetFromURL = async function targetFromURL(url) {
if (isNaN(id)) {
id = 0;
}
const response = await client.mainRoot.getProcess(id);
form = response.form;
front = await client.mainRoot.getProcess(id);
chrome = true;
} catch (ex) {
if (ex.error == "noProcess") {
@ -107,7 +106,7 @@ exports.targetFromURL = async function targetFromURL(url) {
throw new Error(`targetFromURL, unsupported type '${type}' parameter`);
}
return TargetFactory.forRemoteTab({ client, form, chrome });
return TargetFactory.forRemoteTab({ client, form, activeTab: front, chrome });
};
/**

View File

@ -525,8 +525,17 @@ Target.prototype = {
// Attach the target actor
const attachBrowsingContextTarget = async () => {
const [, targetFront] = await this._client.attachTarget(this.form.actor);
this.activeTab = targetFront;
// Some BrowsingContextTargetFront are already instantiated and passed as
// contructor's argument, like for ParentProcessTargetActor.
// For them, we only need to attach them.
// The call to attachTarget is to be removed once all Target are having a front
// passed as contructor's argument.
if (!this.activeTab) {
const [, targetFront] = await this._client.attachTarget(this.form.actor);
this.activeTab = targetFront;
} else {
await this.activeTab.attach();
}
this.activeTab.on("tabNavigated", this._onTabNavigated);
this._onFrameUpdate = packet => {

View File

@ -7,10 +7,10 @@
function test() {
waitForExplicitFinish();
getParentProcessActors((client, response) => {
getParentProcessActors((client, front) => {
const options = {
form: response,
client: client,
activeTab: front,
client,
chrome: true,
};

View File

@ -52,10 +52,10 @@ async function testTarget(client, target) {
function test() {
waitForExplicitFinish();
getParentProcessActors((client, response) => {
getParentProcessActors((client, front) => {
const options = {
form: response,
client: client,
activeTab: front,
client,
chrome: true,
};

View File

@ -35,8 +35,8 @@ function getParentProcessActors(callback) {
const client = new DebuggerClient(DebuggerServer.connectPipe());
client.connect()
.then(() => client.mainRoot.getMainProcess())
.then(response => {
callback(client, response.form);
.then(front => {
callback(client, front);
});
SimpleTest.registerCleanupFunction(() => {

View File

@ -93,8 +93,8 @@ var connect = async function() {
const addonTargetActor = addons.filter(addon => addon.id === addonID).pop();
await openToolbox({form: addonTargetActor, chrome: true});
} else {
const response = await gClient.mainRoot.getMainProcess();
await openToolbox({form: response.form, chrome: true});
const front = await gClient.mainRoot.getMainProcess();
await openToolbox({activeTab: front, chrome: true});
}
};
@ -140,13 +140,14 @@ function onCloseCommand(event) {
window.close();
}
async function openToolbox({ form, chrome }) {
async function openToolbox({ form, activeTab, chrome }) {
let options = {
form: form,
form,
activeTab,
client: gClient,
chrome: chrome,
chrome,
};
appendStatusMessage(`Create toolbox target: ${JSON.stringify(arguments, null, 2)}`);
appendStatusMessage(`Create toolbox target: ${JSON.stringify({form, chrome}, null, 2)}`);
const target = await TargetFactory.forRemoteTab(options);
const frame = document.getElementById("toolbox-iframe");

View File

@ -2071,8 +2071,12 @@ ScratchpadWindow.prototype = extend(ScratchpadTab.prototype, {
const client = new DebuggerClient(DebuggerServer.connectPipe());
await client.connect();
const response = await client.mainRoot.getMainProcess();
return { form: response.form, client };
const front = await client.mainRoot.getMainProcess();
const target = await TargetFactory.forRemoteTab({
activeTab: front,
client,
});
return target;
},
});

View File

@ -136,8 +136,8 @@ HUDService.prototype = {
const client = new DebuggerClient(DebuggerServer.connectPipe());
await client.connect();
const response = await client.mainRoot.getMainProcess();
return { form: response.form, client, chrome: true };
const front = await client.mainRoot.getMainProcess();
return { activeTab: front, client, chrome: true };
}
async function openWindow(t) {

View File

@ -255,9 +255,9 @@ var AppManager = exports.AppManager = {
// Fx >=39 exposes a ParentProcessTargetActor to debug the main process
if (this.connection.client.mainRoot.traits.allowChromeProcess) {
return this.connection.client.mainRoot.getMainProcess()
.then(aResponse => {
.then(front => {
return TargetFactory.forRemoteTab({
form: aResponse.form,
activeTab: front,
client: this.connection.client,
chrome: true,
});

View File

@ -85,7 +85,8 @@ function runTests() {
// Connect to the first content processe available
const content = response.processes.filter(p => (!p.parent))[0];
client.mainRoot.getProcess(content.id).then(({form: actor}) => {
client.mainRoot.getProcess(content.id).then(front => {
const actor = front.targetForm;
ok(actor.consoleActor, "Got the console actor");
ok(actor.chromeDebugger, "Got the thread actor");
@ -106,8 +107,8 @@ function runTests() {
// Assert that calling client.getProcess against the same process id is
// returning the same actor.
function getProcessAgain(firstActor, id) {
client.mainRoot.getProcess(id).then(response => {
const actor = response.form;
client.mainRoot.getProcess(id).then(front => {
const actor = front.targetForm;
is(actor, firstActor,
"Second call to getProcess with the same id returns the same form");
closeClient();

View File

@ -101,9 +101,9 @@ async function createFullRuntimeMemoryFront() {
const client = new DebuggerClient(DebuggerServer.connectPipe());
await client.connect();
const { form } = await client.mainRoot.getMainProcess();
const front = await client.mainRoot.getMainProcess();
const options = {
form,
activeTab: front,
client,
chrome: true,
};
@ -405,7 +405,7 @@ async function finishClient(client) {
function getParentProcessActors(client, server = DebuggerServer) {
server.allowChromeProcess = true;
return client.mainRoot.getMainProcess().then(response => response.form);
return client.mainRoot.getMainProcess().then(response => response.targetForm);
}
/**

View File

@ -25,11 +25,9 @@ add_task(async function() {
const desc = await deviceFront.getDescription();
equal(desc.geckobuildid, Services.appinfo.platformBuildID, "device actor works");
// Even though we have no tabs, getMainProcess gives us the chromeDebugger.
const response = await client.mainRoot.getMainProcess();
const { chromeDebugger } = response.form;
const [, threadClient] = await client.attachThread(chromeDebugger);
// Even though we have no tabs, getMainProcess gives us the chrome debugger.
const front = await client.mainRoot.getMainProcess();
const [, threadClient] = await front.attachThread();
const onResumed = new Promise(resolve => {
threadClient.addOneTimeListener("paused", (event, packet) => {
equal(packet.why.type, "breakpoint",

View File

@ -9,6 +9,7 @@ const protocol = require("devtools/shared/protocol");
const {custom} = protocol;
loader.lazyRequireGetter(this, "getFront", "devtools/shared/protocol", true);
loader.lazyRequireGetter(this, "BrowsingContextTargetFront", "devtools/shared/fronts/targets/browsing-context", true);
loader.lazyRequireGetter(this, "ContentProcessTargetFront", "devtools/shared/fronts/targets/content-process", true);
const RootFront = protocol.FrontClassWithSpec(rootSpec, {
@ -68,12 +69,8 @@ const RootFront = protocol.FrontClassWithSpec(rootSpec, {
if (process.parent) {
continue;
}
const { form } = await this.getProcess(process.id);
const processActor = form.actor;
const response = await this._client.request({
to: processActor,
type: "listWorkers",
});
const front = await this.getProcess(process.id);
const response = await front.listWorkers();
workers = workers.concat(response.workers);
}
} catch (e) {
@ -147,6 +144,33 @@ const RootFront = protocol.FrontClassWithSpec(rootSpec, {
return this.getProcess(0);
},
getProcess: custom(async function(id) {
// Do not use specification automatic marshalling as getProcess may return
// two different type: ParentProcessTargetActor or ContentProcessTargetActor.
// Also, we do want to memoize the fronts and return already existing ones.
const { form } = await this._getProcess(id);
let front = this.actor(form.actor);
if (front) {
return front;
}
// getProcess may return a ContentProcessTargetActor or a ParentProcessTargetActor
// In most cases getProcess(0) will return the main process target actor,
// which is a ParentProcessTargetActor, but not in xpcshell, which uses a
// ContentProcessTargetActor. So select the right front based on the actor ID.
if (form.actor.includes("contentProcessTarget")) {
front = new ContentProcessTargetFront(this._client, form);
} else {
// ParentProcessTargetActor doesn't have a specific front, instead it uses
// BrowsingContextTargetFront on the client side.
front = new BrowsingContextTargetFront(this._client, form);
}
this.manage(front);
return front;
}, {
impl: "_getProcess",
}),
/**
* Fetch the target actor for the currently selected tab, or for a specific
* tab given as first parameter.
@ -191,15 +215,6 @@ const RootFront = protocol.FrontClassWithSpec(rootSpec, {
impl: "_getTab",
}),
attachContentProcessTarget: async function(form) {
let front = this.actor(form.actor);
if (!front) {
front = new ContentProcessTargetFront(this._client, form);
this.manage(front);
}
return front;
},
/**
* Test request that returns the object passed as first argument.
*

View File

@ -24,6 +24,10 @@ protocol.FrontClassWithSpec(browsingContextTargetSpec, {
// TODO: remove once ThreadClient becomes a front
this.client = client;
// Save the full form for Target class usage
// Do not use `form` name to avoid colliding with protocol.js's `form` method
this.targetForm = form;
},
/**

View File

@ -13,6 +13,10 @@ const ContentProcessTargetFront = protocol.FrontClassWithSpec(contentProcessTarg
this.client = client;
this.chromeDebugger = form.chromeDebugger;
// Save the full form for Target class usage
// Do not use `form` name to avoid colliding with protocol.js's `form` method
this.targetForm = form;
this.traits = {};
},

View File

@ -78,9 +78,9 @@ var _attachConsole = async function(
}
if (!attachToTab) {
response = await state.dbgClient.mainRoot.getMainProcess();
await state.dbgClient.attachTarget(response.form.actor);
const consoleActor = response.form.consoleActor;
const front = await state.dbgClient.mainRoot.getMainProcess();
await front.attach();
const consoleActor = front.targetForm.consoleActor;
state.actor = consoleActor;
state.dbgClient.attachConsole(consoleActor, listeners)
.then(_onAttachConsole.bind(null, state), _onAttachError.bind(null, state));