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 "base/strings/stringprintf.h" | |
7 #include "content/browser/devtools/devtools_manager.h" | 8 #include "content/browser/devtools/devtools_manager.h" |
8 #include "content/browser/devtools/devtools_session.h" | 9 #include "content/browser/devtools/devtools_session.h" |
9 #include "content/browser/devtools/render_frame_devtools_agent_host.h" | 10 #include "content/browser/devtools/render_frame_devtools_agent_host.h" |
10 #include "content/browser/devtools/service_worker_devtools_agent_host.h" | 11 #include "content/browser/devtools/service_worker_devtools_agent_host.h" |
11 #include "content/browser/frame_host/frame_tree.h" | 12 #include "content/browser/frame_host/frame_tree.h" |
12 #include "content/browser/frame_host/frame_tree_node.h" | 13 #include "content/browser/frame_host/frame_tree_node.h" |
13 #include "content/browser/frame_host/render_frame_host_impl.h" | 14 #include "content/browser/frame_host/render_frame_host_impl.h" |
15 #include "content/public/browser/devtools_agent_host_client.h" | |
14 | 16 |
15 namespace content { | 17 namespace content { |
16 namespace protocol { | 18 namespace protocol { |
17 | 19 |
18 namespace { | 20 namespace { |
19 | 21 |
20 using ScopeAgentsMap = | 22 using ScopeAgentsMap = |
21 std::map<GURL, std::unique_ptr<ServiceWorkerDevToolsAgentHost::List>>; | 23 std::map<GURL, std::unique_ptr<ServiceWorkerDevToolsAgentHost::List>>; |
22 | 24 |
23 void GetMatchingHostsByScopeMap( | 25 void GetMatchingHostsByScopeMap( |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 return Target::TargetInfo::Create() | 89 return Target::TargetInfo::Create() |
88 .SetTargetId(host->GetId()) | 90 .SetTargetId(host->GetId()) |
89 .SetTitle(host->GetTitle()) | 91 .SetTitle(host->GetTitle()) |
90 .SetUrl(host->GetURL().spec()) | 92 .SetUrl(host->GetURL().spec()) |
91 .SetType(host->GetType()) | 93 .SetType(host->GetType()) |
92 .Build(); | 94 .Build(); |
93 } | 95 } |
94 | 96 |
95 } // namespace | 97 } // namespace |
96 | 98 |
99 class TargetHandler::Session : public DevToolsAgentHostClient { | |
100 public: | |
101 Session(TargetHandler* handler, | |
102 DevToolsAgentHost* agent_host, | |
caseq
2017/06/27 18:29:29
pass as scoped_refptr<> to indicate we keep it.
| |
103 const std::string& id, | |
104 bool is_auto_attach) | |
105 : handler_(handler), | |
106 agent_host_(agent_host), | |
107 id_(id), | |
108 is_auto_attach_(is_auto_attach) {} | |
109 | |
110 ~Session() override { | |
111 if (agent_host_) | |
112 agent_host_->DetachClient(this); | |
113 } | |
114 | |
115 bool is_auto_attach() const { return is_auto_attach_; } | |
116 DevToolsAgentHost* agent_host() const { return agent_host_.get(); } | |
117 | |
118 void Attach() { | |
119 static_cast<DevToolsAgentHostImpl*>(agent_host_.get()) | |
120 ->AttachMultiClient(this); | |
121 } | |
122 | |
123 // DevToolsAgentHostClient implementation. | |
124 void DispatchProtocolMessage(DevToolsAgentHost* agent_host, | |
125 const std::string& message) override { | |
126 handler_->frontend_->ReceivedMessageFromTarget(id_, message); | |
127 } | |
128 | |
129 void AgentHostClosed(DevToolsAgentHost* agent_host, | |
130 bool replaced_with_another_client) override { | |
131 handler_->frontend_->DetachedFromTarget(id_); | |
caseq
2017/06/27 18:29:29
Most of the logic in this methods looks like it co
| |
132 if (is_auto_attach_) | |
133 handler_->auto_attached_hosts_.erase(agent_host->GetId()); | |
134 agent_host_ = nullptr; | |
135 handler_->attached_sessions_.erase(id_); // |this| is deleted here. | |
136 } | |
137 | |
138 private: | |
139 TargetHandler* handler_; | |
140 scoped_refptr<DevToolsAgentHost> agent_host_; | |
141 std::string id_; | |
142 bool is_auto_attach_; | |
143 | |
144 DISALLOW_COPY_AND_ASSIGN(Session); | |
145 }; | |
146 | |
97 TargetHandler::TargetHandler() | 147 TargetHandler::TargetHandler() |
98 : DevToolsDomainHandler(Target::Metainfo::domainName), | 148 : DevToolsDomainHandler(Target::Metainfo::domainName), |
99 discover_(false), | 149 discover_(false), |
100 auto_attach_(false), | 150 auto_attach_(false), |
101 wait_for_debugger_on_start_(false), | 151 wait_for_debugger_on_start_(false), |
102 attach_to_frames_(false), | 152 attach_to_frames_(false), |
103 render_frame_host_(nullptr) { | 153 render_frame_host_(nullptr) { |
104 } | 154 } |
105 | 155 |
106 TargetHandler::~TargetHandler() { | 156 TargetHandler::~TargetHandler() { |
(...skipping 12 matching lines...) Expand all Loading... | |
119 } | 169 } |
120 | 170 |
121 void TargetHandler::SetRenderFrameHost(RenderFrameHostImpl* render_frame_host) { | 171 void TargetHandler::SetRenderFrameHost(RenderFrameHostImpl* render_frame_host) { |
122 render_frame_host_ = render_frame_host; | 172 render_frame_host_ = render_frame_host; |
123 UpdateFrames(); | 173 UpdateFrames(); |
124 } | 174 } |
125 | 175 |
126 Response TargetHandler::Disable() { | 176 Response TargetHandler::Disable() { |
127 SetAutoAttach(false, false); | 177 SetAutoAttach(false, false); |
128 SetDiscoverTargets(false); | 178 SetDiscoverTargets(false); |
129 for (const auto& id_host : attached_hosts_) | 179 attached_sessions_.clear(); |
130 id_host.second->DetachClient(this); | |
131 attached_hosts_.clear(); | |
132 return Response::OK(); | 180 return Response::OK(); |
133 } | 181 } |
134 | 182 |
135 void TargetHandler::UpdateServiceWorkers() { | 183 void TargetHandler::UpdateServiceWorkers() { |
136 UpdateServiceWorkers(false); | 184 UpdateServiceWorkers(false); |
137 } | 185 } |
138 | 186 |
139 void TargetHandler::UpdateFrames() { | 187 void TargetHandler::UpdateFrames() { |
140 if (!auto_attach_ || !attach_to_frames_) | 188 if (!auto_attach_ || !attach_to_frames_) |
141 return; | 189 return; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 auto matching = GetMatchingServiceWorkers(browser_context, frame_urls_); | 230 auto matching = GetMatchingServiceWorkers(browser_context, frame_urls_); |
183 HostsMap new_hosts; | 231 HostsMap new_hosts; |
184 for (const auto& pair : matching) { | 232 for (const auto& pair : matching) { |
185 if (pair.second->IsReadyForInspection()) | 233 if (pair.second->IsReadyForInspection()) |
186 new_hosts[pair.first] = pair.second; | 234 new_hosts[pair.first] = pair.second; |
187 } | 235 } |
188 ReattachTargetsOfType( | 236 ReattachTargetsOfType( |
189 new_hosts, DevToolsAgentHost::kTypeServiceWorker, waiting_for_debugger); | 237 new_hosts, DevToolsAgentHost::kTypeServiceWorker, waiting_for_debugger); |
190 } | 238 } |
191 | 239 |
192 void TargetHandler::ReattachTargetsOfType( | 240 void TargetHandler::ReattachTargetsOfType(const HostsMap& new_hosts, |
193 const HostsMap& new_hosts, | 241 const std::string& type, |
194 const std::string& type, | 242 bool waiting_for_debugger) { |
195 bool waiting_for_debugger) { | 243 std::vector<std::string> ids_to_detach; |
196 HostsMap old_hosts = attached_hosts_; | 244 for (const auto& pair : attached_sessions_) { |
197 for (const auto& pair : old_hosts) { | 245 Session* session = pair.second.get(); |
198 if (pair.second->GetType() == type && | 246 if (session->is_auto_attach() && session->agent_host()->GetType() == type && |
199 new_hosts.find(pair.first) == new_hosts.end()) { | 247 new_hosts.find(session->agent_host()->GetId()) == new_hosts.end()) { |
200 DetachFromTargetInternal(pair.second.get()); | 248 ids_to_detach.push_back(pair.first); |
249 auto_attached_hosts_.erase(session->agent_host()->GetId()); | |
201 } | 250 } |
202 } | 251 } |
252 for (const std::string& session_id : ids_to_detach) | |
253 DetachFromSessionInternal(session_id); | |
203 for (const auto& pair : new_hosts) { | 254 for (const auto& pair : new_hosts) { |
204 if (old_hosts.find(pair.first) == old_hosts.end()) | 255 if (auto_attached_hosts_.find(pair.first) == auto_attached_hosts_.end()) { |
205 AttachToTargetInternal(pair.second.get(), waiting_for_debugger); | 256 DevToolsAgentHost* host = pair.second.get(); |
257 AttachToTargetInternal(host, waiting_for_debugger, true); | |
258 auto_attached_hosts_[host->GetId()] = host; | |
259 } | |
206 } | 260 } |
207 } | 261 } |
208 | 262 |
209 void TargetHandler::TargetCreatedInternal(DevToolsAgentHost* host) { | 263 void TargetHandler::TargetCreatedInternal(DevToolsAgentHost* host) { |
210 if (reported_hosts_.find(host->GetId()) != reported_hosts_.end()) | 264 if (reported_hosts_.find(host->GetId()) != reported_hosts_.end()) |
211 return; | 265 return; |
212 frontend_->TargetCreated(CreateInfo(host)); | 266 frontend_->TargetCreated(CreateInfo(host)); |
213 reported_hosts_[host->GetId()] = host; | 267 reported_hosts_[host->GetId()] = host; |
214 } | 268 } |
215 | 269 |
216 void TargetHandler::TargetDestroyedInternal( | 270 void TargetHandler::TargetDestroyedInternal( |
217 DevToolsAgentHost* host) { | 271 DevToolsAgentHost* host) { |
218 auto it = reported_hosts_.find(host->GetId()); | 272 auto it = reported_hosts_.find(host->GetId()); |
219 if (it == reported_hosts_.end()) | 273 if (it == reported_hosts_.end()) |
220 return; | 274 return; |
221 if (discover_) | 275 if (discover_) |
222 frontend_->TargetDestroyed(host->GetId()); | 276 frontend_->TargetDestroyed(host->GetId()); |
223 reported_hosts_.erase(it); | 277 reported_hosts_.erase(it); |
224 } | 278 } |
225 | 279 |
226 bool TargetHandler::AttachToTargetInternal( | 280 std::string TargetHandler::AttachToTargetInternal(DevToolsAgentHost* host, |
227 DevToolsAgentHost* host, bool waiting_for_debugger) { | 281 bool waiting_for_debugger, |
228 attached_hosts_[host->GetId()] = host; | 282 bool is_auto_attach) { |
229 if (!host->AttachClient(this)) { | 283 std::string session_id = |
230 attached_hosts_.erase(host->GetId()); | 284 base::StringPrintf("%s:%d", host->GetId().c_str(), ++last_session_id_); |
285 Session* session = new Session(this, host, session_id, is_auto_attach); | |
286 attached_sessions_[session_id].reset(session); | |
287 session->Attach(); | |
288 frontend_->AttachedToTarget(session_id, CreateInfo(host), | |
289 waiting_for_debugger); | |
290 return session_id; | |
291 } | |
292 | |
293 bool TargetHandler::DetachFromSessionInternal(const std::string& session_id) { | |
294 auto it = attached_sessions_.find(session_id); | |
295 if (it == attached_sessions_.end()) | |
231 return false; | 296 return false; |
232 } | 297 frontend_->DetachedFromTarget(session_id); |
233 frontend_->AttachedToTarget(CreateInfo(host), waiting_for_debugger); | 298 attached_sessions_.erase(it); |
234 return true; | 299 return true; |
235 } | 300 } |
236 | 301 |
237 void TargetHandler::DetachFromTargetInternal(DevToolsAgentHost* host) { | 302 bool TargetHandler::IsAttachedToAgentHost(DevToolsAgentHost* agent_host) { |
238 auto it = attached_hosts_.find(host->GetId()); | 303 for (auto& it : attached_sessions_) { |
239 if (it == attached_hosts_.end()) | 304 if (it.second->agent_host() == agent_host) |
240 return; | 305 return true; |
241 host->DetachClient(this); | 306 } |
242 frontend_->DetachedFromTarget(host->GetId()); | 307 return false; |
243 attached_hosts_.erase(it); | |
244 } | 308 } |
245 | 309 |
246 // ----------------- Protocol ---------------------- | 310 // ----------------- Protocol ---------------------- |
247 | 311 |
248 Response TargetHandler::SetDiscoverTargets(bool discover) { | 312 Response TargetHandler::SetDiscoverTargets(bool discover) { |
249 if (discover_ == discover) | 313 if (discover_ == discover) |
250 return Response::OK(); | 314 return Response::OK(); |
251 discover_ = discover; | 315 discover_ = discover; |
252 if (discover_) { | 316 if (discover_) { |
253 DevToolsAgentHost::AddObserver(this); | 317 DevToolsAgentHost::AddObserver(this); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 } | 355 } |
292 return Response::OK(); | 356 return Response::OK(); |
293 } | 357 } |
294 | 358 |
295 Response TargetHandler::SetRemoteLocations( | 359 Response TargetHandler::SetRemoteLocations( |
296 std::unique_ptr<protocol::Array<Target::RemoteLocation>>) { | 360 std::unique_ptr<protocol::Array<Target::RemoteLocation>>) { |
297 return Response::Error("Not supported"); | 361 return Response::Error("Not supported"); |
298 } | 362 } |
299 | 363 |
300 Response TargetHandler::AttachToTarget(const std::string& target_id, | 364 Response TargetHandler::AttachToTarget(const std::string& target_id, |
301 bool* out_success) { | 365 Maybe<std::string>* out_session_id) { |
302 // TODO(dgozman): only allow reported hosts. | 366 // TODO(dgozman): only allow reported hosts. |
303 scoped_refptr<DevToolsAgentHost> agent_host = | 367 scoped_refptr<DevToolsAgentHost> agent_host = |
304 DevToolsAgentHost::GetForId(target_id); | 368 DevToolsAgentHost::GetForId(target_id); |
305 if (!agent_host) | 369 if (!agent_host) |
306 return Response::InvalidParams("No target with given id found"); | 370 return Response::InvalidParams("No target with given id found"); |
307 *out_success = AttachToTargetInternal(agent_host.get(), false); | 371 *out_session_id = AttachToTargetInternal(agent_host.get(), false, false); |
308 return Response::OK(); | 372 return Response::OK(); |
309 } | 373 } |
310 | 374 |
311 Response TargetHandler::DetachFromTarget(const std::string& target_id) { | 375 Response TargetHandler::DetachFromTarget(const std::string& session_id) { |
312 auto it = attached_hosts_.find(target_id); | 376 if (!DetachFromSessionInternal(session_id)) |
313 if (it == attached_hosts_.end()) | 377 return Response::Error("No session with given id"); |
314 return Response::Error("Not attached to the target"); | |
315 DevToolsAgentHost* agent_host = it->second.get(); | |
316 DetachFromTargetInternal(agent_host); | |
317 return Response::OK(); | 378 return Response::OK(); |
318 } | 379 } |
319 | 380 |
320 Response TargetHandler::SendMessageToTarget( | 381 Response TargetHandler::SendMessageToTarget(const std::string& session_id, |
321 const std::string& target_id, | 382 const std::string& message) { |
322 const std::string& message) { | 383 auto it = attached_sessions_.find(session_id); |
323 auto it = attached_hosts_.find(target_id); | 384 if (it == attached_sessions_.end()) |
324 if (it == attached_hosts_.end()) | |
325 return Response::FallThrough(); | 385 return Response::FallThrough(); |
326 it->second->DispatchProtocolMessage(this, message); | 386 it->second->agent_host()->DispatchProtocolMessage(it->second.get(), message); |
327 return Response::OK(); | 387 return Response::OK(); |
328 } | 388 } |
329 | 389 |
330 Response TargetHandler::GetTargetInfo( | 390 Response TargetHandler::GetTargetInfo( |
331 const std::string& target_id, | 391 const std::string& target_id, |
332 std::unique_ptr<Target::TargetInfo>* target_info) { | 392 std::unique_ptr<Target::TargetInfo>* target_info) { |
333 // TODO(dgozman): only allow reported hosts. | 393 // TODO(dgozman): only allow reported hosts. |
334 scoped_refptr<DevToolsAgentHost> agent_host( | 394 scoped_refptr<DevToolsAgentHost> agent_host( |
335 DevToolsAgentHost::GetForId(target_id)); | 395 DevToolsAgentHost::GetForId(target_id)); |
336 if (!agent_host) | 396 if (!agent_host) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 } | 446 } |
387 | 447 |
388 Response TargetHandler::GetTargets( | 448 Response TargetHandler::GetTargets( |
389 std::unique_ptr<protocol::Array<Target::TargetInfo>>* target_infos) { | 449 std::unique_ptr<protocol::Array<Target::TargetInfo>>* target_infos) { |
390 *target_infos = protocol::Array<Target::TargetInfo>::create(); | 450 *target_infos = protocol::Array<Target::TargetInfo>::create(); |
391 for (const auto& host : DevToolsAgentHost::GetOrCreateAll()) | 451 for (const auto& host : DevToolsAgentHost::GetOrCreateAll()) |
392 (*target_infos)->addItem(CreateInfo(host.get())); | 452 (*target_infos)->addItem(CreateInfo(host.get())); |
393 return Response::OK(); | 453 return Response::OK(); |
394 } | 454 } |
395 | 455 |
396 // ---------------- DevToolsAgentHostClient ---------------- | |
397 | |
398 void TargetHandler::DispatchProtocolMessage( | |
399 DevToolsAgentHost* host, | |
400 const std::string& message) { | |
401 auto it = attached_hosts_.find(host->GetId()); | |
402 if (it == attached_hosts_.end()) | |
403 return; // Already disconnected. | |
404 | |
405 frontend_->ReceivedMessageFromTarget(host->GetId(), message); | |
406 } | |
407 | |
408 void TargetHandler::AgentHostClosed( | |
409 DevToolsAgentHost* host, | |
410 bool replaced_with_another_client) { | |
411 frontend_->DetachedFromTarget(host->GetId()); | |
412 attached_hosts_.erase(host->GetId()); | |
413 } | |
414 | |
415 // -------------- DevToolsAgentHostObserver ----------------- | 456 // -------------- DevToolsAgentHostObserver ----------------- |
416 | 457 |
417 bool TargetHandler::ShouldForceDevToolsAgentHostCreation() { | 458 bool TargetHandler::ShouldForceDevToolsAgentHostCreation() { |
418 return true; | 459 return true; |
419 } | 460 } |
420 | 461 |
421 void TargetHandler::DevToolsAgentHostCreated(DevToolsAgentHost* agent_host) { | 462 void TargetHandler::DevToolsAgentHostCreated(DevToolsAgentHost* agent_host) { |
422 if (agent_host->GetType() == "node" && agent_host->IsAttached()) | 463 if (agent_host->GetType() == "node" && agent_host->IsAttached()) |
423 return; | 464 return; |
424 // If we start discovering late, all existing agent hosts will be reported, | 465 // If we start discovering late, all existing agent hosts will be reported, |
425 // but we could have already attached to some. | 466 // but we could have already attached to some. |
426 TargetCreatedInternal(agent_host); | 467 TargetCreatedInternal(agent_host); |
427 } | 468 } |
428 | 469 |
429 void TargetHandler::DevToolsAgentHostDestroyed(DevToolsAgentHost* agent_host) { | 470 void TargetHandler::DevToolsAgentHostDestroyed(DevToolsAgentHost* agent_host) { |
430 DCHECK(attached_hosts_.find(agent_host->GetId()) == attached_hosts_.end()); | 471 DCHECK(auto_attached_hosts_.find(agent_host->GetId()) == |
472 auto_attached_hosts_.end()); | |
431 TargetDestroyedInternal(agent_host); | 473 TargetDestroyedInternal(agent_host); |
432 } | 474 } |
433 | 475 |
434 void TargetHandler::DevToolsAgentHostAttached(DevToolsAgentHost* host) { | 476 void TargetHandler::DevToolsAgentHostAttached(DevToolsAgentHost* host) { |
435 if (host->GetType() == "node" && | 477 if (host->GetType() == "node" && |
436 reported_hosts_.find(host->GetId()) != reported_hosts_.end() && | 478 reported_hosts_.find(host->GetId()) != reported_hosts_.end() && |
437 attached_hosts_.find(host->GetId()) == attached_hosts_.end()) { | 479 !IsAttachedToAgentHost(host)) { |
438 TargetDestroyedInternal(host); | 480 TargetDestroyedInternal(host); |
439 } | 481 } |
440 } | 482 } |
441 | 483 |
442 void TargetHandler::DevToolsAgentHostDetached(DevToolsAgentHost* host) { | 484 void TargetHandler::DevToolsAgentHostDetached(DevToolsAgentHost* host) { |
443 if (host->GetType() == "node" && | 485 if (host->GetType() == "node" && |
444 reported_hosts_.find(host->GetId()) == reported_hosts_.end() && | 486 reported_hosts_.find(host->GetId()) == reported_hosts_.end() && |
445 attached_hosts_.find(host->GetId()) == attached_hosts_.end()) { | 487 !IsAttachedToAgentHost(host)) { |
446 TargetCreatedInternal(host); | 488 TargetCreatedInternal(host); |
447 } | 489 } |
448 } | 490 } |
449 | 491 |
450 // -------- ServiceWorkerDevToolsManager::Observer ---------- | 492 // -------- ServiceWorkerDevToolsManager::Observer ---------- |
451 | 493 |
452 void TargetHandler::WorkerCreated( | 494 void TargetHandler::WorkerCreated( |
453 ServiceWorkerDevToolsAgentHost* host) { | 495 ServiceWorkerDevToolsAgentHost* host) { |
454 BrowserContext* browser_context = nullptr; | 496 BrowserContext* browser_context = nullptr; |
455 if (render_frame_host_) | 497 if (render_frame_host_) |
(...skipping 27 matching lines...) Expand all Loading... | |
483 UpdateServiceWorkers(); | 525 UpdateServiceWorkers(); |
484 } | 526 } |
485 | 527 |
486 void TargetHandler::WorkerDestroyed( | 528 void TargetHandler::WorkerDestroyed( |
487 ServiceWorkerDevToolsAgentHost* host) { | 529 ServiceWorkerDevToolsAgentHost* host) { |
488 UpdateServiceWorkers(); | 530 UpdateServiceWorkers(); |
489 } | 531 } |
490 | 532 |
491 } // namespace protocol | 533 } // namespace protocol |
492 } // namespace content | 534 } // namespace content |
OLD | NEW |