tracer-command.js (4051B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const EventEmitter = require("resource://devtools/shared/event-emitter.js"); 8 9 loader.lazyRequireGetter( 10 this, 11 "TRACER_LOG_METHODS", 12 "resource://devtools/shared/specs/tracer.js", 13 true 14 ); 15 16 class TracerCommand extends EventEmitter { 17 constructor({ commands }) { 18 super(); 19 this.#targetConfigurationCommand = commands.targetConfigurationCommand; 20 this.#resourceCommand = commands.resourceCommand; 21 } 22 23 // The tracer has been requested to start, but doesn't necessarily mean it actually started tracing JS executions. 24 // The tracer may wait for next user interaction/document load before being active. 25 isTracingEnabled = false; 26 // The tracer is actively tracking JS executions. 27 isTracingActive = false; 28 29 #resourceCommand; 30 #targetConfigurationCommand; 31 32 async initialize() { 33 return this.#resourceCommand.watchResources( 34 [this.#resourceCommand.TYPES.JSTRACER_STATE], 35 { onAvailable: this.onResourcesAvailable } 36 ); 37 } 38 39 destroy() { 40 this.#resourceCommand.unwatchResources( 41 [this.#resourceCommand.TYPES.JSTRACER_STATE], 42 { onAvailable: this.onResourcesAvailable } 43 ); 44 } 45 46 onResourcesAvailable = resources => { 47 for (const resource of resources) { 48 if (resource.resourceType != this.#resourceCommand.TYPES.JSTRACER_STATE) { 49 continue; 50 } 51 52 // Clear the list of collected frames each time we start a new tracer record. 53 // The tracer will reset its frame counter to zero on stop, but on the frontend 54 // we may inspect frames after the tracer is stopped, until we start a new one. 55 if (resource.enabled) { 56 resource.targetFront.getJsTracerCollectedFramesArray().length = 0; 57 } 58 59 if ( 60 resource.enabled == this.isTracingActive && 61 resource.enabled == this.isTracingEnabled 62 ) { 63 continue; 64 } 65 66 this.isTracingActive = resource.enabled; 67 // In case the tracer is started without the DevTools frontend, also force it to be reported as enabled 68 this.isTracingEnabled = resource.enabled; 69 70 this.emit("toggle"); 71 } 72 }; 73 74 /** 75 * Get the dictionary passed to the server codebase as a SessionData. 76 * This contains all settings to fine tune the tracer actual behavior. 77 * 78 * @return {JSON} 79 * Configuration object. 80 */ 81 getTracingOptions() { 82 const logMethod = Services.prefs.getStringPref( 83 "devtools.debugger.javascript-tracing-log-method", 84 "" 85 ); 86 return { 87 logMethod, 88 // Force enabling DOM Mutation logging as soon as we selected the sidebar log output 89 traceDOMMutations: 90 logMethod == TRACER_LOG_METHODS.DEBUGGER_SIDEBAR || 91 logMethod == TRACER_LOG_METHODS.PROFILER 92 ? ["add", "attributes", "remove"] 93 : null, 94 traceValues: Services.prefs.getBoolPref( 95 "devtools.debugger.javascript-tracing-values", 96 false 97 ), 98 traceOnNextInteraction: Services.prefs.getBoolPref( 99 "devtools.debugger.javascript-tracing-on-next-interaction", 100 false 101 ), 102 traceOnNextLoad: Services.prefs.getBoolPref( 103 "devtools.debugger.javascript-tracing-on-next-load", 104 false 105 ), 106 traceFunctionReturn: Services.prefs.getBoolPref( 107 "devtools.debugger.javascript-tracing-function-return", 108 false 109 ), 110 }; 111 } 112 113 /** 114 * Toggle JavaScript tracing for all targets. 115 */ 116 async toggle() { 117 this.isTracingEnabled = !this.isTracingEnabled; 118 119 // May be wait for the web console to be fully initialized and listening to tracer resources before enabling it 120 await this.emitAsync("toggle"); 121 122 await this.#targetConfigurationCommand.updateConfiguration({ 123 tracerOptions: this.isTracingEnabled 124 ? this.getTracingOptions() 125 : undefined, 126 }); 127 } 128 } 129 130 module.exports = TracerCommand;