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