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/worker_devtools_manager.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 24 matching lines...) Expand all Loading... | |
35 | 35 |
36 class WorkerDevToolsManager::AgentHosts { | 36 class WorkerDevToolsManager::AgentHosts { |
37 public: | 37 public: |
38 static void Add(WorkerId id, WorkerDevToolsAgentHost* host) { | 38 static void Add(WorkerId id, WorkerDevToolsAgentHost* host) { |
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
40 if (!instance_) | 40 if (!instance_) |
41 instance_ = new AgentHosts(); | 41 instance_ = new AgentHosts(); |
42 instance_->map_[id] = host; | 42 instance_->map_[id] = host; |
43 } | 43 } |
44 static void Remove(WorkerId id) { | 44 static void Remove(WorkerId id) { |
45 DCHECK(instance_); | 45 if (!instance_) |
46 return; | |
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
47 Instances& map = instance_->map_; | 48 Instances& map = instance_->map_; |
48 map.erase(id); | 49 map.erase(id); |
49 if (map.empty()) { | 50 if (map.empty()) { |
50 delete instance_; | 51 delete instance_; |
51 instance_ = NULL; | 52 instance_ = NULL; |
52 } | 53 } |
53 } | 54 } |
54 | 55 |
55 static WorkerDevToolsAgentHost* GetAgentHost(WorkerId id) { | 56 static WorkerDevToolsAgentHost* GetAgentHost(WorkerId id) { |
(...skipping 28 matching lines...) Expand all Loading... | |
84 worker_name(name) {} | 85 worker_name(name) {} |
85 WorkerId old_worker_id; | 86 WorkerId old_worker_id; |
86 GURL worker_url; | 87 GURL worker_url; |
87 string16 worker_name; | 88 string16 worker_name; |
88 }; | 89 }; |
89 | 90 |
90 | 91 |
91 class WorkerDevToolsManager::WorkerDevToolsAgentHost | 92 class WorkerDevToolsManager::WorkerDevToolsAgentHost |
92 : public DevToolsAgentHost { | 93 : public DevToolsAgentHost { |
93 public: | 94 public: |
94 explicit WorkerDevToolsAgentHost(WorkerId worker_id) | 95 explicit WorkerDevToolsAgentHost(WorkerId worker_id) : attached_(false) { |
95 : worker_id_(worker_id) { | 96 AttachToWorker(worker_id, false); |
96 AgentHosts::Add(worker_id, this); | 97 } |
98 | |
99 bool attached() { return attached_; } | |
yurys
2012/12/20 11:45:40
Could you pick another name to avoid confusion wit
pfeldman
2012/12/20 16:53:54
Done.
| |
100 | |
101 void AttachToWorker(WorkerId worker_id, bool reattach) { | |
102 AgentHosts::Remove(worker_id_); | |
103 worker_id_ = worker_id; | |
104 AgentHosts::Add(worker_id_, this); | |
105 attached_ = true; | |
106 | |
97 BrowserThread::PostTask( | 107 BrowserThread::PostTask( |
98 BrowserThread::IO, | 108 BrowserThread::IO, |
99 FROM_HERE, | 109 FROM_HERE, |
100 base::Bind( | 110 base::Bind( |
101 &RegisterAgent, | 111 &RegisterAgent, |
102 worker_id.first, | 112 worker_id.first, |
103 worker_id.second)); | 113 worker_id.second)); |
114 | |
115 if (reattach) | |
116 Reattach(state_); | |
104 } | 117 } |
105 | 118 |
106 void WorkerDestroyed() { | 119 virtual void Detach() { |
107 NotifyCloseListener(); | 120 DevToolsAgentHost::Detach(); |
121 AgentHosts::Remove(worker_id_); | |
108 delete this; | 122 delete this; |
109 } | 123 } |
110 | 124 |
125 void DetachFromWorker() { | |
126 attached_ = false; | |
127 } | |
128 | |
129 void SaveAgentRuntimeState(const std::string& state) { | |
130 state_ = state; | |
131 } | |
132 | |
111 private: | 133 private: |
112 virtual ~WorkerDevToolsAgentHost() { | 134 virtual ~WorkerDevToolsAgentHost() { |
113 AgentHosts::Remove(worker_id_); | 135 AgentHosts::Remove(worker_id_); |
114 } | 136 } |
115 | 137 |
116 static void RegisterAgent( | 138 static void RegisterAgent( |
117 int worker_process_id, | 139 int worker_process_id, |
118 int worker_route_id) { | 140 int worker_route_id) { |
119 WorkerDevToolsManager::GetInstance()->RegisterDevToolsAgentHostForWorker( | 141 WorkerDevToolsManager::GetInstance()->RegisterDevToolsAgentHostForWorker( |
120 worker_process_id, worker_route_id); | 142 worker_process_id, worker_route_id); |
121 } | 143 } |
122 | 144 |
123 static void ForwardToWorkerDevToolsAgent( | 145 static void ForwardToWorkerDevToolsAgent( |
124 int worker_process_id, | 146 int worker_process_id, |
125 int worker_route_id, | 147 int worker_route_id, |
126 IPC::Message* message) { | 148 IPC::Message* message) { |
127 WorkerDevToolsManager::GetInstance()->ForwardToWorkerDevToolsAgent( | 149 WorkerDevToolsManager::GetInstance()->ForwardToWorkerDevToolsAgent( |
128 worker_process_id, worker_route_id, *message); | 150 worker_process_id, worker_route_id, *message); |
129 } | 151 } |
130 | 152 |
131 // DevToolsAgentHost implementation. | 153 // DevToolsAgentHost implementation. |
132 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE { | 154 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE { |
155 if (!attached_) | |
156 return; | |
yurys
2012/12/20 11:45:40
The message object will leak here.
pfeldman
2012/12/20 16:53:54
Done.
| |
133 BrowserThread::PostTask( | 157 BrowserThread::PostTask( |
134 BrowserThread::IO, FROM_HERE, | 158 BrowserThread::IO, FROM_HERE, |
135 base::Bind( | 159 base::Bind( |
136 &WorkerDevToolsAgentHost::ForwardToWorkerDevToolsAgent, | 160 &WorkerDevToolsAgentHost::ForwardToWorkerDevToolsAgent, |
137 worker_id_.first, | 161 worker_id_.first, |
138 worker_id_.second, | 162 worker_id_.second, |
139 base::Owned(message))); | 163 base::Owned(message))); |
140 } | 164 } |
165 | |
141 virtual void NotifyClientAttaching() OVERRIDE {} | 166 virtual void NotifyClientAttaching() OVERRIDE {} |
142 virtual void NotifyClientDetaching() OVERRIDE {} | 167 virtual void NotifyClientDetaching() OVERRIDE {} |
143 virtual int GetRenderProcessId() OVERRIDE { return -1; } | 168 virtual int GetRenderProcessId() OVERRIDE { return -1; } |
144 | 169 |
145 WorkerId worker_id_; | 170 WorkerId worker_id_; |
171 bool attached_; | |
172 std::string state_; | |
146 | 173 |
147 DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsAgentHost); | 174 DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsAgentHost); |
148 }; | 175 }; |
149 | 176 |
150 | 177 |
151 class WorkerDevToolsManager::DetachedClientHosts { | 178 class WorkerDevToolsManager::DetachedClientHosts { |
152 public: | 179 public: |
153 static void WorkerReloaded(WorkerId old_id, WorkerId new_id) { | 180 static void WorkerReloaded(WorkerId old_id, WorkerId new_id) { |
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
155 if (instance_ && instance_->ReattachClient(old_id, new_id)) | 182 WorkerDevToolsAgentHost* agent = AgentHosts::GetAgentHost(old_id); |
183 if (agent && agent->attached()) { | |
184 agent->AttachToWorker(new_id, true); | |
156 return; | 185 return; |
186 } | |
157 RemovePendingWorkerData(old_id); | 187 RemovePendingWorkerData(old_id); |
158 } | 188 } |
159 | 189 |
160 static void WorkerDestroyed(WorkerId id) { | 190 static void WorkerDestroyed(WorkerId id) { |
161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
162 WorkerDevToolsAgentHost* agent = AgentHosts::GetAgentHost(id); | 192 WorkerDevToolsAgentHost* agent = AgentHosts::GetAgentHost(id); |
163 if (!agent) { | 193 if (!agent) { |
164 RemovePendingWorkerData(id); | 194 RemovePendingWorkerData(id); |
165 return; | 195 return; |
166 } | 196 } |
167 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend( | 197 DevToolsManagerImpl* devtools_manager = DevToolsManagerImpl::GetInstance(); |
198 devtools_manager->DispatchOnInspectorFrontend( | |
168 agent, | 199 agent, |
169 WebKit::WebDevToolsAgent::workerDisconnectedFromWorkerEvent().utf8()); | 200 WebKit::WebDevToolsAgent::workerDisconnectedFromWorkerEvent().utf8()); |
170 int cookie = DevToolsManagerImpl::GetInstance()->DetachClientHost(agent); | 201 DevToolsClientHost* client_host = |
171 agent->WorkerDestroyed(); | 202 devtools_manager->GetDevToolsClientHostFor(agent); |
172 if (cookie == -1) { | 203 if (!client_host) |
173 RemovePendingWorkerData(id); | 204 RemovePendingWorkerData(id); |
174 return; | 205 return; |
175 } | 206 agent->DetachFromWorker(); |
176 if (!instance_) | |
177 new DetachedClientHosts(); | |
178 instance_->worker_id_to_cookie_[id] = cookie; | |
179 } | 207 } |
180 | 208 |
181 private: | 209 private: |
182 DetachedClientHosts() { | 210 DetachedClientHosts() { } |
183 instance_ = this; | 211 ~DetachedClientHosts() { } |
184 } | |
185 ~DetachedClientHosts() { | |
186 instance_ = NULL; | |
187 } | |
188 | |
189 bool ReattachClient(WorkerId old_id, WorkerId new_id) { | |
190 WorkerIdToCookieMap::iterator it = worker_id_to_cookie_.find(old_id); | |
191 if (it == worker_id_to_cookie_.end()) | |
192 return false; | |
193 DevToolsAgentHost* agent = | |
194 WorkerDevToolsManager::GetDevToolsAgentHostForWorker( | |
195 new_id.first, | |
196 new_id.second); | |
197 DevToolsManagerImpl::GetInstance()->AttachClientHost( | |
198 it->second, | |
199 agent); | |
200 worker_id_to_cookie_.erase(it); | |
201 if (worker_id_to_cookie_.empty()) | |
202 delete this; | |
203 return true; | |
204 } | |
205 | 212 |
206 static void RemovePendingWorkerData(WorkerId id) { | 213 static void RemovePendingWorkerData(WorkerId id) { |
207 BrowserThread::PostTask( | 214 BrowserThread::PostTask( |
208 BrowserThread::IO, FROM_HERE, | 215 BrowserThread::IO, FROM_HERE, |
209 base::Bind(&RemoveInspectedWorkerDataOnIOThread, id)); | 216 base::Bind(&RemoveInspectedWorkerDataOnIOThread, id)); |
210 } | 217 } |
211 | 218 |
212 static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) { | 219 static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) { |
213 WorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(id); | 220 WorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(id); |
214 } | 221 } |
215 | |
216 static DetachedClientHosts* instance_; | |
217 typedef std::map<WorkerId, int> WorkerIdToCookieMap; | |
218 WorkerIdToCookieMap worker_id_to_cookie_; | |
219 }; | 222 }; |
220 | 223 |
221 WorkerDevToolsManager::DetachedClientHosts* | |
222 WorkerDevToolsManager::DetachedClientHosts::instance_ = NULL; | |
223 | |
224 struct WorkerDevToolsManager::InspectedWorker { | 224 struct WorkerDevToolsManager::InspectedWorker { |
225 InspectedWorker(WorkerProcessHost* host, int route_id, const GURL& url, | 225 InspectedWorker(WorkerProcessHost* host, int route_id, const GURL& url, |
226 const string16& name) | 226 const string16& name) |
227 : host(host), | 227 : host(host), |
228 route_id(route_id), | 228 route_id(route_id), |
229 worker_url(url), | 229 worker_url(url), |
230 worker_name(name) {} | 230 worker_name(name) {} |
231 WorkerProcessHost* const host; | 231 WorkerProcessHost* const host; |
232 int const route_id; | 232 int const route_id; |
233 GURL worker_url; | 233 GURL worker_url; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 i != instances.end(); ++i) { | 360 i != instances.end(); ++i) { |
361 if (i->worker_route_id() == worker_route_id) { | 361 if (i->worker_route_id() == worker_route_id) { |
362 DCHECK(FindInspectedWorker(worker_process_id, worker_route_id) == | 362 DCHECK(FindInspectedWorker(worker_process_id, worker_route_id) == |
363 inspected_workers_.end()); | 363 inspected_workers_.end()); |
364 inspected_workers_.push_back( | 364 inspected_workers_.push_back( |
365 InspectedWorker(process, worker_route_id, i->url(), i->name())); | 365 InspectedWorker(process, worker_route_id, i->url(), i->name())); |
366 return; | 366 return; |
367 } | 367 } |
368 } | 368 } |
369 } | 369 } |
370 NotifyWorkerDestroyedOnIOThread(worker_process_id, worker_route_id); | |
yurys
2012/12/20 11:45:40
Now that the notification is removed who will take
pfeldman
2012/12/20 16:53:54
Done.
| |
371 } | 370 } |
372 | 371 |
373 void WorkerDevToolsManager::ForwardToDevToolsClient( | 372 void WorkerDevToolsManager::ForwardToDevToolsClient( |
374 int worker_process_id, | 373 int worker_process_id, |
375 int worker_route_id, | 374 int worker_route_id, |
376 const std::string& message) { | 375 const std::string& message) { |
377 if (FindInspectedWorker(worker_process_id, worker_route_id) == | 376 if (FindInspectedWorker(worker_process_id, worker_route_id) == |
378 inspected_workers_.end()) { | 377 inspected_workers_.end()) { |
379 NOTREACHED(); | 378 NOTREACHED(); |
380 return; | 379 return; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
415 } | 414 } |
416 | 415 |
417 // static | 416 // static |
418 void WorkerDevToolsManager::ForwardToDevToolsClientOnUIThread( | 417 void WorkerDevToolsManager::ForwardToDevToolsClientOnUIThread( |
419 int worker_process_id, | 418 int worker_process_id, |
420 int worker_route_id, | 419 int worker_route_id, |
421 const std::string& message) { | 420 const std::string& message) { |
422 WorkerDevToolsAgentHost* agent_host = AgentHosts::GetAgentHost(WorkerId( | 421 WorkerDevToolsAgentHost* agent_host = AgentHosts::GetAgentHost(WorkerId( |
423 worker_process_id, | 422 worker_process_id, |
424 worker_route_id)); | 423 worker_route_id)); |
425 if (!agent_host) | 424 if (!agent_host || !agent_host->attached()) |
426 return; | 425 return; |
427 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(agent_host, | 426 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(agent_host, |
428 message); | 427 message); |
429 } | 428 } |
430 | 429 |
431 // static | 430 // static |
432 void WorkerDevToolsManager::SaveAgentRuntimeStateOnUIThread( | 431 void WorkerDevToolsManager::SaveAgentRuntimeStateOnUIThread( |
433 int worker_process_id, | 432 int worker_process_id, |
434 int worker_route_id, | 433 int worker_route_id, |
435 const std::string& state) { | 434 const std::string& state) { |
436 WorkerDevToolsAgentHost* agent_host = AgentHosts::GetAgentHost(WorkerId( | 435 WorkerDevToolsAgentHost* agent_host = AgentHosts::GetAgentHost(WorkerId( |
437 worker_process_id, | 436 worker_process_id, |
438 worker_route_id)); | 437 worker_route_id)); |
439 if (!agent_host) | 438 if (!agent_host || !agent_host->attached()) |
440 return; | 439 return; |
441 DevToolsManagerImpl::GetInstance()->SaveAgentRuntimeState(agent_host, state); | 440 agent_host->SaveAgentRuntimeState(state); |
442 } | 441 } |
443 | 442 |
444 // static | 443 // static |
445 void WorkerDevToolsManager::NotifyWorkerDestroyedOnIOThread( | |
446 int worker_process_id, | |
447 int worker_route_id) { | |
448 BrowserThread::PostTask( | |
449 BrowserThread::UI, FROM_HERE, | |
450 base::Bind( | |
451 &WorkerDevToolsManager::NotifyWorkerDestroyedOnUIThread, | |
452 worker_process_id, | |
453 worker_route_id)); | |
454 } | |
455 | |
456 // static | |
457 void WorkerDevToolsManager::NotifyWorkerDestroyedOnUIThread( | |
458 int worker_process_id, | |
459 int worker_route_id) { | |
460 WorkerDevToolsAgentHost* host = | |
461 AgentHosts::GetAgentHost(WorkerId(worker_process_id, worker_route_id)); | |
462 if (host) | |
463 host->WorkerDestroyed(); | |
464 } | |
465 | |
466 // static | |
467 void WorkerDevToolsManager::SendResumeToWorker(const WorkerId& id) { | 444 void WorkerDevToolsManager::SendResumeToWorker(const WorkerId& id) { |
468 if (WorkerProcessHost* process = FindWorkerProcess(id.first)) | 445 if (WorkerProcessHost* process = FindWorkerProcess(id.first)) |
469 process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second)); | 446 process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second)); |
470 } | 447 } |
471 | 448 |
472 } // namespace content | 449 } // namespace content |
OLD | NEW |