blob: f0cb4ee0f4c2e292fc0c484673161d730eaa0fc0 [file] [log] [blame]
Dmitry Gozmanb27efd1e2018-10-01 22:08:111// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/devtools/devtools_renderer_channel.h"
6
Sebastien Marchandf8cbfab2019-01-25 16:02:307#include "base/bind.h"
Sebastien Marchand17fa2782019-01-25 19:28:108#include "base/bind_helpers.h"
Dmitry Gozmanb27efd1e2018-10-01 22:08:119#include "content/browser/devtools/devtools_agent_host_impl.h"
10#include "content/browser/devtools/devtools_session.h"
Dmitry Gozman08a40e2f2018-10-02 21:16:4111#include "content/browser/devtools/protocol/devtools_domain_handler.h"
Dmitry Gozmanbe2073b2018-10-29 22:15:4612#include "content/browser/devtools/protocol/target_auto_attacher.h"
13#include "content/browser/devtools/worker_devtools_agent_host.h"
14#include "content/public/browser/render_process_host.h"
Dmitry Gozmanb27efd1e2018-10-01 22:08:1115#include "content/public/common/child_process_host.h"
16#include "ui/gfx/geometry/point.h"
17
18namespace content {
19
20DevToolsRendererChannel::DevToolsRendererChannel(DevToolsAgentHostImpl* owner)
Dmitry Gozman6adf95b2018-10-10 22:12:1921 : owner_(owner),
Jeremy Roman3bca4bf2019-07-11 03:41:2522 process_id_(ChildProcessHost::kInvalidUniqueID) {}
Dmitry Gozmanb27efd1e2018-10-01 22:08:1123
24DevToolsRendererChannel::~DevToolsRendererChannel() = default;
25
26void DevToolsRendererChannel::SetRenderer(
Julie Jeongeun Kime1b546e2019-08-13 09:39:3827 mojo::PendingRemote<blink::mojom::DevToolsAgent> agent_remote,
28 mojo::PendingReceiver<blink::mojom::DevToolsAgentHost> host_receiver,
Dmitry Gozmanbe2073b2018-10-29 22:15:4629 int process_id,
Julie Jeongeun Kime1b546e2019-08-13 09:39:3830 base::OnceClosure connection_error) {
Dmitry Gozmanbe2073b2018-10-29 22:15:4631 CleanupConnection();
Julie Jeongeun Kime1b546e2019-08-13 09:39:3832 blink::mojom::DevToolsAgent* agent = nullptr;
33 if (agent_remote.is_valid()) {
34 agent_remote_.Bind(std::move(agent_remote));
35 agent = agent_remote_.get();
36 }
37 if (connection_error)
38 agent_remote_.set_disconnect_handler(std::move(connection_error));
39 if (host_receiver)
40 receiver_.Bind(std::move(host_receiver));
Albert J. Wongbde14322019-08-16 00:09:0041 SetRendererInternal(agent, process_id, nullptr);
Dmitry Gozmanbe2073b2018-10-29 22:15:4642}
43
44void DevToolsRendererChannel::SetRendererAssociated(
Julie Jeongeun Kime1b546e2019-08-13 09:39:3845 mojo::PendingAssociatedRemote<blink::mojom::DevToolsAgent> agent_remote,
46 mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgentHost>
47 host_receiver,
Dmitry Gozmanb27efd1e2018-10-01 22:08:1148 int process_id,
49 RenderFrameHostImpl* frame_host) {
Dmitry Gozmanbe2073b2018-10-29 22:15:4650 CleanupConnection();
Julie Jeongeun Kime1b546e2019-08-13 09:39:3851 blink::mojom::DevToolsAgent* agent = nullptr;
52 if (agent_remote.is_valid()) {
53 associated_agent_remote_.Bind(std::move(agent_remote));
54 agent = associated_agent_remote_.get();
55 }
56 if (host_receiver)
57 associated_receiver_.Bind(std::move(host_receiver));
58 SetRendererInternal(agent, process_id, frame_host);
Dmitry Gozmanbe2073b2018-10-29 22:15:4659}
60
61void DevToolsRendererChannel::CleanupConnection() {
Julie Jeongeun Kime1b546e2019-08-13 09:39:3862 receiver_.reset();
63 associated_receiver_.reset();
64 associated_agent_remote_.reset();
65 agent_remote_.reset();
Dmitry Gozmanbe2073b2018-10-29 22:15:4666}
67
Andrey Lushnikov6deca112019-01-16 02:06:1268void DevToolsRendererChannel::ForceDetachWorkerSessions() {
69 for (WorkerDevToolsAgentHost* host : child_workers_)
70 host->ForceDetachAllSessions();
71}
72
Dmitry Gozmanbe2073b2018-10-29 22:15:4673void DevToolsRendererChannel::SetRendererInternal(
74 blink::mojom::DevToolsAgent* agent,
75 int process_id,
76 RenderFrameHostImpl* frame_host) {
Dmitry Gozmane3ceda742018-12-05 22:06:0177 ReportChildWorkersCallback();
Dmitry Gozmanb27efd1e2018-10-01 22:08:1178 process_id_ = process_id;
79 frame_host_ = frame_host;
Dmitry Gozmanbe2073b2018-10-29 22:15:4680 if (agent && !report_attachers_.empty()) {
81 agent->ReportChildWorkers(true /* report */,
Dmitry Gozmane3ceda742018-12-05 22:06:0182 !wait_for_debugger_attachers_.empty(),
83 base::DoNothing());
Dmitry Gozmanbe2073b2018-10-29 22:15:4684 }
Dmitry Gozman08a40e2f2018-10-02 21:16:4185 for (DevToolsSession* session : owner_->sessions()) {
86 for (auto& pair : session->handlers())
87 pair.second->SetRenderer(process_id_, frame_host_);
Dmitry Gozmanbe2073b2018-10-29 22:15:4688 session->AttachToAgent(agent);
Dmitry Gozman08a40e2f2018-10-02 21:16:4189 }
Dmitry Gozmanb27efd1e2018-10-01 22:08:1190}
91
92void DevToolsRendererChannel::AttachSession(DevToolsSession* session) {
Julie Jeongeun Kime1b546e2019-08-13 09:39:3893 if (!agent_remote_ && !associated_agent_remote_)
Dmitry Gozmanb27efd1e2018-10-01 22:08:1194 owner_->UpdateRendererChannel(true /* force */);
Dmitry Gozman08a40e2f2018-10-02 21:16:4195 for (auto& pair : session->handlers())
96 pair.second->SetRenderer(process_id_, frame_host_);
Julie Jeongeun Kime1b546e2019-08-13 09:39:3897 if (agent_remote_)
98 session->AttachToAgent(agent_remote_.get());
99 else if (associated_agent_remote_)
100 session->AttachToAgent(associated_agent_remote_.get());
Dmitry Gozmanb27efd1e2018-10-01 22:08:11101}
102
103void DevToolsRendererChannel::InspectElement(const gfx::Point& point) {
Julie Jeongeun Kime1b546e2019-08-13 09:39:38104 if (!agent_remote_ && !associated_agent_remote_)
Dmitry Gozmanb27efd1e2018-10-01 22:08:11105 owner_->UpdateRendererChannel(true /* force */);
Julie Jeongeun Kime1b546e2019-08-13 09:39:38106 // Previous call might update |agent_remote_| or |associated_agent_remote_|
Dmitry Gozmanbe2073b2018-10-29 22:15:46107 // via SetRenderer(), so we should check them again.
Julie Jeongeun Kime1b546e2019-08-13 09:39:38108 if (agent_remote_)
109 agent_remote_->InspectElement(point);
110 else if (associated_agent_remote_)
111 associated_agent_remote_->InspectElement(point);
Dmitry Gozmanbe2073b2018-10-29 22:15:46112}
113
114void DevToolsRendererChannel::SetReportChildWorkers(
115 protocol::TargetAutoAttacher* attacher,
116 bool report,
Dmitry Gozmane3ceda742018-12-05 22:06:01117 bool wait_for_debugger,
118 base::OnceClosure callback) {
119 ReportChildWorkersCallback();
120 set_report_callback_ = std::move(callback);
Dmitry Gozmanbe2073b2018-10-29 22:15:46121 if (report) {
122 if (report_attachers_.find(attacher) == report_attachers_.end()) {
123 report_attachers_.insert(attacher);
124 for (DevToolsAgentHostImpl* host : child_workers_)
125 attacher->ChildWorkerCreated(host, false /* waiting_for_debugger */);
126 }
127 } else {
128 report_attachers_.erase(attacher);
129 }
130 if (wait_for_debugger)
131 wait_for_debugger_attachers_.insert(attacher);
132 else
133 wait_for_debugger_attachers_.erase(attacher);
Julie Jeongeun Kime1b546e2019-08-13 09:39:38134 if (agent_remote_) {
135 agent_remote_->ReportChildWorkers(
Dmitry Gozmane3ceda742018-12-05 22:06:01136 !report_attachers_.empty(), !wait_for_debugger_attachers_.empty(),
137 base::BindOnce(&DevToolsRendererChannel::ReportChildWorkersCallback,
138 base::Unretained(this)));
Julie Jeongeun Kime1b546e2019-08-13 09:39:38139 } else if (associated_agent_remote_) {
140 associated_agent_remote_->ReportChildWorkers(
Dmitry Gozmane3ceda742018-12-05 22:06:01141 !report_attachers_.empty(), !wait_for_debugger_attachers_.empty(),
142 base::BindOnce(&DevToolsRendererChannel::ReportChildWorkersCallback,
143 base::Unretained(this)));
144 } else {
145 ReportChildWorkersCallback();
Dmitry Gozmanbe2073b2018-10-29 22:15:46146 }
147}
148
Dmitry Gozmane3ceda742018-12-05 22:06:01149void DevToolsRendererChannel::ReportChildWorkersCallback() {
150 if (set_report_callback_)
151 std::move(set_report_callback_).Run();
152}
153
Dmitry Gozmanbe2073b2018-10-29 22:15:46154void DevToolsRendererChannel::ChildWorkerCreated(
Julie Jeongeun Kime1b546e2019-08-13 09:39:38155 mojo::PendingRemote<blink::mojom::DevToolsAgent> worker_devtools_agent,
156 mojo::PendingReceiver<blink::mojom::DevToolsAgentHost> host_receiver,
Dmitry Gozmanbe2073b2018-10-29 22:15:46157 const GURL& url,
Joel Einbinderb764187e2019-02-27 01:20:04158 const std::string& name,
Dmitry Gozmanbe2073b2018-10-29 22:15:46159 const base::UnguessableToken& devtools_worker_token,
160 bool waiting_for_debugger) {
161 if (content::DevToolsAgentHost::GetForId(devtools_worker_token.ToString())) {
162 mojo::ReportBadMessage("Workers should have unique tokens.");
163 return;
164 }
165 RenderProcessHost* process = RenderProcessHost::FromID(process_id_);
166 if (!process)
167 return;
168 GURL filtered_url = url;
169 process->FilterURL(true /* empty_allowed */, &filtered_url);
170 auto agent_host = base::MakeRefCounted<WorkerDevToolsAgentHost>(
Julie Jeongeun Kime1b546e2019-08-13 09:39:38171 process_id_, std::move(worker_devtools_agent), std::move(host_receiver),
Joel Einbinderb764187e2019-02-27 01:20:04172 filtered_url, std::move(name), devtools_worker_token, owner_->GetId(),
Dmitry Gozmanbe2073b2018-10-29 22:15:46173 base::BindOnce(&DevToolsRendererChannel::ChildWorkerDestroyed,
174 weak_factory_.GetWeakPtr()));
175 child_workers_.insert(agent_host.get());
176 for (protocol::TargetAutoAttacher* attacher : report_attachers_)
177 attacher->ChildWorkerCreated(agent_host.get(), waiting_for_debugger);
178}
179
180void DevToolsRendererChannel::ChildWorkerDestroyed(
181 DevToolsAgentHostImpl* host) {
182 child_workers_.erase(host);
Dmitry Gozmanb27efd1e2018-10-01 22:08:11183}
184
185} // namespace content