diff options
-rw-r--r-- | chrome/browser/browser.cc | 15 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 3 | ||||
-rw-r--r-- | chrome/browser/debugger/debugger.scons | 1 | ||||
-rw-r--r-- | chrome/browser/debugger/debugger.vcproj | 4 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_client_host.h | 62 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_manager.cc | 190 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_manager.h | 108 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_manager_unittest.cc | 117 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_view.cc | 37 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_view.h | 11 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_window.h | 27 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_window_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_window_mac.cc | 2 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_window_win.cc | 26 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_window_win.h | 10 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 5 | ||||
-rw-r--r-- | chrome/chrome.gyp | 1 | ||||
-rw-r--r-- | chrome/test/data/purify/unit_tests.exe.gtest.txt | 3 |
18 files changed, 336 insertions, 288 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index b45ab43..b2d7f7b 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -16,6 +16,7 @@ #include "chrome/browser/browser_window.h" #include "chrome/browser/character_encoding.h" #include "chrome/browser/debugger/devtools_manager.h" +#include "chrome/browser/debugger/devtools_window.h" #include "chrome/browser/location_bar.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/net/url_fixer_upper.h" @@ -941,11 +942,19 @@ void Browser::OpenDebuggerWindow() { #ifndef CHROME_DEBUGGER_DISABLED UserMetrics::RecordAction(L"Debugger", profile_); TabContents* current_tab = GetSelectedTabContents(); - if (current_tab->AsWebContents()) { + WebContents* wc = current_tab->AsWebContents(); + if (wc) { if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableOutOfProcessDevTools)) { - WebContents* wc = current_tab->AsWebContents(); - g_browser_process->devtools_manager()->ShowDevToolsForWebContents(wc); + DevToolsManager* manager = g_browser_process->devtools_manager(); + DevToolsClientHost* host = manager->GetDevToolsClientHostFor(*wc); + if (!host) { + host = DevToolsWindow::Create(); + manager->RegisterDevToolsClientHostFor(*wc, host); + } + DevToolsWindow* window = host->AsDevToolsWindow(); + if (window) + window->Show(); } else { // Only one debugger instance can exist at a time right now. // TODO(erikkay): need an alert, dialog, something diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 1e4d0aa..5e1d9f3 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -363,8 +363,7 @@ void BrowserProcessImpl::CreateDebuggerWrapper(int port) { void BrowserProcessImpl::CreateDevToolsManager() { DCHECK(!devtools_manager_.get()); created_devtools_manager_ = true; - devtools_manager_.reset(new DevToolsManager( - NULL /*Create DevToolsWindows directly*/)); + devtools_manager_.reset(new DevToolsManager()); } void BrowserProcessImpl::CreateAcceleratorHandler() { diff --git a/chrome/browser/debugger/debugger.scons b/chrome/browser/debugger/debugger.scons index adcc4a7..0990813 100644 --- a/chrome/browser/debugger/debugger.scons +++ b/chrome/browser/debugger/debugger.scons @@ -53,6 +53,7 @@ input_files = ChromeFileList([ 'debugger_window.h', 'debugger_wrapper.cc', 'debugger_wrapper.h', + 'devtools_client_host.h', 'devtools_manager.h', 'devtools_manager.cc', 'devtools_view.cc', diff --git a/chrome/browser/debugger/debugger.vcproj b/chrome/browser/debugger/debugger.vcproj index 8fdb2f5..e40fb81 100644 --- a/chrome/browser/debugger/debugger.vcproj +++ b/chrome/browser/debugger/debugger.vcproj @@ -206,6 +206,10 @@ > </File> <File + RelativePath=".\devtools_client_host.h" + > + </File> + <File RelativePath=".\devtools_manager.cc" > </File> diff --git a/chrome/browser/debugger/devtools_client_host.h b/chrome/browser/debugger/devtools_client_host.h new file mode 100644 index 0000000..71534fb --- /dev/null +++ b/chrome/browser/debugger/devtools_client_host.h @@ -0,0 +1,62 @@ +// 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. + +#ifndef CHROME_BROWSER_DEBUGGER_DEVTOOLS_CLIENT_HOST_H_ +#define CHROME_BROWSER_DEBUGGER_DEVTOOLS_CLIENT_HOST_H_ + +#include "base/basictypes.h" + +namespace IPC { +class Message; +} + +class DevToolsWindow; + +// Describes interface for managing devtools clients from browser process. There +// are currently two types of clients: devtools windows and TCP socket +// debuggers. +class DevToolsClientHost { + public: + class CloseListener { + public: + CloseListener() {} + virtual ~CloseListener() {} + virtual void ClientHostClosing(DevToolsClientHost* host) = 0; + private: + DISALLOW_COPY_AND_ASSIGN(CloseListener); + }; + + virtual ~DevToolsClientHost() {} + + // This method is called when tab inspected by this devtools client is + // closing. + virtual void InspectedTabClosing() = 0; + + // Sends the message to the devtools client hosted by this object. + virtual void SendMessageToClient(const IPC::Message& msg) = 0; + + void set_close_listener(CloseListener* listener) { + close_listener_ = listener; + } + + virtual DevToolsWindow* AsDevToolsWindow() { return NULL; } + + protected: + DevToolsClientHost() : close_listener_(NULL) {} + + // Should be called when the devtools client is going to die and this + // DevToolsClientHost should not be used anymore. + void NotifyCloseListener() { + if (close_listener_) { + close_listener_->ClientHostClosing(this); + close_listener_ = NULL; + } + } + + private: + CloseListener* close_listener_; + DISALLOW_COPY_AND_ASSIGN(DevToolsClientHost); +}; + +#endif // CHROME_BROWSER_DEBUGGER_DEVTOOLS_CLIENT_HOST_H_ diff --git a/chrome/browser/debugger/devtools_manager.cc b/chrome/browser/debugger/devtools_manager.cc index 8a4edf4..470fb5c 100644 --- a/chrome/browser/debugger/devtools_manager.cc +++ b/chrome/browser/debugger/devtools_manager.cc @@ -5,132 +5,89 @@ #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/debugger/devtools_window.h" +#include "chrome/browser/debugger/devtools_client_host.h" #include "chrome/browser/renderer_host/render_view_host.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( - DevToolsManager* manager, - NavigationController* navigation_controller) - : manager_(manager), - 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() { - 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: - DevToolsManager* manager_; - NavigationController* navigation_controller_; - RenderViewHost* devtools_host_; - DevToolsWindow* devtools_window_; - - DISALLOW_COPY_AND_ASSIGN(DevToolsInstanceDescriptorImpl); -}; - -DevToolsManager::DevToolsManager(DevToolsWindowFactory* factory) - : web_contents_listeners_(NULL), - devtools_window_factory_(factory) { +DevToolsManager::DevToolsManager() : web_contents_listeners_(NULL) { } DevToolsManager::~DevToolsManager() { DCHECK(!web_contents_listeners_.get()) << - "All devtools windows must alredy have been closed."; -} - -DevToolsWindow* DevToolsManager::CreateDevToolsWindow( - DevToolsInstanceDescriptor* descriptor) { - if (devtools_window_factory_) { - return devtools_window_factory_->CreateDevToolsWindow(descriptor); - } else { - return DevToolsWindow::Create(descriptor); - } + "All devtools client hosts must alredy have been destroyed."; + DCHECK(navcontroller_to_client_host_.empty()); + DCHECK(client_host_to_navcontroller_.empty()); } 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()) { + DevToolsClientHost* client_host = GetDevToolsClientHostFor(*src.ptr()); + if (!client_host) { return; } + + NavigationController* controller = src->controller(); bool active = (controller->active_contents() == src.ptr()); - if (!active) { - return; + if (active) { + // Active tab contents disconnecting from its renderer means that the tab + // is closing. + client_host->InspectedTabClosing(); } - // 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(); +DevToolsClientHost* DevToolsManager::GetDevToolsClientHostFor( + const WebContents& web_contents) { + NavigationController* navigation_controller = web_contents.controller(); + ClientHostMap::const_iterator it = + navcontroller_to_client_host_.find(navigation_controller); + if (it != navcontroller_to_client_host_.end()) { + return it->second; + } + return NULL; +} - 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(this, navigation_controller); - navcontroller_to_descriptor_[navigation_controller] = desc; +void DevToolsManager::RegisterDevToolsClientHostFor( + const WebContents& web_contents, + DevToolsClientHost* client_host) { + DCHECK(!GetDevToolsClientHostFor(web_contents)); - StartListening(navigation_controller); + NavigationController* navigation_controller = web_contents.controller(); + navcontroller_to_client_host_[navigation_controller] = client_host; + client_host_to_navcontroller_[client_host] = navigation_controller; + client_host->set_close_listener(this); - window = CreateDevToolsWindow(desc); - } - - window->Show(); + StartListening(navigation_controller); } -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(); +void DevToolsManager::ForwardToDevToolsAgent( + const RenderViewHost& client_rvh, + const IPC::Message& message) { + for (ClientHostMap::const_iterator it = + navcontroller_to_client_host_.begin(); + it != navcontroller_to_client_host_.end(); ++it) { - if (it->second->devtools_host() == from) { - nav_controller = it->second->navigation_controller(); - break; + DevToolsWindow* win = it->second->AsDevToolsWindow(); + if (!win) { + continue; + } + if (win->HasRenderViewHost(client_rvh)) { + ForwardToDevToolsAgent(*win, message); + return; } } +} +void DevToolsManager::ForwardToDevToolsAgent(const DevToolsClientHost& from, + const IPC::Message& message) { + NavigationController* nav_controller = + GetDevToolsAgentNavigationController(from); if (!nav_controller) { NOTREACHED(); return; @@ -155,39 +112,43 @@ void DevToolsManager::ForwardToDevToolsAgent(RenderViewHost* from, target_host->Send(m); } -void DevToolsManager::ForwardToDevToolsClient(RenderViewHost* from, +void DevToolsManager::ForwardToDevToolsClient(const RenderViewHost& from, const IPC::Message& message) { - WebContents* wc = from->delegate()->GetAsWebContents(); + 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()) { + DevToolsClientHost* target_host = GetDevToolsClientHostFor(*wc); + if (!target_host) { 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); + target_host->SendMessageToClient(message); } -void DevToolsManager::RemoveDescriptor( - DevToolsInstanceDescriptorImpl* descriptor) { - NavigationController* navigation_controller = - descriptor->navigation_controller(); +void DevToolsManager::ClientHostClosing(DevToolsClientHost* host) { + NavigationController* controller = GetDevToolsAgentNavigationController( + *host); + DCHECK(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); + navcontroller_to_client_host_.erase(controller); + client_host_to_navcontroller_.erase(host); + + StopListening(controller); } +NavigationController* DevToolsManager::GetDevToolsAgentNavigationController( + const DevToolsClientHost& client_host) { + NavControllerMap::const_iterator it = + client_host_to_navcontroller_.find(&client_host); + if (it != client_host_to_navcontroller_.end()) { + return it->second; + } + return NULL; +} void DevToolsManager::StartListening( NavigationController* navigation_controller) { @@ -204,7 +165,8 @@ void DevToolsManager::StartListening( void DevToolsManager::StopListening( NavigationController* navigation_controller) { DCHECK(web_contents_listeners_.get()); - if (navcontroller_to_descriptor_.empty()) { + if (navcontroller_to_client_host_.empty()) { + DCHECK(client_host_to_navcontroller_.empty()); web_contents_listeners_.reset(); } } diff --git a/chrome/browser/debugger/devtools_manager.h b/chrome/browser/debugger/devtools_manager.h index ce6ee73..fe1c803 100644 --- a/chrome/browser/debugger/devtools_manager.h +++ b/chrome/browser/debugger/devtools_manager.h @@ -9,104 +9,84 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" +#include "chrome/browser/debugger/devtools_client_host.h" #include "chrome/common/notification_service.h" namespace IPC { class Message; } -class DevToolsInstanceDescriptor; -class DevToolsInstanceDescriptorImpl; -class DevToolsWindow; -class DevToolsWindowFactory; +class DevToolsClientHost; class NavigationController; class NotificationRegistrar; class RenderViewHost; class WebContents; -// This class is a singleton that manages DevToolsWindow instances and routes -// messages between developer tools clients and agents. -class DevToolsManager : public NotificationObserver { +// This class is a singleton that manages DevToolsClientHost instances and +// routes messages between developer tools clients and agents. +class DevToolsManager : public NotificationObserver, + public DevToolsClientHost::CloseListener { public: - // If the factory is NULL, this will create DevToolsWindow objects using - // DevToolsWindow::Create static method. - DevToolsManager(DevToolsWindowFactory* factory); + DevToolsManager(); virtual ~DevToolsManager(); - // Opend developer tools window for |web_contents|. If there is already - // one it will be revealed otherwise a new instance will be created. The - // devtools window is actually opened for the tab owning |web_contents|. If - // navigation occurs in it causing change of contents in the tab the devtools - // window will attach to the new contents. When the tab is closed the manager - // will close related devtools window. - void ShowDevToolsForWebContents(WebContents* web_contents); + // Returns DevToolsClientHost registered for |web_contents| or NULL if + // there is no alive DevToolsClientHost registered for |web_contents|. + DevToolsClientHost* GetDevToolsClientHostFor(const WebContents& web_contents); - void ForwardToDevToolsAgent(RenderViewHost* from, + // Registers new DevToolsClientHost for |web_contents|. There must be no + // other DevToolsClientHosts registered for the WebContents at the moment. + void RegisterDevToolsClientHostFor(const WebContents& web_contents, + DevToolsClientHost* client_host); + + void ForwardToDevToolsAgent(const RenderViewHost& client_rvh, + const IPC::Message& message); + void ForwardToDevToolsAgent(const DevToolsClientHost& from, const IPC::Message& message); - void ForwardToDevToolsClient(RenderViewHost* from, + void ForwardToDevToolsClient(const RenderViewHost& from, const IPC::Message& message); private: - // Creates a DevToolsWindow using devtools_window_factory_ or by calling - // DevToolsWindow::Create, if the factory is NULL. All DevToolsWindows should - // be created by means of this method. - DevToolsWindow* CreateDevToolsWindow(DevToolsInstanceDescriptor* descriptor); - // NotificationObserver override. virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); - friend class DevToolsInstanceDescriptorImpl; + // DevToolsClientHost::CloseListener override. + // This method will remove all references from the manager to the + // DevToolsClientHost and unregister all listeners related to the + // DevToolsClientHost. + virtual void ClientHostClosing(DevToolsClientHost* host); - // This method is called by DevToolsInstanceDescriptorImpl when it's about - // to be destroyed. It will remove all references from the manager to the - // descriptor and unregister all listeners related to the descriptor. - void RemoveDescriptor(DevToolsInstanceDescriptorImpl* descriptor); + // Returns NavigationController for the tab that is inspected by devtools + // client hosted by DevToolsClientHost. + NavigationController* GetDevToolsAgentNavigationController( + const DevToolsClientHost& client_host); void StartListening(NavigationController* navigation_controller); void StopListening(NavigationController* navigation_controller); - // This object is not NULL iff there is at least one open DevToolsWindow. + // This object is not NULL iff there is at least one registered + // DevToolsClientHost. scoped_ptr<NotificationRegistrar> web_contents_listeners_; - // This maps is for tracking devtools instances opened for browser tabs. It - // allows us to have at most one devtools window per tab. - // We use NavigationController* as key because it survives crosee-site - // navigation in cases when tab contents may change. + // These two maps are for tracking dependencies between inspected tabs and + // their DevToolsClientHosts. They are usful for routing devtools messages + // and allow us to have at most one devtools client host per tab. We use + // NavigationController* as key because it survives crosee-site navigation in + // cases when tab contents may change. // - // This map doesn't own its values but DevToolsInstanceDescriptorImpl is - // expected to call RemoveDescriptor before dying to remove itself from the - // map. - typedef std::map<NavigationController*, - DevToolsInstanceDescriptorImpl*> DescriptorMap; - DescriptorMap navcontroller_to_descriptor_; - DevToolsWindowFactory* devtools_window_factory_; - - DISALLOW_COPY_AND_ASSIGN(DevToolsManager); -}; + // DevToolsManager start listening to DevToolsClientHosts when they are put + // into these maps and removes them when they are closing. + typedef std::map<const NavigationController*, + DevToolsClientHost*> ClientHostMap; + ClientHostMap navcontroller_to_client_host_; + typedef std::map<const DevToolsClientHost*, + NavigationController*> NavControllerMap; + NavControllerMap client_host_to_navcontroller_; -// Incapsulates information about devtools window instance necessary for -// routing devtools messages and managing the window. It should be initialized -// by DevToolsWindow concrete implementation. -class DevToolsInstanceDescriptor { - public: - DevToolsInstanceDescriptor() {} - - virtual void SetDevToolsHost(RenderViewHost* render_view_host) = 0; - virtual void SetDevToolsWindow(DevToolsWindow* window) = 0; - - // This method is called when DevToolsWindow is closing and the descriptor - // becomes invalid. It will clean up DevToolsManager and delete this instance. - virtual void Destroy() = 0; - - protected: - // This method should be called from Destroy only. - virtual ~DevToolsInstanceDescriptor() {} - - private: - DISALLOW_COPY_AND_ASSIGN(DevToolsInstanceDescriptor); + DISALLOW_COPY_AND_ASSIGN(DevToolsManager); }; #endif // CHROME_BROWSER_DEBUGGER_DEVTOOLS_MANAGER_H_ diff --git a/chrome/browser/debugger/devtools_manager_unittest.cc b/chrome/browser/debugger/devtools_manager_unittest.cc index a43f95a..6169f60 100644 --- a/chrome/browser/debugger/devtools_manager_unittest.cc +++ b/chrome/browser/debugger/devtools_manager_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/basictypes.h" +#include "chrome/browser/debugger/devtools_client_host.h" #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/debugger/devtools_window.h" #include "chrome/browser/renderer_host/test_render_view_host.h" @@ -11,68 +12,46 @@ namespace { -class TestDevToolsWindow : public DevToolsWindow { +class TestDevToolsClientHost : public DevToolsClientHost { public: - TestDevToolsWindow(DevToolsInstanceDescriptor* descriptor) - : descriptor_(descriptor), - shown_(false), + TestDevToolsClientHost() + : last_sent_message(NULL), closed_(false) { - descriptor->SetDevToolsWindow(this); } - virtual ~TestDevToolsWindow() { - EXPECT_EQ(shown_, closed_); - } - - virtual void Show() { - open_counter++; - shown_ = true; + virtual ~TestDevToolsClientHost() { + EXPECT_TRUE(closed_); } virtual void Close() { - EXPECT_TRUE(shown_); + EXPECT_FALSE(closed_); close_counter++; - descriptor_->Destroy(); + NotifyCloseListener(); closed_ = true; } + virtual void InspectedTabClosing() { + Close(); + } + + virtual void SendMessageToClient(const IPC::Message& message) { + last_sent_message = &message; + } static void ResetCounters() { - open_counter = 0; close_counter = 0; } - static int open_counter; static int close_counter; + const IPC::Message* last_sent_message; + private: - DevToolsInstanceDescriptor* descriptor_; - bool shown_; bool closed_; - DISALLOW_COPY_AND_ASSIGN(TestDevToolsWindow); + DISALLOW_COPY_AND_ASSIGN(TestDevToolsClientHost); }; -int TestDevToolsWindow::open_counter = 0; -int TestDevToolsWindow::close_counter = 0; - - -class TestDevToolsWindowFactory : public DevToolsWindowFactory { - public: - TestDevToolsWindowFactory() : DevToolsWindowFactory(), - last_created_window(NULL) {} - virtual ~TestDevToolsWindowFactory() {} - - virtual DevToolsWindow* CreateDevToolsWindow( - DevToolsInstanceDescriptor* descriptor) { - last_created_window = new TestDevToolsWindow(descriptor); - return last_created_window; - } - - DevToolsWindow* last_created_window; - - private: - DISALLOW_COPY_AND_ASSIGN(TestDevToolsWindowFactory); -}; +int TestDevToolsClientHost::close_counter = 0; } // namespace @@ -84,27 +63,45 @@ class DevToolsManagerTest : public RenderViewHostTestHarness { protected: virtual void SetUp() { RenderViewHostTestHarness::SetUp(); - TestDevToolsWindow::ResetCounters(); + TestDevToolsClientHost::ResetCounters(); } }; -TEST_F(DevToolsManagerTest, OpenAndManuallyCloseDevToolsWindow) { - TestDevToolsWindowFactory window_factory; - DevToolsManager manager(&window_factory); - - manager.ShowDevToolsForWebContents(contents()); - EXPECT_EQ(TestDevToolsWindow::open_counter, 1); - EXPECT_EQ(TestDevToolsWindow::close_counter, 0); - - DevToolsWindow* window = window_factory.last_created_window; - // Test that same devtools window is used. - manager.ShowDevToolsForWebContents(contents()); - // Check that no new windows were created. - EXPECT_TRUE(window == window_factory.last_created_window); - EXPECT_EQ(TestDevToolsWindow::open_counter, 2); - EXPECT_EQ(TestDevToolsWindow::close_counter, 0); - - window->Close(); - EXPECT_EQ(TestDevToolsWindow::open_counter, 2); - EXPECT_EQ(TestDevToolsWindow::close_counter, 1); +TEST_F(DevToolsManagerTest, OpenAndManuallyCloseDevToolsClientHost) { + DevToolsManager manager; + + DevToolsClientHost* host = manager.GetDevToolsClientHostFor(*contents()); + EXPECT_TRUE(NULL == host); + + TestDevToolsClientHost client_host; + manager.RegisterDevToolsClientHostFor(*contents(), &client_host); + // Test that just registered devtools host is returned. + host = manager.GetDevToolsClientHostFor(*contents()); + EXPECT_TRUE(&client_host == host); + EXPECT_EQ(0, TestDevToolsClientHost::close_counter); + + // Test that the same devtools host is returned. + host = manager.GetDevToolsClientHostFor(*contents()); + EXPECT_TRUE(&client_host == host); + EXPECT_EQ(0, TestDevToolsClientHost::close_counter); + + client_host.Close(); + EXPECT_EQ(1, TestDevToolsClientHost::close_counter); + host = manager.GetDevToolsClientHostFor(*contents()); + EXPECT_TRUE(NULL == host); +} + +TEST_F(DevToolsManagerTest, ForwardMessageToClient) { + DevToolsManager manager; + + TestDevToolsClientHost client_host; + manager.RegisterDevToolsClientHostFor(*contents(), &client_host); + EXPECT_EQ(0, TestDevToolsClientHost::close_counter); + + IPC::Message m; + manager.ForwardToDevToolsClient(*contents()->render_view_host(), m); + EXPECT_TRUE(&m == client_host.last_sent_message); + + client_host.Close(); + EXPECT_EQ(1, TestDevToolsClientHost::close_counter); } diff --git a/chrome/browser/debugger/devtools_view.cc b/chrome/browser/debugger/devtools_view.cc index ca43a94..5913190 100644 --- a/chrome/browser/debugger/devtools_view.cc +++ b/chrome/browser/debugger/devtools_view.cc @@ -7,7 +7,7 @@ #include <string> #include "chrome/browser/browser_list.h" -#include "chrome/browser/debugger/devtools_manager.h" +#include "chrome/browser/debugger/devtools_client_host.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/browser/views/tab_contents_container_view.h" @@ -15,9 +15,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" -DevToolsView::DevToolsView(DevToolsInstanceDescriptor* descriptor) - : descriptor_(descriptor), - web_contents_(NULL) { +DevToolsView::DevToolsView() : web_contents_(NULL) { web_container_ = new TabContentsContainerView(); AddChildView(web_container_); } @@ -58,7 +56,6 @@ void DevToolsView::Init() { web_contents_->set_delegate(this); web_container_->SetTabContents(web_contents_); web_contents_->render_view_host()->AllowDOMUIBindings(); - descriptor_->SetDevToolsHost(web_contents_->render_view_host()); // chrome-ui://devtools/devtools.html GURL contents(std::string(chrome::kChromeUIDevToolsURL) + "devtools.html"); @@ -69,13 +66,31 @@ void DevToolsView::Init() { } void DevToolsView::OnWindowClosing() { - DCHECK(descriptor_) << "OnWindowClosing is called twice"; - if (descriptor_) { - descriptor_->Destroy(); - descriptor_ = NULL; + DCHECK(web_contents_) << "OnWindowClosing is called twice"; + if (web_contents_) { + // Detach last (and only) tab. + web_container_->SetTabContents(NULL); + + // Destroy the tab and navigation controller. + web_contents_->CloseContents(); + web_contents_ = NULL; + } +} + +void DevToolsView::SendMessageToClient(const IPC::Message& message) { + if (web_contents_) { + RenderViewHost* target_host = web_contents_->render_view_host(); + IPC::Message* m = new IPC::Message(message); + m->set_routing_id(target_host->routing_id()); + target_host->Send(m); + } +} + +bool DevToolsView::HasRenderViewHost(const RenderViewHost& rvh) const { + if (web_contents_) { + return (&rvh == web_contents_->render_view_host()); } - web_container_->SetTabContents(NULL); // detach last (and only) tab - web_contents_->CloseContents(); // destroy the tab and navigation controller + return false; } void DevToolsView::OpenURLFromTab(TabContents* source, diff --git a/chrome/browser/debugger/devtools_view.h b/chrome/browser/debugger/devtools_view.h index 2dc956c..873f7e0 100644 --- a/chrome/browser/debugger/devtools_view.h +++ b/chrome/browser/debugger/devtools_view.h @@ -12,18 +12,24 @@ #include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/views/view.h" -class DevToolsInstanceDescriptor; +namespace IPC { +class Message; +} + +class RenderViewHost; class TabContentsContainerView; class WebContents; class DevToolsView : public views::View, public TabContentsDelegate { public: - explicit DevToolsView(DevToolsInstanceDescriptor* descriptor); + explicit DevToolsView(); virtual ~DevToolsView(); // Destroy content views when the window is closing. void OnWindowClosing(); + void SendMessageToClient(const IPC::Message& message); + bool HasRenderViewHost(const RenderViewHost& rvh) const; private: // Overridden from TabContentsDelegate: @@ -63,7 +69,6 @@ class DevToolsView : public views::View, void Init(); - DevToolsInstanceDescriptor* descriptor_; WebContents* web_contents_; TabContentsContainerView* web_container_; diff --git a/chrome/browser/debugger/devtools_window.h b/chrome/browser/debugger/devtools_window.h index 257c44d..da13ae2 100644 --- a/chrome/browser/debugger/devtools_window.h +++ b/chrome/browser/debugger/devtools_window.h @@ -6,32 +6,29 @@ #define CHROME_BROWSER_DEBUGGER_DEV_TOOLS_WINDOW_H_ #include "base/basictypes.h" +#include "chrome/browser/debugger/devtools_client_host.h" -class DevToolsInstanceDescriptor; +class RenderViewHost; -class DevToolsWindow { +class DevToolsWindow : public DevToolsClientHost { public: - static DevToolsWindow* Create(DevToolsInstanceDescriptor* descriptor); + // Factory method for creating platform specific devtools windows. + static DevToolsWindow* Create(); + virtual ~DevToolsWindow() {} - // Show developer tools window. + // Show this window. virtual void Show() = 0; - virtual void Close() = 0; + virtual bool HasRenderViewHost(const RenderViewHost& rvh) const = 0; + + // DevToolsClientHost override. + virtual DevToolsWindow* AsDevToolsWindow() { return this; } protected: - DevToolsWindow() {} + DevToolsWindow() : DevToolsClientHost() {} private: DISALLOW_COPY_AND_ASSIGN(DevToolsWindow); }; -// Factory for creating DevToolsWindows. Useful for unit tests. -class DevToolsWindowFactory { - public: - virtual ~DevToolsWindowFactory() {} - virtual DevToolsWindow* CreateDevToolsWindow( - DevToolsInstanceDescriptor* descriptor) = 0; -}; - - #endif // CHROME_BROWSER_DEBUGGER_DEV_TOOLS_WINDOW_H_ diff --git a/chrome/browser/debugger/devtools_window_gtk.cc b/chrome/browser/debugger/devtools_window_gtk.cc index be7096d..99b37c7 100644 --- a/chrome/browser/debugger/devtools_window_gtk.cc +++ b/chrome/browser/debugger/devtools_window_gtk.cc @@ -7,7 +7,7 @@ #include "base/logging.h" // static -DevToolsWindow* DevToolsWindow::Create(DevToolsInstanceDescriptor* descriptor) { +DevToolsWindow* DevToolsWindow::Create() { NOTIMPLEMENTED(); return NULL; } diff --git a/chrome/browser/debugger/devtools_window_mac.cc b/chrome/browser/debugger/devtools_window_mac.cc index be7096d..99b37c7 100644 --- a/chrome/browser/debugger/devtools_window_mac.cc +++ b/chrome/browser/debugger/devtools_window_mac.cc @@ -7,7 +7,7 @@ #include "base/logging.h" // static -DevToolsWindow* DevToolsWindow::Create(DevToolsInstanceDescriptor* descriptor) { +DevToolsWindow* DevToolsWindow::Create() { NOTIMPLEMENTED(); return NULL; } diff --git a/chrome/browser/debugger/devtools_window_win.cc b/chrome/browser/debugger/devtools_window_win.cc index d5dba5f..25175f5 100644 --- a/chrome/browser/debugger/devtools_window_win.cc +++ b/chrome/browser/debugger/devtools_window_win.cc @@ -6,20 +6,21 @@ #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/debugger/devtools_view.h" +#include "chrome/browser/debugger/devtools_window.h" #include "chrome/views/window/window.h" // static -DevToolsWindow* DevToolsWindow::Create(DevToolsInstanceDescriptor* descriptor) { - DevToolsView* view = new DevToolsView(descriptor); +DevToolsWindow* DevToolsWindow::Create() { + DevToolsView* view = new DevToolsView(); DevToolsWindowWin* window = new DevToolsWindowWin(view); - descriptor->SetDevToolsWindow(window); views::Window::CreateChromeWindow(NULL, gfx::Rect(), window); return window; } DevToolsWindowWin::DevToolsWindowWin(DevToolsView* view) - : tools_view_(view) { + : DevToolsWindow(), + tools_view_(view) { } DevToolsWindowWin::~DevToolsWindowWin() { @@ -34,7 +35,14 @@ void DevToolsWindowWin::Show() { } } -void DevToolsWindowWin::Close() { +bool DevToolsWindowWin::HasRenderViewHost(const RenderViewHost& rvh) const { + if (tools_view_) { + return tools_view_->HasRenderViewHost(rvh); + } + return false; +} + +void DevToolsWindowWin::InspectedTabClosing() { if (window()) { window()->Close(); } else { @@ -42,12 +50,20 @@ void DevToolsWindowWin::Close() { } } +void DevToolsWindowWin::SendMessageToClient(const IPC::Message& message) { + if (tools_view_) { + tools_view_->SendMessageToClient(message); + } +} + std::wstring DevToolsWindowWin::GetWindowTitle() const { return L"Developer Tools"; } void DevToolsWindowWin::WindowClosing() { if (tools_view_) { + NotifyCloseListener(); + ReleaseWindow(); tools_view_->OnWindowClosing(); tools_view_ = NULL; diff --git a/chrome/browser/debugger/devtools_window_win.h b/chrome/browser/debugger/devtools_window_win.h index 0ebf01b..4cea5a3 100644 --- a/chrome/browser/debugger/devtools_window_win.h +++ b/chrome/browser/debugger/devtools_window_win.h @@ -12,7 +12,6 @@ namespace views { class Window; } -class DevToolsInstanceDescriptor; class DevToolsView; class TabContents; @@ -21,13 +20,16 @@ class DevToolsWindowWin : public DevToolsWindow, public: virtual ~DevToolsWindowWin(); - // Show developer tools window. + // DevToolsWindow implementation. virtual void Show(); - virtual void Close(); + virtual bool HasRenderViewHost(const RenderViewHost& rvh) const; + + virtual void InspectedTabClosing(); + virtual void SendMessageToClient(const IPC::Message& message); private: friend class DevToolsWindow; - explicit DevToolsWindowWin(DevToolsView* view); + DevToolsWindowWin(DevToolsView* view); // views::WindowDelegate methods: virtual std::wstring GetWindowTitle() const; diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 6a4160e..826dff2 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1194,11 +1194,12 @@ void RenderViewHost::DidDebugAttach() { } void RenderViewHost::OnForwardToDevToolsAgent(const IPC::Message& message) { - g_browser_process->devtools_manager()->ForwardToDevToolsAgent(this, message); + g_browser_process->devtools_manager()->ForwardToDevToolsAgent(*this, message); } void RenderViewHost::OnForwardToDevToolsClient(const IPC::Message& message) { - g_browser_process->devtools_manager()->ForwardToDevToolsClient(this, message); + g_browser_process->devtools_manager()->ForwardToDevToolsClient(*this, + message); } void RenderViewHost::OnUserMetricsRecordAction(const std::wstring& action) { diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index d0a4246..f75a25e8 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -543,6 +543,7 @@ 'browser/debugger/debugger_window.h', 'browser/debugger/debugger_wrapper.cc', 'browser/debugger/debugger_wrapper.h', + 'browser/debugger/devtools_client_host.h', 'browser/debugger/devtools_manager.h', 'browser/debugger/devtools_manager.cc', 'browser/debugger/devtools_window.h', diff --git a/chrome/test/data/purify/unit_tests.exe.gtest.txt b/chrome/test/data/purify/unit_tests.exe.gtest.txt index 6f0ea56..081eb0b 100644 --- a/chrome/test/data/purify/unit_tests.exe.gtest.txt +++ b/chrome/test/data/purify/unit_tests.exe.gtest.txt @@ -16,6 +16,3 @@ IPCSyncChannelTest.ChattyServer # issue 8362 ExtensionViewTest.Index - -# issue 9150 -DevToolsManagerTest.* |