1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/browser/devtools/embedded_worker_devtools_manager.h" 6 7#include "content/browser/devtools/devtools_protocol.h" 8#include "content/browser/devtools/devtools_protocol_constants.h" 9#include "content/browser/devtools/embedded_worker_devtools_agent_host.h" 10#include "content/browser/devtools/ipc_devtools_agent_host.h" 11#include "content/browser/shared_worker/shared_worker_instance.h" 12#include "content/common/devtools_messages.h" 13#include "content/public/browser/browser_thread.h" 14#include "content/public/browser/render_process_host.h" 15#include "content/public/browser/worker_service.h" 16#include "ipc/ipc_listener.h" 17 18namespace content { 19 20// Called on the UI thread. 21// static 22scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForWorker( 23 int worker_process_id, 24 int worker_route_id) { 25 return EmbeddedWorkerDevToolsManager::GetInstance() 26 ->GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id); 27} 28 29EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier( 30 const ServiceWorkerContextCore* context, 31 base::WeakPtr<ServiceWorkerContextCore> context_weak, 32 int64 version_id, 33 const GURL& url) 34 : context_(context), 35 context_weak_(context_weak), 36 version_id_(version_id), 37 url_(url) { 38} 39 40EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier( 41 const ServiceWorkerIdentifier& other) 42 : context_(other.context_), 43 context_weak_(other.context_weak_), 44 version_id_(other.version_id_), 45 url_(other.url_) { 46} 47 48EmbeddedWorkerDevToolsManager:: 49ServiceWorkerIdentifier::~ServiceWorkerIdentifier() { 50} 51 52bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches( 53 const ServiceWorkerIdentifier& other) const { 54 return context_ == other.context_ && version_id_ == other.version_id_; 55} 56 57const ServiceWorkerContextCore* 58EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::context() const { 59 return context_; 60} 61 62base::WeakPtr<ServiceWorkerContextCore> 63EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::context_weak() const { 64 return context_weak_; 65} 66 67int64 68EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::version_id() const { 69 return version_id_; 70} 71 72GURL EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::url() const { 73 return url_; 74} 75 76// static 77EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() { 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 79 return Singleton<EmbeddedWorkerDevToolsManager>::get(); 80} 81 82DevToolsAgentHostImpl* 83EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker( 84 int worker_process_id, 85 int worker_route_id) { 86 AgentHostMap::iterator it = workers_.find( 87 WorkerId(worker_process_id, worker_route_id)); 88 return it == workers_.end() ? NULL : it->second; 89} 90 91EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager() 92 : debug_service_worker_on_start_(false) { 93} 94 95EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() { 96} 97 98bool EmbeddedWorkerDevToolsManager::SharedWorkerCreated( 99 int worker_process_id, 100 int worker_route_id, 101 const SharedWorkerInstance& instance) { 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 103 const WorkerId id(worker_process_id, worker_route_id); 104 AgentHostMap::iterator it = FindExistingSharedWorkerAgentHost(instance); 105 if (it == workers_.end()) { 106 workers_[id] = new EmbeddedWorkerDevToolsAgentHost(id, instance); 107 return false; 108 } 109 WorkerRestarted(id, it); 110 return true; 111} 112 113bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated( 114 int worker_process_id, 115 int worker_route_id, 116 const ServiceWorkerIdentifier& service_worker_id) { 117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 118 const WorkerId id(worker_process_id, worker_route_id); 119 AgentHostMap::iterator it = 120 FindExistingServiceWorkerAgentHost(service_worker_id); 121 if (it == workers_.end()) { 122 workers_[id] = new EmbeddedWorkerDevToolsAgentHost( 123 id, service_worker_id, debug_service_worker_on_start_); 124 return debug_service_worker_on_start_; 125 } 126 WorkerRestarted(id, it); 127 return true; 128} 129 130void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id, 131 int worker_route_id) { 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 133 const WorkerId id(worker_process_id, worker_route_id); 134 AgentHostMap::iterator it = workers_.find(id); 135 DCHECK(it != workers_.end()); 136 it->second->WorkerDestroyed(); 137} 138 139void EmbeddedWorkerDevToolsManager::WorkerReadyForInspection( 140 int worker_process_id, 141 int worker_route_id) { 142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 143 const WorkerId id(worker_process_id, worker_route_id); 144 AgentHostMap::iterator it = workers_.find(id); 145 DCHECK(it != workers_.end()); 146 it->second->WorkerReadyForInspection(); 147} 148 149void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id, 150 int worker_route_id) { 151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 152 const WorkerId id(worker_process_id, worker_route_id); 153 AgentHostMap::iterator it = workers_.find(id); 154 DCHECK(it != workers_.end()); 155 it->second->WorkerContextStarted(); 156} 157 158void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(WorkerId id) { 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 160 workers_.erase(id); 161} 162 163EmbeddedWorkerDevToolsManager::AgentHostMap::iterator 164EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerAgentHost( 165 const SharedWorkerInstance& instance) { 166 AgentHostMap::iterator it = workers_.begin(); 167 for (; it != workers_.end(); ++it) { 168 if (it->second->Matches(instance)) 169 break; 170 } 171 return it; 172} 173 174EmbeddedWorkerDevToolsManager::AgentHostMap::iterator 175EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerAgentHost( 176 const ServiceWorkerIdentifier& service_worker_id) { 177 AgentHostMap::iterator it = workers_.begin(); 178 for (; it != workers_.end(); ++it) { 179 if (it->second->Matches(service_worker_id)) 180 break; 181 } 182 return it; 183} 184 185DevToolsAgentHost::List 186EmbeddedWorkerDevToolsManager::GetOrCreateAllAgentHosts() { 187 DevToolsAgentHost::List result; 188 EmbeddedWorkerDevToolsManager* instance = GetInstance(); 189 for (AgentHostMap::iterator it = instance->workers_.begin(); 190 it != instance->workers_.end(); ++it) { 191 if (!it->second->IsTerminated()) 192 result.push_back(it->second); 193 } 194 return result; 195} 196 197void EmbeddedWorkerDevToolsManager::WorkerRestarted( 198 const WorkerId& id, 199 const AgentHostMap::iterator& it) { 200 EmbeddedWorkerDevToolsAgentHost* agent_host = it->second; 201 agent_host->WorkerRestarted(id); 202 workers_.erase(it); 203 workers_[id] = agent_host; 204} 205 206void EmbeddedWorkerDevToolsManager::ResetForTesting() { 207 workers_.clear(); 208} 209 210} // namespace content 211