Chromium Code Reviews| Index: content/browser/devtools/protocol/target_handler.cc |
| diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc |
| index dd1b8b8b67493134a9e17ee0a817c202e9bfc311..fe9b7d56205bbb64412ebf465a401658e3ec44a3 100644 |
| --- a/content/browser/devtools/protocol/target_handler.cc |
| +++ b/content/browser/devtools/protocol/target_handler.cc |
| @@ -4,6 +4,7 @@ |
| #include "content/browser/devtools/protocol/target_handler.h" |
| +#include "base/strings/stringprintf.h" |
| #include "content/browser/devtools/devtools_manager.h" |
| #include "content/browser/devtools/devtools_session.h" |
| #include "content/browser/devtools/render_frame_devtools_agent_host.h" |
| @@ -11,6 +12,7 @@ |
| #include "content/browser/frame_host/frame_tree.h" |
| #include "content/browser/frame_host/frame_tree_node.h" |
| #include "content/browser/frame_host/render_frame_host_impl.h" |
| +#include "content/public/browser/devtools_agent_host_client.h" |
| namespace content { |
| namespace protocol { |
| @@ -94,6 +96,54 @@ std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) { |
| } // namespace |
| +class TargetHandler::Session : public DevToolsAgentHostClient { |
| + public: |
| + Session(TargetHandler* handler, |
| + DevToolsAgentHost* agent_host, |
|
caseq
2017/06/27 18:29:29
pass as scoped_refptr<> to indicate we keep it.
|
| + const std::string& id, |
| + bool is_auto_attach) |
| + : handler_(handler), |
| + agent_host_(agent_host), |
| + id_(id), |
| + is_auto_attach_(is_auto_attach) {} |
| + |
| + ~Session() override { |
| + if (agent_host_) |
| + agent_host_->DetachClient(this); |
| + } |
| + |
| + bool is_auto_attach() const { return is_auto_attach_; } |
| + DevToolsAgentHost* agent_host() const { return agent_host_.get(); } |
| + |
| + void Attach() { |
| + static_cast<DevToolsAgentHostImpl*>(agent_host_.get()) |
| + ->AttachMultiClient(this); |
| + } |
| + |
| + // DevToolsAgentHostClient implementation. |
| + void DispatchProtocolMessage(DevToolsAgentHost* agent_host, |
| + const std::string& message) override { |
| + handler_->frontend_->ReceivedMessageFromTarget(id_, message); |
| + } |
| + |
| + void AgentHostClosed(DevToolsAgentHost* agent_host, |
| + bool replaced_with_another_client) override { |
| + handler_->frontend_->DetachedFromTarget(id_); |
|
caseq
2017/06/27 18:29:29
Most of the logic in this methods looks like it co
|
| + if (is_auto_attach_) |
| + handler_->auto_attached_hosts_.erase(agent_host->GetId()); |
| + agent_host_ = nullptr; |
| + handler_->attached_sessions_.erase(id_); // |this| is deleted here. |
| + } |
| + |
| + private: |
| + TargetHandler* handler_; |
| + scoped_refptr<DevToolsAgentHost> agent_host_; |
| + std::string id_; |
| + bool is_auto_attach_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(Session); |
| +}; |
| + |
| TargetHandler::TargetHandler() |
| : DevToolsDomainHandler(Target::Metainfo::domainName), |
| discover_(false), |
| @@ -126,9 +176,7 @@ void TargetHandler::SetRenderFrameHost(RenderFrameHostImpl* render_frame_host) { |
| Response TargetHandler::Disable() { |
| SetAutoAttach(false, false); |
| SetDiscoverTargets(false); |
| - for (const auto& id_host : attached_hosts_) |
| - id_host.second->DetachClient(this); |
| - attached_hosts_.clear(); |
| + attached_sessions_.clear(); |
| return Response::OK(); |
| } |
| @@ -189,20 +237,26 @@ void TargetHandler::UpdateServiceWorkers(bool waiting_for_debugger) { |
| new_hosts, DevToolsAgentHost::kTypeServiceWorker, waiting_for_debugger); |
| } |
| -void TargetHandler::ReattachTargetsOfType( |
| - const HostsMap& new_hosts, |
| - const std::string& type, |
| - bool waiting_for_debugger) { |
| - HostsMap old_hosts = attached_hosts_; |
| - for (const auto& pair : old_hosts) { |
| - if (pair.second->GetType() == type && |
| - new_hosts.find(pair.first) == new_hosts.end()) { |
| - DetachFromTargetInternal(pair.second.get()); |
| +void TargetHandler::ReattachTargetsOfType(const HostsMap& new_hosts, |
| + const std::string& type, |
| + bool waiting_for_debugger) { |
| + std::vector<std::string> ids_to_detach; |
| + for (const auto& pair : attached_sessions_) { |
| + Session* session = pair.second.get(); |
| + if (session->is_auto_attach() && session->agent_host()->GetType() == type && |
| + new_hosts.find(session->agent_host()->GetId()) == new_hosts.end()) { |
| + ids_to_detach.push_back(pair.first); |
| + auto_attached_hosts_.erase(session->agent_host()->GetId()); |
| } |
| } |
| + for (const std::string& session_id : ids_to_detach) |
| + DetachFromSessionInternal(session_id); |
| for (const auto& pair : new_hosts) { |
| - if (old_hosts.find(pair.first) == old_hosts.end()) |
| - AttachToTargetInternal(pair.second.get(), waiting_for_debugger); |
| + if (auto_attached_hosts_.find(pair.first) == auto_attached_hosts_.end()) { |
| + DevToolsAgentHost* host = pair.second.get(); |
| + AttachToTargetInternal(host, waiting_for_debugger, true); |
| + auto_attached_hosts_[host->GetId()] = host; |
| + } |
| } |
| } |
| @@ -223,24 +277,34 @@ void TargetHandler::TargetDestroyedInternal( |
| reported_hosts_.erase(it); |
| } |
| -bool TargetHandler::AttachToTargetInternal( |
| - DevToolsAgentHost* host, bool waiting_for_debugger) { |
| - attached_hosts_[host->GetId()] = host; |
| - if (!host->AttachClient(this)) { |
| - attached_hosts_.erase(host->GetId()); |
| +std::string TargetHandler::AttachToTargetInternal(DevToolsAgentHost* host, |
| + bool waiting_for_debugger, |
| + bool is_auto_attach) { |
| + std::string session_id = |
| + base::StringPrintf("%s:%d", host->GetId().c_str(), ++last_session_id_); |
| + Session* session = new Session(this, host, session_id, is_auto_attach); |
| + attached_sessions_[session_id].reset(session); |
| + session->Attach(); |
| + frontend_->AttachedToTarget(session_id, CreateInfo(host), |
| + waiting_for_debugger); |
| + return session_id; |
| +} |
| + |
| +bool TargetHandler::DetachFromSessionInternal(const std::string& session_id) { |
| + auto it = attached_sessions_.find(session_id); |
| + if (it == attached_sessions_.end()) |
| return false; |
| - } |
| - frontend_->AttachedToTarget(CreateInfo(host), waiting_for_debugger); |
| + frontend_->DetachedFromTarget(session_id); |
| + attached_sessions_.erase(it); |
| return true; |
| } |
| -void TargetHandler::DetachFromTargetInternal(DevToolsAgentHost* host) { |
| - auto it = attached_hosts_.find(host->GetId()); |
| - if (it == attached_hosts_.end()) |
| - return; |
| - host->DetachClient(this); |
| - frontend_->DetachedFromTarget(host->GetId()); |
| - attached_hosts_.erase(it); |
| +bool TargetHandler::IsAttachedToAgentHost(DevToolsAgentHost* agent_host) { |
| + for (auto& it : attached_sessions_) { |
| + if (it.second->agent_host() == agent_host) |
| + return true; |
| + } |
| + return false; |
| } |
| // ----------------- Protocol ---------------------- |
| @@ -298,32 +362,28 @@ Response TargetHandler::SetRemoteLocations( |
| } |
| Response TargetHandler::AttachToTarget(const std::string& target_id, |
| - bool* out_success) { |
| + Maybe<std::string>* out_session_id) { |
| // TODO(dgozman): only allow reported hosts. |
| scoped_refptr<DevToolsAgentHost> agent_host = |
| DevToolsAgentHost::GetForId(target_id); |
| if (!agent_host) |
| return Response::InvalidParams("No target with given id found"); |
| - *out_success = AttachToTargetInternal(agent_host.get(), false); |
| + *out_session_id = AttachToTargetInternal(agent_host.get(), false, false); |
| return Response::OK(); |
| } |
| -Response TargetHandler::DetachFromTarget(const std::string& target_id) { |
| - auto it = attached_hosts_.find(target_id); |
| - if (it == attached_hosts_.end()) |
| - return Response::Error("Not attached to the target"); |
| - DevToolsAgentHost* agent_host = it->second.get(); |
| - DetachFromTargetInternal(agent_host); |
| +Response TargetHandler::DetachFromTarget(const std::string& session_id) { |
| + if (!DetachFromSessionInternal(session_id)) |
| + return Response::Error("No session with given id"); |
| return Response::OK(); |
| } |
| -Response TargetHandler::SendMessageToTarget( |
| - const std::string& target_id, |
| - const std::string& message) { |
| - auto it = attached_hosts_.find(target_id); |
| - if (it == attached_hosts_.end()) |
| +Response TargetHandler::SendMessageToTarget(const std::string& session_id, |
| + const std::string& message) { |
| + auto it = attached_sessions_.find(session_id); |
| + if (it == attached_sessions_.end()) |
| return Response::FallThrough(); |
| - it->second->DispatchProtocolMessage(this, message); |
| + it->second->agent_host()->DispatchProtocolMessage(it->second.get(), message); |
| return Response::OK(); |
| } |
| @@ -393,25 +453,6 @@ Response TargetHandler::GetTargets( |
| return Response::OK(); |
| } |
| -// ---------------- DevToolsAgentHostClient ---------------- |
| - |
| -void TargetHandler::DispatchProtocolMessage( |
| - DevToolsAgentHost* host, |
| - const std::string& message) { |
| - auto it = attached_hosts_.find(host->GetId()); |
| - if (it == attached_hosts_.end()) |
| - return; // Already disconnected. |
| - |
| - frontend_->ReceivedMessageFromTarget(host->GetId(), message); |
| -} |
| - |
| -void TargetHandler::AgentHostClosed( |
| - DevToolsAgentHost* host, |
| - bool replaced_with_another_client) { |
| - frontend_->DetachedFromTarget(host->GetId()); |
| - attached_hosts_.erase(host->GetId()); |
| -} |
| - |
| // -------------- DevToolsAgentHostObserver ----------------- |
| bool TargetHandler::ShouldForceDevToolsAgentHostCreation() { |
| @@ -427,14 +468,15 @@ void TargetHandler::DevToolsAgentHostCreated(DevToolsAgentHost* agent_host) { |
| } |
| void TargetHandler::DevToolsAgentHostDestroyed(DevToolsAgentHost* agent_host) { |
| - DCHECK(attached_hosts_.find(agent_host->GetId()) == attached_hosts_.end()); |
| + DCHECK(auto_attached_hosts_.find(agent_host->GetId()) == |
| + auto_attached_hosts_.end()); |
| TargetDestroyedInternal(agent_host); |
| } |
| void TargetHandler::DevToolsAgentHostAttached(DevToolsAgentHost* host) { |
| if (host->GetType() == "node" && |
| reported_hosts_.find(host->GetId()) != reported_hosts_.end() && |
| - attached_hosts_.find(host->GetId()) == attached_hosts_.end()) { |
| + !IsAttachedToAgentHost(host)) { |
| TargetDestroyedInternal(host); |
| } |
| } |
| @@ -442,7 +484,7 @@ void TargetHandler::DevToolsAgentHostAttached(DevToolsAgentHost* host) { |
| void TargetHandler::DevToolsAgentHostDetached(DevToolsAgentHost* host) { |
| if (host->GetType() == "node" && |
| reported_hosts_.find(host->GetId()) == reported_hosts_.end() && |
| - attached_hosts_.find(host->GetId()) == attached_hosts_.end()) { |
| + !IsAttachedToAgentHost(host)) { |
| TargetCreatedInternal(host); |
| } |
| } |