зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1160199 - Implement TabActor.listWorkers;r=jlong
This commit is contained in:
Родитель
c688992859
Коммит
1c6bb60c9a
|
@ -22,6 +22,8 @@ support-files =
|
|||
code_function-search-02.js
|
||||
code_function-search-03.js
|
||||
code_location-changes.js
|
||||
code_listworkers-worker1.js
|
||||
code_listworkers-worker2.js
|
||||
code_math.js
|
||||
code_math.map
|
||||
code_math.min.js
|
||||
|
@ -72,6 +74,7 @@ support-files =
|
|||
doc_inline-debugger-statement.html
|
||||
doc_inline-script.html
|
||||
doc_large-array-buffer.html
|
||||
doc_listworkers-tab.html
|
||||
doc_minified.html
|
||||
doc_minified_bogus_map.html
|
||||
doc_native-event-handler.html
|
||||
|
@ -250,6 +253,7 @@ skip-if = e10s # TODO
|
|||
skip-if = e10s # TODO
|
||||
[browser_dbg_listtabs-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_listworkers.js]
|
||||
[browser_dbg_location-changes-01-simple.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_location-changes-02-blank.js]
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
let TAB_URL = EXAMPLE_URL + "doc_listworkers-tab.html";
|
||||
let WORKER1_URL = "code_listworkers-worker1.js";
|
||||
let WORKER2_URL = "code_listworkers-worker2.js";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client);
|
||||
|
||||
let tab = yield addTab(TAB_URL);
|
||||
let { tabs } = yield listTabs(client);
|
||||
let [, tabClient] = yield attachTab(client, findTab(tabs, TAB_URL));
|
||||
|
||||
let { workers } = yield listWorkers(tabClient);
|
||||
is(workers.length, 0);
|
||||
|
||||
executeSoon(() => {
|
||||
evalInTab(tab, "let worker1 = new Worker('" + WORKER1_URL + "');");
|
||||
});
|
||||
yield waitForWorkerListChanged(tabClient);
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
is(workers.length, 1);
|
||||
is(workers[0].url, WORKER1_URL);
|
||||
|
||||
executeSoon(() => {
|
||||
evalInTab(tab, "let worker2 = new Worker('" + WORKER2_URL + "');");
|
||||
});
|
||||
yield waitForWorkerListChanged(tabClient);
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
is(workers.length, 2);
|
||||
is(workers[0].url, WORKER1_URL);
|
||||
is(workers[1].url, WORKER2_URL);
|
||||
|
||||
executeSoon(() => {
|
||||
evalInTab(tab, "worker1.terminate()");
|
||||
});
|
||||
yield waitForWorkerListChanged(tabClient);
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
is(workers.length, 1);
|
||||
is(workers[0].url, WORKER2_URL);
|
||||
|
||||
executeSoon(() => {
|
||||
evalInTab(tab, "worker2.terminate()");
|
||||
});
|
||||
yield waitForWorkerListChanged(tabClient);
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
is(workers.length, 0);
|
||||
|
||||
yield close(client);
|
||||
finish();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
|
||||
self.onmessage = function () {};
|
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
|
||||
self.onmessage = function () {};
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -1025,3 +1025,68 @@ function getSourceForm(aSources, aURL) {
|
|||
let item = aSources.getItemByValue(getSourceActor(gSources, aURL));
|
||||
return item.attachment.source;
|
||||
}
|
||||
|
||||
function connect(client) {
|
||||
info("Connecting client.");
|
||||
return new Promise(function (resolve) {
|
||||
client.connect(function () {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function close(client) {
|
||||
info("Closing client.\n");
|
||||
return new Promise(function (resolve) {
|
||||
client.close(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function listTabs(client) {
|
||||
info("Listing tabs.");
|
||||
return new Promise(function (resolve) {
|
||||
client.listTabs(function (response) {
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function findTab(tabs, url) {
|
||||
info("Finding tab with url '" + url + "'.");
|
||||
for (let tab of tabs) {
|
||||
if (tab.url === url) {
|
||||
return tab;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function attachTab(client, tab) {
|
||||
info("Attaching to tab with url '" + tab.url + "'.");
|
||||
return new Promise(function (resolve) {
|
||||
client.attachTab(tab.actor, function (response, tabClient) {
|
||||
resolve([response, tabClient]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function listWorkers(tabClient) {
|
||||
info("Listing workers.");
|
||||
return new Promise(function (resolve) {
|
||||
tabClient.listWorkers(function (response) {
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function waitForWorkerListChanged(tabClient) {
|
||||
info("Waiting for worker list to change.");
|
||||
return new Promise(function (resolve) {
|
||||
tabClient.addListener("workerListChanged", function listener() {
|
||||
tabClient.removeListener("workerListChanged", listener);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5526,6 +5526,20 @@
|
|||
"n_buckets": "1000",
|
||||
"description": "The time (in milliseconds) that it took a 'reconfigure tab' request to go round trip."
|
||||
},
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_LISTWORKERS_MS": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"high": "10000",
|
||||
"n_buckets": "1000",
|
||||
"description": "The time (in milliseconds) that it took a 'listWorkers' request to go round trip."
|
||||
},
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_LISTWORKERS_MS": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"high": "10000",
|
||||
"n_buckets": "1000",
|
||||
"description": "The time (in milliseconds) that it took a 'listWorkers' request to go round trip."
|
||||
},
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_RECONFIGURETHREAD_MS": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
|
|
|
@ -1218,7 +1218,7 @@ function TabClient(aClient, aForm) {
|
|||
this.thread = null;
|
||||
this.request = this.client.request;
|
||||
this.traits = aForm.traits || {};
|
||||
this.events = [];
|
||||
this.events = ["workerListChanged"];
|
||||
}
|
||||
|
||||
TabClient.prototype = {
|
||||
|
@ -1321,6 +1321,12 @@ TabClient.prototype = {
|
|||
}, {
|
||||
telemetry: "RECONFIGURETAB"
|
||||
}),
|
||||
|
||||
listWorkers: DebuggerClient.requester({
|
||||
type: "listWorkers"
|
||||
}, {
|
||||
telemetry: "LISTWORKERS"
|
||||
})
|
||||
};
|
||||
|
||||
eventSource(TabClient.prototype);
|
||||
|
|
|
@ -15,6 +15,7 @@ let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
|
|||
let { dbg_assert } = DevToolsUtils;
|
||||
let { TabSources } = require("./utils/TabSources");
|
||||
let makeDebugger = require("./utils/make-debugger");
|
||||
let { WorkerActorList } = require("devtools/server/actors/worker");
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
|
@ -725,6 +726,10 @@ function TabActor(aConnection)
|
|||
this.listenForNewDocShells = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
|
||||
|
||||
this.traits = { reconfigure: true, frames: true };
|
||||
|
||||
this._workerActorList = null;
|
||||
this._workerActorPool = null;
|
||||
this._onWorkerActorListChanged = this._onWorkerActorListChanged.bind(this);
|
||||
}
|
||||
|
||||
// XXX (bug 710213): TabActor attach/detach/exit/disconnect is a
|
||||
|
@ -1076,6 +1081,37 @@ TabActor.prototype = {
|
|||
return { frames: windows };
|
||||
},
|
||||
|
||||
onListWorkers: function BTA_onListWorkers(aRequest) {
|
||||
if (this._workerActorList === null) {
|
||||
this._workerActorList = new WorkerActorList({
|
||||
window: this.window
|
||||
});
|
||||
}
|
||||
|
||||
return this._workerActorList.getList().then((actors) => {
|
||||
let pool = new ActorPool(this.conn);
|
||||
for (let actor of actors) {
|
||||
pool.addActor(actor);
|
||||
}
|
||||
|
||||
this.conn.removeActorPool(this._workerActorPool);
|
||||
this._workerActorPool = pool;
|
||||
this.conn.addActorPool(this._workerActorPool);
|
||||
|
||||
this._workerActorList.onListChanged = this._onWorkerActorListChanged;
|
||||
|
||||
return {
|
||||
"from": this.actorID,
|
||||
"workers": actors.map((actor) => actor.form())
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
_onWorkerActorListChanged: function () {
|
||||
this._workerActorList.onListChanged = null;
|
||||
this.conn.sendActorEvent(this.actorID, "workerListChanged");
|
||||
},
|
||||
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
// Ignore any event that comes before/after the tab actor is attached
|
||||
// That typically happens during firefox shutdown.
|
||||
|
@ -1769,7 +1805,8 @@ TabActor.prototype.requestTypes = {
|
|||
"navigateTo": TabActor.prototype.onNavigateTo,
|
||||
"reconfigure": TabActor.prototype.onReconfigure,
|
||||
"switchToFrame": TabActor.prototype.onSwitchToFrame,
|
||||
"listFrames": TabActor.prototype.onListFrames
|
||||
"listFrames": TabActor.prototype.onListFrames,
|
||||
"listWorkers": TabActor.prototype.onListWorkers
|
||||
};
|
||||
|
||||
exports.TabActor = TabActor;
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
"use strict";
|
||||
|
||||
let { Ci, Cu } = require("chrome");
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this, "wdm",
|
||||
"@mozilla.org/dom/workers/workerdebuggermanager;1",
|
||||
"nsIWorkerDebuggerManager"
|
||||
);
|
||||
|
||||
function matchWorkerDebugger(dbg, options) {
|
||||
if ("window" in options) {
|
||||
let window = dbg.window;
|
||||
while (window !== null && window.parent !== window) {
|
||||
window = window.parent;
|
||||
}
|
||||
|
||||
if (window !== options.window) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function WorkerActor(dbg) {
|
||||
this._dbg = dbg;
|
||||
}
|
||||
|
||||
WorkerActor.prototype = {
|
||||
actorPrefix: "worker",
|
||||
|
||||
form: function () {
|
||||
return {
|
||||
actor: this.actorID,
|
||||
url: this._dbg.url
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
exports.WorkerActor = WorkerActor;
|
||||
|
||||
function WorkerActorList(options) {
|
||||
this._options = options;
|
||||
this._actors = new Map();
|
||||
this._onListChanged = null;
|
||||
this._mustNotify = false;
|
||||
this.onRegister = this.onRegister.bind(this);
|
||||
this.onUnregister = this.onUnregister.bind(this);
|
||||
}
|
||||
|
||||
WorkerActorList.prototype = {
|
||||
getList: function () {
|
||||
let dbgs = new Set();
|
||||
let e = wdm.getWorkerDebuggerEnumerator();
|
||||
while (e.hasMoreElements()) {
|
||||
let dbg = e.getNext().QueryInterface(Ci.nsIWorkerDebugger);
|
||||
if (matchWorkerDebugger(dbg, this._options)) {
|
||||
dbgs.add(dbg);
|
||||
}
|
||||
}
|
||||
|
||||
for (let [dbg, ] of this._actors) {
|
||||
if (!dbgs.has(dbg)) {
|
||||
this._actors.delete(dbg);
|
||||
}
|
||||
}
|
||||
|
||||
for (let dbg of dbgs) {
|
||||
if (!this._actors.has(dbg)) {
|
||||
this._actors.set(dbg, new WorkerActor(dbg));
|
||||
}
|
||||
}
|
||||
|
||||
let actors = [];
|
||||
for (let [, actor] of this._actors) {
|
||||
actors.push(actor);
|
||||
}
|
||||
|
||||
this._mustNotify = true;
|
||||
this._checkListening();
|
||||
|
||||
return Promise.resolve(actors);
|
||||
},
|
||||
|
||||
get onListChanged() {
|
||||
return this._onListChanged;
|
||||
},
|
||||
|
||||
set onListChanged(onListChanged) {
|
||||
if (typeof onListChanged !== "function" && onListChanged !== null) {
|
||||
throw new Error("onListChanged must be either a function or null.");
|
||||
}
|
||||
|
||||
this._onListChanged = onListChanged;
|
||||
this._checkListening();
|
||||
},
|
||||
|
||||
_checkListening: function () {
|
||||
if (this._onListChanged !== null && this._mustNotify) {
|
||||
wdm.addListener(this);
|
||||
} else {
|
||||
wdm.removeListener(this);
|
||||
}
|
||||
},
|
||||
|
||||
_notifyListChanged: function () {
|
||||
if (this._mustNotify) {
|
||||
this._onListChanged();
|
||||
this._mustNotify = false;
|
||||
}
|
||||
},
|
||||
|
||||
onRegister: function (dbg) {
|
||||
if (matchWorkerDebugger(dbg, this._options)) {
|
||||
this._notifyListChanged();
|
||||
}
|
||||
},
|
||||
|
||||
onUnregister: function (dbg) {
|
||||
if (matchWorkerDebugger(dbg, this._options)) {
|
||||
this._notifyListChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.WorkerActorList = WorkerActorList;
|
|
@ -72,6 +72,7 @@ EXTRA_JS_MODULES.devtools.server.actors += [
|
|||
'actors/webbrowser.js',
|
||||
'actors/webconsole.js',
|
||||
'actors/webgl.js',
|
||||
'actors/worker.js',
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES.devtools.server.actors.utils += [
|
||||
|
|
Загрузка…
Ссылка в новой задаче