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
|
/* 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";
const {
TYPES: { JSTRACER_STATE },
} = require("resource://devtools/server/actors/resources/index.js");
const { JSTracer } = ChromeUtils.importESModule(
"resource://devtools/server/tracer/tracer.sys.mjs",
{ global: "contextual" }
);
const { LOG_METHODS } = require("resource://devtools/server/actors/tracer.js");
const Targets = require("resource://devtools/server/actors/targets/index.js");
class TracingStateWatcher {
/**
* Start watching for tracing state changes for a given target actor.
*
* @param TargetActor targetActor
* The target actor from which we should observe
* @param Object options
* Dictionary object with following attributes:
* - onAvailable: mandatory function
* This will be called for each resource.
*/
async watch(targetActor, { onAvailable }) {
// Bug 1874204: tracer doesn't support tracing content process from the browser toolbox just yet
if (targetActor.targetType == Targets.TYPES.PROCESS) {
return;
}
this.targetActor = targetActor;
this.onAvailable = onAvailable;
this.tracingListener = {
onTracingToggled: this.onTracingToggled.bind(this),
};
JSTracer.addTracingListener(this.tracingListener);
}
/**
* Stop watching for tracing state
*/
destroy() {
if (!this.tracingListener) {
return;
}
JSTracer.removeTracingListener(this.tracingListener);
}
/**
* Be notified by the underlying JavaScriptTracer class
* in case it stops by itself, instead of being stopped when the Actor's stopTracing
* method is called by the user.
*
* @param {Boolean} enabled
* True if the tracer starts tracing, false it it stops.
* @param {String} reason
* Optional string to justify why the tracer stopped.
*/
onTracingToggled(enabled, reason) {
const tracerActor = this.targetActor.getTargetScopedActor("tracer");
const logMethod = tracerActor?.getLogMethod();
// JavascriptTracer only supports recording once in the same process/thread.
// If we open another DevTools, on the same process, we would receive notification
// about a JavascriptTracer controlled by another toolbox's tracer actor.
// Ignore them as our current tracer actor didn't start tracing.
if (!logMethod) {
return;
}
this.onAvailable([
{
resourceType: JSTRACER_STATE,
enabled,
logMethod,
profile:
logMethod == LOG_METHODS.PROFILER && !enabled
? tracerActor.getProfile()
: undefined,
timeStamp: ChromeUtils.dateNow(),
reason,
},
]);
}
}
module.exports = TracingStateWatcher;
|