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