1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
/* 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";
/**
* The following functions are used in testing to control and inspect
* the nsIProfiler in child process content. These should be called from
* the parent process.
*/
const { Cc, Ci } = require("chrome");
const { Task } = require("devtools/shared/task");
const FRAME_SCRIPT_UTILS_URL = "chrome://devtools/content/shared/frame-script-utils.js";
let gMM = null;
/**
* Loads the relevant frame scripts into the provided browser's message manager.
*/
exports.pmmLoadFrameScripts = (gBrowser) => {
gMM = gBrowser.selectedBrowser.messageManager;
gMM.loadFrameScript(FRAME_SCRIPT_UTILS_URL, false);
};
/**
* Clears the cached message manager.
*/
exports.pmmClearFrameScripts = () => {
gMM = null;
};
/**
* Sends a message to the message listener, attaching an id to the payload data.
* Resolves a returned promise when the response is received from the message
* listener, with the same id as part of the response payload data.
*/
exports.pmmUniqueMessage = function (message, payload) {
if (!gMM) {
throw new Error("`pmmLoadFrameScripts()` must be called when using MessageManager.");
}
let { generateUUID } = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator);
payload.id = generateUUID().toString();
return new Promise(resolve => {
gMM.addMessageListener(message + ":response", function onHandler({ data }) {
if (payload.id == data.id) {
gMM.removeMessageListener(message + ":response", onHandler);
resolve(data.data);
}
});
gMM.sendAsyncMessage(message, payload);
});
};
/**
* Checks if the nsProfiler module is active.
*/
exports.pmmIsProfilerActive = () => {
return exports.pmmSendProfilerCommand("IsActive");
};
/**
* Starts the nsProfiler module.
*/
exports.pmmStartProfiler = Task.async(function* ({ entries, interval, features }) {
let isActive = (yield exports.pmmSendProfilerCommand("IsActive")).isActive;
if (!isActive) {
return exports.pmmSendProfilerCommand("StartProfiler", [entries, interval, features,
features.length]);
}
return null;
});
/**
* Stops the nsProfiler module.
*/
exports.pmmStopProfiler = Task.async(function* () {
let isActive = (yield exports.pmmSendProfilerCommand("IsActive")).isActive;
if (isActive) {
return exports.pmmSendProfilerCommand("StopProfiler");
}
return null;
});
/**
* Calls a method on the nsProfiler module.
*/
exports.pmmSendProfilerCommand = (method, args = []) => {
return exports.pmmUniqueMessage("devtools:test:profiler", { method, args });
};
/**
* Evaluates a script in content, returning a promise resolved with the
* returned result.
*/
exports.pmmEvalInDebuggee = (script) => {
return exports.pmmUniqueMessage("devtools:test:eval", { script });
};
/**
* Evaluates a console method in content.
*/
exports.pmmConsoleMethod = function (method, ...args) {
// Terrible ugly hack -- this gets stringified when it uses the
// message manager, so an undefined arg in `console.profileEnd()`
// turns into a stringified "null", which is terrible. This method
// is only used for test helpers, so swap out the argument if its undefined
// with an empty string. Differences between empty string and undefined are
// tested on the front itself.
if (args[0] == null) {
args[0] = "";
}
return exports.pmmUniqueMessage("devtools:test:console", { method, args });
};
|