| 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 |