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

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: http://crrev.com/214343002 has landed. So I rebased. Created 6 years, 8 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"
12 #include "content/browser/devtools/devtools_manager_impl.h" 7 #include "content/browser/devtools/devtools_manager_impl.h"
13 #include "content/browser/devtools/devtools_protocol.h" 8 #include "content/browser/devtools/devtools_protocol.h"
14 #include "content/browser/devtools/devtools_protocol_constants.h" 9 #include "content/browser/devtools/devtools_protocol_constants.h"
15 #include "content/browser/devtools/ipc_devtools_agent_host.h" 10 #include "content/browser/devtools/ipc_devtools_agent_host.h"
16 #include "content/browser/devtools/worker_devtools_message_filter.h" 11 #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" 12 #include "content/common/devtools_messages.h"
19 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/child_process_data.h" 14 #include "content/public/browser/render_process_host.h"
21 #include "content/public/common/process_type.h" 15 #include "content/public/browser/worker_service.h"
16 #include "ipc/ipc_listener.h"
22 17
23 namespace content { 18 namespace content {
24 19
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 { 20 namespace {
36 21
37 typedef std::map<WorkerDevToolsManager::WorkerId, 22 bool SendMessageToWorker(const SharedWorkerDevToolsManager::WorkerId& worker_id,
38 WorkerDevToolsManager::WorkerDevToolsAgentHost*> AgentHosts; 23 IPC::Message* message) {
39 base::LazyInstance<AgentHosts>::Leaky g_agent_map = LAZY_INSTANCE_INITIALIZER; 24 RenderProcessHost* host = RenderProcessHost::FromID(worker_id.first);
40 base::LazyInstance<AgentHosts>::Leaky g_orphan_map = LAZY_INSTANCE_INITIALIZER; 25 if (!host) {
26 delete message;
27 return false;
28 }
29 message->set_routing_id(worker_id.second);
30 host->Send(message);
31 return true;
32 }
41 33
42 } // namespace 34 } // namespace
43 35
44 struct WorkerDevToolsManager::TerminatedInspectedWorker { 36 class SharedWorkerDevToolsManager::SharedWorkerDevToolsAgentHost
45 TerminatedInspectedWorker(WorkerId id, 37 : public IPCDevToolsAgentHost,
46 const GURL& url, 38 public IPC::Listener {
47 const base::string16& name)
48 : old_worker_id(id),
49 worker_url(url),
50 worker_name(name) {}
51 WorkerId old_worker_id;
52 GURL worker_url;
53 base::string16 worker_name;
54 };
55
56
57 class WorkerDevToolsManager::WorkerDevToolsAgentHost
58 : public IPCDevToolsAgentHost {
59 public: 39 public:
60 explicit WorkerDevToolsAgentHost(WorkerId worker_id) 40 SharedWorkerDevToolsAgentHost(WorkerId worker_id)
61 : has_worker_id_(false) { 41 : worker_id_(worker_id), worker_attached_(true) {
62 SetWorkerId(worker_id, false); 42 AddRef();
63 } 43 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
64 44 host->AddRoute(worker_id_.second, this);
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 } 45 }
116 46
117 // IPCDevToolsAgentHost implementation. 47 // IPCDevToolsAgentHost implementation.
118 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE { 48 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
119 if (!has_worker_id_) { 49 if (worker_attached_)
120 delete message; 50 SendMessageToWorker(worker_id_, message);
121 return; 51 }
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 {} 52 virtual void OnClientAttached() OVERRIDE {}
133 virtual void OnClientDetached() OVERRIDE {} 53 virtual void OnClientDetached() OVERRIDE {}
134 54
135 bool has_worker_id_; 55 // IPC::Listener implementation.
56 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
58 bool handled = true;
59 IPC_BEGIN_MESSAGE_MAP(SharedWorkerDevToolsAgentHost, msg)
60 IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
61 OnDispatchOnInspectorFrontend)
62 IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
63 OnSaveAgentRuntimeState)
64 IPC_MESSAGE_UNHANDLED(handled = false)
65 IPC_END_MESSAGE_MAP()
66 return handled;
67 }
68
69 void ReattachToWorker(WorkerId worker_id) {
70 CHECK(!worker_attached_);
71 worker_attached_ = true;
72 worker_id_ = worker_id;
73 AddRef();
74 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
75 host->AddRoute(worker_id_.second, this);
76 Reattach(state_);
77 }
78
79 void DetachFromWorker() {
80 CHECK(worker_attached_);
81 worker_attached_ = false;
82 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
83 host->RemoveRoute(worker_id_.second);
84 Release();
85 }
86
87 WorkerId worker_id() const { return worker_id_; }
88
89 private:
90 virtual ~SharedWorkerDevToolsAgentHost() {
91 CHECK(!worker_attached_);
92 SharedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(this);
93 }
94
95 void OnDispatchOnInspectorFrontend(const std::string& message) {
96 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this,
97 message);
98 }
99
100 void OnSaveAgentRuntimeState(const std::string& state) { state_ = state; }
101
136 WorkerId worker_id_; 102 WorkerId worker_id_;
103 bool worker_attached_;
137 std::string state_; 104 std::string state_;
138 105 DISALLOW_COPY_AND_ASSIGN(SharedWorkerDevToolsAgentHost);
139 DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsAgentHost);
140 }; 106 };
141 107
142 108 class SharedWorkerDevToolsManager::WorkerInfo {
143 class WorkerDevToolsManager::DetachedClientHosts {
144 public: 109 public:
145 static void WorkerReloaded(WorkerId old_id, WorkerId new_id) { 110 WorkerInfo(const SharedWorkerInstance& instance)
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 111 : instance_(instance), agent_host_(NULL) {}
147 AgentHosts::iterator it = g_orphan_map.Get().find(old_id); 112
148 if (it != g_orphan_map.Get().end()) { 113 const SharedWorkerInstance& instance() const { return instance_; }
149 it->second->SetWorkerId(new_id, true); 114
150 g_orphan_map.Get().erase(old_id); 115 SharedWorkerDevToolsAgentHost* agent_host() { return agent_host_; }
151 return; 116 void set_agent_host(SharedWorkerDevToolsAgentHost* agent_host) {
152 } 117 agent_host_ = agent_host;
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 } 118 }
185 119
186 private: 120 private:
187 DetachedClientHosts() {} 121 const SharedWorkerInstance instance_;
yurys 2014/03/31 13:48:23 Is it OK to store it by value?
horo 2014/04/01 08:34:09 Yes it is OK. SharedWorkerInstance has WorkerStora
188 ~DetachedClientHosts() {} 122 SharedWorkerDevToolsAgentHost* agent_host_;
189
190 static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) {
191 WorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(id);
192 }
193 }; 123 };
194 124
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 125 // static
209 WorkerDevToolsManager* WorkerDevToolsManager::GetInstance() { 126 SharedWorkerDevToolsManager* SharedWorkerDevToolsManager::GetInstance() {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211 return Singleton<WorkerDevToolsManager>::get(); 128 return Singleton<SharedWorkerDevToolsManager>::get();
212 } 129 }
213 130
214 // static 131 DevToolsAgentHost* SharedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
215 DevToolsAgentHost* WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
216 int worker_process_id, 132 int worker_process_id,
217 int worker_route_id) { 133 int worker_route_id) {
218 WorkerId id(worker_process_id, worker_route_id); 134 WorkerId id(worker_process_id, worker_route_id);
219 AgentHosts::iterator it = g_agent_map.Get().find(id); 135
220 if (it == g_agent_map.Get().end()) 136 WorkerInfoMap::iterator inspected_it = inspected_workers_.find(id);
221 return new WorkerDevToolsAgentHost(id); 137 if (inspected_it != inspected_workers_.end())
222 return it->second; 138 return inspected_it->second->agent_host();
223 } 139
224 140 WorkerInfoMap::iterator terminated_it = terminated_workers_.find(id);
225 WorkerDevToolsManager::WorkerDevToolsManager() { 141 if (terminated_it != terminated_workers_.end())
226 } 142 return terminated_it->second->agent_host();
227 143
228 WorkerDevToolsManager::~WorkerDevToolsManager() { 144 WorkerInfoMap::iterator paused_it = paused_workers_.find(id);
229 } 145 if (paused_it != paused_workers_.end())
230 146 return paused_it->second->agent_host();
231 bool WorkerDevToolsManager::WorkerCreated( 147
232 WorkerProcessHost* worker, 148 WorkerInfoMap::iterator uninspected_it = uninspected_workers_.find(id);
233 const WorkerProcessHost::WorkerInstance& instance) { 149 if (uninspected_it != uninspected_workers_.end()) {
234 for (TerminatedInspectedWorkers::iterator it = terminated_workers_.begin(); 150 scoped_ptr<WorkerInfo> info =
235 it != terminated_workers_.end(); ++it) { 151 uninspected_workers_.take_and_erase(uninspected_it);
236 if (instance.Matches(it->worker_url, it->worker_name, 152 SharedWorkerDevToolsAgentHost* agent_host =
237 instance.partition(), 153 new SharedWorkerDevToolsAgentHost(id);
238 instance.resource_context())) { 154 info->set_agent_host(agent_host);
239 WorkerId new_worker_id(worker->GetData().id, instance.worker_route_id()); 155 inspected_workers_.set(id, info.Pass());
240 paused_workers_[new_worker_id] = it->old_worker_id; 156 return agent_host;
241 terminated_workers_.erase(it); 157 }
242 return true; 158 return NULL;
243 } 159 }
244 } 160
245 return false; 161 SharedWorkerDevToolsManager::SharedWorkerDevToolsManager() {}
246 } 162
247 163 SharedWorkerDevToolsManager::~SharedWorkerDevToolsManager() {}
248 void WorkerDevToolsManager::WorkerDestroyed( 164
249 WorkerProcessHost* worker, 165 bool SharedWorkerDevToolsManager::WorkerCreated(
250 int worker_route_id) { 166 int worker_process_id,
251 InspectedWorkersList::iterator it = FindInspectedWorker( 167 int worker_route_id,
252 worker->GetData().id, 168 const SharedWorkerInstance& instance) {
253 worker_route_id); 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
254 if (it == inspected_workers_.end()) 170 const WorkerId id(worker_process_id, worker_route_id);
255 return; 171 WorkerInfoMap::iterator terminated_it = FindTerminatedWorker(instance);
256 172 if (terminated_it == terminated_workers_.end()) {
257 WorkerId worker_id(worker->GetData().id, worker_route_id); 173 scoped_ptr<WorkerInfo> info(new WorkerInfo(instance));
258 terminated_workers_.push_back(TerminatedInspectedWorker( 174 uninspected_workers_.set(id, info.Pass());
259 worker_id, 175 return false;
260 it->worker_url, 176 }
261 it->worker_name)); 177 scoped_ptr<WorkerInfo> info =
262 inspected_workers_.erase(it); 178 terminated_workers_.take_and_erase(terminated_it);
263 BrowserThread::PostTask( 179 paused_workers_.set(id, info.Pass());
264 BrowserThread::UI, FROM_HERE, 180 return true;
265 base::Bind(&DetachedClientHosts::WorkerDestroyed, worker_id)); 181 }
266 } 182
267 183 void SharedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
268 void WorkerDevToolsManager::WorkerContextStarted(WorkerProcessHost* process, 184 int worker_route_id) {
269 int worker_route_id) { 185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
270 WorkerId new_worker_id(process->GetData().id, worker_route_id); 186 const WorkerId id(worker_process_id, worker_route_id);
271 PausedWorkers::iterator it = paused_workers_.find(new_worker_id); 187 if (uninspected_workers_.erase(id))
272 if (it == paused_workers_.end()) 188 return;
273 return; 189 WorkerInfoMap::iterator paused_it = paused_workers_.find(id);
274 190 if (paused_it != paused_workers_.end()) {
275 BrowserThread::PostTask( 191 scoped_ptr<WorkerInfo> info = paused_workers_.take_and_erase(paused_it);
276 BrowserThread::UI, FROM_HERE, 192 const WorkerId old_id = info->agent_host()->worker_id();
277 base::Bind( 193 terminated_workers_.set(old_id, info.Pass());
278 &DetachedClientHosts::WorkerReloaded, 194 return;
279 it->second, 195 }
280 new_worker_id)); 196
281 paused_workers_.erase(it); 197 WorkerInfoMap::iterator inspected_it = inspected_workers_.find(id);
282 } 198 if (inspected_it == inspected_workers_.end())
283 199 return;
284 void WorkerDevToolsManager::RemoveInspectedWorkerData( 200 scoped_ptr<WorkerInfo> info = inspected_workers_.take_and_erase(inspected_it);
285 const WorkerId& id) { 201
286 for (TerminatedInspectedWorkers::iterator it = terminated_workers_.begin(); 202 SharedWorkerDevToolsAgentHost* agent_host = info->agent_host();
287 it != terminated_workers_.end(); ++it) { 203 if (!agent_host->IsAttached()) {
288 if (it->old_worker_id == id) { 204 agent_host->DetachFromWorker();
289 terminated_workers_.erase(it); 205 return;
206 }
207
208 terminated_workers_.set(id, info.Pass());
209 // Client host is debugging this worker agent host.
210 std::string notification =
211 DevToolsProtocol::CreateNotification(
212 devtools::Worker::disconnectedFromWorker::kName, NULL)->Serialize();
213 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(agent_host,
214 notification);
215 agent_host->DetachFromWorker();
216 }
217
218 void SharedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
219 int worker_route_id) {
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
221 const WorkerId id(worker_process_id, worker_route_id);
222 WorkerInfoMap::iterator paused_it = paused_workers_.find(id);
223 if (paused_it == paused_workers_.end())
224 return;
225 scoped_ptr<WorkerInfo> info = paused_workers_.take_and_erase(paused_it);
226 info->agent_host()->ReattachToWorker(id);
227 inspected_workers_.set(id, info.Pass());
228 }
229
230 void SharedWorkerDevToolsManager::RemoveInspectedWorkerData(
231 SharedWorkerDevToolsAgentHost* agent_host) {
232 if (terminated_workers_.erase(agent_host->worker_id()))
233 return;
234
235 for (WorkerInfoMap::iterator paused_it = paused_workers_.begin();
yurys 2014/03/31 13:48:23 How can the worker be in paused_workers_ map when
horo 2014/04/01 08:34:09 This could be occur when the DevToolsAgent is deta
yurys 2014/04/01 09:01:45 Got it, thanks for explaining.
236 paused_it != paused_workers_.end();
237 ++paused_it) {
238 if (paused_it->second->agent_host() == agent_host) {
239 SendMessageToWorker(
240 paused_it->first,
241 new DevToolsAgentMsg_ResumeWorkerContext(paused_it->first.second));
242 paused_workers_.erase(paused_it);
290 return; 243 return;
291 } 244 }
292 } 245 }
293 246 }
294 for (PausedWorkers::iterator it = paused_workers_.begin(); 247
295 it != paused_workers_.end(); ++it) { 248 SharedWorkerDevToolsManager::WorkerInfoMap::iterator
296 if (it->second == id) { 249 SharedWorkerDevToolsManager::FindTerminatedWorker(
297 SendResumeToWorker(it->first); 250 const SharedWorkerInstance& instance) {
298 paused_workers_.erase(it); 251 WorkerInfoMap::iterator terminated_it = terminated_workers_.begin();
299 return; 252 for (; terminated_it != terminated_workers_.end(); ++terminated_it) {
300 } 253 if (terminated_it->second->instance().Matches(instance))
301 }
302 }
303
304 WorkerDevToolsManager::InspectedWorkersList::iterator
305 WorkerDevToolsManager::FindInspectedWorker(
306 int host_id, int route_id) {
307 InspectedWorkersList::iterator it = inspected_workers_.begin();
308 while (it != inspected_workers_.end()) {
309 if (it->host->GetData().id == host_id && it->route_id == route_id)
310 break; 254 break;
311 ++it; 255 }
312 } 256 return terminated_it;
313 return it;
314 }
315
316 static WorkerProcessHost* FindWorkerProcess(int worker_process_id) {
317 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
318 if (iter.GetData().id == worker_process_id)
319 return *iter;
320 }
321 return NULL;
322 }
323
324 void WorkerDevToolsManager::ConnectDevToolsAgentHostToWorker(
325 int worker_process_id,
326 int worker_route_id) {
327 if (WorkerProcessHost* process = FindWorkerProcess(worker_process_id)) {
328 const WorkerProcessHost::Instances& instances = process->instances();
329 for (WorkerProcessHost::Instances::const_iterator i = instances.begin();
330 i != instances.end(); ++i) {
331 if (i->worker_route_id() == worker_route_id) {
332 DCHECK(FindInspectedWorker(worker_process_id, worker_route_id) ==
333 inspected_workers_.end());
334 inspected_workers_.push_back(
335 InspectedWorker(process, worker_route_id, i->url(), i->name()));
336 return;
337 }
338 }
339 }
340 NotifyConnectionFailedOnIOThread(worker_process_id, worker_route_id);
341 }
342
343 void WorkerDevToolsManager::ForwardToDevToolsClient(
344 int worker_process_id,
345 int worker_route_id,
346 const std::string& message) {
347 if (FindInspectedWorker(worker_process_id, worker_route_id) ==
348 inspected_workers_.end()) {
349 NOTREACHED();
350 return;
351 }
352 BrowserThread::PostTask(
353 BrowserThread::UI, FROM_HERE,
354 base::Bind(
355 &ForwardToDevToolsClientOnUIThread,
356 worker_process_id,
357 worker_route_id,
358 message));
359 }
360
361 void WorkerDevToolsManager::SaveAgentRuntimeState(int worker_process_id,
362 int worker_route_id,
363 const std::string& state) {
364 BrowserThread::PostTask(
365 BrowserThread::UI, FROM_HERE,
366 base::Bind(
367 &SaveAgentRuntimeStateOnUIThread,
368 worker_process_id,
369 worker_route_id,
370 state));
371 }
372
373 void WorkerDevToolsManager::ForwardToWorkerDevToolsAgent(
374 int worker_process_id,
375 int worker_route_id,
376 const IPC::Message& message) {
377 InspectedWorkersList::iterator it = FindInspectedWorker(
378 worker_process_id,
379 worker_route_id);
380 if (it == inspected_workers_.end())
381 return;
382 IPC::Message* msg = new IPC::Message(message);
383 msg->set_routing_id(worker_route_id);
384 it->host->Send(msg);
385 }
386
387 // static
388 void WorkerDevToolsManager::ForwardToDevToolsClientOnUIThread(
389 int worker_process_id,
390 int worker_route_id,
391 const std::string& message) {
392 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id,
393 worker_route_id));
394 if (it == g_agent_map.Get().end())
395 return;
396 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(it->second,
397 message);
398 }
399
400 // static
401 void WorkerDevToolsManager::SaveAgentRuntimeStateOnUIThread(
402 int worker_process_id,
403 int worker_route_id,
404 const std::string& state) {
405 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id,
406 worker_route_id));
407 if (it == g_agent_map.Get().end())
408 return;
409 it->second->SaveAgentRuntimeState(state);
410 }
411
412 // static
413 void WorkerDevToolsManager::NotifyConnectionFailedOnIOThread(
414 int worker_process_id,
415 int worker_route_id) {
416 BrowserThread::PostTask(
417 BrowserThread::UI, FROM_HERE,
418 base::Bind(
419 &WorkerDevToolsManager::NotifyConnectionFailedOnUIThread,
420 worker_process_id,
421 worker_route_id));
422 }
423
424 // static
425 void WorkerDevToolsManager::NotifyConnectionFailedOnUIThread(
426 int worker_process_id,
427 int worker_route_id) {
428 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id,
429 worker_route_id));
430 if (it != g_agent_map.Get().end())
431 it->second->ConnectionFailed();
432 }
433
434 // static
435 void WorkerDevToolsManager::SendResumeToWorker(const WorkerId& id) {
436 if (WorkerProcessHost* process = FindWorkerProcess(id.first))
437 process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second));
438 }
439
440 WorkerDevToolsManager::WorkerDevToolsAgentHost::~WorkerDevToolsAgentHost() {
441 DetachedClientHosts::RemovePendingWorkerData(worker_id_);
442 g_agent_map.Get().erase(worker_id_);
443 g_orphan_map.Get().erase(worker_id_);
444 } 257 }
445 258
446 } // namespace content 259 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698