diff options
Diffstat (limited to 'remote/cdp/domains/parent/Target.sys.mjs')
-rw-r--r-- | remote/cdp/domains/parent/Target.sys.mjs | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/remote/cdp/domains/parent/Target.sys.mjs b/remote/cdp/domains/parent/Target.sys.mjs new file mode 100644 index 0000000000..5f0229ce4d --- /dev/null +++ b/remote/cdp/domains/parent/Target.sys.mjs @@ -0,0 +1,193 @@ +/* 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/. */ + +import { Domain } from "chrome://remote/content/cdp/domains/Domain.sys.mjs"; + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + ContextualIdentityService: + "resource://gre/modules/ContextualIdentityService.sys.mjs", + MainProcessTarget: + "chrome://remote/content/cdp/targets/MainProcessTarget.sys.mjs", + TabManager: "chrome://remote/content/shared/TabManager.sys.mjs", + TabSession: "chrome://remote/content/cdp/sessions/TabSession.sys.mjs", + windowManager: "chrome://remote/content/shared/WindowManager.sys.mjs", +}); + +let browserContextIds = 1; + +export class Target extends Domain { + constructor(session) { + super(session); + + this._onTargetCreated = this._onTargetCreated.bind(this); + this._onTargetDestroyed = this._onTargetDestroyed.bind(this); + } + + getBrowserContexts() { + return { + browserContextIds: [], + }; + } + + createBrowserContext() { + const identity = lazy.ContextualIdentityService.create( + "remote-agent-" + browserContextIds++ + ); + return { browserContextId: identity.userContextId }; + } + + disposeBrowserContext(options = {}) { + const { browserContextId } = options; + + lazy.ContextualIdentityService.remove(browserContextId); + lazy.ContextualIdentityService.closeContainerTabs(browserContextId); + } + + getTargets() { + const { targetList } = this.session.target; + + const targetInfos = []; + for (const target of targetList) { + if (target instanceof lazy.MainProcessTarget) { + continue; + } + + targetInfos.push(this._getTargetInfo(target)); + } + + return { targetInfos }; + } + + setDiscoverTargets(options = {}) { + const { discover } = options; + const { targetList } = this.session.target; + if (discover) { + targetList.on("target-created", this._onTargetCreated); + targetList.on("target-destroyed", this._onTargetDestroyed); + } else { + targetList.off("target-created", this._onTargetCreated); + targetList.off("target-destroyed", this._onTargetDestroyed); + } + for (const target of targetList) { + this._onTargetCreated("target-created", target); + } + } + + async createTarget(options = {}) { + const { browserContextId } = options; + const { targetList, window } = this.session.target; + const onTarget = targetList.once("target-created"); + const tab = await lazy.TabManager.addTab({ + focus: true, + userContextId: browserContextId, + window, + }); + const target = await onTarget; + if (tab.linkedBrowser != target.browser) { + throw new Error( + "Unexpected tab opened: " + tab.linkedBrowser.currentURI.spec + ); + } + return { targetId: target.id }; + } + + async closeTarget(options = {}) { + const { targetId } = options; + const { targetList } = this.session.target; + const target = targetList.getById(targetId); + + if (!target) { + throw new Error(`Unable to find target with id '${targetId}'`); + } + + await lazy.TabManager.removeTab(target.tab); + } + + async activateTarget(options = {}) { + const { targetId } = options; + const { targetList, window } = this.session.target; + const target = targetList.getById(targetId); + + if (!target) { + throw new Error(`Unable to find target with id '${targetId}'`); + } + + // Focus the window, and select the corresponding tab + await lazy.windowManager.focusWindow(window); + await lazy.TabManager.selectTab(target.tab); + } + + attachToTarget(options = {}) { + const { targetId } = options; + const { targetList } = this.session.target; + const target = targetList.getById(targetId); + + if (!target) { + throw new Error(`Unable to find target with id '${targetId}'`); + } + + const tabSession = new lazy.TabSession( + this.session.connection, + target, + Services.uuid + .generateUUID() + .toString() + .slice(1, -1) + ); + this.session.connection.registerSession(tabSession); + + this._emitAttachedToTarget(target, tabSession); + + return { + sessionId: tabSession.id, + }; + } + + setAutoAttach() {} + + sendMessageToTarget(options = {}) { + const { sessionId, message } = options; + const { connection } = this.session; + connection.sendMessageToTarget(sessionId, message); + } + + /** + * Internal methods: the following methods are not part of CDP; + * note the _ prefix. + */ + + _emitAttachedToTarget(target, tabSession) { + const targetInfo = this._getTargetInfo(target); + this.emit("Target.attachedToTarget", { + targetInfo, + sessionId: tabSession.id, + waitingForDebugger: false, + }); + } + + _getTargetInfo(target) { + return { + targetId: target.id, + type: target.type, + title: target.title, + url: target.url, + // TODO: Correctly determine if target is attached (bug 1680780) + attached: target.id == this.session.target.id, + browserContextId: target.browserContextId, + }; + } + + _onTargetCreated(eventName, target) { + const targetInfo = this._getTargetInfo(target); + this.emit("Target.targetCreated", { targetInfo }); + } + + _onTargetDestroyed(eventName, target) { + this.emit("Target.targetDestroyed", { + targetId: target.id, + }); + } +} |