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

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

Issue 7248076: DevTools: add initial support for shared workers debugging (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments addressed 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_io.cc
diff --git a/content/browser/debugger/worker_devtools_manager_io.cc b/content/browser/debugger/worker_devtools_manager_io.cc
new file mode 100644
index 0000000000000000000000000000000000000000..55fe5a4f8144f9c411b560072b0ac1b2d19d9e95
--- /dev/null
+++ b/content/browser/debugger/worker_devtools_manager_io.cc
@@ -0,0 +1,306 @@
+// 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_io.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"
+
+namespace {
+
+
pfeldman 2011/07/11 12:07:16 Blank line
yurys 2011/07/11 15:13:11 Done.
+void NotifyWorkerDevToolsClientClosingOnIOThread(int worker_process_host_id,
+ int worker_route_id) {
+ WorkerDevToolsManagerIO::GetInstance()->WorkerDevToolsClientClosing(
+ worker_process_host_id,
+ worker_route_id);
+}
+
+class WorkerDevToolsClients : public DevToolsClientHost::CloseListener {
pfeldman 2011/07/11 12:07:16 ClientsUI ?
yurys 2011/07/11 15:13:11 Done.
+ public:
+ static WorkerDevToolsClients* GetInstance() {
+ static WorkerDevToolsClients* instance = new WorkerDevToolsClients();
+ return instance;
+ }
+
+ DevToolsClientHost* FindDevToolsClient(int worker_process_host_id,
+ int worker_route_id) {
+ WorkerIdToClientHostMap::iterator it =
+ worker_id_to_client_host_.find(WorkerId(worker_process_host_id,
+ worker_route_id));
+ if (it == worker_id_to_client_host_.end())
+ return NULL;
+ return it->second;
+ }
+
+ bool FindWorkerInfo(DevToolsClientHost* client_host,
+ int* host_id,
+ int* route_id) {
+ for (WorkerIdToClientHostMap::const_iterator it =
+ worker_id_to_client_host_.begin();
+ it != worker_id_to_client_host_.end(); ++it) {
+ if (it->second == client_host) {
+ WorkerId id = it->first;
+ *host_id = id.first;
+ *route_id = id.second;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void RegisterDevToolsClientForWorker(int worker_process_host_id,
+ int worker_route_id,
+ DevToolsClientHost* client) {
+ client->set_close_listener(this);
+ WorkerId worker_id(worker_process_host_id, worker_route_id);
+ worker_id_to_client_host_[worker_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) {
+ WorkerId id = it->first;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(NotifyWorkerDevToolsClientClosingOnIOThread,
+ id.first, id.second));
+ worker_id_to_client_host_.erase(it);
+ return;
+ }
+ }
+ }
+
+ typedef std::pair<int, int> WorkerId;
+ typedef std::map<WorkerId, DevToolsClientHost*> WorkerIdToClientHostMap;
+ WorkerIdToClientHostMap worker_id_to_client_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsClients);
+};
+
+} // namespace
+
+class WorkerDevToolsManagerIO::InspectedWorkersList {
+ public:
+ InspectedWorkersList() {}
+
+ void AddInstance(WorkerProcessHost* host, int route_id) {
+ DCHECK(!Contains(host->id(), route_id));
+ map_.push_back(Entry(host, route_id));
+ }
+
+ bool Contains(int host_id, int route_id) {
+ return FindHost(host_id, route_id) != NULL;
+ }
+
+ WorkerProcessHost* FindHost(int host_id, int route_id) {
+ Entries::iterator it = FindEntry(host_id, route_id);
+ if (it == map_.end())
+ return NULL;
+ return it->host;
+ }
+
+ WorkerProcessHost* RemoveInstance(int host_id, int route_id) {
+ Entries::iterator it = FindEntry(host_id, route_id);
+ if (it == map_.end())
+ return NULL;
+ WorkerProcessHost* host = it->host;
+ map_.erase(it);
+ return host;
+ }
+
+ void WorkerDevToolsMessageFilterClosing(int worker_process_host_id) {
+ Entries::iterator it = map_.begin();
+ while (it != map_.end()) {
+ if (it->host->id() == worker_process_host_id)
+ it = map_.erase(it);
+ else
+ ++it;
+ }
+ }
+
+ private:
+ struct Entry {
+ Entry(WorkerProcessHost* host, int route_id)
+ : host(host),
+ route_id(route_id) {}
+ WorkerProcessHost* const host;
+ int const route_id;
+ };
+ typedef std::list<Entry> Entries;
+
+ Entries::iterator FindEntry(int host_id, int route_id) {
+ Entries::iterator it = map_.begin();
+ while (it != map_.end()) {
+ if (it->host->id() == host_id && it->route_id == route_id)
+ break;
+ }
+ return it;
+ }
+
+ Entries map_;
+ DISALLOW_COPY_AND_ASSIGN(InspectedWorkersList);
+};
+
+// static
+WorkerDevToolsManagerIO* WorkerDevToolsManagerIO::GetInstance() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return Singleton<WorkerDevToolsManagerIO>::get();
+}
+
+WorkerDevToolsManagerIO::WorkerDevToolsManagerIO()
+ : inspected_workers_(new InspectedWorkersList()) {
+}
+
+WorkerDevToolsManagerIO::~WorkerDevToolsManagerIO() {
+}
+
+bool WorkerDevToolsManagerIO::ForwardToWorkerDevToolsAgentOnUIThread(
+ DevToolsClientHost* from,
+ const IPC::Message& message) {
+ int worker_process_host_id;
+ int worker_route_id;
+ if (!WorkerDevToolsClients::GetInstance()->FindWorkerInfo(
+ from, &worker_process_host_id, &worker_route_id))
+ return false;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(
+ ForwardToWorkerDevToolsAgentOnIOThread,
+ worker_process_host_id,
+ worker_route_id,
+ IPC::Message(message)));
+ return true;
+}
+
+static void OpenDevToolsForWorkerOnUIThread(int worker_process_host_id,
+ int worker_route_id) {
+ Profile* profile = ProfileManager::GetDefaultProfile();
+ if (!profile)
+ return;
+ DevToolsWindow* window = DevToolsWindow::CreateDevToolsWindowForWorker(
+ profile);
+ window->Show(DEVTOOLS_TOGGLE_ACTION_NONE);
+ WorkerDevToolsClients::GetInstance()->RegisterDevToolsClientForWorker(
+ worker_process_host_id, worker_route_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 WorkerDevToolsManagerIO::OpenDevToolsForWorker(int worker_process_host_id,
+ int worker_route_id) {
+ WorkerProcessHost* host = FindWorkerProcessHostForWorker(
+ worker_process_host_id,
+ worker_route_id);
+ if (!host)
+ return;
+
+ // DevTools client is already attached.
+ if (inspected_workers_->Contains(worker_process_host_id, worker_route_id))
+ return;
+
+ host->Send(new WorkerDevToolsAgentMsg_Attach(worker_route_id));
+
+ inspected_workers_->AddInstance(host, worker_route_id);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableFunction(
+ OpenDevToolsForWorkerOnUIThread,
+ worker_process_host_id,
+ worker_route_id));
+}
+
+void WorkerDevToolsManagerIO::WorkerDevToolsClientClosing(
+ int worker_process_host_id,
+ int worker_route_id) {
+ WorkerProcessHost* host = inspected_workers_->RemoveInstance(
+ worker_process_host_id, worker_route_id);
+ if (host)
+ host->Send(new WorkerDevToolsAgentMsg_Detach(worker_route_id));
+}
+
+static void ForwardToDevToolsClientOnUIThread(
+ int worker_process_host_id,
+ int worker_route_id,
+ const IPC::Message& message) {
+ DevToolsClientHost* client = WorkerDevToolsClients::GetInstance()->
+ FindDevToolsClient(worker_process_host_id, worker_route_id);
+ if (client)
+ client->SendMessageToClient(message);
+}
+
+void WorkerDevToolsManagerIO::ForwardToDevToolsClient(
+ int worker_process_host_id,
+ int worker_route_id,
+ const IPC::Message& message) {
+ if (!inspected_workers_->Contains(worker_process_host_id, worker_route_id)) {
+ NOTREACHED();
+ return;
+ }
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableFunction(
+ ForwardToDevToolsClientOnUIThread,
+ worker_process_host_id,
+ worker_route_id,
+ IPC::Message(message)));
+}
+
+void WorkerDevToolsManagerIO::WorkerProcessDestroying(
+ int worker_process_host_id) {
+ inspected_workers_->WorkerDevToolsMessageFilterClosing(
+ worker_process_host_id);
+}
+
+void WorkerDevToolsManagerIO::ForwardToWorkerDevToolsAgentOnIOThread(
+ int worker_process_host_id,
+ int worker_route_id,
+ const IPC::Message& message) {
+ WorkerDevToolsManagerIO::GetInstance()->ForwardToWorkerDevToolsAgent(
+ worker_process_host_id, worker_route_id, message);
+}
+
+void WorkerDevToolsManagerIO::ForwardToWorkerDevToolsAgent(
+ int worker_process_host_id,
+ int worker_route_id,
+ const IPC::Message& message) {
+ WorkerProcessHost* host = inspected_workers_->FindHost(
+ worker_process_host_id,
+ worker_route_id);
+ if (!host)
+ return;
+ IPC::Message* msg = new IPC::Message(message);
+ msg->set_routing_id(worker_route_id);
+ host->Send(msg);
+}

Powered by Google App Engine
This is Rietveld 408576698