Bug 1160199 - Implement TabActor.listWorkers;r=jlong

This commit is contained in:
Eddy Bruël 2015-05-12 18:58:34 +02:00
Родитель c688992859
Коммит 1c6bb60c9a
11 изменённых файлов: 331 добавлений и 2 удалений

Просмотреть файл

@ -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 += [