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

Side by Side Diff: content/browser/debugger/worker_devtools_manager.cc

Issue 11630004: DevTools: rename debugger/ to devtools/, move DevTools files into content/renderer/devtools. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: For landing Created 8 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/debugger/worker_devtools_manager.h"
6
7 #include <list>
8 #include <map>
9
10 #include "base/bind.h"
11 #include "content/browser/debugger/devtools_agent_host.h"
12 #include "content/browser/debugger/devtools_manager_impl.h"
13 #include "content/browser/debugger/worker_devtools_message_filter.h"
14 #include "content/browser/worker_host/worker_service_impl.h"
15 #include "content/common/devtools_messages.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/child_process_data.h"
18 #include "content/public/browser/devtools_agent_host_registry.h"
19 #include "content/public/common/process_type.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h "
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
23
24 namespace content {
25
26 // Called on the UI thread.
27 // static
28 DevToolsAgentHost* DevToolsAgentHostRegistry::GetDevToolsAgentHostForWorker(
29 int worker_process_id,
30 int worker_route_id) {
31 return WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
32 worker_process_id,
33 worker_route_id);
34 }
35
36 class WorkerDevToolsManager::AgentHosts {
37 public:
38 static void Add(WorkerId id, WorkerDevToolsAgentHost* host) {
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40 if (!instance_)
41 instance_ = new AgentHosts();
42 instance_->map_[id] = host;
43 }
44 static void Remove(WorkerId id) {
45 DCHECK(instance_);
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
47 Instances& map = instance_->map_;
48 map.erase(id);
49 if (map.empty()) {
50 delete instance_;
51 instance_ = NULL;
52 }
53 }
54
55 static WorkerDevToolsAgentHost* GetAgentHost(WorkerId id) {
56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
57 if (!instance_)
58 return NULL;
59 Instances& map = instance_->map_;
60 Instances::iterator it = map.find(id);
61 if (it == map.end())
62 return NULL;
63 return it->second;
64 }
65
66 private:
67 AgentHosts() {
68 }
69 ~AgentHosts() {}
70
71 static AgentHosts* instance_;
72 typedef std::map<WorkerId, WorkerDevToolsAgentHost*> Instances;
73 Instances map_;
74 };
75
76 WorkerDevToolsManager::AgentHosts*
77 WorkerDevToolsManager::AgentHosts::instance_ = NULL;
78
79
80 struct WorkerDevToolsManager::TerminatedInspectedWorker {
81 TerminatedInspectedWorker(WorkerId id, const GURL& url, const string16& name)
82 : old_worker_id(id),
83 worker_url(url),
84 worker_name(name) {}
85 WorkerId old_worker_id;
86 GURL worker_url;
87 string16 worker_name;
88 };
89
90
91 class WorkerDevToolsManager::WorkerDevToolsAgentHost
92 : public DevToolsAgentHost {
93 public:
94 explicit WorkerDevToolsAgentHost(WorkerId worker_id)
95 : worker_id_(worker_id) {
96 AgentHosts::Add(worker_id, this);
97 BrowserThread::PostTask(
98 BrowserThread::IO,
99 FROM_HERE,
100 base::Bind(
101 &RegisterAgent,
102 worker_id.first,
103 worker_id.second));
104 }
105
106 void WorkerDestroyed() {
107 NotifyCloseListener();
108 delete this;
109 }
110
111 private:
112 virtual ~WorkerDevToolsAgentHost() {
113 AgentHosts::Remove(worker_id_);
114 }
115
116 static void RegisterAgent(
117 int worker_process_id,
118 int worker_route_id) {
119 WorkerDevToolsManager::GetInstance()->RegisterDevToolsAgentHostForWorker(
120 worker_process_id, worker_route_id);
121 }
122
123 static void ForwardToWorkerDevToolsAgent(
124 int worker_process_id,
125 int worker_route_id,
126 IPC::Message* message) {
127 WorkerDevToolsManager::GetInstance()->ForwardToWorkerDevToolsAgent(
128 worker_process_id, worker_route_id, *message);
129 }
130
131 // DevToolsAgentHost implementation.
132 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
133 BrowserThread::PostTask(
134 BrowserThread::IO, FROM_HERE,
135 base::Bind(
136 &WorkerDevToolsAgentHost::ForwardToWorkerDevToolsAgent,
137 worker_id_.first,
138 worker_id_.second,
139 base::Owned(message)));
140 }
141 virtual void NotifyClientAttaching() OVERRIDE {}
142 virtual void NotifyClientDetaching() OVERRIDE {}
143 virtual int GetRenderProcessId() OVERRIDE { return -1; }
144
145 WorkerId worker_id_;
146
147 DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsAgentHost);
148 };
149
150
151 class WorkerDevToolsManager::DetachedClientHosts {
152 public:
153 static void WorkerReloaded(WorkerId old_id, WorkerId new_id) {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
155 if (instance_ && instance_->ReattachClient(old_id, new_id))
156 return;
157 RemovePendingWorkerData(old_id);
158 }
159
160 static void WorkerDestroyed(WorkerId id) {
161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
162 WorkerDevToolsAgentHost* agent = AgentHosts::GetAgentHost(id);
163 if (!agent) {
164 RemovePendingWorkerData(id);
165 return;
166 }
167 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
168 agent,
169 WebKit::WebDevToolsAgent::workerDisconnectedFromWorkerEvent().utf8());
170 int cookie = DevToolsManagerImpl::GetInstance()->DetachClientHost(agent);
171 agent->WorkerDestroyed();
172 if (cookie == -1) {
173 RemovePendingWorkerData(id);
174 return;
175 }
176 if (!instance_)
177 new DetachedClientHosts();
178 instance_->worker_id_to_cookie_[id] = cookie;
179 }
180
181 private:
182 DetachedClientHosts() {
183 instance_ = this;
184 }
185 ~DetachedClientHosts() {
186 instance_ = NULL;
187 }
188
189 bool ReattachClient(WorkerId old_id, WorkerId new_id) {
190 WorkerIdToCookieMap::iterator it = worker_id_to_cookie_.find(old_id);
191 if (it == worker_id_to_cookie_.end())
192 return false;
193 DevToolsAgentHost* agent =
194 WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
195 new_id.first,
196 new_id.second);
197 DevToolsManagerImpl::GetInstance()->AttachClientHost(
198 it->second,
199 agent);
200 worker_id_to_cookie_.erase(it);
201 if (worker_id_to_cookie_.empty())
202 delete this;
203 return true;
204 }
205
206 static void RemovePendingWorkerData(WorkerId id) {
207 BrowserThread::PostTask(
208 BrowserThread::IO, FROM_HERE,
209 base::Bind(&RemoveInspectedWorkerDataOnIOThread, id));
210 }
211
212 static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) {
213 WorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(id);
214 }
215
216 static DetachedClientHosts* instance_;
217 typedef std::map<WorkerId, int> WorkerIdToCookieMap;
218 WorkerIdToCookieMap worker_id_to_cookie_;
219 };
220
221 WorkerDevToolsManager::DetachedClientHosts*
222 WorkerDevToolsManager::DetachedClientHosts::instance_ = NULL;
223
224 struct WorkerDevToolsManager::InspectedWorker {
225 InspectedWorker(WorkerProcessHost* host, int route_id, const GURL& url,
226 const string16& name)
227 : host(host),
228 route_id(route_id),
229 worker_url(url),
230 worker_name(name) {}
231 WorkerProcessHost* const host;
232 int const route_id;
233 GURL worker_url;
234 string16 worker_name;
235 };
236
237 // static
238 WorkerDevToolsManager* WorkerDevToolsManager::GetInstance() {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
240 return Singleton<WorkerDevToolsManager>::get();
241 }
242
243 // static
244 DevToolsAgentHost* WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
245 int worker_process_id,
246 int worker_route_id) {
247 WorkerId id(worker_process_id, worker_route_id);
248 WorkerDevToolsAgentHost* result = AgentHosts::GetAgentHost(id);
249 if (!result)
250 result = new WorkerDevToolsAgentHost(id);
251 return result;
252 }
253
254 WorkerDevToolsManager::WorkerDevToolsManager() {
255 }
256
257 WorkerDevToolsManager::~WorkerDevToolsManager() {
258 }
259
260 void WorkerDevToolsManager::WorkerCreated(
261 WorkerProcessHost* worker,
262 const WorkerProcessHost::WorkerInstance& instance) {
263 for (TerminatedInspectedWorkers::iterator it = terminated_workers_.begin();
264 it != terminated_workers_.end(); ++it) {
265 if (instance.Matches(it->worker_url, it->worker_name,
266 instance.partition(),
267 instance.resource_context())) {
268 worker->Send(new DevToolsAgentMsg_PauseWorkerContextOnStart(
269 instance.worker_route_id()));
270 WorkerId new_worker_id(worker->GetData().id, instance.worker_route_id());
271 paused_workers_[new_worker_id] = it->old_worker_id;
272 terminated_workers_.erase(it);
273 return;
274 }
275 }
276 }
277
278 void WorkerDevToolsManager::WorkerDestroyed(
279 WorkerProcessHost* worker,
280 int worker_route_id) {
281 InspectedWorkersList::iterator it = FindInspectedWorker(
282 worker->GetData().id,
283 worker_route_id);
284 if (it == inspected_workers_.end())
285 return;
286
287 WorkerId worker_id(worker->GetData().id, worker_route_id);
288 terminated_workers_.push_back(TerminatedInspectedWorker(
289 worker_id,
290 it->worker_url,
291 it->worker_name));
292 inspected_workers_.erase(it);
293 BrowserThread::PostTask(
294 BrowserThread::UI, FROM_HERE,
295 base::Bind(&DetachedClientHosts::WorkerDestroyed, worker_id));
296 }
297
298 void WorkerDevToolsManager::WorkerContextStarted(WorkerProcessHost* process,
299 int worker_route_id) {
300 WorkerId new_worker_id(process->GetData().id, worker_route_id);
301 PausedWorkers::iterator it = paused_workers_.find(new_worker_id);
302 if (it == paused_workers_.end())
303 return;
304
305 BrowserThread::PostTask(
306 BrowserThread::UI, FROM_HERE,
307 base::Bind(
308 &DetachedClientHosts::WorkerReloaded,
309 it->second,
310 new_worker_id));
311 paused_workers_.erase(it);
312 }
313
314 void WorkerDevToolsManager::RemoveInspectedWorkerData(
315 const WorkerId& id) {
316 for (TerminatedInspectedWorkers::iterator it = terminated_workers_.begin();
317 it != terminated_workers_.end(); ++it) {
318 if (it->old_worker_id == id) {
319 terminated_workers_.erase(it);
320 return;
321 }
322 }
323
324 for (PausedWorkers::iterator it = paused_workers_.begin();
325 it != paused_workers_.end(); ++it) {
326 if (it->second == id) {
327 SendResumeToWorker(it->first);
328 paused_workers_.erase(it);
329 return;
330 }
331 }
332 }
333
334 WorkerDevToolsManager::InspectedWorkersList::iterator
335 WorkerDevToolsManager::FindInspectedWorker(
336 int host_id, int route_id) {
337 InspectedWorkersList::iterator it = inspected_workers_.begin();
338 while (it != inspected_workers_.end()) {
339 if (it->host->GetData().id == host_id && it->route_id == route_id)
340 break;
341 ++it;
342 }
343 return it;
344 }
345
346 static WorkerProcessHost* FindWorkerProcess(int worker_process_id) {
347 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
348 if (iter.GetData().id == worker_process_id)
349 return *iter;
350 }
351 return NULL;
352 }
353
354 void WorkerDevToolsManager::RegisterDevToolsAgentHostForWorker(
355 int worker_process_id,
356 int worker_route_id) {
357 if (WorkerProcessHost* process = FindWorkerProcess(worker_process_id)) {
358 const WorkerProcessHost::Instances& instances = process->instances();
359 for (WorkerProcessHost::Instances::const_iterator i = instances.begin();
360 i != instances.end(); ++i) {
361 if (i->worker_route_id() == worker_route_id) {
362 DCHECK(FindInspectedWorker(worker_process_id, worker_route_id) ==
363 inspected_workers_.end());
364 inspected_workers_.push_back(
365 InspectedWorker(process, worker_route_id, i->url(), i->name()));
366 return;
367 }
368 }
369 }
370 NotifyWorkerDestroyedOnIOThread(worker_process_id, worker_route_id);
371 }
372
373 void WorkerDevToolsManager::ForwardToDevToolsClient(
374 int worker_process_id,
375 int worker_route_id,
376 const std::string& message) {
377 if (FindInspectedWorker(worker_process_id, worker_route_id) ==
378 inspected_workers_.end()) {
379 NOTREACHED();
380 return;
381 }
382 BrowserThread::PostTask(
383 BrowserThread::UI, FROM_HERE,
384 base::Bind(
385 &ForwardToDevToolsClientOnUIThread,
386 worker_process_id,
387 worker_route_id,
388 message));
389 }
390
391 void WorkerDevToolsManager::SaveAgentRuntimeState(int worker_process_id,
392 int worker_route_id,
393 const std::string& state) {
394 BrowserThread::PostTask(
395 BrowserThread::UI, FROM_HERE,
396 base::Bind(
397 &SaveAgentRuntimeStateOnUIThread,
398 worker_process_id,
399 worker_route_id,
400 state));
401 }
402
403 void WorkerDevToolsManager::ForwardToWorkerDevToolsAgent(
404 int worker_process_id,
405 int worker_route_id,
406 const IPC::Message& message) {
407 InspectedWorkersList::iterator it = FindInspectedWorker(
408 worker_process_id,
409 worker_route_id);
410 if (it == inspected_workers_.end())
411 return;
412 IPC::Message* msg = new IPC::Message(message);
413 msg->set_routing_id(worker_route_id);
414 it->host->Send(msg);
415 }
416
417 // static
418 void WorkerDevToolsManager::ForwardToDevToolsClientOnUIThread(
419 int worker_process_id,
420 int worker_route_id,
421 const std::string& message) {
422 WorkerDevToolsAgentHost* agent_host = AgentHosts::GetAgentHost(WorkerId(
423 worker_process_id,
424 worker_route_id));
425 if (!agent_host)
426 return;
427 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(agent_host,
428 message);
429 }
430
431 // static
432 void WorkerDevToolsManager::SaveAgentRuntimeStateOnUIThread(
433 int worker_process_id,
434 int worker_route_id,
435 const std::string& state) {
436 WorkerDevToolsAgentHost* agent_host = AgentHosts::GetAgentHost(WorkerId(
437 worker_process_id,
438 worker_route_id));
439 if (!agent_host)
440 return;
441 DevToolsManagerImpl::GetInstance()->SaveAgentRuntimeState(agent_host, state);
442 }
443
444 // static
445 void WorkerDevToolsManager::NotifyWorkerDestroyedOnIOThread(
446 int worker_process_id,
447 int worker_route_id) {
448 BrowserThread::PostTask(
449 BrowserThread::UI, FROM_HERE,
450 base::Bind(
451 &WorkerDevToolsManager::NotifyWorkerDestroyedOnUIThread,
452 worker_process_id,
453 worker_route_id));
454 }
455
456 // static
457 void WorkerDevToolsManager::NotifyWorkerDestroyedOnUIThread(
458 int worker_process_id,
459 int worker_route_id) {
460 WorkerDevToolsAgentHost* host =
461 AgentHosts::GetAgentHost(WorkerId(worker_process_id, worker_route_id));
462 if (host)
463 host->WorkerDestroyed();
464 }
465
466 // static
467 void WorkerDevToolsManager::SendResumeToWorker(const WorkerId& id) {
468 if (WorkerProcessHost* process = FindWorkerProcess(id.first))
469 process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second));
470 }
471
472 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/debugger/worker_devtools_manager.h ('k') | content/browser/debugger/worker_devtools_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698