session-context.js (8190B)
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 // Module to create all the Session Context objects. 8 // 9 // These are static JSON serializable object that help describe 10 // the debugged context. It is passed around to most of the server codebase 11 // in order to know which object to consider inspecting and communicating back to the client. 12 // 13 // These objects are all instantiated by the Descriptor actors 14 // and passed as a constructor argument to the Watcher actor. 15 // 16 // These objects have attributes used by all the Session contexts: 17 // - type: String 18 // Describes which type of context we are debugging. 19 // See SESSION_TYPES for all possible values. 20 // See each create* method for more info about each type and their specific attributes. 21 // - isServerTargetSwitchingEnabled: Boolean 22 // If true, targets should all be spawned by the server codebase. 23 // Especially the first, top level target. 24 // - supportedTargets: Boolean 25 // An object keyed by target type, whose value indicates if we have watcher support 26 // for the target. 27 // - supportedResources: Boolean 28 // An object keyed by resource type, whose value indicates if we have watcher support 29 // for the resource. 30 // - enableWindowGlobalThreadActors: Boolean 31 // If false (the default), Resource Watchers will avoid spawning the thread actors of 32 // WindowGlobal targets. In such configuration, the WindowGlobal scripts will be 33 // debugged by the Content Process targets. 34 // This is used by the Browser Toolbox, and explicitly not used by VS.Code 35 // which reuse the Browser Toolbox codepath, but doesn't use the Content Process targets. 36 37 const Targets = require("resource://devtools/server/actors/targets/index.js"); 38 const Resources = require("resource://devtools/server/actors/resources/index.js"); 39 40 const SESSION_TYPES = { 41 ALL: "all", 42 BROWSER_ELEMENT: "browser-element", 43 CONTENT_PROCESS: "content-process", 44 WEBEXTENSION: "webextension", 45 WORKER: "worker", 46 }; 47 48 /** 49 * Create the SessionContext used by the Browser Toolbox and Browser Console. 50 * 51 * This context means debugging everything. 52 * The whole browser: 53 * - all processes: parent and content, 54 * - all privileges: privileged/chrome and content/web, 55 * - all components/targets: HTML documents, processes, workers, add-ons,... 56 * 57 * @param {object} config 58 * An object with optional configuration. Only supports "enableWindowGlobalThreadActors" attribute. 59 * See jsdoc in this file header for more info. 60 */ 61 function createBrowserSessionContext({ 62 enableWindowGlobalThreadActors = false, 63 } = {}) { 64 const type = SESSION_TYPES.ALL; 65 66 return { 67 type, 68 // For now, the top level target (ParentProcessTargetActor) is created via ProcessDescriptor.getTarget 69 // and is never replaced by any other, nor is it created by the WatcherActor. 70 isServerTargetSwitchingEnabled: false, 71 supportedTargets: getWatcherSupportedTargets(type), 72 supportedResources: getWatcherSupportedResources(type), 73 74 enableWindowGlobalThreadActors, 75 }; 76 } 77 78 /** 79 * Create the SessionContext used by the regular web page toolboxes as well as remote debugging android device tabs. 80 * 81 * @param {BrowserElement} browserElement 82 * The tab to debug. It should be a reference to a <browser> element. 83 * @param {object} config 84 * An object with optional configuration. Only supports "isServerTargetSwitchingEnabled" attribute. 85 * See jsdoc in this file header for more info. 86 */ 87 function createBrowserElementSessionContext(browserElement, config) { 88 const type = SESSION_TYPES.BROWSER_ELEMENT; 89 return { 90 type, 91 browserId: browserElement.browserId, 92 // Nowaday, it should always be enabled except for WebExtension special 93 // codepath and some tests. 94 isServerTargetSwitchingEnabled: config.isServerTargetSwitchingEnabled, 95 // Should we instantiate targets for popups opened in distinct tabs/windows? 96 // Driven by devtools.popups.debug=true preference. 97 isPopupDebuggingEnabled: config.isPopupDebuggingEnabled, 98 supportedTargets: getWatcherSupportedTargets(type), 99 supportedResources: getWatcherSupportedResources(type), 100 }; 101 } 102 103 /** 104 * Create the SessionContext used by the web extension toolboxes. 105 * 106 * @param {object} addon 107 * First object argument to describe the add-on. 108 * @param {string} addon.addonId 109 * The web extension ID, to uniquely identify the debugged add-on. 110 * @param {object} config 111 * An object with optional configuration. Only supports "isServerTargetSwitchingEnabled" attribute. 112 * See jsdoc in this file header for more info. 113 */ 114 function createWebExtensionSessionContext({ addonId }, config) { 115 const type = SESSION_TYPES.WEBEXTENSION; 116 return { 117 type, 118 addonId, 119 isServerTargetSwitchingEnabled: config.isServerTargetSwitchingEnabled, 120 supportedTargets: getWatcherSupportedTargets(type), 121 supportedResources: getWatcherSupportedResources(type), 122 }; 123 } 124 125 /** 126 * Create the SessionContext used by the Browser Content Toolbox, to debug only one content process. 127 * Or when debugging XpcShell via about:debugging, where we instantiate only one content process target. 128 */ 129 function createContentProcessSessionContext() { 130 const type = SESSION_TYPES.CONTENT_PROCESS; 131 return { 132 type, 133 supportedTargets: getWatcherSupportedTargets(type), 134 supportedResources: getWatcherSupportedResources(type), 135 }; 136 } 137 138 /** 139 * Create the SessionContext used when debugging one specific Service Worker or special chrome worker. 140 * This is only used from about:debugging. 141 */ 142 function createWorkerSessionContext() { 143 const type = SESSION_TYPES.WORKER; 144 return { 145 type, 146 supportedTargets: getWatcherSupportedTargets(type), 147 supportedResources: getWatcherSupportedResources(type), 148 }; 149 } 150 151 /** 152 * Get the supported targets by the watcher given a session context type. 153 * 154 * @param {string} type 155 * @returns {object} 156 */ 157 function getWatcherSupportedTargets(type) { 158 return { 159 [Targets.TYPES.FRAME]: true, 160 [Targets.TYPES.PROCESS]: true, 161 [Targets.TYPES.WORKER]: true, 162 [Targets.TYPES.SERVICE_WORKER]: 163 type == SESSION_TYPES.BROWSER_ELEMENT || type == SESSION_TYPES.ALL, 164 165 // Bug 1607778 - Shared workers aren't yet exposed in tab toolboxes 166 [Targets.TYPES.SHARED_WORKER]: type == SESSION_TYPES.ALL, 167 168 // Content scripts may only be exposed to tab and browser toolboxes 169 // (and not the extension toolboxes) 170 [Targets.TYPES.CONTENT_SCRIPT]: 171 type == SESSION_TYPES.BROWSER_ELEMENT || type == SESSION_TYPES.ALL, 172 }; 173 } 174 175 /** 176 * Get the supported resources by the watcher given a session context type. 177 * 178 * @param {string} _type 179 * @returns {object} 180 */ 181 function getWatcherSupportedResources(_type) { 182 return { 183 [Resources.TYPES.CONSOLE_MESSAGE]: true, 184 [Resources.TYPES.CSS_CHANGE]: true, 185 [Resources.TYPES.CSS_MESSAGE]: true, 186 [Resources.TYPES.CSS_REGISTERED_PROPERTIES]: true, 187 [Resources.TYPES.DOCUMENT_EVENT]: true, 188 [Resources.TYPES.CACHE_STORAGE]: true, 189 [Resources.TYPES.COOKIE]: true, 190 [Resources.TYPES.ERROR_MESSAGE]: true, 191 [Resources.TYPES.EXTENSION_STORAGE]: true, 192 [Resources.TYPES.INDEXED_DB]: true, 193 [Resources.TYPES.LOCAL_STORAGE]: true, 194 [Resources.TYPES.SESSION_STORAGE]: true, 195 [Resources.TYPES.PLATFORM_MESSAGE]: true, 196 [Resources.TYPES.NETWORK_EVENT]: true, 197 [Resources.TYPES.NETWORK_EVENT_STACKTRACE]: true, 198 [Resources.TYPES.REFLOW]: true, 199 [Resources.TYPES.STYLESHEET]: true, 200 [Resources.TYPES.SOURCE]: true, 201 [Resources.TYPES.THREAD_STATE]: true, 202 [Resources.TYPES.SERVER_SENT_EVENT]: true, 203 [Resources.TYPES.WEBSOCKET]: true, 204 [Resources.TYPES.WEBTRANSPORT]: true, 205 [Resources.TYPES.JSTRACER_TRACE]: true, 206 [Resources.TYPES.JSTRACER_STATE]: true, 207 [Resources.TYPES.LAST_PRIVATE_CONTEXT_EXIT]: true, 208 }; 209 } 210 211 module.exports = { 212 createBrowserSessionContext, 213 createBrowserElementSessionContext, 214 createWebExtensionSessionContext, 215 createContentProcessSessionContext, 216 createWorkerSessionContext, 217 SESSION_TYPES, 218 };