зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1479524 - Always use message manager with NetworkMonitorActor. r=jdescottes
MozReview-Commit-ID: AXOd0i4NOjH
This commit is contained in:
Родитель
edb2dd1da5
Коммит
b840eb27bf
|
@ -28,43 +28,43 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
* To be removed, specify the ID of the Web console actor.
|
||||
* This is used to fake emitting an event from it to prevent changing RDP
|
||||
* behavior.
|
||||
* @param nsIMessageManager messageManager (optional)
|
||||
* Passed only when it is instanciated across processes. This is the manager to
|
||||
* use to communicate with the other process.
|
||||
* @param object stackTraceCollector (optional)
|
||||
* When the actor runs in the same process than the requests we are inspecting,
|
||||
* the web console actor hands over a shared instance to the stack trace
|
||||
* collector.
|
||||
* @param nsIMessageManager messageManager
|
||||
* This is the manager to use to communicate with the console actor. When both
|
||||
* netmonitor and console actor runs in the same process, this is an instance
|
||||
* of MockMessageManager instead of a real message manager.
|
||||
*/
|
||||
initialize(conn, filters, parentID, messageManager, stackTraceCollector) {
|
||||
initialize(conn, filters, parentID, messageManager) {
|
||||
Actor.prototype.initialize.call(this, conn);
|
||||
|
||||
this.parentID = parentID;
|
||||
this.messageManager = messageManager;
|
||||
this.stackTraceCollector = stackTraceCollector;
|
||||
|
||||
// Immediately start watching for new request according to `filters`.
|
||||
// NetworkMonitor will call `onNetworkEvent` method.
|
||||
this.netMonitor = new NetworkMonitor(filters, this);
|
||||
this.netMonitor.init();
|
||||
|
||||
if (this.messageManager) {
|
||||
this.stackTraces = new Set();
|
||||
this.onStackTraceAvailable = this.onStackTraceAvailable.bind(this);
|
||||
this.messageManager.addMessageListener("debug:request-stack-available",
|
||||
this.onStackTraceAvailable);
|
||||
this.onRequestContent = this.onRequestContent.bind(this);
|
||||
this.messageManager.addMessageListener("debug:request-content",
|
||||
this.onRequestContent);
|
||||
this.onSetPreference = this.onSetPreference.bind(this);
|
||||
this.messageManager.addMessageListener("debug:netmonitor-preference",
|
||||
this.onSetPreference);
|
||||
this.onGetNetworkEventActor = this.onGetNetworkEventActor.bind(this);
|
||||
this.messageManager.addMessageListener("debug:get-network-event-actor",
|
||||
this.onGetNetworkEventActor);
|
||||
this.destroy = this.destroy.bind(this);
|
||||
this.messageManager.addMessageListener("debug:destroy-network-monitor",
|
||||
this.destroy);
|
||||
this.stackTraces = new Set();
|
||||
this.onStackTraceAvailable = this.onStackTraceAvailable.bind(this);
|
||||
this.messageManager.addMessageListener("debug:request-stack-available",
|
||||
this.onStackTraceAvailable);
|
||||
this.onRequestContent = this.onRequestContent.bind(this);
|
||||
this.messageManager.addMessageListener("debug:request-content",
|
||||
this.onRequestContent);
|
||||
this.onSetPreference = this.onSetPreference.bind(this);
|
||||
this.messageManager.addMessageListener("debug:netmonitor-preference",
|
||||
this.onSetPreference);
|
||||
this.onGetNetworkEventActor = this.onGetNetworkEventActor.bind(this);
|
||||
this.messageManager.addMessageListener("debug:get-network-event-actor",
|
||||
this.onGetNetworkEventActor);
|
||||
this.onDestroyMessage = this.onDestroyMessage.bind(this);
|
||||
this.messageManager.addMessageListener("debug:destroy-network-monitor",
|
||||
this.onDestroyMessage);
|
||||
},
|
||||
|
||||
onDestroyMessage({ data }) {
|
||||
if (data.actorID == this.parentID) {
|
||||
this.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -76,8 +76,8 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
this.netMonitor = null;
|
||||
}
|
||||
|
||||
this.stackTraces.clear();
|
||||
if (this.messageManager) {
|
||||
this.stackTraces.clear();
|
||||
this.messageManager.removeMessageListener("debug:request-stack-available",
|
||||
this.onStackTraceAvailable);
|
||||
this.messageManager.removeMessageListener("debug:request-content",
|
||||
|
@ -87,7 +87,7 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
this.messageManager.removeMessageListener("debug:get-network-event-actor",
|
||||
this.onGetNetworkEventActor);
|
||||
this.messageManager.removeMessageListener("debug:destroy-network-monitor",
|
||||
this.destroy);
|
||||
this.onDestroyMessage);
|
||||
this.messageManager = null;
|
||||
}
|
||||
},
|
||||
|
@ -101,11 +101,7 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
}
|
||||
},
|
||||
|
||||
getRequestContentForURL(url) {
|
||||
const actor = this._networkEventActorsByURL.get(url);
|
||||
if (!actor) {
|
||||
return null;
|
||||
}
|
||||
getRequestContentForActor(actor) {
|
||||
const content = actor._response.content;
|
||||
if (actor._discardResponseBody || actor._truncated || !content || !content.size) {
|
||||
// Do not return the stylesheet text if there is no meaningful content or if it's
|
||||
|
@ -133,7 +129,10 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
|
||||
onRequestContent(msg) {
|
||||
const { url } = msg.data;
|
||||
const content = this.getRequestContentForURL(url);
|
||||
const actor = this._networkEventActorsByURL.get(url);
|
||||
// Always reply with a message, but with a null `content` if this instance
|
||||
// did not processed this request
|
||||
const content = actor ? this.getRequestContentForActor(actor) : null;
|
||||
this.messageManager.sendAsyncMessage("debug:request-content", {
|
||||
url,
|
||||
content,
|
||||
|
@ -151,7 +150,10 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
|
||||
onGetNetworkEventActor({ data }) {
|
||||
const actor = this.getNetworkEventActor(data.channelId);
|
||||
this.messageManager.sendAsyncMessage("debug:get-network-event-actor", actor.form());
|
||||
this.messageManager.sendAsyncMessage("debug:get-network-event-actor", {
|
||||
channelId: data.channelId,
|
||||
actor: actor.form()
|
||||
});
|
||||
},
|
||||
|
||||
getNetworkEventActor(channelId) {
|
||||
|
@ -175,13 +177,9 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
const actor = this.getNetworkEventActor(channelId);
|
||||
this._netEvents.set(channelId, actor);
|
||||
|
||||
if (this.messageManager) {
|
||||
event.cause.stacktrace = this.stackTraces.has(channelId);
|
||||
if (event.cause.stacktrace) {
|
||||
this.stackTraces.delete(channelId);
|
||||
}
|
||||
} else {
|
||||
event.cause.stacktrace = this.stackTraceCollector.getStackTrace(channelId);
|
||||
event.cause.stacktrace = this.stackTraces.has(channelId);
|
||||
if (event.cause.stacktrace) {
|
||||
this.stackTraces.delete(channelId);
|
||||
}
|
||||
actor.init(event);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ loader.lazyRequireGetter(this, "addWebConsoleCommands", "devtools/server/actors/
|
|||
loader.lazyRequireGetter(this, "formatCommand", "devtools/server/actors/webconsole/commands", true);
|
||||
loader.lazyRequireGetter(this, "isCommand", "devtools/server/actors/webconsole/commands", true);
|
||||
loader.lazyRequireGetter(this, "validCommands", "devtools/server/actors/webconsole/commands", true);
|
||||
loader.lazyRequireGetter(this, "createMessageManagerMocks", "devtools/server/actors/webconsole/message-manager-mock", true);
|
||||
loader.lazyRequireGetter(this, "CONSOLE_WORKER_IDS", "devtools/server/actors/webconsole/utils", true);
|
||||
loader.lazyRequireGetter(this, "WebConsoleUtils", "devtools/server/actors/webconsole/utils", true);
|
||||
loader.lazyRequireGetter(this, "EnvironmentActor", "devtools/server/actors/environment", true);
|
||||
|
@ -325,22 +326,13 @@ WebConsoleActor.prototype =
|
|||
this.consoleServiceListener.destroy();
|
||||
this.consoleServiceListener = null;
|
||||
}
|
||||
if (this.networkMonitorActor) {
|
||||
this.networkMonitorActor.destroy();
|
||||
this.networkMonitorActor = null;
|
||||
}
|
||||
if (this.networkMonitorActorId) {
|
||||
const messageManager = this.parentActor.messageManager;
|
||||
if (messageManager) {
|
||||
if (this.netmonitors) {
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.sendAsyncMessage("debug:destroy-network-monitor", {
|
||||
actorId: this.networkMonitorActorId
|
||||
actorID: this.actorID
|
||||
});
|
||||
}
|
||||
this.networkMonitorActorId = null;
|
||||
}
|
||||
if (this.networkMonitorChildActor) {
|
||||
this.networkMonitorChildActor.destroy();
|
||||
this.networkMonitorChildActor = null;
|
||||
this.netmonitors = null;
|
||||
}
|
||||
if (this.consoleAPIListener) {
|
||||
this.consoleAPIListener.destroy();
|
||||
|
@ -589,20 +581,6 @@ WebConsoleActor.prototype =
|
|||
startListeners: async function(request) {
|
||||
const startedListeners = [];
|
||||
const window = !this.parentActor.isRootActor ? this.window : null;
|
||||
let messageManager = null;
|
||||
|
||||
// Check if the actor is running in a child process (but only if
|
||||
// Services.appinfo exists, to prevent startListeners to fail
|
||||
// when the target is a Worker).
|
||||
const processBoundary = Services.appinfo && (
|
||||
Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT
|
||||
);
|
||||
|
||||
// Retrieve a message manager from the parent actor if this actor is
|
||||
// not currently running in the main process.
|
||||
if (processBoundary) {
|
||||
messageManager = this.parentActor.messageManager;
|
||||
}
|
||||
|
||||
while (request.listeners.length > 0) {
|
||||
const listener = request.listeners.shift();
|
||||
|
@ -634,19 +612,33 @@ WebConsoleActor.prototype =
|
|||
if (isWorker) {
|
||||
break;
|
||||
}
|
||||
if (!this.networkMonitorActorId && !this.networkMonitorActor) {
|
||||
// Create a StackTraceCollector that's going to be shared both by
|
||||
// the NetworkMonitorActor running in the same process for service worker
|
||||
// requests, as well with the NetworkMonitorActor running in the parent
|
||||
// process. It will communicate via message manager for this one.
|
||||
this.stackTraceCollector = new StackTraceCollector({ window },
|
||||
messageManager);
|
||||
this.stackTraceCollector.init();
|
||||
if (!this.netmonitors) {
|
||||
// Instanciate fake message managers used for service worker's netmonitor
|
||||
// when running in the content process, and for netmonitor running in the
|
||||
// same process when running in the parent process.
|
||||
// `createMessageManagerMocks` returns a couple of connected messages
|
||||
// managers that pass messages to each other to simulate the process
|
||||
// boundary. We will use the first one for the webconsole-actor and the
|
||||
// second one will be used by the netmonitor-actor.
|
||||
const [ mmMockParent, mmMockChild ] = createMessageManagerMocks();
|
||||
|
||||
if (messageManager && processBoundary) {
|
||||
// Maintain the list of message manager we should message to/listen from
|
||||
// to support the netmonitor instances, also records actorID of each
|
||||
// NetworkMonitorActor.
|
||||
// Array of `{ messageManager, parentProcess }`.
|
||||
// Where `parentProcess` is true for the netmonitor actor instanciated in the
|
||||
// parent process.
|
||||
this.netmonitors = [];
|
||||
|
||||
// Check if the actor is running in a content process
|
||||
const isInContentProcess =
|
||||
Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT &&
|
||||
this.parentActor.messageManager;
|
||||
if (isInContentProcess) {
|
||||
// Start a network monitor in the parent process to listen to
|
||||
// most requests than happen in parent
|
||||
this.networkMonitorActorId = await this.conn.spawnActorInParentProcess(
|
||||
// most requests that happen in parent. This one will communicate through
|
||||
// `messageManager`.
|
||||
await this.conn.spawnActorInParentProcess(
|
||||
this.actorID, {
|
||||
module: "devtools/server/actors/network-monitor",
|
||||
constructor: "NetworkMonitorActor",
|
||||
|
@ -655,17 +647,34 @@ WebConsoleActor.prototype =
|
|||
this.actorID
|
||||
],
|
||||
});
|
||||
|
||||
// Spawn also one in the child to listen to service workers
|
||||
this.networkMonitorChildActor = new NetworkMonitorActor(this.conn,
|
||||
{ window },
|
||||
this.actorID,
|
||||
null,
|
||||
this.stackTraceCollector);
|
||||
} else {
|
||||
this.networkMonitorActor = new NetworkMonitorActor(this.conn, { window },
|
||||
this.actorID, null, this.stackTraceCollector);
|
||||
this.netmonitors.push({
|
||||
messageManager: this.parentActor.messageManager,
|
||||
parentProcess: true
|
||||
});
|
||||
}
|
||||
|
||||
// When the console actor runs in the parent process, Netmonitor can be ran
|
||||
// in the process and communicate through `messageManagerMock`.
|
||||
// And while it runs in the content process, we also spawn one in the content
|
||||
// to listen to requests that happen in the content process (for instance
|
||||
// service workers requests)
|
||||
new NetworkMonitorActor(this.conn,
|
||||
{ window },
|
||||
this.actorID,
|
||||
mmMockParent);
|
||||
|
||||
this.netmonitors.push({
|
||||
messageManager: mmMockChild,
|
||||
parentProcess: !isInContentProcess
|
||||
});
|
||||
|
||||
// Create a StackTraceCollector that's going to be shared both by
|
||||
// the NetworkMonitorActor running in the same process for service worker
|
||||
// requests, as well with the NetworkMonitorActor running in the parent
|
||||
// process. It will communicate via message manager for this one.
|
||||
this.stackTraceCollector = new StackTraceCollector({ window },
|
||||
this.netmonitors);
|
||||
this.stackTraceCollector.init();
|
||||
}
|
||||
startedListeners.push(listener);
|
||||
break;
|
||||
|
@ -764,22 +773,13 @@ WebConsoleActor.prototype =
|
|||
stoppedListeners.push(listener);
|
||||
break;
|
||||
case "NetworkActivity":
|
||||
if (this.networkMonitorActor) {
|
||||
this.networkMonitorActor.destroy();
|
||||
this.networkMonitorActor = null;
|
||||
}
|
||||
if (this.networkMonitorActorId) {
|
||||
const messageManager = this.parentActor.messageManager;
|
||||
if (messageManager) {
|
||||
if (this.netmonitors) {
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.sendAsyncMessage("debug:destroy-network-monitor", {
|
||||
actorId: this.networkMonitorActorId
|
||||
actorID: this.actorID
|
||||
});
|
||||
}
|
||||
this.networkMonitorActorId = null;
|
||||
}
|
||||
if (this.networkMonitorChildActor) {
|
||||
this.networkMonitorChildActor.destroy();
|
||||
this.networkMonitorChildActor = null;
|
||||
this.netmonitors = null;
|
||||
}
|
||||
if (this.stackTraceCollector) {
|
||||
this.stackTraceCollector.destroy();
|
||||
|
@ -1252,31 +1252,19 @@ WebConsoleActor.prototype =
|
|||
for (const key in request.preferences) {
|
||||
this._prefs[key] = request.preferences[key];
|
||||
|
||||
if (key == "NetworkMonitor.saveRequestAndResponseBodies") {
|
||||
if (this.networkMonitorActor) {
|
||||
this.networkMonitorActor.netMonitor.saveRequestAndResponseBodies =
|
||||
this._prefs[key];
|
||||
}
|
||||
if (this.networkMonitorChildActor) {
|
||||
this.networkMonitorChildActor.netMonitor.saveRequestAndResponseBodies =
|
||||
this._prefs[key];
|
||||
}
|
||||
if (this.networkMonitorActorId) {
|
||||
const messageManager = this.parentActor.messageManager;
|
||||
messageManager.sendAsyncMessage("debug:netmonitor-preference",
|
||||
{ saveRequestAndResponseBodies: this._prefs[key] });
|
||||
}
|
||||
} else if (key == "NetworkMonitor.throttleData") {
|
||||
if (this.networkMonitorActor) {
|
||||
this.networkMonitorActor.netMonitor.throttleData = this._prefs[key];
|
||||
}
|
||||
if (this.networkMonitorChildActor) {
|
||||
this.networkMonitorChildActor.netMonitor.throttleData = this._prefs[key];
|
||||
}
|
||||
if (this.networkMonitorActorId) {
|
||||
const messageManager = this.parentActor.messageManager;
|
||||
messageManager.sendAsyncMessage("debug:netmonitor-preference",
|
||||
{ throttleData: this._prefs[key] });
|
||||
if (this.netmonitors) {
|
||||
if (key == "NetworkMonitor.saveRequestAndResponseBodies") {
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.sendAsyncMessage("debug:netmonitor-preference", {
|
||||
saveRequestAndResponseBodies: this._prefs[key]
|
||||
});
|
||||
}
|
||||
} else if (key == "NetworkMonitor.throttleData") {
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.sendAsyncMessage("debug:netmonitor-preference", {
|
||||
throttleData: this._prefs[key]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1818,26 +1806,30 @@ WebConsoleActor.prototype =
|
|||
* The URL of the request to search for.
|
||||
*/
|
||||
getRequestContentForURL(url) {
|
||||
// When running in Parent Process, call the NetworkMonitorActor directly.
|
||||
if (this.networkMonitorActor) {
|
||||
return this.networkMonitorActor.getRequestContentForURL(url);
|
||||
} else if (this.networkMonitorActorId) {
|
||||
// Otherwise, if the netmonitor is started, but on the parent process,
|
||||
// pipe the data through the message manager
|
||||
const messageManager = this.parentActor.messageManager;
|
||||
return new Promise(resolve => {
|
||||
const onMessage = ({ data }) => {
|
||||
if (data.url == url) {
|
||||
if (!this.netmonitors) {
|
||||
return null;
|
||||
}
|
||||
return new Promise(resolve => {
|
||||
let messagesReceived = 0;
|
||||
const onMessage = ({ data }) => {
|
||||
if (data.url != url) {
|
||||
return;
|
||||
}
|
||||
messagesReceived++;
|
||||
// Either use the first response with a content, or return a null content
|
||||
// if we received the responses from all the message managers.
|
||||
if (data.content || messagesReceived == this.netmonitors.length) {
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.removeMessageListener("debug:request-content", onMessage);
|
||||
resolve(data.content);
|
||||
}
|
||||
};
|
||||
resolve(data.content);
|
||||
}
|
||||
};
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.addMessageListener("debug:request-content", onMessage);
|
||||
messageManager.sendAsyncMessage("debug:request-content", { url });
|
||||
});
|
||||
}
|
||||
// Finally, if the netmonitor is not started at all, return null
|
||||
return null;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1883,30 +1875,28 @@ WebConsoleActor.prototype =
|
|||
|
||||
NetUtil.asyncFetch(channel, () => {});
|
||||
|
||||
// When running in Parent Process, call the NetworkMonitorActor directly.
|
||||
if (!this.netmonitors) {
|
||||
return null;
|
||||
}
|
||||
const { channelId } = channel;
|
||||
if (this.networkMonitorActor) {
|
||||
const actor = this.networkMonitorActor.getNetworkEventActor(channelId);
|
||||
return {
|
||||
eventActor: actor.form()
|
||||
};
|
||||
} else if (this.networkMonitorActorId) {
|
||||
// Otherwise, if the netmonitor is started, but on the parent process,
|
||||
// pipe the data through the message manager
|
||||
const messageManager = this.parentActor.messageManager;
|
||||
return new Promise(resolve => {
|
||||
const onMessage = ({ data }) => {
|
||||
// Only query the NetworkMonitorActor running in the parent process, where the
|
||||
// request will be done. There always is one listener running in the parent process,
|
||||
// see startListeners.
|
||||
const netmonitor = this.netmonitors.filter(({ parentProcess }) => parentProcess)[0];
|
||||
const { messageManager } = netmonitor;
|
||||
return new Promise(resolve => {
|
||||
const onMessage = ({ data }) => {
|
||||
if (data.channelId == channelId) {
|
||||
messageManager.removeMessageListener("debug:get-network-event-actor",
|
||||
onMessage);
|
||||
resolve({
|
||||
eventActor: data
|
||||
eventActor: data.actor
|
||||
});
|
||||
};
|
||||
messageManager.addMessageListener("debug:get-network-event-actor", onMessage);
|
||||
messageManager.sendAsyncMessage("debug:get-network-event-actor", { channelId });
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
messageManager.addMessageListener("debug:get-network-event-actor", onMessage);
|
||||
messageManager.sendAsyncMessage("debug:get-network-event-actor", { channelId });
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/* 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";
|
||||
|
||||
/**
|
||||
* Implements a fake MessageManager class that allows to use the message
|
||||
* manager API within the same process. This implementation will forward
|
||||
* messages within the same process.
|
||||
*
|
||||
* It helps having the same codepath for actors being evaluated in the same
|
||||
* process *and* in a remote one.
|
||||
*/
|
||||
function MessageManagerMock() {
|
||||
this._listeners = new Map();
|
||||
}
|
||||
MessageManagerMock.prototype = {
|
||||
addMessageListener(name, listener) {
|
||||
let listeners = this._listeners.get(name);
|
||||
if (!listeners) {
|
||||
listeners = [];
|
||||
this._listeners.set(name, listeners);
|
||||
}
|
||||
if (!listeners.includes(listener)) {
|
||||
listeners.push(listener);
|
||||
}
|
||||
},
|
||||
removeMessageListener(name, listener) {
|
||||
const listeners = this._listeners.get(name);
|
||||
const idx = listeners.indexOf(listener);
|
||||
listeners.splice(idx, 1);
|
||||
},
|
||||
sendAsyncMessage(name, data) {
|
||||
this.other.internalSendAsyncMessage(name, data);
|
||||
},
|
||||
internalSendAsyncMessage(name, data) {
|
||||
const listeners = this._listeners.get(name);
|
||||
if (!listeners) {
|
||||
return;
|
||||
}
|
||||
const message = {
|
||||
target: this,
|
||||
data
|
||||
};
|
||||
for (const listener of listeners) {
|
||||
if (typeof listener === "object" &&
|
||||
typeof listener.receiveMessage === "function") {
|
||||
listener.receiveMessage(message);
|
||||
} else if (typeof listener === "function") {
|
||||
listener(message);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Create two MessageManager mocks, connected to each others.
|
||||
* Calling sendAsyncMessage on the first will dispatch messages on the second one,
|
||||
* and the other way around
|
||||
*/
|
||||
exports.createMessageManagerMocks = function() {
|
||||
const a = new MessageManagerMock();
|
||||
const b = new MessageManagerMock();
|
||||
a.other = b;
|
||||
b.other = a;
|
||||
return [a, b];
|
||||
};
|
|
@ -8,6 +8,7 @@ DevToolsModules(
|
|||
'commands.js',
|
||||
'content-process-forward.js',
|
||||
'listeners.js',
|
||||
'message-manager-mock.js',
|
||||
'screenshot.js',
|
||||
'utils.js',
|
||||
'worker-listeners.js',
|
||||
|
|
|
@ -177,33 +177,33 @@ ChannelEventSinkFactory.getService = function() {
|
|||
return Cc[SINK_CONTRACT_ID].getService(Ci.nsIChannelEventSink).wrappedJSObject;
|
||||
};
|
||||
|
||||
function StackTraceCollector(filters, messageManager) {
|
||||
function StackTraceCollector(filters, netmonitors) {
|
||||
this.filters = filters;
|
||||
this.stacktracesById = new Map();
|
||||
this.messageManager = messageManager;
|
||||
this.netmonitors = netmonitors;
|
||||
}
|
||||
|
||||
StackTraceCollector.prototype = {
|
||||
init() {
|
||||
Services.obs.addObserver(this, "http-on-opening-request");
|
||||
ChannelEventSinkFactory.getService().registerCollector(this);
|
||||
if (this.messageManager) {
|
||||
this.onGetStack = this.onGetStack.bind(this);
|
||||
this.messageManager.addMessageListener("debug:request-stack", this.onGetStack);
|
||||
this.onGetStack = this.onGetStack.bind(this);
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.addMessageListener("debug:request-stack", this.onGetStack);
|
||||
}
|
||||
},
|
||||
|
||||
destroy() {
|
||||
Services.obs.removeObserver(this, "http-on-opening-request");
|
||||
ChannelEventSinkFactory.getService().unregisterCollector(this);
|
||||
if (this.messageManager) {
|
||||
this.messageManager.removeMessageListener("debug:request-stack", this.onGetStack);
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.removeMessageListener("debug:request-stack", this.onGetStack);
|
||||
}
|
||||
},
|
||||
|
||||
_saveStackTrace(channel, stacktrace) {
|
||||
if (this.messageManager) {
|
||||
this.messageManager.sendAsyncMessage("debug:request-stack-available", {
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.sendAsyncMessage("debug:request-stack-available", {
|
||||
channelId: channel.channelId,
|
||||
stacktrace: stacktrace && stacktrace.length > 0
|
||||
});
|
||||
|
@ -263,9 +263,10 @@ StackTraceCollector.prototype = {
|
|||
},
|
||||
|
||||
onGetStack(msg) {
|
||||
const messageManager = msg.target;
|
||||
const channelId = msg.data;
|
||||
const stack = this.getStackTrace(channelId);
|
||||
this.messageManager.sendAsyncMessage("debug:request-stack", {
|
||||
messageManager.sendAsyncMessage("debug:request-stack", {
|
||||
channelId,
|
||||
stack,
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче