diff options
Diffstat (limited to '')
-rw-r--r-- | devtools/server/actors/watcher/session-context.js | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/devtools/server/actors/watcher/session-context.js b/devtools/server/actors/watcher/session-context.js new file mode 100644 index 0000000000..6457399455 --- /dev/null +++ b/devtools/server/actors/watcher/session-context.js @@ -0,0 +1,219 @@ +/* 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"; + +// Module to create all the Session Context objects. +// +// These are static JSON serializable object that help describe +// the debugged context. It is passed around to most of the server codebase +// in order to know which object to consider inspecting and communicating back to the client. +// +// These objects are all instantiated by the Descriptor actors +// and passed as a constructor argument to the Watcher actor. +// +// These objects have attributes used by all the Session contexts: +// - type: String +// Describes which type of context we are debugging. +// See SESSION_TYPES for all possible values. +// See each create* method for more info about each type and their specific attributes. +// - isServerTargetSwitchingEnabled: Boolean +// If true, targets should all be spawned by the server codebase. +// Especially the first, top level target. +// - supportedTargets: Boolean +// An object keyed by target type, whose value indicates if we have watcher support +// for the target. +// - supportedResources: Boolean +// An object keyed by resource type, whose value indicates if we have watcher support +// for the resource. + +const Targets = require("resource://devtools/server/actors/targets/index.js"); +const Resources = require("resource://devtools/server/actors/resources/index.js"); + +const SESSION_TYPES = { + ALL: "all", + BROWSER_ELEMENT: "browser-element", + CONTENT_PROCESS: "content-process", + WEBEXTENSION: "webextension", + WORKER: "worker", +}; + +/** + * Create the SessionContext used by the Browser Toolbox and Browser Console. + * + * This context means debugging everything. + * The whole browser: + * - all processes: parent and content, + * - all privileges: privileged/chrome and content/web, + * - all components/targets: HTML documents, processes, workers, add-ons,... + */ +function createBrowserSessionContext() { + const type = SESSION_TYPES.ALL; + + return { + type, + // For now, the top level target (ParentProcessTargetActor) is created via ProcessDescriptor.getTarget + // and is never replaced by any other, nor is it created by the WatcherActor. + isServerTargetSwitchingEnabled: false, + supportedTargets: getWatcherSupportedTargets(type), + supportedResources: getWatcherSupportedResources(type), + }; +} + +/** + * Create the SessionContext used by the regular web page toolboxes as well as remote debugging android device tabs. + * + * @param {BrowserElement} browserElement + * The tab to debug. It should be a reference to a <browser> element. + * @param {Object} config + * An object with optional configuration. Only supports "isServerTargetSwitchingEnabled" attribute. + * See jsdoc in this file header for more info. + */ +function createBrowserElementSessionContext(browserElement, config) { + const type = SESSION_TYPES.BROWSER_ELEMENT; + return { + type, + browserId: browserElement.browserId, + // Nowaday, it should always be enabled except for WebExtension special + // codepath and some tests. + isServerTargetSwitchingEnabled: config.isServerTargetSwitchingEnabled, + // Should we instantiate targets for popups opened in distinct tabs/windows? + // Driven by devtools.popups.debug=true preference. + isPopupDebuggingEnabled: config.isPopupDebuggingEnabled, + supportedTargets: getWatcherSupportedTargets(type), + supportedResources: getWatcherSupportedResources(type), + }; +} + +/** + * Create the SessionContext used by the web extension toolboxes. + * + * @param {Object} addon + * First object argument to describe the add-on. + * @param {String} addon.addonId + * The web extension ID, to uniquely identify the debugged add-on. + * @param {String} addon.browsingContextID + * The ID of the BrowsingContext into which this add-on is loaded. + * For now the top level target is associated with this one precise BrowsingContext. + * Knowing about it later helps associate resources to the same BrowsingContext ID and so the same target. + * @param {String} addon.innerWindowId + * The ID of the WindowGlobal into which this add-on is loaded. + * This is used for the same reason as browsingContextID. It helps match the resource with the right target. + * We now also use the WindowGlobal ID/innerWindowId to identify the targets. + * @param {Object} config + * An object with optional configuration. Only supports "isServerTargetSwitchingEnabled" attribute. + * See jsdoc in this file header for more info. + */ +function createWebExtensionSessionContext( + { addonId, browsingContextID, innerWindowId }, + config +) { + const type = SESSION_TYPES.WEBEXTENSION; + return { + type, + addonId, + addonBrowsingContextID: browsingContextID, + addonInnerWindowId: innerWindowId, + // For now, there is only one target (WebExtensionTargetActor), it is never replaced, + // and is only created via WebExtensionDescriptor.getTarget (and never by the watcher actor). + isServerTargetSwitchingEnabled: config.isServerTargetSwitchingEnabled, + supportedTargets: getWatcherSupportedTargets(type), + supportedResources: getWatcherSupportedResources(type), + }; +} + +/** + * Create the SessionContext used by the Browser Content Toolbox, to debug only one content process. + * Or when debugging XpcShell via about:debugging, where we instantiate only one content process target. + */ +function createContentProcessSessionContext() { + const type = SESSION_TYPES.CONTENT_PROCESS; + return { + type, + supportedTargets: getWatcherSupportedTargets(type), + supportedResources: getWatcherSupportedResources(type), + }; +} + +/** + * Create the SessionContext used when debugging one specific Service Worker or special chrome worker. + * This is only used from about:debugging. + */ +function createWorkerSessionContext() { + const type = SESSION_TYPES.WORKER; + return { + type, + supportedTargets: getWatcherSupportedTargets(type), + supportedResources: getWatcherSupportedResources(type), + }; +} + +/** + * Get the supported targets by the watcher given a session context type. + * + * @param {String} type + * @returns {Object} + */ +function getWatcherSupportedTargets(type) { + return { + [Targets.TYPES.FRAME]: true, + [Targets.TYPES.PROCESS]: true, + [Targets.TYPES.WORKER]: + type == SESSION_TYPES.BROWSER_ELEMENT || + type == SESSION_TYPES.WEBEXTENSION, + [Targets.TYPES.SERVICE_WORKER]: type == SESSION_TYPES.BROWSER_ELEMENT, + }; +} + +/** + * Get the supported resources by the watcher given a session context type. + * + * @param {String} type + * @returns {Object} + */ +function getWatcherSupportedResources(type) { + // All resources types are supported for tab debugging and web extensions. + // Some watcher classes are still disabled for the Multiprocess Browser Toolbox (type=SESSION_TYPES.ALL). + // And they may also be disabled for workers once we start supporting them by the watcher. + // So set the traits to false for all the resources that we don't support yet + // and keep using the legacy listeners. + const isTabOrWebExtensionToolbox = + type == SESSION_TYPES.BROWSER_ELEMENT || type == SESSION_TYPES.WEBEXTENSION; + + return { + [Resources.TYPES.CONSOLE_MESSAGE]: true, + [Resources.TYPES.CSS_CHANGE]: isTabOrWebExtensionToolbox, + [Resources.TYPES.CSS_MESSAGE]: true, + [Resources.TYPES.CSS_REGISTERED_PROPERTIES]: true, + [Resources.TYPES.DOCUMENT_EVENT]: true, + [Resources.TYPES.CACHE_STORAGE]: true, + [Resources.TYPES.COOKIE]: true, + [Resources.TYPES.ERROR_MESSAGE]: true, + [Resources.TYPES.EXTENSION_STORAGE]: true, + [Resources.TYPES.INDEXED_DB]: true, + [Resources.TYPES.LOCAL_STORAGE]: true, + [Resources.TYPES.SESSION_STORAGE]: true, + [Resources.TYPES.PLATFORM_MESSAGE]: true, + [Resources.TYPES.NETWORK_EVENT]: true, + [Resources.TYPES.NETWORK_EVENT_STACKTRACE]: true, + [Resources.TYPES.REFLOW]: true, + [Resources.TYPES.STYLESHEET]: true, + [Resources.TYPES.SOURCE]: true, + [Resources.TYPES.THREAD_STATE]: true, + [Resources.TYPES.SERVER_SENT_EVENT]: true, + [Resources.TYPES.WEBSOCKET]: true, + [Resources.TYPES.JSTRACER_TRACE]: true, + [Resources.TYPES.JSTRACER_STATE]: true, + [Resources.TYPES.LAST_PRIVATE_CONTEXT_EXIT]: true, + }; +} + +module.exports = { + createBrowserSessionContext, + createBrowserElementSessionContext, + createWebExtensionSessionContext, + createContentProcessSessionContext, + createWorkerSessionContext, + SESSION_TYPES, +}; |