Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1084)

Side by Side Diff: content/browser/devtools/shared_worker_devtools_manager.cc

Issue 196503005: Make DevTools support for the embedded SharedWorker. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add comments Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/worker_devtools_manager.h" 5 #include "content/browser/devtools/shared_worker_devtools_manager.h"
6 6
7 #include <list>
8 #include <map>
9
10 #include "base/bind.h"
11 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/logging.h"
9 #include "base/memory/singleton.h"
kinuko 2014/03/24 12:24:02 nit: we already have this in .h
horo 2014/03/25 06:28:17 Done.
12 #include "content/browser/devtools/devtools_manager_impl.h" 10 #include "content/browser/devtools/devtools_manager_impl.h"
13 #include "content/browser/devtools/devtools_protocol.h" 11 #include "content/browser/devtools/devtools_protocol.h"
14 #include "content/browser/devtools/devtools_protocol_constants.h" 12 #include "content/browser/devtools/devtools_protocol_constants.h"
15 #include "content/browser/devtools/ipc_devtools_agent_host.h" 13 #include "content/browser/devtools/ipc_devtools_agent_host.h"
16 #include "content/browser/devtools/worker_devtools_message_filter.h" 14 #include "content/browser/shared_worker/shared_worker_instance.h"
17 #include "content/browser/worker_host/worker_service_impl.h"
18 #include "content/common/devtools_messages.h" 15 #include "content/common/devtools_messages.h"
19 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/child_process_data.h" 17 #include "content/public/browser/render_process_host.h"
21 #include "content/public/common/process_type.h" 18 #include "content/public/browser/worker_service.h"
19 #include "ipc/ipc_listener.h"
22 20
23 namespace content { 21 namespace content {
24 22
25 // Called on the UI thread.
26 // static
27 scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForWorker(
28 int worker_process_id,
29 int worker_route_id) {
30 return WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
31 worker_process_id,
32 worker_route_id);
33 }
34
35 namespace { 23 namespace {
36 24
37 typedef std::map<WorkerDevToolsManager::WorkerId, 25 typedef std::map<SharedWorkerDevToolsManager::WorkerId,
38 WorkerDevToolsManager::WorkerDevToolsAgentHost*> AgentHosts; 26 SharedWorkerDevToolsManager::SharedWorkerDevToolsAgentHost*>
27 AgentHosts;
39 base::LazyInstance<AgentHosts>::Leaky g_agent_map = LAZY_INSTANCE_INITIALIZER; 28 base::LazyInstance<AgentHosts>::Leaky g_agent_map = LAZY_INSTANCE_INITIALIZER;
40 base::LazyInstance<AgentHosts>::Leaky g_orphan_map = LAZY_INSTANCE_INITIALIZER; 29 base::LazyInstance<AgentHosts>::Leaky g_orphan_map = LAZY_INSTANCE_INITIALIZER;
41 30
31 bool SendMessageToWorker(const SharedWorkerDevToolsManager::WorkerId& worker_id,
32 IPC::Message* message) {
33 RenderProcessHost* host = RenderProcessHost::FromID(worker_id.first);
34 if (!host) {
35 delete message;
36 return false;
37 }
38 message->set_routing_id(worker_id.second);
39 host->Send(message);
40 return true;
41 }
42
42 } // namespace 43 } // namespace
43 44
44 struct WorkerDevToolsManager::TerminatedInspectedWorker { 45 class SharedWorkerDevToolsManager::SharedWorkerDevToolsAgentHost
45 TerminatedInspectedWorker(WorkerId id, 46 : public IPCDevToolsAgentHost,
46 const GURL& url, 47 public IPC::Listener {
47 const base::string16& name) 48 public:
48 : old_worker_id(id), 49 SharedWorkerDevToolsAgentHost(WorkerId worker_id)
49 worker_url(url), 50 : has_worker_id_(false) {
50 worker_name(name) {} 51 SetWorkerId(worker_id, false);
kinuko 2014/03/24 12:24:02 nit: can you add '/* reattach */' comment after 'f
horo 2014/03/25 06:28:17 Done.
51 WorkerId old_worker_id; 52 }
53 // IPCDevToolsAgentHost implementation.
54 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
55 SendMessageToWorker(worker_id_, message);
56 }
57 virtual void OnClientAttached() OVERRIDE {}
58 virtual void OnClientDetached() OVERRIDE {}
59
60 // IPC::Listener implementation.
61 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63 bool handled = true;
64 IPC_BEGIN_MESSAGE_MAP(SharedWorkerDevToolsAgentHost, msg)
65 IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
66 OnDispatchOnInspectorFrontend)
67 IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
68 OnSaveAgentRumtimeState)
kinuko 2014/03/24 12:24:02 typo: Rumtime -> Runtime
horo 2014/03/25 06:28:17 Done.
69 IPC_MESSAGE_UNHANDLED(handled = false)
70 IPC_END_MESSAGE_MAP()
71 return handled;
72 }
73
74 void OnDispatchOnInspectorFrontend(const std::string& message) {
75 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this,
76 message);
kinuko 2014/03/24 12:24:02 indent is off
horo 2014/03/25 06:28:17 Done.
77 }
kinuko 2014/03/24 12:24:02 nit: please have an empty line between methods unl
horo 2014/03/25 06:28:17 Done. Moved to private.
78 void OnSaveAgentRumtimeState(const std::string& state) {
79 SaveAgentRuntimeState(state);
kinuko 2014/03/24 12:24:02 nit: as far as this is the only place we call it,
horo 2014/03/25 06:28:17 Done.
80 }
81
82 void SetWorkerId(WorkerId worker_id, bool reattach) {
83 if (!SharedWorkerDevToolsManager::GetInstance()
84 ->ConnectDevToolsAgentHostToWorker(worker_id)) {
85 NotifyCloseListener();
86 return;
87 }
88 worker_id_ = worker_id;
89 if (!has_worker_id_) {
90 AddRef(); // Balanced in ResetWorkerId.
91 }
kinuko 2014/03/24 12:24:02 nit: no need of { } for single-line body
horo 2014/03/25 06:28:17 Done.
92 has_worker_id_ = true;
93 g_agent_map.Get()[worker_id_] = this;
94
95 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
96 host->AddRoute(worker_id_.second, this);
97
98 if (reattach)
99 Reattach(state_);
100 }
101
102 void ResetWorkerId() {
103 CHECK(has_worker_id_);
104 g_agent_map.Get().erase(worker_id_);
105 has_worker_id_ = false;
106 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
107 host->RemoveRoute(worker_id_.second);
108 Release(); // Balanced in SetWorkerId.
109 }
110
111 void SaveAgentRuntimeState(const std::string& state) { state_ = state; }
112
113 private:
114 virtual ~SharedWorkerDevToolsAgentHost() {
115 if (has_worker_id_) {
kinuko 2014/03/24 12:24:02 Could we reach here other without going through Re
horo 2014/03/25 06:28:17 Done. We should call RemoveInspectedWorkerData and
116 SharedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(
117 worker_id_);
118 g_agent_map.Get().erase(worker_id_);
119 g_orphan_map.Get().erase(worker_id_);
120 if (RenderProcessHost* host =
121 RenderProcessHost::FromID(worker_id_.first)) {
122 host->RemoveRoute(worker_id_.second);
123 }
124 }
125 }
kinuko 2014/03/24 12:24:02 nit: can we have one empty line here?
horo 2014/03/25 06:28:17 Done.
126 bool has_worker_id_;
127 WorkerId worker_id_;
128 std::string state_;
129 DISALLOW_COPY_AND_ASSIGN(SharedWorkerDevToolsAgentHost);
130 };
131
132 struct SharedWorkerDevToolsManager::WorkerInfo {
133 WorkerInfo(WorkerId id, const GURL& url, const base::string16& name)
134 : worker_id(id), worker_url(url), worker_name(name) {}
135 WorkerId worker_id;
52 GURL worker_url; 136 GURL worker_url;
53 base::string16 worker_name; 137 base::string16 worker_name;
54 }; 138 };
55 139
56
57 class WorkerDevToolsManager::WorkerDevToolsAgentHost
58 : public IPCDevToolsAgentHost {
59 public:
60 explicit WorkerDevToolsAgentHost(WorkerId worker_id)
61 : has_worker_id_(false) {
62 SetWorkerId(worker_id, false);
63 }
64
65 void SetWorkerId(WorkerId worker_id, bool reattach) {
66 worker_id_ = worker_id;
67 if (!has_worker_id_)
68 AddRef(); // Balanced in ResetWorkerId.
69 has_worker_id_ = true;
70 g_agent_map.Get()[worker_id_] = this;
71
72 BrowserThread::PostTask(
73 BrowserThread::IO,
74 FROM_HERE,
75 base::Bind(
76 &ConnectToWorker,
77 worker_id.first,
78 worker_id.second));
79
80 if (reattach)
81 Reattach(state_);
82 }
83
84 void ResetWorkerId() {
85 g_agent_map.Get().erase(worker_id_);
86 has_worker_id_ = false;
87 Release(); // Balanced in SetWorkerId.
88 }
89
90 void SaveAgentRuntimeState(const std::string& state) {
91 state_ = state;
92 }
93
94 void ConnectionFailed() {
95 NotifyCloseListener();
96 // Object can be deleted here.
97 }
98
99 private:
100 virtual ~WorkerDevToolsAgentHost();
101
102 static void ConnectToWorker(
103 int worker_process_id,
104 int worker_route_id) {
105 WorkerDevToolsManager::GetInstance()->ConnectDevToolsAgentHostToWorker(
106 worker_process_id, worker_route_id);
107 }
108
109 static void ForwardToWorkerDevToolsAgent(
110 int worker_process_id,
111 int worker_route_id,
112 IPC::Message* message) {
113 WorkerDevToolsManager::GetInstance()->ForwardToWorkerDevToolsAgent(
114 worker_process_id, worker_route_id, *message);
115 }
116
117 // IPCDevToolsAgentHost implementation.
118 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
119 if (!has_worker_id_) {
120 delete message;
121 return;
122 }
123 BrowserThread::PostTask(
124 BrowserThread::IO, FROM_HERE,
125 base::Bind(
126 &WorkerDevToolsAgentHost::ForwardToWorkerDevToolsAgent,
127 worker_id_.first,
128 worker_id_.second,
129 base::Owned(message)));
130 }
131
132 virtual void OnClientAttached() OVERRIDE {}
133 virtual void OnClientDetached() OVERRIDE {}
134
135 bool has_worker_id_;
136 WorkerId worker_id_;
137 std::string state_;
138
139 DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsAgentHost);
140 };
141
142
143 class WorkerDevToolsManager::DetachedClientHosts {
144 public:
145 static void WorkerReloaded(WorkerId old_id, WorkerId new_id) {
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
147 AgentHosts::iterator it = g_orphan_map.Get().find(old_id);
148 if (it != g_orphan_map.Get().end()) {
149 it->second->SetWorkerId(new_id, true);
150 g_orphan_map.Get().erase(old_id);
151 return;
152 }
153 RemovePendingWorkerData(old_id);
154 }
155
156 static void WorkerDestroyed(WorkerId id) {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
158 AgentHosts::iterator it = g_agent_map.Get().find(id);
159 if (it == g_agent_map.Get().end()) {
160 RemovePendingWorkerData(id);
161 return;
162 }
163
164 WorkerDevToolsAgentHost* agent = it->second;
165 DevToolsManagerImpl* devtools_manager = DevToolsManagerImpl::GetInstance();
166 if (!agent->IsAttached()) {
167 // Agent has no client hosts -> delete it.
168 RemovePendingWorkerData(id);
169 return;
170 }
171
172 // Client host is debugging this worker agent host.
173 std::string notification = DevToolsProtocol::CreateNotification(
174 devtools::Worker::disconnectedFromWorker::kName, NULL)->Serialize();
175 devtools_manager->DispatchOnInspectorFrontend(agent, notification);
176 g_orphan_map.Get()[id] = agent;
177 agent->ResetWorkerId();
178 }
179
180 static void RemovePendingWorkerData(WorkerId id) {
181 BrowserThread::PostTask(
182 BrowserThread::IO, FROM_HERE,
183 base::Bind(&RemoveInspectedWorkerDataOnIOThread, id));
184 }
185
186 private:
187 DetachedClientHosts() {}
188 ~DetachedClientHosts() {}
189
190 static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) {
191 WorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(id);
192 }
193 };
194
195 struct WorkerDevToolsManager::InspectedWorker {
196 InspectedWorker(WorkerProcessHost* host, int route_id, const GURL& url,
197 const base::string16& name)
198 : host(host),
199 route_id(route_id),
200 worker_url(url),
201 worker_name(name) {}
202 WorkerProcessHost* const host;
203 int const route_id;
204 GURL worker_url;
205 base::string16 worker_name;
206 };
207
208 // static 140 // static
209 WorkerDevToolsManager* WorkerDevToolsManager::GetInstance() { 141 SharedWorkerDevToolsManager* SharedWorkerDevToolsManager::GetInstance() {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 142 DCHECK(WorkerService::EmbeddedSharedWorkerEnabled());
211 return Singleton<WorkerDevToolsManager>::get(); 143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
144 return Singleton<SharedWorkerDevToolsManager>::get();
212 } 145 }
213 146
214 // static 147 // static
215 DevToolsAgentHost* WorkerDevToolsManager::GetDevToolsAgentHostForWorker( 148 DevToolsAgentHost* SharedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
216 int worker_process_id, 149 int worker_process_id,
217 int worker_route_id) { 150 int worker_route_id) {
151 DCHECK(WorkerService::EmbeddedSharedWorkerEnabled());
218 WorkerId id(worker_process_id, worker_route_id); 152 WorkerId id(worker_process_id, worker_route_id);
219 AgentHosts::iterator it = g_agent_map.Get().find(id); 153 AgentHosts::iterator it = g_agent_map.Get().find(id);
220 if (it == g_agent_map.Get().end()) 154 if (it == g_agent_map.Get().end())
221 return new WorkerDevToolsAgentHost(id); 155 return new SharedWorkerDevToolsAgentHost(id);
kinuko 2014/03/24 12:24:02 It looks we could return a new refptr without stor
horo 2014/03/25 06:28:17 It is OK. When ConnectDevToolsAgentHostToWorker fa
222 return it->second; 156 return it->second;
223 } 157 }
224 158
225 WorkerDevToolsManager::WorkerDevToolsManager() { 159 // static
226 } 160 bool SharedWorkerDevToolsManager::HasDevToolsAgentHostForWorker(
227 161 int worker_process_id,
228 WorkerDevToolsManager::~WorkerDevToolsManager() {
229 }
230
231 void WorkerDevToolsManager::WorkerCreated(
232 WorkerProcessHost* worker,
233 const WorkerProcessHost::WorkerInstance& instance) {
234 for (TerminatedInspectedWorkers::iterator it = terminated_workers_.begin();
235 it != terminated_workers_.end(); ++it) {
236 if (instance.Matches(it->worker_url, it->worker_name,
237 instance.partition(),
238 instance.resource_context())) {
239 worker->Send(new DevToolsAgentMsg_PauseWorkerContextOnStart(
240 instance.worker_route_id()));
241 WorkerId new_worker_id(worker->GetData().id, instance.worker_route_id());
242 paused_workers_[new_worker_id] = it->old_worker_id;
243 terminated_workers_.erase(it);
244 return;
245 }
246 }
247 }
248
249 void WorkerDevToolsManager::WorkerDestroyed(
250 WorkerProcessHost* worker,
251 int worker_route_id) { 162 int worker_route_id) {
252 InspectedWorkersList::iterator it = FindInspectedWorker( 163 DCHECK(WorkerService::EmbeddedSharedWorkerEnabled());
253 worker->GetData().id, 164 WorkerId id(worker_process_id, worker_route_id);
254 worker_route_id); 165 return g_agent_map.Get().find(id) != g_agent_map.Get().end();
166 }
167
168 SharedWorkerDevToolsManager::SharedWorkerDevToolsManager() {}
169
170 SharedWorkerDevToolsManager::~SharedWorkerDevToolsManager() {}
171
172 void SharedWorkerDevToolsManager::WorkerCreated(int worker_process_id,
173 int worker_route_id,
174 const GURL& url,
175 const base::string16& name) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
177 const WorkerId id(worker_process_id, worker_route_id);
178 WorkerInfoMap::iterator it = FindTerminatedWorker(url, name);
179 if (it != terminated_workers_.end()) {
180 scoped_ptr<WorkerInfo> info = terminated_workers_.take_and_erase(it);
181 WorkerId old_id = info->worker_id;
182 AgentHosts::iterator orphan_agent_host_it = g_orphan_map.Get().find(old_id);
183 if (orphan_agent_host_it != g_orphan_map.Get().end()) {
184 g_agent_map.Get()[id] = orphan_agent_host_it->second;
185 }
186 paused_workers_.set(id, info.Pass());
187 SendMessageToWorker(
188 id, new DevToolsAgentMsg_PauseWorkerContextOnStart(worker_route_id));
189 } else {
190 scoped_ptr<WorkerInfo> info(new WorkerInfo(id, url, name));
191 uninspected_workers_.set(id, info.Pass());
192 }
193 }
194
195 void SharedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
196 int worker_route_id) {
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
198 const WorkerId id(worker_process_id, worker_route_id);
199 if (uninspected_workers_.erase(id))
200 return;
201 WorkerInfoMap::iterator it = inspected_workers_.find(id);
255 if (it == inspected_workers_.end()) 202 if (it == inspected_workers_.end())
256 return; 203 return;
257 204 scoped_ptr<WorkerInfo> info = inspected_workers_.take_and_erase(it);
258 WorkerId worker_id(worker->GetData().id, worker_route_id); 205
259 terminated_workers_.push_back(TerminatedInspectedWorker( 206 AgentHosts::iterator agent_host_it = g_agent_map.Get().find(id);
260 worker_id, 207 if (agent_host_it == g_agent_map.Get().end())
261 it->worker_url, 208 return;
262 it->worker_name)); 209
263 inspected_workers_.erase(it); 210 if (!agent_host_it->second->IsAttached()) {
264 BrowserThread::PostTask( 211 RemoveInspectedWorkerData(id);
265 BrowserThread::UI, FROM_HERE, 212 agent_host_it->second->ResetWorkerId();
266 base::Bind(&DetachedClientHosts::WorkerDestroyed, worker_id)); 213 return;
267 } 214 }
268 215
269 void WorkerDevToolsManager::WorkerContextStarted(WorkerProcessHost* process, 216 // Client host is debugging this worker agent host.
270 int worker_route_id) { 217 std::string notification =
271 WorkerId new_worker_id(process->GetData().id, worker_route_id); 218 DevToolsProtocol::CreateNotification(
272 PausedWorkers::iterator it = paused_workers_.find(new_worker_id); 219 devtools::Worker::disconnectedFromWorker::kName, NULL)->Serialize();
220 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
221 agent_host_it->second, notification);
222 terminated_workers_.set(id, info.Pass());
223 g_orphan_map.Get()[id] = agent_host_it->second;
224 agent_host_it->second->ResetWorkerId();
225 }
226
227 void SharedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
228 int worker_route_id) {
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
230 const WorkerId id(worker_process_id, worker_route_id);
231 WorkerInfoMap::iterator it = paused_workers_.find(id);
273 if (it == paused_workers_.end()) 232 if (it == paused_workers_.end())
274 return; 233 return;
275 234 scoped_ptr<WorkerInfo> info = paused_workers_.take_and_erase(it);
276 BrowserThread::PostTask( 235 const WorkerId old_id(info->worker_id);
277 BrowserThread::UI, FROM_HERE, 236 info->worker_id = id;
278 base::Bind( 237 uninspected_workers_.set(id, info.Pass());
279 &DetachedClientHosts::WorkerReloaded, 238
280 it->second, 239 AgentHosts::iterator orphan_agent_host_it = g_orphan_map.Get().find(old_id);
281 new_worker_id)); 240 if (orphan_agent_host_it == g_orphan_map.Get().end())
282 paused_workers_.erase(it); 241 return;
283 } 242 orphan_agent_host_it->second->SetWorkerId(id, true);
284 243 g_orphan_map.Get().erase(old_id);
285 void WorkerDevToolsManager::RemoveInspectedWorkerData( 244 g_agent_map.Get().erase(old_id);
286 const WorkerId& id) { 245 }
287 for (TerminatedInspectedWorkers::iterator it = terminated_workers_.begin(); 246
288 it != terminated_workers_.end(); ++it) { 247 bool SharedWorkerDevToolsManager::ConnectDevToolsAgentHostToWorker(
289 if (it->old_worker_id == id) { 248 const WorkerId& worker_id) {
290 terminated_workers_.erase(it); 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
291 return; 250 WorkerInfoMap::iterator it = uninspected_workers_.find(worker_id);
292 } 251 if (it == uninspected_workers_.end())
293 } 252 return false;
294 253 inspected_workers_.set(worker_id, uninspected_workers_.take_and_erase(it));
295 for (PausedWorkers::iterator it = paused_workers_.begin(); 254 return true;
296 it != paused_workers_.end(); ++it) { 255 }
297 if (it->second == id) { 256
298 SendResumeToWorker(it->first); 257 void SharedWorkerDevToolsManager::RemoveInspectedWorkerData(
258 const WorkerId& worker_id) {
259 if (terminated_workers_.erase(worker_id))
260 return;
261
262 for (WorkerInfoMap::iterator it = paused_workers_.begin();
263 it != paused_workers_.end();
264 ++it) {
265 if (it->second->worker_id == worker_id) {
266 SendMessageToWorker(
267 it->first,
268 new DevToolsAgentMsg_ResumeWorkerContext(it->first.second));
299 paused_workers_.erase(it); 269 paused_workers_.erase(it);
300 return; 270 return;
301 } 271 }
302 } 272 }
303 } 273 }
304 274
305 WorkerDevToolsManager::InspectedWorkersList::iterator 275 SharedWorkerDevToolsManager::WorkerInfoMap::iterator
306 WorkerDevToolsManager::FindInspectedWorker( 276 SharedWorkerDevToolsManager::FindTerminatedWorker(const GURL& url,
307 int host_id, int route_id) { 277 const base::string16& name) {
308 InspectedWorkersList::iterator it = inspected_workers_.begin(); 278 WorkerInfoMap::iterator it = terminated_workers_.begin();
309 while (it != inspected_workers_.end()) { 279 for (; it != terminated_workers_.end(); ++it) {
310 if (it->host->GetData().id == host_id && it->route_id == route_id) 280 if (SharedWorkerInstance::UrlNameMatches(it->second->worker_url,
281 it->second->worker_name,
282 url,
283 name)) {
311 break; 284 break;
312 ++it; 285 }
313 } 286 }
314 return it; 287 return it;
315 } 288 }
316 289
317 static WorkerProcessHost* FindWorkerProcess(int worker_process_id) {
318 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
319 if (iter.GetData().id == worker_process_id)
320 return *iter;
321 }
322 return NULL;
323 }
324
325 void WorkerDevToolsManager::ConnectDevToolsAgentHostToWorker(
326 int worker_process_id,
327 int worker_route_id) {
328 if (WorkerProcessHost* process = FindWorkerProcess(worker_process_id)) {
329 const WorkerProcessHost::Instances& instances = process->instances();
330 for (WorkerProcessHost::Instances::const_iterator i = instances.begin();
331 i != instances.end(); ++i) {
332 if (i->worker_route_id() == worker_route_id) {
333 DCHECK(FindInspectedWorker(worker_process_id, worker_route_id) ==
334 inspected_workers_.end());
335 inspected_workers_.push_back(
336 InspectedWorker(process, worker_route_id, i->url(), i->name()));
337 return;
338 }
339 }
340 }
341 NotifyConnectionFailedOnIOThread(worker_process_id, worker_route_id);
342 }
343
344 void WorkerDevToolsManager::ForwardToDevToolsClient(
345 int worker_process_id,
346 int worker_route_id,
347 const std::string& message) {
348 if (FindInspectedWorker(worker_process_id, worker_route_id) ==
349 inspected_workers_.end()) {
350 NOTREACHED();
351 return;
352 }
353 BrowserThread::PostTask(
354 BrowserThread::UI, FROM_HERE,
355 base::Bind(
356 &ForwardToDevToolsClientOnUIThread,
357 worker_process_id,
358 worker_route_id,
359 message));
360 }
361
362 void WorkerDevToolsManager::SaveAgentRuntimeState(int worker_process_id,
363 int worker_route_id,
364 const std::string& state) {
365 BrowserThread::PostTask(
366 BrowserThread::UI, FROM_HERE,
367 base::Bind(
368 &SaveAgentRuntimeStateOnUIThread,
369 worker_process_id,
370 worker_route_id,
371 state));
372 }
373
374 void WorkerDevToolsManager::ForwardToWorkerDevToolsAgent(
375 int worker_process_id,
376 int worker_route_id,
377 const IPC::Message& message) {
378 InspectedWorkersList::iterator it = FindInspectedWorker(
379 worker_process_id,
380 worker_route_id);
381 if (it == inspected_workers_.end())
382 return;
383 IPC::Message* msg = new IPC::Message(message);
384 msg->set_routing_id(worker_route_id);
385 it->host->Send(msg);
386 }
387
388 // static
389 void WorkerDevToolsManager::ForwardToDevToolsClientOnUIThread(
390 int worker_process_id,
391 int worker_route_id,
392 const std::string& message) {
393 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id,
394 worker_route_id));
395 if (it == g_agent_map.Get().end())
396 return;
397 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(it->second,
398 message);
399 }
400
401 // static
402 void WorkerDevToolsManager::SaveAgentRuntimeStateOnUIThread(
403 int worker_process_id,
404 int worker_route_id,
405 const std::string& state) {
406 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id,
407 worker_route_id));
408 if (it == g_agent_map.Get().end())
409 return;
410 it->second->SaveAgentRuntimeState(state);
411 }
412
413 // static
414 void WorkerDevToolsManager::NotifyConnectionFailedOnIOThread(
415 int worker_process_id,
416 int worker_route_id) {
417 BrowserThread::PostTask(
418 BrowserThread::UI, FROM_HERE,
419 base::Bind(
420 &WorkerDevToolsManager::NotifyConnectionFailedOnUIThread,
421 worker_process_id,
422 worker_route_id));
423 }
424
425 // static
426 void WorkerDevToolsManager::NotifyConnectionFailedOnUIThread(
427 int worker_process_id,
428 int worker_route_id) {
429 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id,
430 worker_route_id));
431 if (it != g_agent_map.Get().end())
432 it->second->ConnectionFailed();
433 }
434
435 // static
436 void WorkerDevToolsManager::SendResumeToWorker(const WorkerId& id) {
437 if (WorkerProcessHost* process = FindWorkerProcess(id.first))
438 process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second));
439 }
440
441 WorkerDevToolsManager::WorkerDevToolsAgentHost::~WorkerDevToolsAgentHost() {
442 DetachedClientHosts::RemovePendingWorkerData(worker_id_);
443 g_agent_map.Get().erase(worker_id_);
444 g_orphan_map.Get().erase(worker_id_);
445 }
446
447 } // namespace content 290 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698