Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: content/browser/devtools/protocol/target_handler.cc

Issue 2354973003: [DevTools] Move subtargets functionality from ServiceWorker to Target domain. (Closed)
Patch Set: review comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
new file mode 100644
index 0000000000000000000000000000000000000000..ffd83ae259e574e3336dd500d12faa608a4bf1d3
--- /dev/null
+++ b/content/browser/devtools/protocol/target_handler.cc
@@ -0,0 +1,291 @@
+// Copyright 2016 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.
+
+#include "content/browser/devtools/protocol/target_handler.h"
+
+#include "content/browser/devtools/service_worker_devtools_agent_host.h"
+#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"
+
+namespace content {
+namespace devtools {
+namespace target {
+
+using Response = DevToolsProtocolClient::Response;
+
+namespace {
+
+using ScopeAgentsMap =
+ std::map<GURL, std::unique_ptr<ServiceWorkerDevToolsAgentHost::List>>;
+
+void GetMatchingHostsByScopeMap(
+ const ServiceWorkerDevToolsAgentHost::List& agent_hosts,
+ const std::set<GURL>& urls,
+ ScopeAgentsMap* scope_agents_map) {
+ std::set<base::StringPiece> host_name_set;
+ for (const GURL& url : urls)
+ host_name_set.insert(url.host_piece());
+ for (const auto& host : agent_hosts) {
+ if (host_name_set.find(host->scope().host_piece()) == host_name_set.end())
+ continue;
+ const auto& it = scope_agents_map->find(host->scope());
+ if (it == scope_agents_map->end()) {
+ std::unique_ptr<ServiceWorkerDevToolsAgentHost::List> new_list(
+ new ServiceWorkerDevToolsAgentHost::List());
+ new_list->push_back(host);
+ (*scope_agents_map)[host->scope()] = std::move(new_list);
+ } else {
+ it->second->push_back(host);
+ }
+ }
+}
+
+void AddEligibleHosts(const ServiceWorkerDevToolsAgentHost::List& list,
+ ServiceWorkerDevToolsAgentHost::Map* result) {
+ base::Time last_installed_time;
+ base::Time last_doomed_time;
+ for (const auto& host : list) {
+ if (host->version_installed_time() > last_installed_time)
+ last_installed_time = host->version_installed_time();
+ if (host->version_doomed_time() > last_doomed_time)
+ last_doomed_time = host->version_doomed_time();
+ }
+ for (const auto& host : list) {
+ // We don't attech old redundant Service Workers when there is newer
+ // installed Service Worker.
+ if (host->version_doomed_time().is_null() ||
+ (last_installed_time < last_doomed_time &&
+ last_doomed_time == host->version_doomed_time())) {
+ (*result)[host->GetId()] = host;
+ }
+ }
+}
+
+ServiceWorkerDevToolsAgentHost::Map GetMatchingServiceWorkers(
+ BrowserContext* browser_context,
+ const std::set<GURL>& urls) {
+ ServiceWorkerDevToolsAgentHost::Map result;
+ if (!browser_context)
+ return result;
+
+ ServiceWorkerDevToolsAgentHost::List agent_hosts;
+ ServiceWorkerDevToolsManager::GetInstance()
+ ->AddAllAgentHostsForBrowserContext(browser_context, &agent_hosts);
+
+ ScopeAgentsMap scope_agents_map;
+ GetMatchingHostsByScopeMap(agent_hosts, urls, &scope_agents_map);
+
+ for (const auto& it : scope_agents_map)
+ AddEligibleHosts(*it.second.get(), &result);
+
+ return result;
+}
+
+} // namespace
+
+TargetHandler::TargetHandler()
+ : enabled_(false),
+ render_frame_host_(nullptr) {
+}
+
+TargetHandler::~TargetHandler() {
+ Disable();
+}
+
+void TargetHandler::SetRenderFrameHost(RenderFrameHostImpl* render_frame_host) {
+ render_frame_host_ = render_frame_host;
+}
+
+void TargetHandler::SetClient(std::unique_ptr<Client> client) {
+ client_.swap(client);
+}
+
+void TargetHandler::Detached() {
+ Disable();
+}
+
+void TargetHandler::UpdateServiceWorkers() {
+ if (!enabled_)
+ return;
+
+ frame_urls_.clear();
+ BrowserContext* browser_context = nullptr;
+ if (render_frame_host_) {
+ // TODO(dgozman): do not traverse inside cross-process subframes.
+ for (FrameTreeNode* node :
+ render_frame_host_->frame_tree_node()->frame_tree()->Nodes()) {
+ frame_urls_.insert(node->current_url());
+ }
+ browser_context = render_frame_host_->GetProcess()->GetBrowserContext();
+ }
+
+ std::map<std::string, scoped_refptr<DevToolsAgentHost>> old_hosts =
+ attached_hosts_;
+ ServiceWorkerDevToolsAgentHost::Map new_hosts =
+ GetMatchingServiceWorkers(browser_context, frame_urls_);
+
+ for (const auto& pair : old_hosts) {
+ if (pair.second->GetType() == DevToolsAgentHost::kTypeServiceWorker &&
+ new_hosts.find(pair.first) == new_hosts.end()) {
+ DetachFromTargetInternal(pair.second.get());
+ }
+ }
+
+ for (const auto& pair : new_hosts) {
+ if (old_hosts.find(pair.first) == old_hosts.end())
+ AttachToTargetInternal(pair.second.get(), true);
+ }
+}
+
+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()
+ ->set_target_id(host->GetId())
+ ->set_url(host->GetURL().spec())
+ ->set_type(host->GetType())
+ ->set_waiting_for_debugger(waiting_for_debugger));
+}
+
+void TargetHandler::DetachFromTargetInternal(DevToolsAgentHost* host) {
+ auto it = attached_hosts_.find(host->GetId());
+ if (it == attached_hosts_.end())
+ return;
+ host->DetachClient(this);
+ client_->TargetRemoved(TargetRemovedParams::Create()->
+ set_target_id(host->GetId()));
+ attached_hosts_.erase(it);
+}
+
+// ----------------- Protocol ----------------------
+
+Response TargetHandler::Enable() {
+ if (enabled_)
+ return Response::OK();
+ enabled_ = true;
+ ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this);
+ UpdateServiceWorkers();
+ return Response::OK();
+}
+
+Response TargetHandler::Disable() {
+ if (!enabled_)
+ return Response::OK();
+ enabled_ = false;
+ ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this);
+ for (const auto& pair : attached_hosts_)
+ pair.second->DetachClient(this);
+ attached_hosts_.clear();
+ return Response::OK();
+}
+
+Response TargetHandler::SetWaitForDebuggerOnStart(bool value) {
+ // TODO(dgozman): implement this.
+ 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())
+ return Response::InternalError("Not attached to the target");
+ it->second->DispatchProtocolMessage(this, message);
+ return Response::OK();
+}
+
+Response TargetHandler::GetTargetInfo(
+ const std::string& target_id,
+ scoped_refptr<TargetInfo>* target_info) {
+ scoped_refptr<DevToolsAgentHost> agent_host(
+ DevToolsAgentHost::GetForId(target_id));
+ if (!agent_host)
+ return Response::InvalidParams("No target with such id");
+ *target_info =TargetInfo::Create()
+ ->set_target_id(agent_host->GetId())
+ ->set_type(agent_host->GetType())
+ ->set_title(agent_host->GetTitle())
+ ->set_url(agent_host->GetURL().spec());
+ return Response::OK();
+}
+
+Response TargetHandler::ActivateTarget(const std::string& target_id) {
+ scoped_refptr<DevToolsAgentHost> agent_host(
+ DevToolsAgentHost::GetForId(target_id));
+ if (!agent_host)
+ return Response::InvalidParams("No target with such id");
+ agent_host->Activate();
+ 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.
+
+ client_->ReceivedMessageFromTarget(
+ ReceivedMessageFromTargetParams::Create()->
+ set_target_id(host->GetId())->
+ set_message(message));
+}
+
+void TargetHandler::AgentHostClosed(
+ DevToolsAgentHost* host,
+ bool replaced_with_another_client) {
+ client_->TargetRemoved(TargetRemovedParams::Create()->
+ set_target_id(host->GetId()));
+ attached_hosts_.erase(host->GetId());
+}
+
+// -------- ServiceWorkerDevToolsManager::Observer ----------
+
+void TargetHandler::WorkerCreated(
+ ServiceWorkerDevToolsAgentHost* host) {
+ BrowserContext* browser_context = nullptr;
+ if (render_frame_host_)
+ browser_context = render_frame_host_->GetProcess()->GetBrowserContext();
+ auto hosts = GetMatchingServiceWorkers(browser_context, frame_urls_);
+ if (hosts.find(host->GetId()) != hosts.end() && !host->IsAttached() &&
+ !host->IsPausedForDebugOnStart()) {
+ host->PauseForDebugOnStart();
+ }
+}
+
+void TargetHandler::WorkerReadyForInspection(
+ ServiceWorkerDevToolsAgentHost* host) {
+ if (ServiceWorkerDevToolsManager::GetInstance()
+ ->debug_service_worker_on_start()) {
+ // When debug_service_worker_on_start is true, a new DevTools window will
+ // be opened in ServiceWorkerDevToolsManager::WorkerReadyForInspection.
+ return;
+ }
+ UpdateServiceWorkers();
+}
+
+void TargetHandler::WorkerVersionInstalled(
+ ServiceWorkerDevToolsAgentHost* host) {
+ UpdateServiceWorkers();
+}
+
+void TargetHandler::WorkerVersionDoomed(
+ ServiceWorkerDevToolsAgentHost* host) {
+ UpdateServiceWorkers();
+}
+
+void TargetHandler::WorkerDestroyed(
+ ServiceWorkerDevToolsAgentHost* host) {
+ UpdateServiceWorkers();
+}
+
+} // namespace target
+} // namespace devtools
+} // namespace content
« no previous file with comments | « content/browser/devtools/protocol/target_handler.h ('k') | content/browser/devtools/render_frame_devtools_agent_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698