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

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

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

Powered by Google App Engine
This is Rietveld 408576698