Chromium Code Reviews| 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 |