Commit bf5f2536 authored by dgozman's avatar dgozman Committed by Commit bot

[DevTools] Introduce Target.setAutoAttach.

This separates passive "listen to all targets" behavior from
"auto-attach to related targets" required by DevTools frontend.

BUG=648775

Review-Url: https://codereview.chromium.org/2391823002
Cr-Commit-Position: refs/heads/master@{#422674}
parent 3752d135
......@@ -87,6 +87,7 @@ ServiceWorkerDevToolsAgentHost::Map GetMatchingServiceWorkers(
TargetHandler::TargetHandler()
: enabled_(false),
auto_attach_(false),
wait_for_debugger_on_start_(false),
attach_to_frames_(false),
render_frame_host_(nullptr) {
......@@ -114,7 +115,7 @@ void TargetHandler::UpdateServiceWorkers() {
}
void TargetHandler::UpdateFrames() {
if (!enabled_ || !attach_to_frames_)
if (!enabled_ || !auto_attach_ || !attach_to_frames_)
return;
HostsMap new_hosts;
......@@ -142,7 +143,7 @@ void TargetHandler::UpdateFrames() {
}
void TargetHandler::UpdateServiceWorkers(bool waiting_for_debugger) {
if (!enabled_)
if (!enabled_ || !auto_attach_)
return;
frame_urls_.clear();
......@@ -173,24 +174,39 @@ void TargetHandler::ReattachTargetsOfType(
if (pair.second->GetType() == type &&
new_hosts.find(pair.first) == new_hosts.end()) {
DetachFromTargetInternal(pair.second.get());
TargetRemovedInternal(pair.second.get());
}
}
for (const auto& pair : new_hosts) {
if (old_hosts.find(pair.first) == old_hosts.end())
if (old_hosts.find(pair.first) == old_hosts.end()) {
TargetCreatedInternal(pair.second.get());
AttachToTargetInternal(pair.second.get(), waiting_for_debugger);
}
}
}
void TargetHandler::TargetCreatedInternal(DevToolsAgentHost* host) {
client_->TargetCreated(
TargetCreatedParams::Create()->set_target_info(
TargetInfo::Create()->set_target_id(host->GetId())
->set_title(host->GetTitle())
->set_url(host->GetURL().spec())
->set_type(host->GetType())));
}
void TargetHandler::TargetRemovedInternal(DevToolsAgentHost* host) {
client_->TargetRemoved(TargetRemovedParams::Create()
->set_target_id(host->GetId()));
}
void TargetHandler::AttachToTargetInternal(
DevToolsAgentHost* host, bool waiting_for_debugger) {
if (host->IsAttached())
return;
attached_hosts_[host->GetId()] = host;
host->AttachClient(this);
client_->TargetCreated(TargetCreatedParams::Create()
client_->AttachedToTarget(AttachedToTargetParams::Create()
->set_target_id(host->GetId())
->set_url(host->GetURL().spec())
->set_type(host->GetType())
->set_waiting_for_debugger(waiting_for_debugger));
}
......@@ -199,7 +215,7 @@ void TargetHandler::DetachFromTargetInternal(DevToolsAgentHost* host) {
if (it == attached_hosts_.end())
return;
host->DetachClient(this);
client_->TargetRemoved(TargetRemovedParams::Create()->
client_->DetachedFromTarget(DetachedFromTargetParams::Create()->
set_target_id(host->GetId()));
attached_hosts_.erase(it);
}
......@@ -220,6 +236,7 @@ Response TargetHandler::Disable() {
if (!enabled_)
return Response::OK();
enabled_ = false;
auto_attach_ = false;
wait_for_debugger_on_start_ = false;
ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this);
for (const auto& pair : attached_hosts_)
......@@ -228,8 +245,16 @@ Response TargetHandler::Disable() {
return Response::OK();
}
Response TargetHandler::SetWaitForDebuggerOnStart(bool value) {
wait_for_debugger_on_start_ = value;
Response TargetHandler::SetAutoAttach(
bool auto_attach, bool wait_for_debugger_on_start) {
wait_for_debugger_on_start_ = wait_for_debugger_on_start;
if (auto_attach_ == auto_attach)
return Response::OK();
auto_attach_ = auto_attach;
if (auto_attach_) {
UpdateServiceWorkers();
UpdateFrames();
}
return Response::OK();
}
......@@ -263,7 +288,7 @@ Response TargetHandler::GetTargetInfo(
DevToolsAgentHost::GetForId(target_id));
if (!agent_host)
return Response::InvalidParams("No target with such id");
*target_info =TargetInfo::Create()
*target_info = TargetInfo::Create()
->set_target_id(agent_host->GetId())
->set_type(agent_host->GetType())
->set_title(agent_host->GetTitle())
......
......@@ -37,7 +37,7 @@ class TargetHandler : public DevToolsAgentHostClient,
// Domain implementation.
Response Enable();
Response Disable();
Response SetWaitForDebuggerOnStart(bool value);
Response SetAutoAttach(bool auto_attach, bool wait_for_debugger_on_start);
Response SetAttachToFrames(bool value);
Response SendMessageToTarget(const std::string& target_id,
const std::string& message);
......@@ -52,6 +52,8 @@ class TargetHandler : public DevToolsAgentHostClient,
void ReattachTargetsOfType(const HostsMap& new_hosts,
const std::string& type,
bool waiting_for_debugger);
void TargetCreatedInternal(DevToolsAgentHost* host);
void TargetRemovedInternal(DevToolsAgentHost* host);
void AttachToTargetInternal(DevToolsAgentHost* host,
bool waiting_for_debugger);
void DetachFromTargetInternal(DevToolsAgentHost* host);
......@@ -71,6 +73,7 @@ class TargetHandler : public DevToolsAgentHostClient,
std::unique_ptr<Client> client_;
bool enabled_;
bool auto_attach_;
bool wait_for_debugger_on_start_;
bool attach_to_frames_;
RenderFrameHostImpl* render_frame_host_;
......
......@@ -8,7 +8,7 @@ frontend: {"id":<number>,"method":"Debugger.setAsyncCallStackDepth","params":{"m
frontend: {"id":<number>,"method":"Page.configureOverlay","params":{"suspended":true}}
frontend: {"id":<number>,"method":"DOM.disable"}
frontend: {"id":<number>,"method":"CSS.disable"}
frontend: {"id":<number>,"method":"Target.setWaitForDebuggerOnStart","params":{"value":false}}
frontend: {"id":<number>,"method":"Target.setAutoAttach","params":{"autoAttach":true,"waitForDebuggerOnStart":false}}
--> WebInspector.targetManager.resumeAllTargets();
frontend: {"id":<number>,"method":"Page.configureOverlay","params":{"suspended":false}}
......@@ -18,7 +18,7 @@ frontend: {"id":<number>,"method":"Debugger.setPauseOnExceptions","params":{"sta
frontend: {"id":<number>,"method":"Debugger.setAsyncCallStackDepth","params":{"maxDepth":4}}
frontend: {"id":<number>,"method":"DOM.enable"}
frontend: {"id":<number>,"method":"CSS.enable"}
frontend: {"id":<number>,"method":"Target.setWaitForDebuggerOnStart","params":{"value":true}}
frontend: {"id":<number>,"method":"Target.setAutoAttach","params":{"autoAttach":true,"waitForDebuggerOnStart":true}}
--> done
......@@ -3264,7 +3264,7 @@
},
{
"domain": "Target",
"description": "Supports discovery and auto-attach to related targets.",
"description": "Supports additional targets discovery and allows to attach to them.",
"experimental": true,
"types": [
{
......@@ -3290,7 +3290,7 @@
"commands": [
{
"name": "enable",
"description": "Start discovering targets and attach to all related targets from now on.",
"description": "Start discovering targets.",
"handlers": ["browser"]
},
{
......@@ -3299,9 +3299,11 @@
"handlers": ["browser"]
},
{
"name": "setWaitForDebuggerOnStart",
"name": "setAutoAttach",
"description": "Controls whether to automatically attach to new targets which are considered to be related to this one. When turned on, attaches to all existing related targets as well. When turned off, does not automatically detach.",
"parameters": [
{ "name": "value", "type": "boolean", "description": "Whether to pause new targets when attaching to them. Use <code>Runtime.runIfWaitingForDebugger</code> to run puased targets." }
{ "name": "autoAttach", "type": "boolean", "description": "Whether to auto-attach to related targets." },
{ "name": "waitForDebuggerOnStart", "type": "boolean", "description": "Whether to pause new targets when attaching to them. Use <code>Runtime.runIfWaitingForDebugger</code> to run paused targets." }
],
"handlers": ["browser"]
},
......@@ -3341,16 +3343,28 @@
"events": [
{
"name": "targetCreated",
"parameters": [
{ "name": "targetInfo", "$ref": "TargetInfo" }
],
"handlers": ["browser"]
},
{
"name": "targetRemoved",
"parameters": [
{ "name": "targetId", "$ref": "TargetID" }
],
"handlers": ["browser"]
},
{
"name": "attachedToTarget",
"parameters": [
{ "name": "targetId", "$ref": "TargetID" },
{ "name": "type", "$ref": "TargetType" },
{ "name": "url", "type": "string" },
{ "name": "waitingForDebugger", "type": "boolean" }
],
"handlers": ["browser"]
},
{
"name": "targetRemoved",
"name": "detachedFromTarget",
"parameters": [
{ "name": "targetId", "$ref": "TargetID" }
],
......
......@@ -611,9 +611,10 @@ WebInspector.ServiceWorkerContextNamer.prototype = {
var parent = target.parentTarget();
if (!parent || parent.parentTarget() !== this._target)
return null;
if (this._subTargetsManager.targetType(parent) !== "service_worker")
var targetInfo = this._subTargetsManager.targetInfo(parent);
if (!targetInfo || targetInfo.type !== "service_worker")
return null;
return this._subTargetsManager.targetId(parent);
return targetInfo.id;
},
_updateAllContextLabels: function()
......
......@@ -14,12 +14,15 @@ WebInspector.SubTargetsManager = function(target)
this._lastAnonymousTargetId = 0;
this._agent = target.targetAgent();
/** @type {!Map<string, !WebInspector.TargetInfo>} */
this._allTargets = new Map();
/** @type {!Map<string, !WebInspector.Target>} */
this._targets = new Map();
this._attachedTargets = new Map();
/** @type {!Map<string, !WebInspector.SubTargetConnection>} */
this._connections = new Map();
this._agent.setWaitForDebuggerOnStart(true);
this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnStart */);
this._agent.setAttachToFrames(Runtime.experiments.isEnabled("autoAttachToCrossProcessSubframes"));
this._agent.enable();
}
......@@ -30,8 +33,7 @@ WebInspector.SubTargetsManager.Events = {
SubTargetRemoved: Symbol("SubTargetRemoved"),
}
WebInspector.SubTargetsManager._TypeSymbol = Symbol("SubTargetType");
WebInspector.SubTargetsManager._IdSymbol = Symbol("SubTargetId");
WebInspector.SubTargetsManager._InfoSymbol = Symbol("SubTargetInfo");
WebInspector.SubTargetsManager.prototype = {
/**
......@@ -42,7 +44,7 @@ WebInspector.SubTargetsManager.prototype = {
{
var fulfill;
var promise = new Promise(f => fulfill = f);
this._agent.setWaitForDebuggerOnStart(false, fulfill);
this._agent.setAutoAttach(true /* autoAttach */, false /* waitForDebuggerOnStart */, fulfill);
return promise;
},
......@@ -54,7 +56,7 @@ WebInspector.SubTargetsManager.prototype = {
{
var fulfill;
var promise = new Promise(f => fulfill = f);
this._agent.setWaitForDebuggerOnStart(true, fulfill);
this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnStart */, fulfill);
return promise;
},
......@@ -66,7 +68,7 @@ WebInspector.SubTargetsManager.prototype = {
for (var connection of this._connections.values())
connection._close();
this._connections.clear();
this._targets.clear();
this._attachedTargets.clear();
},
/**
......@@ -108,25 +110,16 @@ WebInspector.SubTargetsManager.prototype = {
*/
targetForId: function(targetId)
{
return this._targets.get(targetId) || null;
},
/**
* @param {!WebInspector.Target} target
* @return {?string}
*/
targetId: function(target)
{
return target[WebInspector.SubTargetsManager._IdSymbol] || null;
return this._attachedTargets.get(targetId) || null;
},
/**
* @param {!WebInspector.Target} target
* @return {?string}
* @return {?WebInspector.TargetInfo}
*/
targetType: function(target)
targetInfo: function(target)
{
return target[WebInspector.SubTargetsManager._TypeSymbol] || null;
return target[WebInspector.SubTargetsManager._InfoSymbol] || null;
},
/**
......@@ -146,26 +139,45 @@ WebInspector.SubTargetsManager.prototype = {
return 0;
},
/**
* @param {!WebInspector.TargetInfo} targetInfo
*/
_targetCreated: function(targetInfo)
{
console.assert(!this._allTargets.has(targetInfo.id));
console.assert(!this._attachedTargets.has(targetInfo.id));
this._allTargets.set(targetInfo.id, targetInfo);
},
/**
* @param {string} targetId
*/
_targetRemoved: function(targetId)
{
console.assert(this._allTargets.has(targetId));
console.assert(!this._attachedTargets.has(targetId));
this._allTargets.delete(targetId);
},
/**
* @param {string} targetId
* @param {string} type
* @param {string} url
* @param {boolean} waitingForDebugger
*/
_targetCreated: function(targetId, type, url, waitingForDebugger)
_attachedToTarget: function(targetId, waitingForDebugger)
{
var targetInfo = /** @type {!WebInspector.TargetInfo} */ (this._allTargets.get(targetId));
var connection = new WebInspector.SubTargetConnection(this._agent, targetId);
this._connections.set(targetId, connection);
var targetName = "";
if (type !== "iframe") {
var parsedURL = url.asParsedURL();
if (targetInfo.type !== "iframe") {
var parsedURL = targetInfo.url.asParsedURL();
targetName = parsedURL ? parsedURL.lastPathComponentWithFragment() : "#" + (++this._lastAnonymousTargetId);
}
var target = WebInspector.targetManager.createTarget(targetName, this._capabilitiesForType(type), connection, this.target());
target[WebInspector.SubTargetsManager._TypeSymbol] = type;
target[WebInspector.SubTargetsManager._IdSymbol] = targetId;
this._targets.set(targetId, target);
var target = WebInspector.targetManager.createTarget(targetName, this._capabilitiesForType(targetInfo.type), connection, this.target());
target[WebInspector.SubTargetsManager._InfoSymbol] = targetInfo;
this._attachedTargets.set(targetId, target);
// Only pause new worker if debugging SW - we are going through the pause on start checkbox.
var mainIsServiceWorker = !this.target().parentTarget() && this.target().hasWorkerCapability() && !this.target().hasBrowserCapability();
......@@ -179,14 +191,14 @@ WebInspector.SubTargetsManager.prototype = {
/**
* @param {string} targetId
*/
_targetRemoved: function(targetId)
_detachedFromTarget: function(targetId)
{
var connection = this._connections.get(targetId);
if (connection)
connection._close();
this._connections.delete(targetId);
var target = this._targets.get(targetId);
this._targets.delete(targetId);
var target = this._attachedTargets.get(targetId);
this._attachedTargets.delete(targetId);
this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubTargetRemoved, target);
},
......@@ -217,14 +229,11 @@ WebInspector.SubTargetsDispatcher = function(manager)
WebInspector.SubTargetsDispatcher.prototype = {
/**
* @override
* @param {string} targetId
* @param {string} type
* @param {string} url
* @param {boolean} waitingForDebugger
* @param {!TargetAgent.TargetInfo} targetInfo
*/
targetCreated: function(targetId, type, url, waitingForDebugger)
targetCreated: function(targetInfo)
{
this._manager._targetCreated(targetId, type, url, waitingForDebugger);
this._manager._targetCreated(new WebInspector.TargetInfo(targetInfo));
},
/**
......@@ -236,6 +245,25 @@ WebInspector.SubTargetsDispatcher.prototype = {
this._manager._targetRemoved(targetId);
},
/**
* @override
* @param {string} targetId
* @param {boolean} waitingForDebugger
*/
attachedToTarget: function(targetId, waitingForDebugger)
{
this._manager._attachedToTarget(targetId, waitingForDebugger);
},
/**
* @override
* @param {string} targetId
*/
detachedFromTarget: function(targetId)
{
this._manager._detachedFromTarget(targetId);
},
/**
* @override
* @param {string} targetId
......@@ -286,7 +314,8 @@ WebInspector.TargetInfo = function(payload)
{
this.id = payload.targetId;
this.url = payload.url;
if (payload.type !== "page" && payload.type !== "iframe") {
this.type = payload.type;
if (this.type !== "page" && this.type !== "iframe") {
this.title = WebInspector.UIString("Worker: %s", this.url);
this.canActivate = false;
} else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment