OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/devtools/protocol/target_handler.h" | 5 #include "content/browser/devtools/protocol/target_handler.h" |
6 | 6 |
7 #include "content/browser/devtools/service_worker_devtools_agent_host.h" | 7 #include "content/browser/devtools/service_worker_devtools_agent_host.h" |
8 #include "content/browser/frame_host/frame_tree.h" | 8 #include "content/browser/frame_host/frame_tree.h" |
9 #include "content/browser/frame_host/frame_tree_node.h" | 9 #include "content/browser/frame_host/frame_tree_node.h" |
10 #include "content/browser/frame_host/render_frame_host_impl.h" | 10 #include "content/browser/frame_host/render_frame_host_impl.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 | 79 |
80 for (const auto& it : scope_agents_map) | 80 for (const auto& it : scope_agents_map) |
81 AddEligibleHosts(*it.second.get(), &result); | 81 AddEligibleHosts(*it.second.get(), &result); |
82 | 82 |
83 return result; | 83 return result; |
84 } | 84 } |
85 | 85 |
86 } // namespace | 86 } // namespace |
87 | 87 |
88 TargetHandler::TargetHandler() | 88 TargetHandler::TargetHandler() |
89 : enabled_(false), | 89 : discover_(false), |
90 auto_attach_(false), | 90 auto_attach_(false), |
91 wait_for_debugger_on_start_(false), | 91 wait_for_debugger_on_start_(false), |
92 attach_to_frames_(false), | 92 attach_to_frames_(false), |
93 render_frame_host_(nullptr) { | 93 render_frame_host_(nullptr) { |
94 } | 94 } |
95 | 95 |
96 TargetHandler::~TargetHandler() { | 96 TargetHandler::~TargetHandler() { |
97 Disable(); | 97 Detached(); |
98 } | 98 } |
99 | 99 |
100 void TargetHandler::SetRenderFrameHost(RenderFrameHostImpl* render_frame_host) { | 100 void TargetHandler::SetRenderFrameHost(RenderFrameHostImpl* render_frame_host) { |
101 render_frame_host_ = render_frame_host; | 101 render_frame_host_ = render_frame_host; |
102 UpdateFrames(); | 102 UpdateFrames(); |
103 } | 103 } |
104 | 104 |
105 void TargetHandler::SetClient(std::unique_ptr<Client> client) { | 105 void TargetHandler::SetClient(std::unique_ptr<Client> client) { |
106 client_.swap(client); | 106 client_.swap(client); |
107 } | 107 } |
108 | 108 |
109 void TargetHandler::Detached() { | 109 void TargetHandler::Detached() { |
110 Disable(); | 110 SetAutoAttach(false, false); |
| 111 SetDiscoverTargets(false); |
111 } | 112 } |
112 | 113 |
113 void TargetHandler::UpdateServiceWorkers() { | 114 void TargetHandler::UpdateServiceWorkers() { |
114 UpdateServiceWorkers(false); | 115 UpdateServiceWorkers(false); |
115 } | 116 } |
116 | 117 |
117 void TargetHandler::UpdateFrames() { | 118 void TargetHandler::UpdateFrames() { |
118 if (!enabled_ || !auto_attach_ || !attach_to_frames_) | 119 if (!auto_attach_ || !attach_to_frames_) |
119 return; | 120 return; |
120 | 121 |
121 HostsMap new_hosts; | 122 HostsMap new_hosts; |
122 if (render_frame_host_) { | 123 if (render_frame_host_) { |
123 FrameTreeNode* root = render_frame_host_->frame_tree_node(); | 124 FrameTreeNode* root = render_frame_host_->frame_tree_node(); |
124 std::queue<FrameTreeNode*> queue; | 125 std::queue<FrameTreeNode*> queue; |
125 queue.push(root); | 126 queue.push(root); |
126 while (!queue.empty()) { | 127 while (!queue.empty()) { |
127 FrameTreeNode* node = queue.front(); | 128 FrameTreeNode* node = queue.front(); |
128 queue.pop(); | 129 queue.pop(); |
129 bool cross_process = node->current_frame_host()->IsCrossProcessSubframe(); | 130 bool cross_process = node->current_frame_host()->IsCrossProcessSubframe(); |
130 if (node != root && cross_process) { | 131 if (node != root && cross_process) { |
131 scoped_refptr<DevToolsAgentHost> new_host = | 132 scoped_refptr<DevToolsAgentHost> new_host = |
132 DevToolsAgentHost::GetOrCreateFor(node->current_frame_host()); | 133 DevToolsAgentHost::GetOrCreateFor(node->current_frame_host()); |
133 new_hosts[new_host->GetId()] = new_host; | 134 new_hosts[new_host->GetId()] = new_host; |
134 } else { | 135 } else { |
135 for (size_t i = 0; i < node->child_count(); ++i) | 136 for (size_t i = 0; i < node->child_count(); ++i) |
136 queue.push(node->child_at(i)); | 137 queue.push(node->child_at(i)); |
137 } | 138 } |
138 } | 139 } |
139 } | 140 } |
140 | 141 |
141 // TODO(dgozman): support wait_for_debugger_on_start_. | 142 // TODO(dgozman): support wait_for_debugger_on_start_. |
142 ReattachTargetsOfType(new_hosts, DevToolsAgentHost::kTypeFrame, false); | 143 ReattachTargetsOfType(new_hosts, DevToolsAgentHost::kTypeFrame, false); |
143 } | 144 } |
144 | 145 |
145 void TargetHandler::UpdateServiceWorkers(bool waiting_for_debugger) { | 146 void TargetHandler::UpdateServiceWorkers(bool waiting_for_debugger) { |
146 if (!enabled_ || !auto_attach_) | 147 if (!auto_attach_) |
147 return; | 148 return; |
148 | 149 |
149 frame_urls_.clear(); | 150 frame_urls_.clear(); |
150 BrowserContext* browser_context = nullptr; | 151 BrowserContext* browser_context = nullptr; |
151 if (render_frame_host_) { | 152 if (render_frame_host_) { |
152 // TODO(dgozman): do not traverse inside cross-process subframes. | 153 // TODO(dgozman): do not traverse inside cross-process subframes. |
153 for (FrameTreeNode* node : | 154 for (FrameTreeNode* node : |
154 render_frame_host_->frame_tree_node()->frame_tree()->Nodes()) { | 155 render_frame_host_->frame_tree_node()->frame_tree()->Nodes()) { |
155 frame_urls_.insert(node->current_url()); | 156 frame_urls_.insert(node->current_url()); |
156 } | 157 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 ->set_title(host->GetTitle()) | 193 ->set_title(host->GetTitle()) |
193 ->set_url(host->GetURL().spec()) | 194 ->set_url(host->GetURL().spec()) |
194 ->set_type(host->GetType()))); | 195 ->set_type(host->GetType()))); |
195 } | 196 } |
196 | 197 |
197 void TargetHandler::TargetRemovedInternal(DevToolsAgentHost* host) { | 198 void TargetHandler::TargetRemovedInternal(DevToolsAgentHost* host) { |
198 client_->TargetRemoved(TargetRemovedParams::Create() | 199 client_->TargetRemoved(TargetRemovedParams::Create() |
199 ->set_target_id(host->GetId())); | 200 ->set_target_id(host->GetId())); |
200 } | 201 } |
201 | 202 |
202 void TargetHandler::AttachToTargetInternal( | 203 bool TargetHandler::AttachToTargetInternal( |
203 DevToolsAgentHost* host, bool waiting_for_debugger) { | 204 DevToolsAgentHost* host, bool waiting_for_debugger) { |
204 if (host->IsAttached()) | 205 if (!host->AttachClient(this)) |
205 return; | 206 return false; |
206 attached_hosts_[host->GetId()] = host; | 207 attached_hosts_[host->GetId()] = host; |
207 host->AttachClient(this); | |
208 client_->AttachedToTarget(AttachedToTargetParams::Create() | 208 client_->AttachedToTarget(AttachedToTargetParams::Create() |
209 ->set_target_id(host->GetId()) | 209 ->set_target_id(host->GetId()) |
210 ->set_waiting_for_debugger(waiting_for_debugger)); | 210 ->set_waiting_for_debugger(waiting_for_debugger)); |
| 211 return true; |
211 } | 212 } |
212 | 213 |
213 void TargetHandler::DetachFromTargetInternal(DevToolsAgentHost* host) { | 214 void TargetHandler::DetachFromTargetInternal(DevToolsAgentHost* host) { |
214 auto it = attached_hosts_.find(host->GetId()); | 215 auto it = attached_hosts_.find(host->GetId()); |
215 if (it == attached_hosts_.end()) | 216 if (it == attached_hosts_.end()) |
216 return; | 217 return; |
217 host->DetachClient(this); | 218 host->DetachClient(this); |
218 client_->DetachedFromTarget(DetachedFromTargetParams::Create()-> | 219 client_->DetachedFromTarget(DetachedFromTargetParams::Create()-> |
219 set_target_id(host->GetId())); | 220 set_target_id(host->GetId())); |
220 attached_hosts_.erase(it); | 221 attached_hosts_.erase(it); |
221 } | 222 } |
222 | 223 |
223 // ----------------- Protocol ---------------------- | 224 // ----------------- Protocol ---------------------- |
224 | 225 |
225 Response TargetHandler::Enable() { | 226 Response TargetHandler::SetDiscoverTargets(bool discover) { |
226 if (enabled_) | 227 if (discover_ == discover) |
227 return Response::OK(); | 228 return Response::OK(); |
228 enabled_ = true; | 229 discover_ = discover; |
229 ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this); | 230 // TODO(dgozman): observe all agent hosts here. |
230 UpdateServiceWorkers(); | |
231 UpdateFrames(); | |
232 return Response::OK(); | 231 return Response::OK(); |
233 } | 232 } |
234 | 233 |
235 Response TargetHandler::Disable() { | |
236 if (!enabled_) | |
237 return Response::OK(); | |
238 enabled_ = false; | |
239 auto_attach_ = false; | |
240 wait_for_debugger_on_start_ = false; | |
241 ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this); | |
242 for (const auto& pair : attached_hosts_) | |
243 pair.second->DetachClient(this); | |
244 attached_hosts_.clear(); | |
245 return Response::OK(); | |
246 } | |
247 | |
248 Response TargetHandler::SetAutoAttach( | 234 Response TargetHandler::SetAutoAttach( |
249 bool auto_attach, bool wait_for_debugger_on_start) { | 235 bool auto_attach, bool wait_for_debugger_on_start) { |
250 wait_for_debugger_on_start_ = wait_for_debugger_on_start; | 236 wait_for_debugger_on_start_ = wait_for_debugger_on_start; |
251 if (auto_attach_ == auto_attach) | 237 if (auto_attach_ == auto_attach) |
252 return Response::OK(); | 238 return Response::OK(); |
253 auto_attach_ = auto_attach; | 239 auto_attach_ = auto_attach; |
254 if (auto_attach_) { | 240 if (auto_attach_) { |
| 241 ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this); |
255 UpdateServiceWorkers(); | 242 UpdateServiceWorkers(); |
256 UpdateFrames(); | 243 UpdateFrames(); |
| 244 } else { |
| 245 ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this); |
| 246 HostsMap empty; |
| 247 ReattachTargetsOfType(empty, DevToolsAgentHost::kTypeFrame, false); |
| 248 ReattachTargetsOfType(empty, DevToolsAgentHost::kTypeServiceWorker, false); |
257 } | 249 } |
258 return Response::OK(); | 250 return Response::OK(); |
259 } | 251 } |
260 | 252 |
261 Response TargetHandler::SetAttachToFrames(bool value) { | 253 Response TargetHandler::SetAttachToFrames(bool value) { |
262 if (attach_to_frames_ == value) | 254 if (attach_to_frames_ == value) |
263 return Response::OK(); | 255 return Response::OK(); |
264 attach_to_frames_ = value; | 256 attach_to_frames_ = value; |
265 if (attach_to_frames_) { | 257 if (attach_to_frames_) { |
266 UpdateFrames(); | 258 UpdateFrames(); |
267 } else { | 259 } else { |
268 HostsMap empty; | 260 HostsMap empty; |
269 ReattachTargetsOfType(empty, DevToolsAgentHost::kTypeFrame, false); | 261 ReattachTargetsOfType(empty, DevToolsAgentHost::kTypeFrame, false); |
270 } | 262 } |
271 return Response::OK(); | 263 return Response::OK(); |
272 } | 264 } |
273 | 265 |
| 266 Response TargetHandler::AttachToTarget(const std::string& target_id, |
| 267 bool* out_success) { |
| 268 scoped_refptr<DevToolsAgentHost> agent_host( |
| 269 DevToolsAgentHost::GetForId(target_id)); |
| 270 if (!agent_host) |
| 271 return Response::InvalidParams("No target with such id"); |
| 272 *out_success = AttachToTargetInternal(agent_host.get(), false); |
| 273 return Response::OK(); |
| 274 } |
| 275 |
| 276 Response TargetHandler::DetachFromTarget(const std::string& target_id) { |
| 277 auto it = attached_hosts_.find(target_id); |
| 278 if (it == attached_hosts_.end()) |
| 279 return Response::InternalError("Not attached to the target"); |
| 280 DetachFromTargetInternal(it->second.get()); |
| 281 return Response::OK(); |
| 282 } |
| 283 |
274 Response TargetHandler::SendMessageToTarget( | 284 Response TargetHandler::SendMessageToTarget( |
275 const std::string& target_id, | 285 const std::string& target_id, |
276 const std::string& message) { | 286 const std::string& message) { |
277 auto it = attached_hosts_.find(target_id); | 287 auto it = attached_hosts_.find(target_id); |
278 if (it == attached_hosts_.end()) | 288 if (it == attached_hosts_.end()) |
279 return Response::InternalError("Not attached to the target"); | 289 return Response::InternalError("Not attached to the target"); |
280 it->second->DispatchProtocolMessage(this, message); | 290 it->second->DispatchProtocolMessage(this, message); |
281 return Response::OK(); | 291 return Response::OK(); |
282 } | 292 } |
283 | 293 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 | 326 |
317 client_->ReceivedMessageFromTarget( | 327 client_->ReceivedMessageFromTarget( |
318 ReceivedMessageFromTargetParams::Create()-> | 328 ReceivedMessageFromTargetParams::Create()-> |
319 set_target_id(host->GetId())-> | 329 set_target_id(host->GetId())-> |
320 set_message(message)); | 330 set_message(message)); |
321 } | 331 } |
322 | 332 |
323 void TargetHandler::AgentHostClosed( | 333 void TargetHandler::AgentHostClosed( |
324 DevToolsAgentHost* host, | 334 DevToolsAgentHost* host, |
325 bool replaced_with_another_client) { | 335 bool replaced_with_another_client) { |
326 client_->TargetRemoved(TargetRemovedParams::Create()-> | 336 client_->DetachedFromTarget(DetachedFromTargetParams::Create()-> |
327 set_target_id(host->GetId())); | 337 set_target_id(host->GetId())); |
328 attached_hosts_.erase(host->GetId()); | 338 attached_hosts_.erase(host->GetId()); |
| 339 TargetRemovedInternal(host); |
329 } | 340 } |
330 | 341 |
331 // -------- ServiceWorkerDevToolsManager::Observer ---------- | 342 // -------- ServiceWorkerDevToolsManager::Observer ---------- |
332 | 343 |
333 void TargetHandler::WorkerCreated( | 344 void TargetHandler::WorkerCreated( |
334 ServiceWorkerDevToolsAgentHost* host) { | 345 ServiceWorkerDevToolsAgentHost* host) { |
335 BrowserContext* browser_context = nullptr; | 346 BrowserContext* browser_context = nullptr; |
336 if (render_frame_host_) | 347 if (render_frame_host_) |
337 browser_context = render_frame_host_->GetProcess()->GetBrowserContext(); | 348 browser_context = render_frame_host_->GetProcess()->GetBrowserContext(); |
338 auto hosts = GetMatchingServiceWorkers(browser_context, frame_urls_); | 349 auto hosts = GetMatchingServiceWorkers(browser_context, frame_urls_); |
(...skipping 25 matching lines...) Expand all Loading... |
364 } | 375 } |
365 | 376 |
366 void TargetHandler::WorkerDestroyed( | 377 void TargetHandler::WorkerDestroyed( |
367 ServiceWorkerDevToolsAgentHost* host) { | 378 ServiceWorkerDevToolsAgentHost* host) { |
368 UpdateServiceWorkers(); | 379 UpdateServiceWorkers(); |
369 } | 380 } |
370 | 381 |
371 } // namespace target | 382 } // namespace target |
372 } // namespace devtools | 383 } // namespace devtools |
373 } // namespace content | 384 } // namespace content |
OLD | NEW |