Bug 1126274 - Add new API to listen for sent and received RDP packets. r=jryans

This commit is contained in:
Jan Odvarko 2015-02-13 07:35:44 +01:00
parent d09fac7d70
commit 2da52b69cc
5 changed files with 143 additions and 3 deletions

View File

@ -414,6 +414,8 @@ DevTools.prototype = {
// No toolbox for target, create one
toolbox = new devtools.Toolbox(target, toolId, hostType, hostOptions);
this.emit("toolbox-created", toolbox);
this._toolboxes.set(target, toolbox);
toolbox.once("destroy", () => {

View File

@ -43,6 +43,7 @@ skip-if = e10s # Bug 1069044 - destroyInspector may hang during shutdown
[browser_toolbox_tabsswitch_shortcuts.js]
[browser_toolbox_tool_ready.js]
[browser_toolbox_tool_remote_reopen.js]
[browser_toolbox_transport_events.js]
[browser_toolbox_window_reload_target.js]
[browser_toolbox_window_shortcuts.js]
skip-if = os == "mac" && os_version == "10.8" || os == "win" && os_version == "5.1" # Bug 851129 - Re-enable browser_toolbox_window_shortcuts.js test after leaks are fixed

View File

@ -0,0 +1,104 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const { on, off } = devtools.require("sdk/event/core");
const { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
function test() {
gDevTools.on("toolbox-created", onToolboxCreated);
on(DebuggerClient, "connect", onDebuggerClientConnect);
addTab("about:blank").then(function() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, "webconsole").then(testResults);
});
}
function testResults(toolbox) {
testPackets(sent1, received1);
testPackets(sent2, received2);
cleanUp(toolbox);
}
function cleanUp(toolbox) {
gDevTools.off("toolbox-created", onToolboxCreated);
off(DebuggerClient, "connect", onDebuggerClientConnect);
toolbox.destroy().then(function() {
gBrowser.removeCurrentTab();
executeSoon(function() {
finish();
});
});
}
function testPackets(sent, received) {
ok(sent.length > 0, "There must be at least one sent packet");
ok(received.length > 0, "There must be at leaset one received packet");
if (!sent.length || received.length) {
return;
}
let sentPacket = sent[0];
let receivedPacket = received[0];
is(receivedPacket.from, "root",
"The first received packet is from the root");
is(receivedPacket.applicationType, "browser",
"The first received packet has browser type");
is(sentPacket.type, "listTabs",
"The first sent packet is for list of tabs");
}
// Listen to the transport object that is associated with the
// default Toolbox debugger client
let sent1 = [];
let received1 = [];
function send1(eventId, packet) {
sent1.push(packet);
}
function onPacket1(eventId, packet) {
received1.push(packet);
}
function onToolboxCreated(eventId, toolbox) {
toolbox.target.makeRemote();
let client = toolbox.target.client;
let transport = client._transport;
transport.on("send", send1);
transport.on("onPacket", onPacket1);
client.addOneTimeListener("closed", event => {
transport.off("send", send1);
transport.off("onPacket", onPacket1);
});
}
// Listen to all debugger client object protocols.
let sent2 = [];
let received2 = [];
function send2(eventId, packet) {
sent2.push(packet);
}
function onPacket2(eventId, packet) {
received2.push(packet);
}
function onDebuggerClientConnect(client) {
let transport = client._transport;
transport.on("send", send2);
transport.on("onPacket", onPacket2);
client.addOneTimeListener("closed", event => {
transport.off("send", send2);
transport.off("onPacket", onPacket2);
});
}

View File

@ -396,6 +396,12 @@ DebuggerClient.prototype = {
* received from the debugging server.
*/
connect: function (aOnConnected) {
this.emit("connect");
// Also emit the event on the |DebuggerServer| object (not on
// the instance), so it's possible to track all instances.
events.emit(DebuggerClient, "connect", this);
this.addOneTimeListener("connected", (aName, aApplicationType, aTraits) => {
this.traits = aTraits;
if (aOnConnected) {

View File

@ -30,6 +30,7 @@ const StreamUtils = require("devtools/toolkit/transport/stream-utils");
const { Packet, JSONPacket, BulkPacket } =
require("devtools/toolkit/transport/packets");
const promise = require("promise");
const EventEmitter = require("devtools/toolkit/event-emitter");
DevToolsUtils.defineLazyGetter(this, "Pipe", () => {
return CC("@mozilla.org/pipe;1", "nsIPipe", "init");
@ -100,6 +101,8 @@ const PACKET_HEADER_MAX = 200;
* details on the format of these packets.
*/
function DebuggerTransport(input, output) {
EventEmitter.decorate(this);
this._input = input;
this._scriptableInput = new ScriptableInputStream(input);
this._output = output;
@ -131,6 +134,8 @@ DebuggerTransport.prototype = {
* they are passed to this method.
*/
send: function(object) {
this.emit("send", object);
let packet = new JSONPacket(this);
packet.object = object;
this._outgoing.push(packet);
@ -179,6 +184,8 @@ DebuggerTransport.prototype = {
* that is copied. See stream-utils.js.
*/
startBulkSend: function(header) {
this.emit("startBulkSend", header);
let packet = new BulkPacket(this);
packet.header = header;
this._outgoing.push(packet);
@ -193,6 +200,8 @@ DebuggerTransport.prototype = {
* closing the transport (likely because a stream closed or failed).
*/
close: function(reason) {
this.emit("onClosed", reason);
this.active = false;
this._input.close();
this._scriptableInput.close();
@ -458,6 +467,7 @@ DebuggerTransport.prototype = {
DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => {
// Ensure the transport is still alive by the time this runs.
if (this.active) {
this.emit("onPacket", object);
this.hooks.onPacket(object);
}
}, "DebuggerTransport instance's this.hooks.onPacket"));
@ -473,6 +483,7 @@ DebuggerTransport.prototype = {
DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => {
// Ensure the transport is still alive by the time this runs.
if (this.active) {
this.emit("onBulkPacket", ...args);
this.hooks.onBulkPacket(...args);
}
}, "DebuggerTransport instance's this.hooks.onBulkPacket"));
@ -506,6 +517,8 @@ exports.DebuggerTransport = DebuggerTransport;
* @see DebuggerTransport
*/
function LocalDebuggerTransport(other) {
EventEmitter.decorate(this);
this.other = other;
this.hooks = null;
@ -524,6 +537,8 @@ LocalDebuggerTransport.prototype = {
* endpoint.
*/
send: function(packet) {
this.emit("send", packet);
let serial = this._serial.count++;
if (dumpn.wantLogging) {
/* Check 'from' first, as 'echo' packets have both. */
@ -542,6 +557,7 @@ LocalDebuggerTransport.prototype = {
dumpn("Received packet " + serial + ": " + JSON.stringify(packet, null, 2));
}
if (other.hooks) {
other.emit("onPacket", packet);
other.hooks.onPacket(packet);
}
}, "LocalDebuggerTransport instance's this.other.hooks.onPacket"));
@ -558,6 +574,8 @@ LocalDebuggerTransport.prototype = {
* done with it.
*/
startBulkSend: function({actor, type, length}) {
this.emit("startBulkSend", {actor, type, length});
let serial = this._serial.count++;
dumpn("Sent bulk packet " + serial + " for actor " + actor);
@ -575,8 +593,7 @@ LocalDebuggerTransport.prototype = {
// Receiver
let deferred = promise.defer();
this.other.hooks.onBulkPacket({
let packet = {
actor: actor,
type: type,
length: length,
@ -588,7 +605,10 @@ LocalDebuggerTransport.prototype = {
},
stream: pipe.inputStream,
done: deferred
});
};
this.other.emit("onBulkPacket", packet);
this.other.hooks.onBulkPacket(packet);
// Await the result of reading from the stream
deferred.promise.then(() => pipe.inputStream.close(), this.close);
@ -624,6 +644,8 @@ LocalDebuggerTransport.prototype = {
* Close the transport.
*/
close: function() {
this.emit("close");
if (this.other) {
// Remove the reference to the other endpoint before calling close(), to
// avoid infinite recursion.
@ -681,6 +703,8 @@ exports.LocalDebuggerTransport = LocalDebuggerTransport;
* <prefix> is |prefix|, whose data is the protocol packet.
*/
function ChildDebuggerTransport(sender, prefix) {
EventEmitter.decorate(this);
this._sender = sender.QueryInterface(Ci.nsIMessageSender);
this._messageName = "debug:" + prefix + ":packet";
}
@ -701,14 +725,17 @@ ChildDebuggerTransport.prototype = {
close: function () {
this._sender.removeMessageListener(this._messageName, this);
this.emit("onClosed");
this.hooks.onClosed();
},
receiveMessage: function ({data}) {
this.emit("onPacket", data);
this.hooks.onPacket(data);
},
send: function (packet) {
this.emit("send", packet);
this._sender.sendAsyncMessage(this._messageName, packet);
},