Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1250)

Unified Diff: content/browser/debugger/worker_devtools_manager.cc

Issue 7248076: DevTools: add initial support for shared workers debugging (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..6c59684033ac5b4b3b315c2f5e63806340845bea
--- /dev/null
+++ b/content/browser/debugger/worker_devtools_manager.cc
@@ -0,0 +1,298 @@
+// 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 "chrome/browser/profiles/profile_manager.h"
+#include "content/browser/browser_thread.h"
+#include "content/browser/debugger/devtools_manager.h"
+#include "content/browser/debugger/devtools_window.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 {
pfeldman 2011/07/08 09:17:17 IdsIOMap
yurys 2011/07/08 15:35:53 Done.
+ 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) {
pfeldman 2011/07/08 09:17:17 Does it fit one line?
yurys 2011/07/08 15:35:53 Done.
+ if (it->a->id() == worker_process_host_id && it->b == route_id)
pfeldman 2011/07/08 09:17:17 it-a-id? do we want a struct?
yurys 2011/07/08 15:35:53 Done.
+ return it->c;
+ }
+ return -1;
+ }
+
+ bool FindWorkerInfo(
+ int devtools_id,
pfeldman 2011/07/08 09:17:17 why line break?
yurys 2011/07/08 15:35:53 Doesn't fit on 1 line.
+ WorkerProcessHost** host,
+ int* route_id) {
+ for (IdMap::iterator it = map_.begin();
pfeldman 2011/07/08 09:17:17 ditto
yurys 2011/07/08 15:35:53 Done.
+ 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);
+};
+
+namespace {
+
+void ForwardToWorkerDevToolsAgentOnIOThread(
+ int worker_devtools_id,
+ const IPC::Message& message) {
+ WorkerDevToolsManager::GetInstance()->ForwardToWorkerDevToolsAgent(
+ worker_devtools_id, message);
+}
+
+void NotifyWorkerDevToolsClientClosingOnIOThread(int worker_devtools_id) {
+ WorkerDevToolsManager::GetInstance()->WorkerDevToolsClientClosing(
pfeldman 2011/07/08 09:17:17 WorkerDevToolsManagerIO
yurys 2011/07/08 15:35:53 Done.
+ worker_devtools_id);
+}
+
+class WorkerDevToolsClients : public DevToolsClientHost::CloseListener {
pfeldman 2011/07/08 09:17:17 Can Clients be merged with the Ids?
yurys 2011/07/08 15:35:53 No, they live on different threads.
+ public:
+ static WorkerDevToolsClients* GetInstance() {
+ static WorkerDevToolsClients* instance = new WorkerDevToolsClients();
+ return instance;
+ }
+
+ DevToolsClientHost* FindDevToolsClient(int worker_devtools_id) {
+ WorkerIdToClientHostMap::iterator it =
+ worker_id_to_client_host_.find(worker_devtools_id);
+ if (it == worker_id_to_client_host_.end())
+ return NULL;
+ return it->second;
+ }
+
+ int FindWorkerDevToolsId(DevToolsClientHost* client_host) {
+ for (WorkerIdToClientHostMap::const_iterator it =
+ worker_id_to_client_host_.begin();
+ it != worker_id_to_client_host_.end(); ++it) {
+ if (it->second == client_host)
+ return it->first;
+ }
+ return -1;
+ }
+
+ void RegisterDevToolsClientForWorker(
+ int worker_devtools_id,
+ DevToolsClientHost* client) {
+ client->set_close_listener(this);
+ worker_id_to_client_host_[worker_devtools_id] = client;
+ }
+
+ private:
+ WorkerDevToolsClients() {}
+ virtual ~WorkerDevToolsClients() {}
+
+ virtual void ClientHostClosing(DevToolsClientHost* host) {
+ WorkerIdToClientHostMap::iterator it = worker_id_to_client_host_.begin();
+ for (; it != worker_id_to_client_host_.end(); ++it) {
+ if (it->second == host) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(NotifyWorkerDevToolsClientClosingOnIOThread,
+ it->first));
+ worker_id_to_client_host_.erase(it);
+ return;
+ }
+ }
+ }
+
+ typedef std::map<int, DevToolsClientHost*> WorkerIdToClientHostMap;
+ WorkerIdToClientHostMap worker_id_to_client_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsClients);
+};
+
+} // namespace
+
+// static
+WorkerDevToolsManager* WorkerDevToolsManager::GetInstance() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return Singleton<WorkerDevToolsManager>::get();
+}
+
+WorkerDevToolsManager::WorkerDevToolsManager()
+ : devtools_worker_ids_(new DevToolsWorkerIds()) {
+}
+
+WorkerDevToolsManager::~WorkerDevToolsManager() {
+}
+
+
+bool WorkerDevToolsManager::ForwardToWorkerDevToolsAgent(
+ DevToolsClientHost* from,
+ const IPC::Message& message) {
+ int worker_devtools_id = WorkerDevToolsClients::GetInstance()->
+ FindWorkerDevToolsId(from);
+ if (worker_devtools_id == -1)
+ return false;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(
+ ForwardToWorkerDevToolsAgentOnIOThread,
+ worker_devtools_id,
+ IPC::Message(message)));
+ return true;
+}
+
+static void OpenDevToolsForWorkerOnUIThread(
+ int worker_devtools_id) {
+ Profile* profile = ProfileManager::GetDefaultProfile();
+ if (!profile)
+ return;
+ DevToolsWindow* window = DevToolsWindow::CreateDevToolsWindow(profile);
+ window->Show(DEVTOOLS_TOGGLE_ACTION_NONE);
+ WorkerDevToolsClients::GetInstance()->RegisterDevToolsClientForWorker(
+ worker_devtools_id, window);
+}
+
+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) {
+ DevToolsClientHost* client = WorkerDevToolsClients::GetInstance()->
+ FindDevToolsClient(worker_devtools_id);
+ if (client)
+ client->SendMessageToClient(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);
+}
+
« no previous file with comments | « content/browser/debugger/worker_devtools_manager.h ('k') | content/browser/debugger/worker_devtools_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698