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