blob: 938c219b3229d04efb2b965bb02b45bd4ddc2e58 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @implements {Protocol.TargetDispatcher}
*/
SDK.ChildTargetManager = class extends SDK.SDKModel {
/**
* @param {!SDK.Target} parentTarget
*/
constructor(parentTarget) {
super(parentTarget);
this._targetManager = parentTarget.targetManager();
this._parentTarget = parentTarget;
this._targetAgent = parentTarget.targetAgent();
/** @type {!Map<string, !Protocol.Target.TargetInfo>} */
this._targetInfos = new Map();
/** @type {!Map<string, !SDK.ChildConnection>} */
this._childConnections = new Map();
parentTarget.registerTargetDispatcher(this);
this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true});
if (!parentTarget.parentTarget()) {
this._targetAgent.setDiscoverTargets(true);
this._targetAgent.setRemoteLocations([{host: 'localhost', port: 9229}]);
}
}
/**
* @param {function({target: !SDK.Target, waitingForDebugger: boolean})=} attachCallback
*/
static install(attachCallback) {
SDK.ChildTargetManager._attachCallback = attachCallback;
SDK.SDKModel.register(SDK.ChildTargetManager, SDK.Target.Capability.Target, true);
}
/**
* @override
* @return {!Promise}
*/
suspendModel() {
return this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false});
}
/**
* @override
* @return {!Promise}
*/
resumeModel() {
return this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true});
}
/**
* @override
*/
dispose() {
for (const sessionId of this._childConnections.keys())
this.detachedFromTarget(sessionId, undefined);
}
/**
* @param {string} type
* @return {number}
*/
_capabilitiesForType(type) {
if (type === 'worker') {
return SDK.Target.Capability.JS | SDK.Target.Capability.Log | SDK.Target.Capability.Network |
SDK.Target.Capability.Target;
}
if (type === 'service_worker')
return SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target;
if (type === 'iframe') {
return SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.JS |
SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target |
SDK.Target.Capability.Tracing | SDK.Target.Capability.Emulation | SDK.Target.Capability.Input;
}
return 0;
}
/**
* @override
* @param {!Protocol.Target.TargetInfo} targetInfo
*/
targetCreated(targetInfo) {
this._targetInfos.set(targetInfo.targetId, targetInfo);
this._fireAvailableTargetsChanged();
}
/**
* @override
* @param {!Protocol.Target.TargetInfo} targetInfo
*/
targetInfoChanged(targetInfo) {
this._targetInfos.set(targetInfo.targetId, targetInfo);
this._fireAvailableTargetsChanged();
}
/**
* @override
* @param {string} targetId
*/
targetDestroyed(targetId) {
this._targetInfos.delete(targetId);
this._fireAvailableTargetsChanged();
}
_fireAvailableTargetsChanged() {
SDK.targetManager.dispatchEventToListeners(
SDK.TargetManager.Events.AvailableTargetsChanged, this._targetInfos.valuesArray());
}
/**
* @override
* @param {string} sessionId
* @param {!Protocol.Target.TargetInfo} targetInfo
* @param {boolean} waitingForDebugger
*/
attachedToTarget(sessionId, targetInfo, waitingForDebugger) {
let targetName = '';
if (targetInfo.type !== 'iframe') {
const parsedURL = targetInfo.url.asParsedURL();
targetName = parsedURL ? parsedURL.lastPathComponentWithFragment() :
'#' + (++SDK.ChildTargetManager._lastAnonymousTargetId);
}
const target = this._targetManager.createTarget(
targetInfo.targetId, targetName, this._capabilitiesForType(targetInfo.type),
this._createChildConnection.bind(this, this._targetAgent, sessionId), this._parentTarget);
if (SDK.ChildTargetManager._attachCallback)
SDK.ChildTargetManager._attachCallback({target, waitingForDebugger});
target.runtimeAgent().runIfWaitingForDebugger();
}
/**
* @override
* @param {string} sessionId
* @param {string=} childTargetId
*/
detachedFromTarget(sessionId, childTargetId) {
this._childConnections.get(sessionId).onDisconnect.call(null, 'target terminated');
this._childConnections.delete(sessionId);
}
/**
* @override
* @param {string} sessionId
* @param {string} message
* @param {string=} childTargetId
*/
receivedMessageFromTarget(sessionId, message, childTargetId) {
const connection = this._childConnections.get(sessionId);
if (connection)
connection.onMessage.call(null, message);
}
/**
* @param {!Protocol.TargetAgent} agent
* @param {string} sessionId
* @param {!Protocol.InspectorBackend.Connection.Params} params
* @return {!Protocol.InspectorBackend.Connection}
*/
_createChildConnection(agent, sessionId, params) {
const connection = new SDK.ChildConnection(agent, sessionId, params);
this._childConnections.set(sessionId, connection);
return connection;
}
};
SDK.ChildTargetManager._lastAnonymousTargetId = 0;
/** @type {function({target: !SDK.Target, waitingForDebugger: boolean})|undefined} */
SDK.ChildTargetManager._attachCallback;