Index: content/browser/debugger/worker_devtools_manager.cc |
diff --git a/content/browser/debugger/worker_devtools_manager.cc b/content/browser/debugger/worker_devtools_manager.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..42b225d7abdff5982c940957fc96f244132674c6 |
--- /dev/null |
+++ b/content/browser/debugger/worker_devtools_manager.cc |
@@ -0,0 +1,200 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/debugger/worker_devtools_manager.h" |
+ |
+#include <list> |
+ |
+#include "base/tuple.h" |
+#include "content/browser/browser_thread.h" |
+#include "content/browser/debugger/devtools_manager.h" |
+#include "content/browser/debugger/worker_devtools_message_filter.h" |
+#include "content/browser/worker_host/worker_process_host.h" |
+#include "content/common/devtools_messages.h" |
+ |
+class WorkerDevToolsManager::DevToolsWorkerIds { |
+ public: |
+ DevToolsWorkerIds() : next_id_(1) {} |
+ |
+ int CreateDevToolsId(WorkerProcessHost* host, int route_id) { |
+ DCHECK(-1 == FindDevToolsId(host->id(), route_id)); |
+ int devtools_id = next_id_++; |
+ map_.push_back(Entry(host, route_id, devtools_id)); |
+ return devtools_id; |
+ } |
+ |
+ int FindDevToolsId(int worker_process_host_id, int route_id) { |
+ for (IdMap::iterator it = map_.begin(); |
+ it != map_.end(); ++it) { |
+ if (it->a->id() == worker_process_host_id && it->b == route_id) |
+ return it->c; |
+ } |
+ return -1; |
+ } |
+ |
+ bool FindWorkerInfo( |
+ int devtools_id, |
+ WorkerProcessHost** host, |
+ int* route_id) { |
+ for (IdMap::iterator it = map_.begin(); |
+ it != map_.end(); ++it) { |
+ if (it->c == devtools_id) { |
+ *host = it->a; |
+ *route_id = it->b; |
+ return true; |
+ } |
+ } |
+ return false; |
+ } |
+ |
+ bool TakeWorkerInfo( |
+ int devtools_id, |
+ WorkerProcessHost** host, |
+ int* route_id) { |
+ for (IdMap::iterator it = map_.begin(); |
+ it != map_.end(); ++it) { |
+ if (it->c == devtools_id) { |
+ *host = it->a; |
+ *route_id = it->b; |
+ map_.erase(it); |
+ return true; |
+ } |
+ } |
+ return false; |
+ } |
+ |
+ void WorkerDevToolsMessageFilterClosing(int worker_process_host_id) { |
+ IdMap::iterator it = map_.begin(); |
+ while (it != map_.end()) { |
+ if (it->a->id() == worker_process_host_id) |
+ it = map_.erase(it); |
+ else |
+ ++it; |
+ } |
+ } |
+ |
+ private: |
+ int next_id_; |
+ typedef Tuple3<WorkerProcessHost*, int, int> Entry; |
+ typedef std::list<Entry> IdMap; |
+ IdMap map_; |
+ DISALLOW_COPY_AND_ASSIGN(DevToolsWorkerIds); |
+}; |
+ |
+// static |
+WorkerDevToolsManager* WorkerDevToolsManager::GetInstance() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ return Singleton<WorkerDevToolsManager>::get(); |
+} |
+ |
+WorkerDevToolsManager::WorkerDevToolsManager() |
+ : devtools_worker_ids_(new DevToolsWorkerIds()) { |
+} |
+ |
+WorkerDevToolsManager::~WorkerDevToolsManager() { |
+} |
+ |
+static void OpenDevToolsForWorkerOnUIThread( |
+ int worker_devtools_id) { |
+ DevToolsManager::GetInstance()->OpenDevToolsForWorker( |
+ worker_devtools_id); |
+} |
+ |
+static WorkerProcessHost* FindWorkerProcessHostForWorker( |
+ int worker_process_host_id, |
+ int worker_route_id) { |
+ BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); |
+ for (; !iter.Done(); ++iter) { |
+ if (iter->id() != worker_process_host_id) |
+ continue; |
+ WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
+ const WorkerProcessHost::Instances& instances = worker->instances(); |
+ for (WorkerProcessHost::Instances::const_iterator i = instances.begin(); |
+ i != instances.end(); ++i) { |
+ if (i->shared() && i->worker_route_id() == worker_route_id) |
+ return worker; |
+ } |
+ return NULL; |
+ } |
+ return NULL; |
+} |
+ |
+void WorkerDevToolsManager::OpenDevToolsForWorker(int worker_process_host_id, |
+ int worker_route_id) { |
+ WorkerProcessHost* host = FindWorkerProcessHostForWorker( |
+ worker_process_host_id, |
+ worker_route_id); |
+ if (!host) |
+ return; |
+ |
+ int devtools_id = devtools_worker_ids_->FindDevToolsId( |
+ worker_process_host_id, worker_route_id); |
+ // DevTools client is already attached. |
+ if (devtools_id != -1) |
+ return; |
+ |
+ host->Send(new WorkerDevToolsAgentMsg_Attach(worker_route_id)); |
+ |
+ devtools_id = devtools_worker_ids_->CreateDevToolsId( |
+ host, worker_route_id); |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ NewRunnableFunction( |
+ OpenDevToolsForWorkerOnUIThread, |
+ devtools_id)); |
+} |
+ |
+void WorkerDevToolsManager::WorkerDevToolsClientClosing( |
+ int worker_devtools_id) { |
+ WorkerProcessHost* host; |
+ int route_id; |
+ if (!devtools_worker_ids_->TakeWorkerInfo( |
+ worker_devtools_id, &host, &route_id)) |
+ return; |
+ host->Send(new WorkerDevToolsAgentMsg_Detach(route_id)); |
+} |
+ |
+static void ForwardToDevToolsClientOnUIThread( |
+ int worker_devtools_id, |
+ const IPC::Message& message) { |
+ DevToolsManager::GetInstance()->ForwardToWorkerDevToolsClient( |
+ worker_devtools_id, message); |
+} |
+ |
+void WorkerDevToolsManager::ForwardToDevToolsClient( |
+ int worker_process_host_id, |
+ int worker_route_id, |
+ const IPC::Message& message) { |
+ int devtools_id = devtools_worker_ids_->FindDevToolsId( |
+ worker_process_host_id, worker_route_id); |
+ DCHECK(devtools_id != -1); |
+ if (devtools_id == -1) |
+ return; |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ NewRunnableFunction( |
+ ForwardToDevToolsClientOnUIThread, |
+ devtools_id, |
+ IPC::Message(message))); |
+} |
+ |
+void WorkerDevToolsManager::ForwardToWorkerDevToolsAgent( |
+ int worker_devtools_id, |
+ const IPC::Message& message) { |
+ WorkerProcessHost* host; |
+ int route_id; |
+ if (!devtools_worker_ids_->FindWorkerInfo( |
+ worker_devtools_id, &host, &route_id)) |
+ return; |
+ IPC::Message* msg = new IPC::Message(message); |
+ msg->set_routing_id(route_id); |
+ host->Send(msg); |
+} |
+ |
+void WorkerDevToolsManager::WorkerProcessDestroying( |
+ int worker_process_host_id) { |
+ devtools_worker_ids_->WorkerDevToolsMessageFilterClosing( |
+ worker_process_host_id); |
+} |
+ |