OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/service_worker_handler.h" | 5 #include "content/browser/devtools/protocol/service_worker_handler.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "content/browser/devtools/service_worker_devtools_agent_host.h" | 9 #include "content/browser/devtools/service_worker_devtools_agent_host.h" |
10 #include "content/browser/devtools/service_worker_devtools_manager.h" | 10 #include "content/browser/devtools/service_worker_devtools_manager.h" |
| 11 #include "content/browser/frame_host/frame_tree.h" |
| 12 #include "content/browser/frame_host/frame_tree_node.h" |
| 13 #include "content/browser/frame_host/render_frame_host_impl.h" |
11 #include "content/browser/service_worker/service_worker_context_observer.h" | 14 #include "content/browser/service_worker/service_worker_context_observer.h" |
12 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 15 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
13 #include "content/public/browser/browser_context.h" | 16 #include "content/public/browser/browser_context.h" |
14 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/devtools_agent_host.h" | 18 #include "content/public/browser/devtools_agent_host.h" |
16 #include "content/public/browser/render_frame_host.h" | 19 #include "content/public/browser/render_frame_host.h" |
17 #include "content/public/browser/render_process_host.h" | 20 #include "content/public/browser/render_process_host.h" |
18 #include "content/public/browser/storage_partition.h" | 21 #include "content/public/browser/storage_partition.h" |
19 #include "url/gurl.h" | 22 #include "url/gurl.h" |
20 | 23 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 CreateVersionDictionaryValue(registration_info.waiting_version)); | 98 CreateVersionDictionaryValue(registration_info.waiting_version)); |
96 } | 99 } |
97 if (registration_info.installing_version.version_id != | 100 if (registration_info.installing_version.version_id != |
98 kInvalidServiceWorkerVersionId) { | 101 kInvalidServiceWorkerVersionId) { |
99 registration->set_installing_version( | 102 registration->set_installing_version( |
100 CreateVersionDictionaryValue(registration_info.installing_version)); | 103 CreateVersionDictionaryValue(registration_info.installing_version)); |
101 } | 104 } |
102 return registration; | 105 return registration; |
103 } | 106 } |
104 | 107 |
| 108 scoped_refptr<ServiceWorkerDevToolsAgentHost> GetMatchingServiceWorker( |
| 109 const ServiceWorkerDevToolsAgentHost::List& agent_hosts, |
| 110 const GURL& url) { |
| 111 scoped_refptr<ServiceWorkerDevToolsAgentHost> best_host; |
| 112 std::string best_scope; |
| 113 for (auto host : agent_hosts) { |
| 114 if (host->GetURL().host() != url.host()) |
| 115 continue; |
| 116 std::string path = host->GetURL().path(); |
| 117 std::string file = host->GetURL().ExtractFileName(); |
| 118 std::string scope = path.substr(0, path.length() - file.length()); |
| 119 if (scope.length() > best_scope.length()) { |
| 120 best_host = host; |
| 121 best_scope = scope; |
| 122 } |
| 123 } |
| 124 return best_host; |
| 125 } |
| 126 |
| 127 ServiceWorkerDevToolsAgentHost::Map GetMatchingServiceWorkers( |
| 128 const std::set<GURL>& urls) { |
| 129 ServiceWorkerDevToolsAgentHost::List agent_hosts; |
| 130 ServiceWorkerDevToolsManager::GetInstance()-> |
| 131 AddAllAgentHosts(&agent_hosts); |
| 132 ServiceWorkerDevToolsAgentHost::Map result; |
| 133 for (const GURL& url : urls) { |
| 134 scoped_refptr<ServiceWorkerDevToolsAgentHost> host = |
| 135 GetMatchingServiceWorker(agent_hosts, url); |
| 136 if (host) |
| 137 result[host->GetId()] = host; |
| 138 } |
| 139 return result; |
| 140 } |
| 141 |
| 142 bool CollectURLs(std::set<GURL>* urls, FrameTreeNode* tree_node) { |
| 143 urls->insert(tree_node->current_url()); |
| 144 return false; |
| 145 } |
| 146 |
105 } // namespace | 147 } // namespace |
106 | 148 |
107 using Response = DevToolsProtocolClient::Response; | 149 using Response = DevToolsProtocolClient::Response; |
108 | 150 |
109 class ServiceWorkerHandler::ContextObserver | 151 class ServiceWorkerHandler::ContextObserver |
110 : public ServiceWorkerContextObserver, | 152 : public ServiceWorkerContextObserver, |
111 public base::RefCountedThreadSafe<ContextObserver> { | 153 public base::RefCountedThreadSafe<ContextObserver> { |
112 public: | 154 public: |
113 ContextObserver(scoped_refptr<ServiceWorkerContextWrapper> context, | 155 ContextObserver(scoped_refptr<ServiceWorkerContextWrapper> context, |
114 base::WeakPtr<ServiceWorkerHandler> handler); | 156 base::WeakPtr<ServiceWorkerHandler> handler); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 | 301 |
260 ServiceWorkerHandler::ServiceWorkerHandler() | 302 ServiceWorkerHandler::ServiceWorkerHandler() |
261 : enabled_(false), weak_factory_(this) { | 303 : enabled_(false), weak_factory_(this) { |
262 } | 304 } |
263 | 305 |
264 ServiceWorkerHandler::~ServiceWorkerHandler() { | 306 ServiceWorkerHandler::~ServiceWorkerHandler() { |
265 Disable(); | 307 Disable(); |
266 } | 308 } |
267 | 309 |
268 void ServiceWorkerHandler::SetRenderFrameHost( | 310 void ServiceWorkerHandler::SetRenderFrameHost( |
269 RenderFrameHost* render_frame_host) { | 311 RenderFrameHostImpl* render_frame_host) { |
| 312 render_frame_host_ = render_frame_host; |
| 313 // Do not call UpdateHosts yet, wait for load to commit. |
270 if (!render_frame_host) { | 314 if (!render_frame_host) { |
271 context_ = nullptr; | 315 context_ = nullptr; |
272 return; | 316 return; |
273 } | 317 } |
274 StoragePartition* partition = BrowserContext::GetStoragePartition( | 318 StoragePartition* partition = BrowserContext::GetStoragePartition( |
275 render_frame_host->GetProcess()->GetBrowserContext(), | 319 render_frame_host->GetProcess()->GetBrowserContext(), |
276 render_frame_host->GetSiteInstance()); | 320 render_frame_host->GetSiteInstance()); |
277 DCHECK(partition); | 321 DCHECK(partition); |
278 context_ = static_cast<ServiceWorkerContextWrapper*>( | 322 context_ = static_cast<ServiceWorkerContextWrapper*>( |
279 partition->GetServiceWorkerContext()); | 323 partition->GetServiceWorkerContext()); |
280 } | 324 } |
281 | 325 |
282 void ServiceWorkerHandler::SetClient(scoped_ptr<Client> client) { | 326 void ServiceWorkerHandler::SetClient(scoped_ptr<Client> client) { |
283 client_.swap(client); | 327 client_.swap(client); |
284 } | 328 } |
285 | 329 |
286 void ServiceWorkerHandler::SetURL(const GURL& url) { | 330 void ServiceWorkerHandler::UpdateHosts() { |
287 url_ = url; | 331 if (!enabled_) |
288 if (enabled_) { | 332 return; |
289 for (auto pair : attached_hosts_) { | |
290 if (!MatchesInspectedPage(pair.second.get())) | |
291 WorkerDestroyed(pair.second.get()); | |
292 } | |
293 | 333 |
294 ServiceWorkerDevToolsAgentHost::List agent_hosts; | 334 urls_.clear(); |
295 ServiceWorkerDevToolsManager::GetInstance()-> | 335 if (render_frame_host_) { |
296 AddAllAgentHosts(&agent_hosts); | 336 render_frame_host_->frame_tree_node()->frame_tree()->ForEach( |
297 for (auto host : agent_hosts) { | 337 base::Bind(&CollectURLs, &urls_)); |
298 if (!MatchesInspectedPage(host.get())) | 338 } |
299 continue; | 339 |
300 if (attached_hosts_.find(host->GetId()) != attached_hosts_.end()) | 340 ServiceWorkerDevToolsAgentHost::Map old_hosts = attached_hosts_; |
301 continue; | 341 ServiceWorkerDevToolsAgentHost::Map new_hosts = |
302 // TODO(pfeldman): workers are created concurrently, we need | 342 GetMatchingServiceWorkers(urls_); |
303 // to get notification earlier to go through the Created/Ready | 343 |
304 // lifecycle. | 344 for (auto pair : old_hosts) { |
305 WorkerReadyForInspection(host.get()); | 345 if (new_hosts.find(pair.first) == new_hosts.end()) |
306 } | 346 ReportWorkerTerminated(pair.second.get()); |
| 347 } |
| 348 |
| 349 for (auto pair : new_hosts) { |
| 350 if (old_hosts.find(pair.first) == old_hosts.end()) |
| 351 ReportWorkerCreated(pair.second.get()); |
307 } | 352 } |
308 } | 353 } |
309 | 354 |
310 void ServiceWorkerHandler::Detached() { | 355 void ServiceWorkerHandler::Detached() { |
311 Disable(); | 356 Disable(); |
312 } | 357 } |
313 | 358 |
314 Response ServiceWorkerHandler::Enable() { | 359 Response ServiceWorkerHandler::Enable() { |
315 if (enabled_) | 360 if (enabled_) |
316 return Response::OK(); | 361 return Response::OK(); |
317 if (!context_) | 362 if (!context_) |
318 return Response::InternalError("Could not connect to the context"); | 363 return Response::InternalError("Could not connect to the context"); |
319 enabled_ = true; | 364 enabled_ = true; |
320 | 365 |
321 ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this); | 366 ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this); |
322 | |
323 ServiceWorkerDevToolsAgentHost::List agent_hosts; | |
324 ServiceWorkerDevToolsManager::GetInstance()->AddAllAgentHosts(&agent_hosts); | |
325 for (auto host : agent_hosts) | |
326 WorkerReadyForInspection(host.get()); | |
327 | |
328 context_observer_ = new ContextObserver(context_, weak_factory_.GetWeakPtr()); | 367 context_observer_ = new ContextObserver(context_, weak_factory_.GetWeakPtr()); |
329 context_observer_->Start(); | 368 context_observer_->Start(); |
| 369 UpdateHosts(); |
330 return Response::OK(); | 370 return Response::OK(); |
331 } | 371 } |
332 | 372 |
333 Response ServiceWorkerHandler::Disable() { | 373 Response ServiceWorkerHandler::Disable() { |
334 if (!enabled_) | 374 if (!enabled_) |
335 return Response::OK(); | 375 return Response::OK(); |
336 enabled_ = false; | 376 enabled_ = false; |
337 | 377 |
338 ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this); | 378 ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this); |
339 for (const auto& pair : attached_hosts_) | 379 for (const auto& pair : attached_hosts_) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 } | 447 } |
408 | 448 |
409 void ServiceWorkerHandler::AgentHostClosed( | 449 void ServiceWorkerHandler::AgentHostClosed( |
410 DevToolsAgentHost* host, | 450 DevToolsAgentHost* host, |
411 bool replaced_with_another_client) { | 451 bool replaced_with_another_client) { |
412 WorkerDestroyed(static_cast<ServiceWorkerDevToolsAgentHost*>(host)); | 452 WorkerDestroyed(static_cast<ServiceWorkerDevToolsAgentHost*>(host)); |
413 } | 453 } |
414 | 454 |
415 void ServiceWorkerHandler::WorkerCreated( | 455 void ServiceWorkerHandler::WorkerCreated( |
416 ServiceWorkerDevToolsAgentHost* host) { | 456 ServiceWorkerDevToolsAgentHost* host) { |
417 if (!MatchesInspectedPage(host)) | 457 auto hosts = GetMatchingServiceWorkers(urls_); |
418 return; | 458 if (hosts.find(host->GetId()) != hosts.end()) |
419 host->PauseForDebugOnStart(); | 459 host->PauseForDebugOnStart(); |
420 } | 460 } |
421 | 461 |
422 void ServiceWorkerHandler::WorkerReadyForInspection( | 462 void ServiceWorkerHandler::WorkerReadyForInspection( |
423 ServiceWorkerDevToolsAgentHost* host) { | 463 ServiceWorkerDevToolsAgentHost* host) { |
424 if (host->IsAttached() || !MatchesInspectedPage(host)) | 464 UpdateHosts(); |
| 465 } |
| 466 |
| 467 void ServiceWorkerHandler::WorkerDestroyed( |
| 468 ServiceWorkerDevToolsAgentHost* host) { |
| 469 UpdateHosts(); |
| 470 } |
| 471 |
| 472 void ServiceWorkerHandler::ReportWorkerCreated( |
| 473 ServiceWorkerDevToolsAgentHost* host) { |
| 474 if (host->IsAttached()) |
425 return; | 475 return; |
426 | |
427 attached_hosts_[host->GetId()] = host; | 476 attached_hosts_[host->GetId()] = host; |
428 host->AttachClient(this); | 477 host->AttachClient(this); |
429 client_->WorkerCreated(WorkerCreatedParams::Create()-> | 478 client_->WorkerCreated(WorkerCreatedParams::Create()-> |
430 set_worker_id(host->GetId())-> | 479 set_worker_id(host->GetId())-> |
431 set_url(host->GetURL().spec())); | 480 set_url(host->GetURL().spec())); |
432 } | 481 } |
433 | 482 |
434 void ServiceWorkerHandler::WorkerDestroyed( | 483 void ServiceWorkerHandler::ReportWorkerTerminated( |
435 ServiceWorkerDevToolsAgentHost* host) { | 484 ServiceWorkerDevToolsAgentHost* host) { |
436 auto it = attached_hosts_.find(host->GetId()); | 485 auto it = attached_hosts_.find(host->GetId()); |
437 if (it == attached_hosts_.end()) | 486 if (it == attached_hosts_.end()) |
438 return; | 487 return; |
439 it->second->DetachClient(); | 488 it->second->DetachClient(); |
440 client_->WorkerTerminated(WorkerTerminatedParams::Create()-> | 489 client_->WorkerTerminated(WorkerTerminatedParams::Create()-> |
441 set_worker_id(host->GetId())); | 490 set_worker_id(host->GetId())); |
442 attached_hosts_.erase(it); | 491 attached_hosts_.erase(it); |
443 } | 492 } |
444 | 493 |
445 bool ServiceWorkerHandler::MatchesInspectedPage( | |
446 ServiceWorkerDevToolsAgentHost* host) { | |
447 // TODO(pfeldman): match based on scope. | |
448 // TODO(pfeldman): match iframes. | |
449 return host->GetURL().host() == url_.host(); | |
450 } | |
451 | |
452 } // namespace service_worker | 494 } // namespace service_worker |
453 } // namespace devtools | 495 } // namespace devtools |
454 } // namespace content | 496 } // namespace content |
OLD | NEW |