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

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

Issue 7248076: DevTools: add initial support for shared workers debugging (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 5 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 | Annotate | Revision Log
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
9 #include "base/tuple.h"
10 #include "chrome/browser/profiles/profile_manager.h"
11 #include "content/browser/browser_thread.h"
12 #include "content/browser/debugger/devtools_manager.h"
13 #include "content/browser/debugger/devtools_window.h"
14 #include "content/browser/debugger/worker_devtools_message_filter.h"
15 #include "content/browser/worker_host/worker_process_host.h"
16 #include "content/common/devtools_messages.h"
17
18 class WorkerDevToolsManager::DevToolsWorkerIds {
pfeldman 2011/07/08 09:17:17 IdsIOMap
yurys 2011/07/08 15:35:53 Done.
19 public:
20 DevToolsWorkerIds() : next_id_(1) {}
21
22 int CreateDevToolsId(WorkerProcessHost* host, int route_id) {
23 DCHECK(-1 == FindDevToolsId(host->id(), route_id));
24 int devtools_id = next_id_++;
25 map_.push_back(Entry(host, route_id, devtools_id));
26 return devtools_id;
27 }
28
29 int FindDevToolsId(int worker_process_host_id, int route_id) {
30 for (IdMap::iterator it = map_.begin();
31 it != map_.end(); ++it) {
pfeldman 2011/07/08 09:17:17 Does it fit one line?
yurys 2011/07/08 15:35:53 Done.
32 if (it->a->id() == worker_process_host_id && it->b == route_id)
pfeldman 2011/07/08 09:17:17 it-a-id? do we want a struct?
yurys 2011/07/08 15:35:53 Done.
33 return it->c;
34 }
35 return -1;
36 }
37
38 bool FindWorkerInfo(
39 int devtools_id,
pfeldman 2011/07/08 09:17:17 why line break?
yurys 2011/07/08 15:35:53 Doesn't fit on 1 line.
40 WorkerProcessHost** host,
41 int* route_id) {
42 for (IdMap::iterator it = map_.begin();
pfeldman 2011/07/08 09:17:17 ditto
yurys 2011/07/08 15:35:53 Done.
43 it != map_.end(); ++it) {
44 if (it->c == devtools_id) {
45 *host = it->a;
46 *route_id = it->b;
47 return true;
48 }
49 }
50 return false;
51 }
52
53 bool TakeWorkerInfo(
54 int devtools_id,
55 WorkerProcessHost** host,
56 int* route_id) {
57 for (IdMap::iterator it = map_.begin();
58 it != map_.end(); ++it) {
59 if (it->c == devtools_id) {
60 *host = it->a;
61 *route_id = it->b;
62 map_.erase(it);
63 return true;
64 }
65 }
66 return false;
67 }
68
69 void WorkerDevToolsMessageFilterClosing(int worker_process_host_id) {
70 IdMap::iterator it = map_.begin();
71 while (it != map_.end()) {
72 if (it->a->id() == worker_process_host_id)
73 it = map_.erase(it);
74 else
75 ++it;
76 }
77 }
78
79 private:
80 int next_id_;
81 typedef Tuple3<WorkerProcessHost*, int, int> Entry;
82 typedef std::list<Entry> IdMap;
83 IdMap map_;
84 DISALLOW_COPY_AND_ASSIGN(DevToolsWorkerIds);
85 };
86
87 namespace {
88
89 void ForwardToWorkerDevToolsAgentOnIOThread(
90 int worker_devtools_id,
91 const IPC::Message& message) {
92 WorkerDevToolsManager::GetInstance()->ForwardToWorkerDevToolsAgent(
93 worker_devtools_id, message);
94 }
95
96 void NotifyWorkerDevToolsClientClosingOnIOThread(int worker_devtools_id) {
97 WorkerDevToolsManager::GetInstance()->WorkerDevToolsClientClosing(
pfeldman 2011/07/08 09:17:17 WorkerDevToolsManagerIO
yurys 2011/07/08 15:35:53 Done.
98 worker_devtools_id);
99 }
100
101 class WorkerDevToolsClients : public DevToolsClientHost::CloseListener {
pfeldman 2011/07/08 09:17:17 Can Clients be merged with the Ids?
yurys 2011/07/08 15:35:53 No, they live on different threads.
102 public:
103 static WorkerDevToolsClients* GetInstance() {
104 static WorkerDevToolsClients* instance = new WorkerDevToolsClients();
105 return instance;
106 }
107
108 DevToolsClientHost* FindDevToolsClient(int worker_devtools_id) {
109 WorkerIdToClientHostMap::iterator it =
110 worker_id_to_client_host_.find(worker_devtools_id);
111 if (it == worker_id_to_client_host_.end())
112 return NULL;
113 return it->second;
114 }
115
116 int FindWorkerDevToolsId(DevToolsClientHost* client_host) {
117 for (WorkerIdToClientHostMap::const_iterator it =
118 worker_id_to_client_host_.begin();
119 it != worker_id_to_client_host_.end(); ++it) {
120 if (it->second == client_host)
121 return it->first;
122 }
123 return -1;
124 }
125
126 void RegisterDevToolsClientForWorker(
127 int worker_devtools_id,
128 DevToolsClientHost* client) {
129 client->set_close_listener(this);
130 worker_id_to_client_host_[worker_devtools_id] = client;
131 }
132
133 private:
134 WorkerDevToolsClients() {}
135 virtual ~WorkerDevToolsClients() {}
136
137 virtual void ClientHostClosing(DevToolsClientHost* host) {
138 WorkerIdToClientHostMap::iterator it = worker_id_to_client_host_.begin();
139 for (; it != worker_id_to_client_host_.end(); ++it) {
140 if (it->second == host) {
141 BrowserThread::PostTask(
142 BrowserThread::IO, FROM_HERE,
143 NewRunnableFunction(NotifyWorkerDevToolsClientClosingOnIOThread,
144 it->first));
145 worker_id_to_client_host_.erase(it);
146 return;
147 }
148 }
149 }
150
151 typedef std::map<int, DevToolsClientHost*> WorkerIdToClientHostMap;
152 WorkerIdToClientHostMap worker_id_to_client_host_;
153
154 DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsClients);
155 };
156
157 } // namespace
158
159 // static
160 WorkerDevToolsManager* WorkerDevToolsManager::GetInstance() {
161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
162 return Singleton<WorkerDevToolsManager>::get();
163 }
164
165 WorkerDevToolsManager::WorkerDevToolsManager()
166 : devtools_worker_ids_(new DevToolsWorkerIds()) {
167 }
168
169 WorkerDevToolsManager::~WorkerDevToolsManager() {
170 }
171
172
173 bool WorkerDevToolsManager::ForwardToWorkerDevToolsAgent(
174 DevToolsClientHost* from,
175 const IPC::Message& message) {
176 int worker_devtools_id = WorkerDevToolsClients::GetInstance()->
177 FindWorkerDevToolsId(from);
178 if (worker_devtools_id == -1)
179 return false;
180 BrowserThread::PostTask(
181 BrowserThread::IO, FROM_HERE,
182 NewRunnableFunction(
183 ForwardToWorkerDevToolsAgentOnIOThread,
184 worker_devtools_id,
185 IPC::Message(message)));
186 return true;
187 }
188
189 static void OpenDevToolsForWorkerOnUIThread(
190 int worker_devtools_id) {
191 Profile* profile = ProfileManager::GetDefaultProfile();
192 if (!profile)
193 return;
194 DevToolsWindow* window = DevToolsWindow::CreateDevToolsWindow(profile);
195 window->Show(DEVTOOLS_TOGGLE_ACTION_NONE);
196 WorkerDevToolsClients::GetInstance()->RegisterDevToolsClientForWorker(
197 worker_devtools_id, window);
198 }
199
200 static WorkerProcessHost* FindWorkerProcessHostForWorker(
201 int worker_process_host_id,
202 int worker_route_id) {
203 BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
204 for (; !iter.Done(); ++iter) {
205 if (iter->id() != worker_process_host_id)
206 continue;
207 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
208 const WorkerProcessHost::Instances& instances = worker->instances();
209 for (WorkerProcessHost::Instances::const_iterator i = instances.begin();
210 i != instances.end(); ++i) {
211 if (i->shared() && i->worker_route_id() == worker_route_id)
212 return worker;
213 }
214 return NULL;
215 }
216 return NULL;
217 }
218
219 void WorkerDevToolsManager::OpenDevToolsForWorker(int worker_process_host_id,
220 int worker_route_id) {
221 WorkerProcessHost* host = FindWorkerProcessHostForWorker(
222 worker_process_host_id,
223 worker_route_id);
224 if (!host)
225 return;
226
227 int devtools_id = devtools_worker_ids_->FindDevToolsId(
228 worker_process_host_id, worker_route_id);
229 // DevTools client is already attached.
230 if (devtools_id != -1)
231 return;
232
233 host->Send(new WorkerDevToolsAgentMsg_Attach(worker_route_id));
234
235 devtools_id = devtools_worker_ids_->CreateDevToolsId(
236 host, worker_route_id);
237 BrowserThread::PostTask(
238 BrowserThread::UI, FROM_HERE,
239 NewRunnableFunction(
240 OpenDevToolsForWorkerOnUIThread,
241 devtools_id));
242 }
243
244 void WorkerDevToolsManager::WorkerDevToolsClientClosing(
245 int worker_devtools_id) {
246 WorkerProcessHost* host;
247 int route_id;
248 if (!devtools_worker_ids_->TakeWorkerInfo(
249 worker_devtools_id, &host, &route_id))
250 return;
251 host->Send(new WorkerDevToolsAgentMsg_Detach(route_id));
252 }
253
254 static void ForwardToDevToolsClientOnUIThread(
255 int worker_devtools_id,
256 const IPC::Message& message) {
257 DevToolsClientHost* client = WorkerDevToolsClients::GetInstance()->
258 FindDevToolsClient(worker_devtools_id);
259 if (client)
260 client->SendMessageToClient(message);
261 }
262
263 void WorkerDevToolsManager::ForwardToDevToolsClient(
264 int worker_process_host_id,
265 int worker_route_id,
266 const IPC::Message& message) {
267 int devtools_id = devtools_worker_ids_->FindDevToolsId(
268 worker_process_host_id, worker_route_id);
269 DCHECK(devtools_id != -1);
270 if (devtools_id == -1)
271 return;
272 BrowserThread::PostTask(
273 BrowserThread::UI, FROM_HERE,
274 NewRunnableFunction(
275 ForwardToDevToolsClientOnUIThread,
276 devtools_id,
277 IPC::Message(message)));
278 }
279
280 void WorkerDevToolsManager::ForwardToWorkerDevToolsAgent(
281 int worker_devtools_id,
282 const IPC::Message& message) {
283 WorkerProcessHost* host;
284 int route_id;
285 if (!devtools_worker_ids_->FindWorkerInfo(
286 worker_devtools_id, &host, &route_id))
287 return;
288 IPC::Message* msg = new IPC::Message(message);
289 msg->set_routing_id(route_id);
290 host->Send(msg);
291 }
292
293 void WorkerDevToolsManager::WorkerProcessDestroying(
294 int worker_process_host_id) {
295 devtools_worker_ids_->WorkerDevToolsMessageFilterClosing(
296 worker_process_host_id);
297 }
298
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