diff --git a/devtools/client/shared/workers-listener.js b/devtools/client/shared/workers-listener.js index bf7db2801481..49f176303d94 100644 --- a/devtools/client/shared/workers-listener.js +++ b/devtools/client/shared/workers-listener.js @@ -28,14 +28,6 @@ class WorkersListener { this._listener = listener; this.rootFront.on("workerListChanged", this._listener); - this.rootFront.onFront("processDescriptor", processFront => { - processFront.onFront("contentProcessTarget", front => { - this._contentProcessFronts.push(front); - front.on("workerListChanged", this._listener); - }); - }); - - // Support FF69 and older this.rootFront.onFront("contentProcessTarget", front => { this._contentProcessFronts.push(front); front.on("workerListChanged", this._listener); diff --git a/devtools/server/actors/descriptors/moz.build b/devtools/server/actors/descriptors/moz.build deleted file mode 100644 index 55544d0f218b..000000000000 --- a/devtools/server/actors/descriptors/moz.build +++ /dev/null @@ -1,10 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -DevToolsModules( - 'process.js', -) - diff --git a/devtools/server/actors/descriptors/process.js b/devtools/server/actors/descriptors/process.js deleted file mode 100644 index 56b3fdc946b0..000000000000 --- a/devtools/server/actors/descriptors/process.js +++ /dev/null @@ -1,111 +0,0 @@ -/* 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"; - -const Services = require("Services"); -const { DebuggerServer } = require("devtools/server/main"); -const { Cc, Ci } = require("chrome"); - -const { ActorClassWithSpec, Actor } = require("devtools/shared/protocol"); -const { - processDescriptorSpec, -} = require("devtools/shared/specs/descriptors/process"); - -loader.lazyRequireGetter( - this, - "ContentProcessTargetActor", - "devtools/server/actors/targets/content-process", - true -); -loader.lazyRequireGetter( - this, - "ParentProcessTargetActor", - "devtools/server/actors/targets/parent-process", - true -); - -const ProcessDescriptorActor = ActorClassWithSpec(processDescriptorSpec, { - initialize(connection, options = {}) { - if ("id" in options && typeof options.id != "number") { - throw Error("process connect requires a valid `id` attribute."); - } - Actor.prototype.initialize.call(this, connection); - this.id = options.id; - this.isParent = options.parent; - this.destroy = this.destroy.bind(this); - }, - - _parentProcessConnect() { - const env = Cc["@mozilla.org/process/environment;1"].getService( - Ci.nsIEnvironment - ); - const isXpcshell = env.exists("XPCSHELL_TEST_PROFILE_DIR"); - let targetActor = null; - if (isXpcshell) { - // Check if we are running on xpcshell. - // When running on xpcshell, there is no valid browsing context to attach to - // and so ParentProcessTargetActor doesn't make sense as it inherits from - // BrowsingContextTargetActor. So instead use ContentProcessTargetActor, which - // matches xpcshell needs. - targetActor = new ContentProcessTargetActor(this.conn); - } else { - // Create the target actor for the parent process, which is in the same process - // as this target. Because we are in the same process, we have a true actor that - // should be managed by the ProcessDescriptorActor. - targetActor = new ParentProcessTargetActor(this.conn); - } - this.manage(targetActor); - // to be consistent with the return value of the _childProcessConnect, we are returning - // the form here. This might be memoized in the future - return targetActor.form(); - }, - - /** - * Connect to a remote process actor, always a ContentProcess target. - */ - async _childProcessConnect() { - const { id } = this; - const mm = Services.ppmm.getChildAt(id); - if (!mm) { - return { - error: "noProcess", - message: "There is no process with id '" + id + "'.", - }; - } - const childTargetForm = await DebuggerServer.connectToContentProcess( - this.conn, - mm, - this.destroy - ); - return childTargetForm; - }, - - /** - * Connect the a process actor. - */ - async getTarget() { - if (!DebuggerServer.allowChromeProcess) { - return { - error: "forbidden", - message: "You are not allowed to debug processes.", - }; - } - if (this.isParent) { - return this._parentProcessConnect(); - } - // This is a remote process we are connecting to - return this._childProcessConnect(); - }, - - form() { - return { - actor: this.actorID, - id: this.id, - isParent: this.isParent, - }; - }, -}); - -exports.ProcessDescriptorActor = ProcessDescriptorActor; diff --git a/devtools/server/actors/moz.build b/devtools/server/actors/moz.build index 144eff2183a5..241fe0cb7d8d 100644 --- a/devtools/server/actors/moz.build +++ b/devtools/server/actors/moz.build @@ -7,7 +7,6 @@ DIRS += [ 'accessibility', 'addon', - 'descriptors', 'emulation', 'highlighters', 'inspector', diff --git a/devtools/server/actors/root.js b/devtools/server/actors/root.js index 243709391f0c..910f6e329e79 100644 --- a/devtools/server/actors/root.js +++ b/devtools/server/actors/root.js @@ -6,7 +6,7 @@ "use strict"; -const { Cu } = require("chrome"); +const { Cc, Ci, Cu } = require("chrome"); const Services = require("Services"); const { Pool } = require("devtools/shared/protocol"); const { @@ -23,8 +23,14 @@ loader.lazyRequireGetter( ); loader.lazyRequireGetter( this, - "ProcessDescriptorActor", - "devtools/server/actors/descriptors/process", + "ContentProcessTargetActor", + "devtools/server/actors/targets/content-process", + true +); +loader.lazyRequireGetter( + this, + "ParentProcessTargetActor", + "devtools/server/actors/targets/parent-process", true ); @@ -117,6 +123,7 @@ function RootActor(connection, parameters) { this._globalActorPool = new LazyPool(this.conn); this._parentProcessTargetActor = null; + this._processActors = new Map(); } RootActor.prototype = { @@ -234,9 +241,6 @@ RootActor.prototype = { if (this._tabTargetActorPool) { this._tabTargetActorPool.destroy(); } - if (this._processDescriptorActorPool) { - this._processDescriptorActorPool.destroy(); - } if (this._globalActorPool) { this._globalActorPool.destroy(); } @@ -259,6 +263,7 @@ RootActor.prototype = { this._chromeWindowActorPool = null; this._parameters = null; this._parentProcessTargetActor = null; + this._processActors.clear(); }, /** @@ -555,25 +560,8 @@ RootActor.prototype = { }; } processList.onListChanged = this._onProcessListChanged; - const processes = processList.getList(); - const pool = new Pool(this.conn); - for (const metadata of processes) { - let processDescriptor = this._getKnownProcessDescriptor(metadata.id); - if (!processDescriptor) { - processDescriptor = new ProcessDescriptorActor(this.conn, metadata); - } - pool.manage(processDescriptor); - } - // Do not destroy the pool before transfering ownership to the newly created - // pool, so that we do not accidently destroy actors that are still in use. - if (this._processDescriptorActorPool) { - this._processDescriptorActorPool.destroy(); - } - this._processDescriptorActorPool = pool; - // extract the values in the processActors map - const processActors = [...this._processDescriptorActorPool.poolChildren()]; return { - processes: processActors.map(actor => actor.form()), + processes: processList.getList(), }; }, @@ -597,8 +585,44 @@ RootActor.prototype = { } // If the request doesn't contains id parameter or id is 0 // (id == 0, based on onListProcesses implementation) - const id = request.id || 0; + if (!("id" in request) || request.id === 0) { + // Check if we are running on xpcshell. + // When running on xpcshell, there is no valid browsing context to attach to + // and so ParentProcessTargetActor doesn't make sense as it inherits from + // BrowsingContextTargetActor. So instead use ContentProcessTargetActor, which + // matches xpcshell needs. + const env = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + const isXpcshell = env.exists("XPCSHELL_TEST_PROFILE_DIR"); + if ( + !isXpcshell && + this._parentProcessTargetActor && + (!this._parentProcessTargetActor.docShell || + this._parentProcessTargetActor.docShell.isBeingDestroyed) + ) { + this._parentProcessTargetActor.destroy(); + this._parentProcessTargetActor = null; + } + if (!this._parentProcessTargetActor) { + // Create the target actor for the parent process + if (isXpcshell) { + this._parentProcessTargetActor = new ContentProcessTargetActor( + this.conn + ); + } else { + this._parentProcessTargetActor = new ParentProcessTargetActor( + this.conn + ); + } + this._globalActorPool.manage(this._parentProcessTargetActor); + } + + return { form: this._parentProcessTargetActor.form() }; + } + + const { id } = request; const mm = Services.ppmm.getChildAt(id); if (!mm) { return { @@ -606,28 +630,20 @@ RootActor.prototype = { message: "There is no process with id '" + id + "'.", }; } - let processDescriptor = this._getKnownProcessDescriptor(id); - this._processDescriptorActorPool = - this._processDescriptorActorPool || new Pool(this.conn); - if (!processDescriptor) { - const options = { id, parent: id === 0 }; - processDescriptor = new ProcessDescriptorActor(this.conn, options); - this._processDescriptorActorPool.manage(processDescriptor); + let form = this._processActors.get(id); + if (form) { + return { form }; } - return { form: processDescriptor.form() }; - }, - - _getKnownProcessDescriptor(id) { - // if there is no pool, then we do not have any descriptors - if (!this._processDescriptorActorPool) { - return null; - } - for (const descriptor of this._processDescriptorActorPool.poolChildren()) { - if (descriptor.id === id) { - return descriptor; - } - } - return null; + const onDestroy = () => { + this._processActors.delete(id); + }; + form = await DebuggerServer.connectToContentProcess( + this.conn, + mm, + onDestroy + ); + this._processActors.set(id, form); + return { form }; }, /* This is not in the spec, but it's used by tests. */ diff --git a/devtools/server/tests/mochitest/test_getProcess.html b/devtools/server/tests/mochitest/test_getProcess.html index 824eda861e81..af6faa3a6b6f 100644 --- a/devtools/server/tests/mochitest/test_getProcess.html +++ b/devtools/server/tests/mochitest/test_getProcess.html @@ -83,28 +83,33 @@ function runTests() { "Got one additional process on the second call to listProcesses"); // Connect to the first content processe available - const content = response.processes.filter(p => (!p.isParent))[0]; + const content = response.processes.filter(p => (!p.parent))[0]; - client.mainRoot.getProcess(content.id).then(async front => { - const targetForm = front.targetForm; - ok(targetForm.consoleActor, "Got the console actor"); - ok(targetForm.threadActor, "Got the thread actor"); + client.mainRoot.getProcess(content.id).then(front => { + const actor = front.targetForm; + ok(actor.consoleActor, "Got the console actor"); + ok(actor.threadActor, "Got the thread actor"); // Ensure sending at least one request to an actor... - const consoleFront = await front.getFront("console"); - const { result } = await consoleFront.evaluateJS("var a = 42; a"); - is(result, 42, "console.eval worked"); + client.request({ + to: actor.consoleActor, + type: "evaluateJS", + text: "var a = 42; a", + }, function({result}) { + is(result, 42, "console.eval worked"); - getProcessAgain(front, content.id); + getProcessAgain(actor, content.id); + }); }); }); } // Assert that calling client.getProcess against the same process id is // returning the same actor. - function getProcessAgain(firstTargetFront, id) { + function getProcessAgain(firstActor, id) { client.mainRoot.getProcess(id).then(front => { - is(front, firstTargetFront, + const actor = front.targetForm; + is(actor, firstActor, "Second call to getProcess with the same id returns the same form"); closeClient(); }); diff --git a/devtools/shared/fronts/descriptors/moz.build b/devtools/shared/fronts/descriptors/moz.build deleted file mode 100644 index 55544d0f218b..000000000000 --- a/devtools/shared/fronts/descriptors/moz.build +++ /dev/null @@ -1,10 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -DevToolsModules( - 'process.js', -) - diff --git a/devtools/shared/fronts/descriptors/process.js b/devtools/shared/fronts/descriptors/process.js deleted file mode 100644 index 580fc0037ec9..000000000000 --- a/devtools/shared/fronts/descriptors/process.js +++ /dev/null @@ -1,94 +0,0 @@ -/* 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"; - -const { - processDescriptorSpec, -} = require("devtools/shared/specs/descriptors/process"); -const { - BrowsingContextTargetFront, -} = require("devtools/shared/fronts/targets/browsing-context"); -const { - ContentProcessTargetFront, -} = require("devtools/shared/fronts/targets/content-process"); -const { - FrontClassWithSpec, - registerFront, -} = require("devtools/shared/protocol"); - -class ProcessDescriptorFront extends FrontClassWithSpec(processDescriptorSpec) { - constructor(client) { - super(client); - this.isParent = false; - this._processTargetFront = null; - this._targetFrontPromise = null; - this._client = client; - } - - form(json) { - this.id = json.id; - this.isParent = json.isParent; - } - - async _createProcessTargetFront(form) { - let front = null; - // the request to getTarget 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("parentProcessTarget")) { - // ParentProcessTargetActor doesn't have a specific front, instead it uses - // BrowsingContextTargetFront on the client side. - front = new BrowsingContextTargetFront(this._client); - } else { - front = new ContentProcessTargetFront(this._client); - } - // As these fronts aren't instantiated by protocol.js, we have to set their actor ID - // manually like that: - front.actorID = form.actor; - front.form(form); - this.manage(front); - return front; - } - - async getTarget() { - if (this._processTargetFront && this._processTargetFront.actorID) { - return this._processTargetFront; - } - if (this._targetFrontPromise) { - return this._targetFrontPromise; - } - this._targetFrontPromise = (async () => { - try { - const targetForm = await super.getTarget(); - this._processTargetFront = await this._createProcessTargetFront( - targetForm - ); - await this._processTargetFront.attach(); - // clear the promise if we are finished so that we can re-connect if - // necessary - this._targetFrontPromise = null; - return this._processTargetFront; - } catch (e) { - // This is likely to happen if we get a lot of events which drop previous - // processes. - console.log( - `Request to connect to ProcessDescriptor "${this.id}" failed: ${e}` - ); - return null; - } - })(); - return this._targetFrontPromise; - } - - destroy() { - this._processTargetFront = null; - this._targetFrontPromise = null; - super.destroy(); - } -} - -exports.ProcessDescriptorFront = ProcessDescriptorFront; -registerFront(ProcessDescriptorFront); diff --git a/devtools/shared/fronts/moz.build b/devtools/shared/fronts/moz.build index d9bc16f4767a..0a2531e2f576 100644 --- a/devtools/shared/fronts/moz.build +++ b/devtools/shared/fronts/moz.build @@ -6,7 +6,6 @@ DIRS += [ 'addon', - 'descriptors', 'inspector', 'targets', 'worker', diff --git a/devtools/shared/fronts/root.js b/devtools/shared/fronts/root.js index af388403292d..4f90e8a52cfd 100644 --- a/devtools/shared/fronts/root.js +++ b/devtools/shared/fronts/root.js @@ -11,12 +11,6 @@ const { } = require("devtools/shared/protocol"); loader.lazyRequireGetter(this, "getFront", "devtools/shared/protocol", true); -loader.lazyRequireGetter( - this, - "ProcessDescriptorFront", - "devtools/shared/fronts/descriptors/process", - true -); loader.lazyRequireGetter( this, "BrowsingContextTargetFront", @@ -87,12 +81,12 @@ class RootFront extends FrontClassWithSpec(rootSpec) { // And then from the Child processes const { processes } = await this.listProcesses(); - for (const processDescriptorFront of processes) { + for (const process of processes) { // Ignore parent process - if (processDescriptorFront.isParent) { + if (process.parent) { continue; } - const front = await processDescriptorFront.getTarget(); + const front = await this.getProcess(process.id); const response = await front.listWorkers(); workers = workers.concat(response.workers); } @@ -165,24 +159,6 @@ class RootFront extends FrontClassWithSpec(rootSpec) { return result; } - async listProcesses() { - const { processes } = await super.listProcesses(); - const processDescriptors = processes.map(form => { - if (form.actor && form.actor.includes("processDescriptor")) { - return this._getProcessDescriptorFront(form); - } - // Support FF69 and older - return { - id: form.id, - isParent: form.parent, - getTarget: () => { - return this.getProcess(form.id); - }, - }; - }); - return { processes: processDescriptors }; - } - /** * Fetch the ParentProcessTargetActor for the main process. * @@ -194,18 +170,10 @@ class RootFront extends FrontClassWithSpec(rootSpec) { } async getProcess(id) { - const { form } = await super.getProcess(id); - if (form.actor && form.actor.includes("processDescriptor")) { - // The server currently returns a form, when we can drop backwards compatibility, - // we can use automatic marshalling here instead, making the next line unnecessary - const processDescriptorFront = this._getProcessDescriptorFront(form); - return processDescriptorFront.getTarget(); - } - - // Backwards compatibility for servers up to FF69. // 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 super.getProcess(id); let front = this.actor(form.actor); if (front) { return front; @@ -230,25 +198,6 @@ class RootFront extends FrontClassWithSpec(rootSpec) { return front; } - /** - * Get the previous process descriptor front if it exists, create a new one if not. - * - * If we are using a modern server, we will get a form for a processDescriptorFront. - * Until we can switch to auto marshalling, we need to marshal this into a process - * descriptor front ourselves. - */ - _getProcessDescriptorFront(form) { - let front = this.actor(form.actor); - if (front) { - return front; - } - front = new ProcessDescriptorFront(this._client); - front.form(form); - front.actorID = form.actor; - this.manage(front); - return front; - } - /** * Override default listTabs request in order to return a list of * BrowsingContextTargetFronts while updating their selected state. diff --git a/devtools/shared/specs/descriptors/moz.build b/devtools/shared/specs/descriptors/moz.build deleted file mode 100644 index 55544d0f218b..000000000000 --- a/devtools/shared/specs/descriptors/moz.build +++ /dev/null @@ -1,10 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -DevToolsModules( - 'process.js', -) - diff --git a/devtools/shared/specs/descriptors/process.js b/devtools/shared/specs/descriptors/process.js deleted file mode 100644 index 2727a01887f6..000000000000 --- a/devtools/shared/specs/descriptors/process.js +++ /dev/null @@ -1,19 +0,0 @@ -/* 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"; - -const { generateActorSpec, RetVal } = require("devtools/shared/protocol"); - -const processDescriptorSpec = generateActorSpec({ - typeName: "processDescriptor", - - methods: { - getTarget: { - request: {}, - response: { process: RetVal("json") }, - }, - }, -}); - -exports.processDescriptorSpec = processDescriptorSpec; diff --git a/devtools/shared/specs/index.js b/devtools/shared/specs/index.js index 033166eff0ef..a7417ff279b5 100644 --- a/devtools/shared/specs/index.js +++ b/devtools/shared/specs/index.js @@ -57,11 +57,6 @@ const Types = (exports.__TypesForTests = [ spec: "devtools/shared/specs/css-properties", front: "devtools/shared/fronts/css-properties", }, - { - types: ["processDescriptor"], - spec: "devtools/shared/specs/descriptors/process", - front: "devtools/shared/fronts/descriptors/process", - }, { types: ["device"], spec: "devtools/shared/specs/device", diff --git a/devtools/shared/specs/moz.build b/devtools/shared/specs/moz.build index 3d7326adecf7..30163c788f42 100644 --- a/devtools/shared/specs/moz.build +++ b/devtools/shared/specs/moz.build @@ -6,7 +6,6 @@ DIRS += [ 'addon', - 'descriptors', 'targets', 'worker', ]