mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Bug 1049103 - ensure closing only one child connection when closing a toolbox. r=jryans
This commit is contained in:
parent
ba38bdd0b5
commit
4a8a178441
@ -13,6 +13,7 @@ support-files =
|
||||
[browser_new_activation_workflow.js]
|
||||
[browser_target_events.js]
|
||||
[browser_target_remote.js]
|
||||
[browser_two_tabs.js]
|
||||
[browser_toolbox_dynamic_registration.js]
|
||||
[browser_toolbox_highlight.js]
|
||||
[browser_toolbox_hosts.js]
|
||||
|
101
browser/devtools/framework/test/browser_two_tabs.js
Normal file
101
browser/devtools/framework/test/browser_two_tabs.js
Normal file
@ -0,0 +1,101 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check regression when opening two tabs
|
||||
*/
|
||||
|
||||
let { DebuggerServer } =
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||
let { DebuggerClient } =
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
|
||||
let { devtools } =
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
|
||||
const TAB_URL_1 = "data:text/html;charset=utf-8,foo";
|
||||
const TAB_URL_2 = "data:text/html;charset=utf-8,bar";
|
||||
|
||||
let gClient;
|
||||
let gTab1, gTab2;
|
||||
let gTabActor1, gTabActor2;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
openTabs();
|
||||
}
|
||||
|
||||
function openTabs() {
|
||||
// Open two tabs, select the second
|
||||
gTab1 = gBrowser.addTab(TAB_URL_1);
|
||||
gTab1.linkedBrowser.addEventListener("load", function onLoad1(evt) {
|
||||
gTab1.linkedBrowser.removeEventListener("load", onLoad1);
|
||||
|
||||
gTab2 = gBrowser.selectedTab = gBrowser.addTab(TAB_URL_2);
|
||||
gTab2.linkedBrowser.addEventListener("load", function onLoad2(evt) {
|
||||
gTab2.linkedBrowser.removeEventListener("load", onLoad2);
|
||||
|
||||
connect();
|
||||
}, true);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function connect() {
|
||||
// Connect to debugger server to fetch the two tab actors
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(() => {
|
||||
gClient.listTabs(response => {
|
||||
// Fetch the tab actors for each tab
|
||||
gTabActor1 = response.tabs.filter(a => a.url === TAB_URL_1)[0];
|
||||
gTabActor2 = response.tabs.filter(a => a.url === TAB_URL_2)[0];
|
||||
|
||||
checkSelectedTabActor();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function checkSelectedTabActor() {
|
||||
// Send a naive request to the second tab actor
|
||||
// to check if it works
|
||||
gClient.request({ to: gTabActor2.consoleActor, type: "startListeners", listeners: [] }, aResponse => {
|
||||
ok("startedListeners" in aResponse, "Actor from the selected tab should respond to the request.");
|
||||
|
||||
closeSecondTab();
|
||||
});
|
||||
}
|
||||
|
||||
function closeSecondTab() {
|
||||
// Close the second tab, currently selected
|
||||
let container = gBrowser.tabContainer;
|
||||
container.addEventListener("TabClose", function onTabClose() {
|
||||
container.removeEventListener("TabClose", onTabClose);
|
||||
|
||||
checkFirstTabActor();
|
||||
});
|
||||
gBrowser.removeTab(gTab2);
|
||||
}
|
||||
|
||||
function checkFirstTabActor() {
|
||||
// then send a request to the first tab actor
|
||||
// to check if it still works
|
||||
gClient.request({ to: gTabActor1.consoleActor, type: "startListeners", listeners: [] }, aResponse => {
|
||||
ok("startedListeners" in aResponse, "Actor from the first tab should still respond.");
|
||||
|
||||
cleanup();
|
||||
});
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
let container = gBrowser.tabContainer;
|
||||
container.addEventListener("TabClose", function onTabClose() {
|
||||
container.removeEventListener("TabClose", onTabClose);
|
||||
|
||||
gClient.close(finish);
|
||||
});
|
||||
gBrowser.removeTab(gTab1);
|
||||
}
|
@ -13,6 +13,9 @@ let chromeGlobal = this;
|
||||
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
|
||||
const {DebuggerServer, ActorPool} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||
if (!DebuggerServer.childID) {
|
||||
DebuggerServer.childID = 1;
|
||||
}
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
@ -24,21 +27,24 @@ let chromeGlobal = this;
|
||||
// time we load child.js
|
||||
DebuggerServer.addChildActors();
|
||||
|
||||
let conn;
|
||||
let connections = new Map();
|
||||
|
||||
let onConnect = DevToolsUtils.makeInfallible(function (msg) {
|
||||
removeMessageListener("debug:connect", onConnect);
|
||||
|
||||
let mm = msg.target;
|
||||
let prefix = msg.data.prefix;
|
||||
let id = DebuggerServer.childID++;
|
||||
|
||||
conn = DebuggerServer.connectToParent(msg.data.prefix, mm);
|
||||
let conn = DebuggerServer.connectToParent(prefix, mm);
|
||||
connections.set(id, conn);
|
||||
|
||||
let actor = new DebuggerServer.ContentActor(conn, chromeGlobal);
|
||||
let actorPool = new ActorPool(conn);
|
||||
actorPool.addActor(actor);
|
||||
conn.addActorPool(actorPool);
|
||||
|
||||
sendAsyncMessage("debug:actor", {actor: actor.grip()});
|
||||
sendAsyncMessage("debug:actor", {actor: actor.grip(), childID: id});
|
||||
});
|
||||
|
||||
addMessageListener("debug:connect", onConnect);
|
||||
@ -49,8 +55,12 @@ let chromeGlobal = this;
|
||||
// Call DebuggerServerConnection.close to destroy all child actors
|
||||
// (It should end up calling DebuggerServerConnection.onClosed
|
||||
// that would actually cleanup all actor pools)
|
||||
let childID = msg.data.childID;
|
||||
let conn = connections.get(childID);
|
||||
if (conn) {
|
||||
conn.close();
|
||||
conn = null;
|
||||
connections.delete(childID);
|
||||
}
|
||||
});
|
||||
addMessageListener("debug:disconnect", onDisconnect);
|
||||
})();
|
||||
|
@ -567,11 +567,14 @@ var DebuggerServer = {
|
||||
|
||||
let actor, childTransport;
|
||||
let prefix = aConnection.allocID("child");
|
||||
let childID = null;
|
||||
let netMonitor = null;
|
||||
|
||||
let onActorCreated = DevToolsUtils.makeInfallible(function (msg) {
|
||||
mm.removeMessageListener("debug:actor", onActorCreated);
|
||||
|
||||
childID = msg.json.childID;
|
||||
|
||||
// Pipe Debugger message from/to parent/child via the message manager
|
||||
childTransport = new ChildDebuggerTransport(mm, prefix);
|
||||
childTransport.hooks = {
|
||||
@ -604,7 +607,7 @@ var DebuggerServer = {
|
||||
aConnection.cancelForwarding(prefix);
|
||||
|
||||
// ... and notify the child process to clean the tab actors.
|
||||
mm.sendAsyncMessage("debug:disconnect");
|
||||
mm.sendAsyncMessage("debug:disconnect", { childID: childID });
|
||||
} else {
|
||||
// Otherwise, the app has been closed before the actor
|
||||
// had a chance to be created, so we are not able to create
|
||||
@ -641,7 +644,7 @@ var DebuggerServer = {
|
||||
aConnection.cancelForwarding(prefix);
|
||||
|
||||
// ... and notify the child process to clean the tab actors.
|
||||
mm.sendAsyncMessage("debug:disconnect");
|
||||
mm.sendAsyncMessage("debug:disconnect", { childID: childID });
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user