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 18 namespace content { 19 20 // Called on the UI thread. 21 // static 22 scoped_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 29 EmbeddedWorkerDevToolsManager::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 40 EmbeddedWorkerDevToolsManager::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 48 EmbeddedWorkerDevToolsManager:: 49 ServiceWorkerIdentifier::~ServiceWorkerIdentifier() { 50 } 51 52 bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches( 53 const ServiceWorkerIdentifier& other) const { 54 return context_ == other.context_ && version_id_ == other.version_id_; 55 } 56 57 const ServiceWorkerContextCore* 58 EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::context() const { 59 return context_; 60 } 61 62 base::WeakPtr<ServiceWorkerContextCore> 63 EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::context_weak() const { 64 return context_weak_; 65 } 66 67 int64 68 EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::version_id() const { 69 return version_id_; 70 } 71 72 GURL EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::url() const { 73 return url_; 74 } 75 76 // static 77 EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() { 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 79 return Singleton<EmbeddedWorkerDevToolsManager>::get(); 80 } 81 82 DevToolsAgentHostImpl* 83 EmbeddedWorkerDevToolsManager::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 91 EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager() 92 : debug_service_worker_on_start_(false) { 93 } 94 95 EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() { 96 } 97 98 bool 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 113 bool 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 130 void 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 139 void 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 149 void 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 158 void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(WorkerId id) { 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 160 workers_.erase(id); 161 } 162 163 EmbeddedWorkerDevToolsManager::AgentHostMap::iterator 164 EmbeddedWorkerDevToolsManager::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 174 EmbeddedWorkerDevToolsManager::AgentHostMap::iterator 175 EmbeddedWorkerDevToolsManager::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 185 DevToolsAgentHost::List 186 EmbeddedWorkerDevToolsManager::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 197 void 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 206 void EmbeddedWorkerDevToolsManager::ResetForTesting() { 207 workers_.clear(); 208 } 209 210 } // namespace content 211