summaryrefslogtreecommitdiffstats
path: root/chrome/browser/debugger/devtools_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/debugger/devtools_manager.cc')
-rw-r--r--chrome/browser/debugger/devtools_manager.cc202
1 files changed, 202 insertions, 0 deletions
diff --git a/chrome/browser/debugger/devtools_manager.cc b/chrome/browser/debugger/devtools_manager.cc
new file mode 100644
index 0000000..41d0f7a
--- /dev/null
+++ b/chrome/browser/debugger/devtools_manager.cc
@@ -0,0 +1,202 @@
+// Copyright (c) 2009 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 "chrome/browser/debugger/devtools_manager.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/debugger/devtools_window.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/tab_contents/render_view_host_manager.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_type.h"
+
+
+class DevToolsInstanceDescriptorImpl : public DevToolsInstanceDescriptor {
+ public:
+ explicit DevToolsInstanceDescriptorImpl(
+ NavigationController* navigation_controller)
+ : navigation_controller_(navigation_controller),
+ devtools_host_(NULL),
+ devtools_window_(NULL) {
+ }
+ virtual ~DevToolsInstanceDescriptorImpl() {}
+
+ virtual void SetDevToolsHost(RenderViewHost* render_view_host) {
+ devtools_host_ = render_view_host;
+ }
+
+ virtual void SetDevToolsWindow(DevToolsWindow* window) {
+ devtools_window_ = window;
+ }
+
+ virtual void Destroy() {
+ DevToolsManager* manager = g_browser_process->devtools_manager();
+ DCHECK(manager);
+ if (manager) {
+ manager->RemoveDescriptor(this);
+ }
+ delete this;
+ }
+
+ RenderViewHost* devtools_host() const {
+ return devtools_host_;
+ }
+
+ DevToolsWindow* devtools_window() const {
+ return devtools_window_;
+ }
+
+ NavigationController* navigation_controller() const {
+ return navigation_controller_;
+ }
+
+ private:
+ NavigationController* navigation_controller_;
+ RenderViewHost* devtools_host_;
+ DevToolsWindow* devtools_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsInstanceDescriptorImpl);
+};
+
+DevToolsManager::DevToolsManager() : web_contents_listeners_(NULL) {
+}
+
+DevToolsManager::~DevToolsManager() {
+ DCHECK(!web_contents_listeners_.get()) <<
+ "All devtools windows must alredy have been closed.";
+}
+
+void DevToolsManager::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == NotificationType::WEB_CONTENTS_DISCONNECTED);
+ Source<WebContents> src(source);
+ NavigationController* controller = src->controller();
+ DescriptorMap::const_iterator it =
+ navcontroller_to_descriptor_.find(controller);
+ if (it == navcontroller_to_descriptor_.end()) {
+ return;
+ }
+ bool active = (controller->active_contents() == src.ptr());
+ if (!active) {
+ return;
+ }
+ // Active tab contents disconnecting from its renderer means that the tab
+ // is closing so we are closing devtools as well.
+ it->second->devtools_window()->Close();
+}
+
+void DevToolsManager::ShowDevToolsForWebContents(WebContents* web_contents) {
+ NavigationController* navigation_controller = web_contents->controller();
+
+ DevToolsWindow* window(NULL);
+ DevToolsInstanceDescriptorImpl* desc(NULL);
+ DescriptorMap::const_iterator it =
+ navcontroller_to_descriptor_.find(navigation_controller);
+ if (it != navcontroller_to_descriptor_.end()) {
+ desc = it->second;
+ window = desc->devtools_window();
+ } else {
+ desc = new DevToolsInstanceDescriptorImpl(navigation_controller);
+ navcontroller_to_descriptor_[navigation_controller] = desc;
+
+ StartListening(navigation_controller);
+
+ window = DevToolsWindow::Create(desc);
+ }
+
+ window->Show();
+}
+
+void DevToolsManager::ForwardToDevToolsAgent(RenderViewHost* from,
+ const IPC::Message& message) {
+ NavigationController* nav_controller(NULL);
+ for (DescriptorMap::const_iterator it = navcontroller_to_descriptor_.begin();
+ it != navcontroller_to_descriptor_.end();
+ ++it) {
+ if (it->second->devtools_host() == from) {
+ nav_controller = it->second->navigation_controller();
+ break;
+ }
+ }
+
+ if (!nav_controller) {
+ NOTREACHED();
+ return;
+ }
+
+ // TODO(yurys): notify client that the agent is no longer available
+ TabContents* tc = nav_controller->active_contents();
+ if (!tc) {
+ return;
+ }
+ WebContents* wc = tc->AsWebContents();
+ if (!wc) {
+ return;
+ }
+ RenderViewHost* target_host = wc->render_view_host();
+ if (!target_host) {
+ return;
+ }
+
+ IPC::Message* m = new IPC::Message(message);
+ m->set_routing_id(target_host->routing_id());
+ target_host->Send(m);
+}
+
+void DevToolsManager::ForwardToDevToolsClient(RenderViewHost* from,
+ const IPC::Message& message) {
+ WebContents* wc = from->delegate()->GetAsWebContents();
+ if (!wc) {
+ NOTREACHED();
+ return;
+ }
+
+ NavigationController* navigation_controller = wc->controller();
+
+ DescriptorMap::const_iterator it =
+ navcontroller_to_descriptor_.find(navigation_controller);
+ if (it == navcontroller_to_descriptor_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ RenderViewHost* target_host = it->second->devtools_host();
+ IPC::Message* m = new IPC::Message(message);
+ m->set_routing_id(target_host->routing_id());
+ target_host->Send(m);
+}
+
+void DevToolsManager::RemoveDescriptor(
+ DevToolsInstanceDescriptorImpl* descriptor) {
+ NavigationController* navigation_controller =
+ descriptor->navigation_controller();
+ // This should be done before StopListening as the latter checks number of
+ // alive devtools instances.
+ navcontroller_to_descriptor_.erase(navigation_controller);
+ StopListening(navigation_controller);
+}
+
+
+void DevToolsManager::StartListening(
+ NavigationController* navigation_controller) {
+ // TODO(yurys): add render host change listener
+ if (!web_contents_listeners_.get()) {
+ web_contents_listeners_.reset(new NotificationRegistrar);
+ web_contents_listeners_->Add(
+ this,
+ NotificationType::WEB_CONTENTS_DISCONNECTED,
+ NotificationService::AllSources());
+ }
+}
+
+void DevToolsManager::StopListening(
+ NavigationController* navigation_controller) {
+ DCHECK(web_contents_listeners_.get());
+ if (navcontroller_to_descriptor_.empty()) {
+ web_contents_listeners_.reset();
+ }
+}