diff options
author | yurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-16 14:12:53 +0000 |
---|---|---|
committer | yurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-16 14:12:53 +0000 |
commit | 48764c72b775bdc62aa43eedaea00ca01597e9ff (patch) | |
tree | e3f2e20b62de4fbd071b803d3590d9da765b7023 /chrome | |
parent | c855113f01088a707fb7538f6c54e284635cc779 (diff) | |
download | chromium_src-48764c72b775bdc62aa43eedaea00ca01597e9ff.zip chromium_src-48764c72b775bdc62aa43eedaea00ca01597e9ff.tar.gz chromium_src-48764c72b775bdc62aa43eedaea00ca01597e9ff.tar.bz2 |
Review URL: http://codereview.chromium.org/20405
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9855 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
24 files changed, 947 insertions, 3 deletions
diff --git a/chrome/browser/debugger/debugger.scons b/chrome/browser/debugger/debugger.scons index 30d1a65..f34a8f1 100644 --- a/chrome/browser/debugger/debugger.scons +++ b/chrome/browser/debugger/debugger.scons @@ -54,6 +54,12 @@ input_files = ChromeFileList([ 'debugger_window.h', 'debugger_wrapper.cc', 'debugger_wrapper.h', + 'tools_contents.cc', + 'tools_contents.h', + 'tools_view.cc', + 'tools_view.h', + 'tools_window.cc', + 'tools_window.h', ]) if env.Bit('linux'): @@ -62,6 +68,9 @@ if env.Bit('linux'): 'debugger_contents.cc', 'debugger_view.cc', 'debugger_window.cc', + 'tools_contents.cc', + 'tools_view.cc', + 'tools_window.cc', ) if env.Bit('mac'): @@ -72,6 +81,9 @@ if env.Bit('mac'): 'debugger_node.cc', 'debugger_view.cc', 'debugger_window.cc', + 'tools_contents.cc', + 'tools_view.cc', + 'tools_window.cc', ) if not env.Bit('mac'): diff --git a/chrome/browser/debugger/debugger.vcproj b/chrome/browser/debugger/debugger.vcproj index d72b86a..e02dd18 100644 --- a/chrome/browser/debugger/debugger.vcproj +++ b/chrome/browser/debugger/debugger.vcproj @@ -213,6 +213,30 @@ RelativePath=".\debugger_wrapper.h" > </File> + <File + RelativePath=".\tools_contents.cc" + > + </File> + <File + RelativePath=".\tools_contents.h" + > + </File> + <File + RelativePath=".\tools_view.cc" + > + </File> + <File + RelativePath=".\tools_view.h" + > + </File> + <File + RelativePath=".\tools_window.cc" + > + </File> + <File + RelativePath=".\tools_window.h" + > + </File> </Files> <Globals> </Globals> diff --git a/chrome/browser/debugger/tools_contents.cc b/chrome/browser/debugger/tools_contents.cc new file mode 100644 index 0000000..0a95507 --- /dev/null +++ b/chrome/browser/debugger/tools_contents.cc @@ -0,0 +1,42 @@ +// 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/tools_contents.h"
+
+#include "base/singleton.h"
+
+ToolsContents::ToolsContents(Profile* profile, SiteInstance* instance)
+ : WebContents(profile,
+ instance,
+ NULL,
+ MSG_ROUTING_NONE,
+ NULL) {
+ set_type(TAB_CONTENTS_TOOLS);
+}
+
+void ToolsContents::RendererCreated(RenderViewHost* render_view_host) {
+ std::pair<int, int>* render_view_info =
+ ToolsContents::GetInspectedViewInfoAccessor()->GetProperty(
+ property_bag());
+ DCHECK(render_view_info);
+ if (!render_view_info)
+ return;
+
+ render_view_host->SetUpToolsClient(render_view_info->first,
+ render_view_info->second);
+ ToolsContents::GetInspectedViewInfoAccessor()->DeleteProperty(property_bag());
+}
+
+// static
+bool ToolsContents::IsToolsUrl(const GURL& url) {
+ // TODO(yurys): implement
+ return (url.SchemeIs("chrome-ui") && url.host() == "inspector" &&
+ url.path() == "/debugger-oop.html");
+}
+
+// static
+PropertyAccessor<std::pair<int, int> >*
+ ToolsContents::GetInspectedViewInfoAccessor() {
+ return Singleton<PropertyAccessor<std::pair<int, int> > >().get();
+}
diff --git a/chrome/browser/debugger/tools_contents.h b/chrome/browser/debugger/tools_contents.h new file mode 100644 index 0000000..61c804e --- /dev/null +++ b/chrome/browser/debugger/tools_contents.h @@ -0,0 +1,36 @@ +// 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_TOOLS_CONTENTS_H_
+#define CHROME_BROWSER_DEBUGGER_TOOLS_CONTENTS_H_
+
+#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/common/property_bag.h"
+
+// TODO(yurys): it may be made into DOMUI if the latter supports RendererCreated
+// notification.
+class ToolsContents : public WebContents {
+ public:
+ ToolsContents(Profile* profile, SiteInstance* instance);
+
+ static bool IsToolsUrl(const GURL& url);
+
+ // (render process id, render view id)
+ static PropertyAccessor<std::pair<int, int> >* GetInspectedViewInfoAccessor();
+
+ protected:
+ // WebContents overrides:
+ // We override updating history with a no-op so these pages
+ // are not saved to history.
+ virtual void UpdateHistoryForNavigation(const GURL& url,
+ const ViewHostMsg_FrameNavigate_Params& params) { }
+
+ // Will notify just created renderer that it's going to host developer
+ // tools UI.
+ virtual void RendererCreated(RenderViewHost* render_view_host);
+
+ DISALLOW_COPY_AND_ASSIGN(ToolsContents);
+};
+
+#endif // CHROME_BROWSER_DEBUGGER_TOOLS_CONTENTS_H_
diff --git a/chrome/browser/debugger/tools_view.cc b/chrome/browser/debugger/tools_view.cc new file mode 100644 index 0000000..13e04db --- /dev/null +++ b/chrome/browser/debugger/tools_view.cc @@ -0,0 +1,91 @@ +// 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/tools_view.h"
+
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/debugger/tools_contents.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/browser/views/tab_contents_container_view.h"
+#include "chrome/common/property_bag.h"
+#include "chrome/common/render_messages.h"
+
+ToolsView::ToolsView(int inspected_process_id, int inspected_view_id)
+ : inspected_process_id_(inspected_process_id),
+ inspected_view_id_(inspected_view_id),
+ web_contents_(NULL) {
+ web_container_ = new TabContentsContainerView();
+ AddChildView(web_container_);
+}
+
+ToolsView::~ToolsView() {
+}
+
+void ToolsView::SendToolsClientMessage(int tools_message_type,
+ const std::wstring& body) {
+ if (!web_contents_) {
+ NOTREACHED();
+ return;
+ }
+ int routing_id = web_contents_->render_view_host()->routing_id();
+ web_contents_->render_view_host()->Send(
+ new ViewMsg_ToolsClientMsg(routing_id, tools_message_type, body));
+}
+
+std::string ToolsView::GetClassName() const {
+ return "ToolsView";
+}
+
+gfx::Size ToolsView::GetPreferredSize() {
+ return gfx::Size(700, 400);
+}
+
+void ToolsView::Layout() {
+ web_container_->SetBounds(0, 0, width(), height());
+}
+
+void ToolsView::ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
+ if (is_add && child == this) {
+ DCHECK(GetWidget());
+ Init();
+ }
+}
+
+void ToolsView::Init() {
+ // We can't create the WebContents until we've actually been put into a real
+ // view hierarchy somewhere.
+ Profile* profile = BrowserList::GetLastActive()->profile();
+
+ TabContents* tc = TabContents::CreateWithType(TAB_CONTENTS_TOOLS, profile,
+ NULL);
+ web_contents_ = tc->AsWebContents();
+ web_contents_->SetupController(profile);
+ web_contents_->set_delegate(this);
+ web_container_->SetTabContents(web_contents_);
+ web_contents_->render_view_host()->AllowDOMUIBindings();
+
+ ToolsContents::GetInspectedViewInfoAccessor()->SetProperty(
+ web_contents_->property_bag(),
+ std::pair<int, int>(inspected_process_id_, inspected_view_id_));
+
+ GURL contents("chrome-ui://inspector/debugger-oop.html");
+ // this will call CreateRenderView to create renderer process
+ web_contents_->controller()->LoadURL(contents, GURL(),
+ PageTransition::START_PAGE);
+}
+
+void ToolsView::OnWindowClosing() {
+ web_container_->SetTabContents(NULL); // detach last (and only) tab
+ web_contents_->CloseContents(); // destroy the tab and navigation controller
+}
+
+void ToolsView::OpenURLFromTab(TabContents* source,
+ const GURL& url, const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition) {
+ NOTREACHED();
+}
diff --git a/chrome/browser/debugger/tools_view.h b/chrome/browser/debugger/tools_view.h new file mode 100644 index 0000000..1c1de0a --- /dev/null +++ b/chrome/browser/debugger/tools_view.h @@ -0,0 +1,72 @@ +// 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_TOOLS_VIEW_H_
+#define CHROME_BROWSER_DEBUGGER_TOOLS_VIEW_H_
+
+#include "base/basictypes.h"
+#include "base/gfx/size.h"
+#include "chrome/browser/tab_contents/tab_contents_delegate.h"
+#include "chrome/views/view.h"
+
+class TabContentsContainerView;
+class WebContents;
+
+class ToolsView : public views::View,
+ public TabContentsDelegate {
+ public:
+ explicit ToolsView (int inspected_process_id, int inspected_view_id);
+ virtual ~ToolsView();
+
+ void SendToolsClientMessage(int tools_message_type, const std::wstring& body);
+
+ // Destroy content views when the window is closing.
+ void OnWindowClosing();
+
+ private:
+ // Overridden from TabContentsDelegate:
+ virtual void NavigationStateChanged(const TabContents* source,
+ unsigned changed_flags) {}
+ virtual void ReplaceContents(TabContents* source,
+ TabContents* new_contents) {}
+ virtual void AddNewContents(TabContents* source,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {}
+ virtual void ActivateContents(TabContents* contents) {}
+ virtual void LoadingStateChanged(TabContents* source) {}
+ virtual void CloseContents(TabContents* source) {}
+ virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {}
+ virtual bool IsPopup(TabContents* source) { return false; }
+ virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {}
+ virtual void URLStarredChanged(TabContents* source, bool) {}
+ virtual void UpdateTargetURL(TabContents* source, const GURL& url) {}
+ virtual bool CanBlur() const { return false; }
+ // Opens a new URL inside the passed in TabContents, if source is 0 open
+ // in the current front-most tab.
+ virtual void OpenURLFromTab(TabContents* source,
+ const GURL& url, const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition);
+
+ // Overridden from views::View:
+ virtual std::string GetClassName() const;
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child);
+
+ void Init();
+
+ const int inspected_process_id_;
+ const int inspected_view_id_;
+ WebContents* web_contents_;
+ TabContentsContainerView* web_container_;
+
+ DISALLOW_COPY_AND_ASSIGN(ToolsView);
+};
+
+#endif // CHROME_BROWSER_DEBUGGER_TOOLS_VIEW_H_
diff --git a/chrome/browser/debugger/tools_window.cc b/chrome/browser/debugger/tools_window.cc new file mode 100644 index 0000000..f5a68cd --- /dev/null +++ b/chrome/browser/debugger/tools_window.cc @@ -0,0 +1,53 @@ +// 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/tools_window.h"
+
+#include "chrome/browser/debugger/tools_view.h"
+#include "chrome/views/window.h"
+
+ToolsWindow::ToolsWindow() : window_(NULL), tools_view_(NULL) {
+}
+
+ToolsWindow::~ToolsWindow() {
+}
+
+void ToolsWindow::Show(int inspected_process_id,
+ int inspected_view_id) {
+ if (window_) {
+ window_->Show();
+ return;
+ }
+
+ tools_view_ = new ToolsView(inspected_process_id, inspected_view_id);
+ window_ = views::Window::CreateChromeWindow(NULL, gfx::Rect(), this);
+ window_->Show();
+}
+
+void ToolsWindow::SendToolsClientMessage(int tools_message_type,
+ const std::wstring& body) {
+ if (!tools_view_)
+ return;
+ tools_view_->SendToolsClientMessage(tools_message_type, body);
+}
+
+std::wstring ToolsWindow::GetWindowTitle() const {
+ return L"Developer Tools";
+}
+
+void ToolsWindow::WindowClosing() {
+ if (tools_view_) {
+ tools_view_->OnWindowClosing();
+ tools_view_ = NULL;
+ window_ = NULL;
+ }
+}
+
+bool ToolsWindow::CanResize() const {
+ return true;
+}
+
+views::View* ToolsWindow::GetContentsView() {
+ return tools_view_;
+}
diff --git a/chrome/browser/debugger/tools_window.h b/chrome/browser/debugger/tools_window.h new file mode 100644 index 0000000..cc03a44 --- /dev/null +++ b/chrome/browser/debugger/tools_window.h @@ -0,0 +1,66 @@ +// 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_TOOLS_WINDOW_H_
+#define CHROME_BROWSER_DEBUGGER_TOOLS_WINDOW_H_
+
+#include "base/basictypes.h"
+
+// TODO(yurys): port to other platforms
+#if defined(OS_WIN)
+
+#include "chrome/views/window_delegate.h"
+
+namespace views {
+class Window;
+}
+class ToolsView;
+class TabContents;
+
+class ToolsWindow : public views::WindowDelegate {
+ public:
+ ToolsWindow();
+ virtual ~ToolsWindow();
+
+ // Show inspector window for the tab
+ void Show(int inspected_process_id,
+ int inspected_view_id);
+
+ void SendToolsClientMessage(int tools_message_type,
+ const std::wstring& body);
+
+ private:
+ // views::WindowDelegate methods:
+ virtual std::wstring GetWindowTitle() const;
+ virtual void WindowClosing();
+ virtual bool CanResize() const;
+ virtual views::View* GetContentsView();
+
+ views::Window* window_;
+ ToolsView* tools_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(ToolsWindow);
+};
+
+#else // defined(OS_WIN)
+
+class ToolsWindow {
+ public:
+ ToolsWindow() {};
+ virtual ~ToolsWindow() {};
+
+ // Show inspector window for the tab
+ void Show(int inspected_process_id,
+ int inspected_view_id) {};
+
+ void SendToolsClientMessage(int tools_message_type,
+ const std::wstring& body) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ToolsWindow);
+};
+
+#endif // OS_WIN
+
+#endif // CHROME_BROWSER_DEBUGGER_TOOLS_WINDOW_H_
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 8c64d5f..9750d82 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -14,6 +14,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/cross_site_request_manager.h" #include "chrome/browser/debugger/debugger_wrapper.h" +#include "chrome/browser/debugger/tools_window.h" #include "chrome/browser/profile.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/renderer_host/renderer_security_policy.h" @@ -87,6 +88,7 @@ RenderViewHost::RenderViewHost(SiteInstance* instance, renderer_initialized_(false), waiting_for_drag_context_response_(false), debugger_attached_(false), + tools_window_(NULL), enable_dom_ui_bindings_(false), pending_request_id_(0), enable_external_host_bindings_(false), @@ -96,7 +98,9 @@ RenderViewHost::RenderViewHost(SiteInstance* instance, run_modal_reply_msg_(NULL), has_unload_listener_(false), is_waiting_for_unload_ack_(false), - are_javascript_messages_suppressed_(false) { + are_javascript_messages_suppressed_(false), + inspected_process_id_(0), + inspected_view_id_(0) { DCHECK(instance_); DCHECK(delegate_); if (modal_dialog_event == NULL) @@ -554,6 +558,12 @@ void RenderViewHost::ShowJavaScriptConsole() { Send(new ViewMsg_ShowJavaScriptConsole(routing_id())); } +void RenderViewHost::ShowDeveloperTools() { + if (!tools_window_.get()) + tools_window_.reset(new ToolsWindow); + tools_window_->Show(process()->host_id(), routing_id()); +} + void RenderViewHost::DragSourceEndedAt( int client_x, int client_y, int screen_x, int screen_y) { Send(new ViewMsg_DragSourceEndedOrMoved( @@ -582,6 +592,16 @@ void RenderViewHost::AllowDOMUIBindings() { process()->host_id()); } +void RenderViewHost::SetUpToolsClient(int inspected_process_id, + int inspected_view_id) { + RendererSecurityPolicy::GetInstance()->GrantDOMUIBindings( + process()->host_id()); + Send(new ViewMsg_SetUpToolsClient(routing_id())); + + inspected_process_id_ = inspected_process_id; + inspected_view_id_ = inspected_view_id; +} + void RenderViewHost::AllowExternalHostBindings() { enable_external_host_bindings_ = true; } @@ -732,6 +752,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_AddMessageToConsole, OnAddMessageToConsole) IPC_MESSAGE_HANDLER(ViewHostMsg_DebuggerOutput, OnDebuggerOutput); IPC_MESSAGE_HANDLER(ViewHostMsg_DidDebugAttach, DidDebugAttach); + IPC_MESSAGE_HANDLER(ViewHostMsg_ToolsAgentMsg, OnToolsAgentMsg); + IPC_MESSAGE_HANDLER(ViewHostMsg_ToolsClientMsg, OnToolsClientMsg); IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction, OnUserMetricsRecordAction) IPC_MESSAGE_HANDLER(ViewHostMsg_MissingPluginStatus, OnMissingPluginStatus); @@ -1171,6 +1193,26 @@ void RenderViewHost::DidDebugAttach() { } } +void RenderViewHost::OnToolsAgentMsg(int tools_message_type, + const std::wstring& body) { + RenderViewHost* host = RenderViewHost::FromID(inspected_process_id_, + inspected_view_id_); + CHECK(host); + if (host) { + host->Send(new ViewMsg_ToolsAgentMsg( + inspected_view_id_, tools_message_type, body)); + } +} + +void RenderViewHost::OnToolsClientMsg(int tools_message_type, + const std::wstring& body) { + if (!tools_window_.get()) { + NOTREACHED(); + return; + } + tools_window_->SendToolsClientMessage(tools_message_type, body); +} + void RenderViewHost::OnUserMetricsRecordAction(const std::wstring& action) { UserMetrics::RecordComputedAction(action.c_str(), process()->profile()); } diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 2f36219..6c39393 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -26,6 +26,7 @@ class NavigationEntry; class RenderViewHostDelegate; class SiteInstance; class SkBitmap; +class ToolsWindow; class ViewMsg_Navigate; struct ContextMenuParams; struct ViewHostMsg_DidPrintPage_Params; @@ -291,6 +292,9 @@ class RenderViewHost : public RenderWidgetHost { // Show the JavaScript console. void ShowJavaScriptConsole(); + // Show the Web Inspector. + void ShowDeveloperTools(); + // Notifies the renderer that a drop occurred. This is necessary because the // render may be the one that started the drag. void DragSourceEndedAt( @@ -320,6 +324,11 @@ class RenderViewHost : public RenderWidgetHost { // Must be called before CreateRenderView(). void AllowDOMUIBindings(); + // Tell the render view to connect as a tools client to the specified + // renderer. Must be called when RenderView is created but before any + // navigation. + void SetUpToolsClient(int inspected_process_id, int inspected_view_id); + // Sets a property with the given name and value on the DOM UI binding object. // Must call AllowDOMUIBindings() on this renderer first. void SetDOMUIProperty(const std::string& name, const std::string& value); @@ -506,6 +515,8 @@ class RenderViewHost : public RenderWidgetHost { const std::wstring& source_id); void OnDebuggerOutput(const std::wstring& output); void DidDebugAttach(); + void OnToolsAgentMsg(int tools_message_type, const std::wstring& body); + void OnToolsClientMsg(int tools_message_type, const std::wstring& body); void OnUserMetricsRecordAction(const std::wstring& action); void OnMissingPluginStatus(int status); void OnMessageReceived(IPC::Message* msg) { } @@ -561,9 +572,12 @@ class RenderViewHost : public RenderWidgetHost { // information. bool waiting_for_drag_context_response_; - // is the debugger attached to us or not + // If the debugger attached to us or not. bool debugger_attached_; + // Allows to show exactly one developer tools window for this render view. + scoped_ptr<ToolsWindow> tools_window_; + // True if we've been told to set up the the Javascript bindings for // sending messages back to the browser. bool enable_dom_ui_bindings_; @@ -610,6 +624,10 @@ class RenderViewHost : public RenderWidgetHost { bool are_javascript_messages_suppressed_; + int inspected_process_id_; + + int inspected_view_id_; + DISALLOW_EVIL_CONSTRUCTORS(RenderViewHost); }; diff --git a/chrome/browser/tab_contents/tab_contents_factory.cc b/chrome/browser/tab_contents/tab_contents_factory.cc index 18f3569..64f0605 100644 --- a/chrome/browser/tab_contents/tab_contents_factory.cc +++ b/chrome/browser/tab_contents/tab_contents_factory.cc @@ -11,6 +11,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/debugger/debugger_contents.h" +#include "chrome/browser/debugger/tools_contents.h" #include "chrome/browser/tab_contents/native_ui_contents.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_factory.h" @@ -61,6 +62,9 @@ TabContents* TabContents::CreateWithType(TabContentsType type, case TAB_CONTENTS_DEBUGGER: contents = new DebuggerContents(profile, instance); break; + case TAB_CONTENTS_TOOLS: + contents = new ToolsContents(profile, instance); + break; case TAB_CONTENTS_DOM_UI: contents = new DOMUIContents(profile, instance, NULL); break; @@ -108,6 +112,9 @@ TabContentsType TabContents::TypeForURL(GURL* url) { if (DebuggerContents::IsDebuggerUrl(*url)) return TAB_CONTENTS_DEBUGGER; + if (ToolsContents::IsToolsUrl(*url)) + return TAB_CONTENTS_TOOLS; + if (url->SchemeIs(DOMUIContents::GetScheme().c_str())) return TAB_CONTENTS_DOM_UI; diff --git a/chrome/browser/tab_contents/tab_contents_type.h b/chrome/browser/tab_contents/tab_contents_type.h index 87cd6452..6a8afd9 100644 --- a/chrome/browser/tab_contents/tab_contents_type.h +++ b/chrome/browser/tab_contents/tab_contents_type.h @@ -21,6 +21,7 @@ enum TabContentsType { TAB_CONTENTS_ABOUT_UI, TAB_CONTENTS_DEBUGGER, TAB_CONTENTS_DOM_UI, + TAB_CONTENTS_TOOLS, TAB_CONTENTS_NUM_TYPES }; diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj index ac17f29..bff227e 100644 --- a/chrome/chrome.xcodeproj/project.pbxproj +++ b/chrome/chrome.xcodeproj/project.pbxproj @@ -289,6 +289,7 @@ 844EA08E0F3E0C5900B0EF26 /* debugger_wrapper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 844EA0820F3E0C1000B0EF26 /* debugger_wrapper.cc */; }; 8570EB3F140C07ABF1957F12 /* url_pattern_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = A9C335E39D39A7DE087850FC /* url_pattern_unittest.cc */; }; 8CB218DCFAC761AC876C6531 /* ssl_blocking_page.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5D16ECB0F21451600861FAC /* ssl_blocking_page.cc */; }; + 8BFCF870135974131607BE96 /* tools_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5F14A0FCE27716C1320910BF /* tools_client.cc */; }; 8F51B73AAAF1772ECF9BD180 /* url_fetcher.cc in Sources */ = {isa = PBXBuildFile; fileRef = 778D7927798B7E3FAA498D3D /* url_fetcher.cc */; }; 9084D27A4F8690E6FD31083B /* session_backend.cc in Sources */ = {isa = PBXBuildFile; fileRef = 35AC9D9A03545594C102C5C1 /* session_backend.cc */; }; 94542322A5E5A8F4FDDAB7F0 /* render_view_host_manager.cc in Sources */ = {isa = PBXBuildFile; fileRef = A76E42AD0F28EDB5009A7E88 /* render_view_host_manager.cc */; }; @@ -358,6 +359,7 @@ BAC2B7A80F43595A0063A33E /* resource_dispatcher_host_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = BAC2B7A70F43594A0063A33E /* resource_dispatcher_host_unittest.cc */; }; BAC2B8AD0F436C7F0063A33E /* cross_site_resource_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = A7C613DC0F30D886008CEE5D /* cross_site_resource_handler.cc */; }; BADB8B710F3A35AC00989B26 /* resource_dispatcher_host.cc in Sources */ = {isa = PBXBuildFile; fileRef = BADB8B6D0F3A356000989B26 /* resource_dispatcher_host.cc */; }; + C3264B8F815F3A647E588B3B /* tools_agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = CC4B6C6003DFDA919DF82F03 /* tools_agent.cc */; }; C53EBF7E1E204C3780FD4A7D /* ssl_policy.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5D16ED10F21451600861FAC /* ssl_policy.cc */; }; C6C256C56BA114D53849523F /* greasemonkey_api_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1F43A7C85092C58AAF011F78 /* greasemonkey_api_unittest.cc */; }; C8F5EB819EA38CE9D50AF5B5 /* history.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF9EC0E9D48F7009A6919 /* history.cc */; }; @@ -2398,6 +2400,9 @@ 4F9429998AC2703984BAB828 /* resolve_proxy_msg_helper.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resolve_proxy_msg_helper.cc; sourceTree = "<group>"; }; 534E66C30F311BEC0006B2B2 /* temp_scaffolding_stubs.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = temp_scaffolding_stubs.cc; sourceTree = "<group>"; }; 56E1D7DF17D327BFCB0B895D /* test_web_contents.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test_web_contents.cc; path = tab_contents/test_web_contents.cc; sourceTree = "<group>"; }; + 5EEF2C2CF0433472C652E800 /* tools_agent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tools_agent.h; sourceTree = "<group>"; }; + 5EEF8662A1B4ABE060426953 /* tools_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tools_client.h; sourceTree = "<group>"; }; + 5F14A0FCE27716C1320910BF /* tools_client.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tools_client.cc; sourceTree = "<group>"; }; 629BF493DEA096E2DD844F2B /* autofill_manager.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = autofill_manager.cc; sourceTree = "<group>"; }; 6447F24FADC63E58A44DB762 /* url_pattern.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = url_pattern.cc; path = extensions/url_pattern.cc; sourceTree = "<group>"; }; 699499C4FBA07FB2D7B298A2 /* user_script.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = user_script.cc; path = extensions/user_script.cc; sourceTree = "<group>"; }; @@ -2586,6 +2591,8 @@ C18F2A0A6FB6BEF75406511D /* chrome_paths_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chrome_paths_mac.cc; sourceTree = "<group>"; }; C3F9577C67188A5A4E3A6E41 /* session_restore.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = session_restore.cc; path = browser/sessions/session_restore.cc; sourceTree = SOURCE_ROOT; }; C8D26D9EC81E03E91E270463 /* session_service.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = session_service.cc; path = sessions/session_service.cc; sourceTree = "<group>"; }; + CC4B6C6003DFDA919DF82F03 /* tools_agent.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tools_agent.cc; sourceTree = "<group>"; }; + CEEB8E8A0729671812756F11 /* tools_messages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tools_messages.h; sourceTree = "<group>"; }; D74DA6A9031CAE292790BD5E /* file_descriptor_set_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_descriptor_set_unittest.cc; sourceTree = "<group>"; }; D941DBEFD8B8B537DE8A4DAE /* bookmark_storage.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bookmark_storage.cc; path = bookmarks/bookmark_storage.cc; sourceTree = "<group>"; }; E40CC5E10F2E348900708647 /* history_contents_provider.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = history_contents_provider.cc; path = autocomplete/history_contents_provider.cc; sourceTree = "<group>"; }; @@ -3037,6 +3044,11 @@ B51F6D120F37C4DC00152D66 /* renderer_main_platform_delegate_win.cc */, B5D030EF0F3A3C43001238AB /* renderer_main_unittest.cc */, 4D640CDA0EAE868600EBCFC0 /* renderer_resources.h */, + CC4B6C6003DFDA919DF82F03 /* tools_agent.cc */, + 5EEF2C2CF0433472C652E800 /* tools_agent.h */, + 5F14A0FCE27716C1320910BF /* tools_client.cc */, + 5EEF8662A1B4ABE060426953 /* tools_client.h */, + CEEB8E8A0729671812756F11 /* tools_messages.h */, 4D640CC90EAE868600EBCFC0 /* user_script_slave.cc */, 4D640CCA0EAE868600EBCFC0 /* user_script_slave.h */, 4D640CDC0EAE868600EBCFC0 /* visitedlink_slave.cc */, @@ -5307,6 +5319,8 @@ 3380A6A10F2E91F9004EF74F /* render_process.cc in Sources */, 3380A69D0F2E91D4004EF74F /* render_thread.cc in Sources */, A7A20E650F3A1E1C00F62B4D /* render_view.cc in Sources */, + C3264B8F815F3A647E588B3B /* tools_agent.cc in Sources */, + 8BFCF870135974131607BE96 /* tools_client.cc in Sources */, B503E0F00F0175FD00547DC6 /* user_script_slave.cc in Sources */, B51F6D2E0F37D04200152D66 /* renderer_main.cc in Sources */, B51F6D150F37C4DC00152D66 /* renderer_main_platform_delegate_mac.cc in Sources */, diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 915f8c7..ecff1ab 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -238,6 +238,24 @@ IPC_BEGIN_MESSAGES(View) IPC_MESSAGE_ROUTED1(ViewMsg_DebugCommand, std::wstring /* cmd */) + // Message addressed to ToolsClient. It results from forwarding + // ViewHostMsg_ToolsClientMsg by the browser. + IPC_MESSAGE_ROUTED2(ViewMsg_ToolsClientMsg, + int, /* tools msg type */ + std::wstring /* body */) + + // Message addressed to ToolsAgent. It results from forwarding + // ViewHostMsg_ToolsAgentMsg by the browser. + IPC_MESSAGE_ROUTED2(ViewMsg_ToolsAgentMsg, + int, /* tools msg type */ + std::wstring /* body */) + + // RenderViewHostDelegate::RendererCreated method sends this message to a new + // renderer to notify it that it will host developer tools UI and should set + // up all neccessary bindings and create ToolsClient instance that will + // handle communication with inspected page ToolsAgent. + IPC_MESSAGE_ROUTED0(ViewMsg_SetUpToolsClient) + // Change the zoom level in the renderer. IPC_MESSAGE_ROUTED1(ViewMsg_Zoom, int /* One of PageZoom::Function */) @@ -966,6 +984,18 @@ IPC_BEGIN_MESSAGES(ViewHost) IPC_MESSAGE_ROUTED1(ViewHostMsg_DebuggerOutput, std::wstring /* msg */) + // Message addressed to ToolsClient sent by ToolsAgent to browser so that the + // latter can forward it. + IPC_MESSAGE_ROUTED2(ViewHostMsg_ToolsClientMsg, + int, /* tools msg type */ + std::wstring /* body */) + + // Message addressed to ToolsAgent sent by ToolsClient to browser so that the + // latter can forward it. + IPC_MESSAGE_ROUTED2(ViewHostMsg_ToolsAgentMsg, + int, /* tools msg type */ + std::wstring /* body */) + // Send back a string to be recorded by UserMetrics. IPC_MESSAGE_ROUTED1(ViewHostMsg_UserMetricsRecordAction, std::wstring /* action */) diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index a8adb2f..1fa3650 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/gfx/png_encoder.h" #include "base/gfx/native_widget_types.h" +#include "base/process_util.h" #include "base/string_piece.h" #include "base/string_util.h" #include "build/build_config.h" @@ -25,6 +26,7 @@ #include "chrome/common/thumbnail_score.h" #include "chrome/renderer/about_handler.h" #include "chrome/renderer/debug_message_handler.h" +#include "chrome/renderer/tools_client.h" #include "chrome/renderer/localized_error.h" #include "chrome/renderer/render_process.h" #include "chrome/renderer/user_script_slave.h" @@ -168,6 +170,9 @@ RenderView::RenderView(RenderThreadBase* render_thread) method_factory_(this), first_default_plugin_(NULL), printed_document_width_(0), + tools_agent_(NULL), + enable_tools_client_(false), + tools_client_(NULL), history_back_list_count_(0), history_forward_list_count_(0), disable_popup_blocking_(false), @@ -196,6 +201,10 @@ RenderView::~RenderView() { } render_thread_->RemoveFilter(debug_message_handler_); + render_thread_->RemoveFilter(tools_agent_); + if (tools_client_.get()) { + render_thread_->RemoveFilter(tools_client_); + } #ifdef CHROME_PERSONALIZATION Personalization::CleanupRendererPersonalization(personalization_); @@ -313,6 +322,9 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd, debug_message_handler_ = new DebugMessageHandler(this); render_thread_->AddFilter(debug_message_handler_); + + tools_agent_ = new ToolsAgent(this); + render_thread_->AddFilter(tools_agent_); } void RenderView::OnMessageReceived(const IPC::Message& message) { @@ -355,6 +367,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding) IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement) IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole) + IPC_MESSAGE_HANDLER(ViewMsg_SetUpToolsClient, OnSetUpToolsClient) IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage) IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest) IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole) @@ -897,6 +910,10 @@ void RenderView::OnShowJavaScriptConsole() { webview()->ShowJavaScriptConsole(); } +void RenderView::OnSetUpToolsClient() { + enable_tools_client_ = true; +} + void RenderView::OnStopFinding(bool clear_selection) { WebView* view = webview(); if (!view) @@ -1502,6 +1519,13 @@ void RenderView::BindDOMAutomationController(WebFrame* webframe) { L"domAutomationController"); } +void RenderView::CreateToolsClient() { + DCHECK(!tools_client_.get()); + tools_client_ = new ToolsClient(this); + webview()->SetUpToolsProxy(tools_client_); + render_thread_->AddFilter(tools_client_); +} + void RenderView::WindowObjectCleared(WebFrame* webframe) { external_js_object_.set_render_view(this); external_js_object_.BindToJavascript(webframe, L"external"); @@ -1517,6 +1541,11 @@ void RenderView::WindowObjectCleared(WebFrame* webframe) { external_host_bindings_.set_routing_id(routing_id_); external_host_bindings_.BindToJavascript(webframe, L"externalHost"); } + // TODO(yurys): we wouldn't need to check that tools_client_ is not set yet if + // WindowObjectCleared were not called several times recursively + if (enable_tools_client_ && !tools_client_.get()) { + CreateToolsClient(); + } #ifdef CHROME_PERSONALIZATION Personalization::ConfigureRendererPersonalization(personalization_, this, diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 6cafaa6..64e0caa 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -22,6 +22,8 @@ #include "chrome/renderer/dom_ui_bindings.h" #include "chrome/renderer/external_host_bindings.h" #include "chrome/renderer/external_js_object.h" +#include "chrome/renderer/tools_agent.h" +#include "chrome/renderer/tools_client.h" #include "chrome/renderer/render_widget.h" #include "testing/gtest/include/gtest/gtest_prod.h" #include "webkit/glue/console_message_level.h" @@ -438,6 +440,7 @@ class RenderView : public RenderWidget, void OnCopyImageAt(int x, int y); void OnInspectElement(int x, int y); void OnShowJavaScriptConsole(); + void OnSetUpToolsClient(); void OnCancelDownload(int32 download_id); void OnFind(const FindInPageRequest& request); void OnZoom(int function); @@ -551,6 +554,10 @@ class RenderView : public RenderWidget, // information to the browser process. void BindDOMAutomationController(WebFrame* webframe); + // Creates ToolsClient and sets up JavaScript bindings for developer tools UI + // that is going to be hosted by this RenderView. + void CreateToolsClient(); + void set_opened_by_user_gesture(bool value) { opened_by_user_gesture_ = value; } @@ -693,6 +700,14 @@ class RenderView : public RenderWidget, scoped_refptr<DebugMessageHandler> debug_message_handler_; + // Provides access to this renderer from the remote Inspector UI. + scoped_refptr<ToolsAgent> tools_agent_; + + // Whether this renderer will serve as Inspector UI. + bool enable_tools_client_; + + scoped_refptr<ToolsClient> tools_client_; + scoped_ptr<WebFileChooserCallback> file_chooser_; int history_back_list_count_; diff --git a/chrome/renderer/renderer.scons b/chrome/renderer/renderer.scons index 4f5ba60..f1ed92f 100644 --- a/chrome/renderer/renderer.scons +++ b/chrome/renderer/renderer.scons @@ -79,6 +79,11 @@ input_files = ChromeFileList([ 'renderer_glue.cc', 'renderer_main.cc', 'renderer_resources.h', + 'tools_agent.cc', + 'tools_agent.h', + 'tools_client.cc', + 'tools_client.h', + 'tools_messages.h', 'user_script_slave.cc', 'user_script_slave.h', 'visitedlink_slave.cc', diff --git a/chrome/renderer/renderer.vcproj b/chrome/renderer/renderer.vcproj index 7e50f8f..8a1dc13 100644 --- a/chrome/renderer/renderer.vcproj +++ b/chrome/renderer/renderer.vcproj @@ -310,6 +310,26 @@ > </File> <File + RelativePath=".\tools_agent.cc" + > + </File> + <File + RelativePath=".\tools_agent.h" + > + </File> + <File + RelativePath=".\tools_client.cc" + > + </File> + <File + RelativePath=".\tools_client.h" + > + </File> + <File + RelativePath=".\tools_messages.h" + > + </File> + <File RelativePath=".\user_script_slave.cc" > </File> diff --git a/chrome/renderer/tools_agent.cc b/chrome/renderer/tools_agent.cc new file mode 100644 index 0000000..2f3fe2c --- /dev/null +++ b/chrome/renderer/tools_agent.cc @@ -0,0 +1,150 @@ +// 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/renderer/tools_agent.h"
+
+#include "chrome/common/render_messages.h"
+// TODO(yurys): remove this macros once plugins available on other platforms
+#if defined(OS_WIN)
+#include "chrome/renderer/plugin_channel_host.h"
+#endif // OS_WIN
+#include "chrome/renderer/render_process.h"
+#include "chrome/renderer/render_view.h"
+
+ToolsAgent::ToolsAgent(RenderView* view)
+ : channel_(NULL),
+ debugger_(NULL),
+ view_(view),
+ view_loop_(MessageLoop::current()) {
+}
+
+ToolsAgent::~ToolsAgent() {
+ OnDebugDetach();
+}
+
+void ToolsAgent::Send(ToolsClientMessageType message_type,
+ const std::wstring& body) {
+ DCHECK(channel_);
+ view_->Send(new ViewHostMsg_ToolsClientMsg(
+ view_->routing_id(), message_type, body));
+}
+
+// IPC::ChannelProxy::MessageFilter overrides:
+void ToolsAgent::OnFilterAdded(IPC::Channel* channel) {
+ channel_ = channel;
+}
+
+void ToolsAgent::OnFilterRemoved() {
+ OnDebugDetach();
+ channel_ = NULL;
+}
+
+// Called on IO thread.
+bool ToolsAgent::OnMessageReceived(const IPC::Message& message) {
+ if (message.routing_id() != view_->routing_id())
+ return false;
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ToolsAgent, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_ToolsAgentMsg, OnToolsAgentMsg)
+ IPC_MESSAGE_UNHANDLED(handled = false);
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+// Called on IO thread.
+void ToolsAgent::OnToolsAgentMsg(int tools_message_type,
+ const std::wstring& body) {
+ view_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this,
+ &ToolsAgent::HandleMessageInRenderThread,
+ tools_message_type,
+ body));
+}
+
+void ToolsAgent::HandleMessageInRenderThread(
+ int tools_message_type, const std::wstring& body) {
+ DCHECK(MessageLoop::current() == view_loop_);
+
+ switch(tools_message_type) {
+ case TOOLS_AGENT_MSG_DEBUG_ATTACH:
+ OnDebugAttach();
+ break;
+ case TOOLS_AGENT_MSG_DEBUG_DETACH:
+ OnDebugDetach();
+ break;
+ case TOOLS_AGENT_MSG_DEBUG_BREAK:
+ OnDebugBreak(body == L"true");
+ break;
+ case TOOLS_AGENT_MSG_DEBUG_COMMAND:
+ OnCommand(body);
+ break;
+ default:
+ NOTREACHED() << "Unknown ToolsAgentMessageType: " << tools_message_type;
+ }
+}
+
+void ToolsAgent::DebuggerOutput(const std::wstring& out) {
+ Send(TOOLS_CLIENT_MSG_DEBUGGER_OUTPUT, out);
+}
+
+void ToolsAgent::EvaluateScript(const std::wstring& script) {
+ DCHECK(MessageLoop::current() == view_loop_);
+ // It's possible that this will get cleared out from under us.
+ view_->EvaluateScript(L"", script);
+}
+
+void ToolsAgent::OnDebugAttach() {
+ if (!debugger_) {
+ debugger_ = new DebuggerBridge(this);
+ }
+
+ // Run the actual debugger attach in the renderer as it uses V8 methods which
+ // must run in the V8 thread.
+ DCHECK(MessageLoop::current() == view_loop_);
+ debugger_->Attach();
+
+ Send(TOOLS_CLIENT_MSG_DID_DEBUG_ATTACH, L"");
+
+// TODO(yurys): remove this macros once plugins available on other platforms
+#if defined(OS_WIN)
+ // Tell the plugin host to stop accepting messages in order to avoid
+ // hangs while the renderer is paused.
+ // TODO(yurys): It might be an improvement to add more plumbing to do this
+ // when the renderer is actually paused vs. just the debugger being attached.
+ // http://code.google.com/p/chromium/issues/detail?id=7556
+ PluginChannelHost::SetListening(false);
+#endif // OS_WIN
+}
+
+void ToolsAgent::OnDebugDetach() {
+ if (debugger_)
+ debugger_->Detach();
+// TODO(yurys): remove this macros once plugins available on other platforms
+#if defined(OS_WIN)
+ PluginChannelHost::SetListening(true);
+#endif // OS_WIN
+}
+
+void ToolsAgent::OnDebugBreak(bool force) {
+ // Set the debug break flag in the V8 engine.
+ debugger_->Break(force);
+
+ // If a forced break has been requested make sure that it will occour by
+ // running some JavaScript in the renderer.
+ DCHECK(MessageLoop::current() == view_loop_);
+ if (force)
+ EvaluateScript(std::wstring(L"javascript:void(0)"));
+}
+
+void ToolsAgent::OnCommand(const std::wstring& cmd) {
+ if (!debugger_) {
+ NOTREACHED();
+ std::wstring msg =
+ StringPrintf(L"before attach, ignored command (%S)", cmd.c_str());
+ DebuggerOutput(msg);
+ } else {
+ debugger_->Command(cmd);
+ }
+}
diff --git a/chrome/renderer/tools_agent.h b/chrome/renderer/tools_agent.h new file mode 100644 index 0000000..41f988c --- /dev/null +++ b/chrome/renderer/tools_agent.h @@ -0,0 +1,63 @@ +// 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_RENDERER_TOOLS_AGENT_H_
+#define CHROME_RENDERER_TOOLS_AGENT_H_
+
+#include "base/basictypes.h"
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/ipc_channel_proxy.h"
+#include "chrome/renderer/tools_messages.h"
+#include "webkit/glue/debugger_bridge.h"
+
+class Message;
+class RenderView;
+
+// Inspected page end of communication channel between the render process of
+// the page being inspected and tools UI renderer process. All messages will
+// go through browser process. On the renderer side of the tools UI there's
+// a corresponding ToolsClient object.
+class ToolsAgent : public IPC::ChannelProxy::MessageFilter,
+ public DebuggerBridge::Delegate {
+ public:
+ // ToolsAgent is a field of the RenderView. The view is supposed to be alive
+ // at least until OnFilterRemoved method is called.
+ explicit ToolsAgent(RenderView* view);
+ virtual ~ToolsAgent();
+
+ private:
+ // Sends message to ToolsClient.
+ void Send(ToolsClientMessageType message_type, const std::wstring& body);
+
+ // IPC::ChannelProxy::MessageFilter overrides:
+ virtual void OnFilterAdded(IPC::Channel* channel);
+ virtual void OnFilterRemoved();
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ void OnToolsAgentMsg(int tools_message_type, const std::wstring& body);
+ void HandleMessageInRenderThread(int tools_message_type,
+ const std::wstring& body);
+
+ // Debugger::Delegate callback method to handle debugger output.
+ void DebuggerOutput(const std::wstring& out);
+
+ // Evaluate javascript URL in the renderer
+ void EvaluateScript(const std::wstring& script);
+
+ void OnDebugAttach();
+ void OnDebugDetach();
+ void OnDebugBreak(bool force);
+ void OnCommand(const std::wstring& cmd);
+
+ IPC::Channel* channel_;
+ scoped_refptr<DebuggerBridge> debugger_;
+ RenderView* view_;
+ MessageLoop* view_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(ToolsAgent);
+};
+
+#endif // CHROME_RENDERER_TOOLS_AGENT_H_
diff --git a/chrome/renderer/tools_client.cc b/chrome/renderer/tools_client.cc new file mode 100644 index 0000000..1c673dc --- /dev/null +++ b/chrome/renderer/tools_client.cc @@ -0,0 +1,80 @@ +// 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/renderer/tools_client.h"
+
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/render_view.h"
+#include "webkit/glue/tools_proxy.h"
+
+ToolsClient::ToolsClient(RenderView* view)
+ : tools_ui_(NULL),
+ render_view_(view),
+ view_loop_(MessageLoop::current()) {
+}
+
+ToolsClient::~ToolsClient() {
+ tools_ui_ = NULL;
+}
+
+void ToolsClient::Send(ToolsAgentMessageType message_type,
+ const std::wstring& json_arg) {
+ render_view_->Send(new ViewHostMsg_ToolsAgentMsg(
+ render_view_->routing_id(), message_type, json_arg));
+}
+
+// IPC::ChannelProxy::MessageFilter overrides:
+bool ToolsClient::OnMessageReceived(const IPC::Message& message) {
+ if (message.routing_id() != render_view_->routing_id()) {
+ NOTREACHED();
+ return false;
+ }
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ToolsClient, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_ToolsClientMsg, OnToolsClientMessage)
+ IPC_MESSAGE_UNHANDLED(handled = false);
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void ToolsClient::OnToolsClientMessage(int tools_message_type,
+ const std::wstring& body) {
+ view_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this,
+ &ToolsClient::HandleMessageInRenderThread,
+ tools_message_type,
+ body));
+}
+
+void ToolsClient::HandleMessageInRenderThread(int tools_message_type,
+ const std::wstring& body) {
+ DCHECK(view_loop_ == MessageLoop::current());
+
+ switch(tools_message_type) {
+ case TOOLS_CLIENT_MSG_DID_DEBUG_ATTACH:
+ OnDidDebugAttach();
+ break;
+ default:
+ NOTREACHED() << "Unknown message type: " << tools_message_type;
+ }
+}
+
+void ToolsClient::OnDidDebugAttach() {
+ if (tools_ui_)
+ tools_ui_->OnDidDebugAttach();
+}
+
+// DebuggerProxy methods:
+void ToolsClient::SetToolsUI(ToolsUI* tools_ui) {
+ tools_ui_ = tools_ui;
+}
+
+void ToolsClient::DebugAttach() {
+ Send(TOOLS_AGENT_MSG_DEBUG_ATTACH, L"");
+}
+
+void ToolsClient::DebugDetach() {
+ Send(TOOLS_AGENT_MSG_DEBUG_DETACH, L"");
+}
diff --git a/chrome/renderer/tools_client.h b/chrome/renderer/tools_client.h new file mode 100644 index 0000000..8aad3df --- /dev/null +++ b/chrome/renderer/tools_client.h @@ -0,0 +1,53 @@ +// 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_RENDERER_TOOLS_CLIENT_H_
+#define CHROME_RENDERER_TOOLS_CLIENT_H_
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/ipc_channel_proxy.h"
+#include "chrome/renderer/tools_messages.h"
+#include "webkit/glue/tools_proxy.h"
+
+class MessageLoop;
+class RenderView;
+
+// Developer tools UI end of communication channel between the render process of
+// the page being inspected and tools UI renderer process. All messages will
+// go through browser process. On the side of the inspected page there's
+// corresponding ToolsAgent object.
+class ToolsClient : public ToolsProxy,
+ public IPC::ChannelProxy::MessageFilter {
+ public:
+ explicit ToolsClient(RenderView* view);
+ virtual ~ToolsClient();
+
+ private:
+ // DebuggerProxy overrides
+ virtual void SetToolsUI(ToolsUI*);
+ virtual void DebugAttach();
+ virtual void DebugDetach();
+
+ void OnDidDebugAttach();
+
+ // Sends message to ToolsAgent.
+ void Send(ToolsAgentMessageType message_type, const std::wstring& json_arg);
+
+ // IPC::ChannelProxy::MessageFilter overrides:
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ void OnToolsClientMessage(int tools_message_type, const std::wstring& body);
+ void HandleMessageInRenderThread(int tools_message_type,
+ const std::wstring& body);
+
+ ToolsUI* tools_ui_;
+ RenderView* render_view_;
+ MessageLoop* view_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(ToolsClient);
+};
+
+#endif // CHROME_RENDERER_TOOLS_CLIENT_H_
diff --git a/chrome/renderer/tools_messages.h b/chrome/renderer/tools_messages.h new file mode 100644 index 0000000..c8b3884 --- /dev/null +++ b/chrome/renderer/tools_messages.h @@ -0,0 +1,21 @@ +// 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_RENDERER_TOOLS_MESSAGES_H_
+#define CHROME_RENDERER_TOOLS_MESSAGES_H_
+
+enum ToolsAgentMessageType {
+ TOOLS_AGENT_MSG_DEBUG_ATTACH = 0,
+ TOOLS_AGENT_MSG_DEBUG_BREAK,
+ TOOLS_AGENT_MSG_DEBUG_COMMAND,
+ TOOLS_AGENT_MSG_DEBUG_DETACH
+};
+
+enum ToolsClientMessageType {
+ TOOLS_CLIENT_MSG_ADD_MESSAGE_TO_CONSOLE = 0,
+ TOOLS_CLIENT_MSG_DEBUGGER_OUTPUT,
+ TOOLS_CLIENT_MSG_DID_DEBUG_ATTACH
+};
+
+#endif // CHROME_RENDERER_TOOLS_MESSAGES_H_
diff --git a/chrome/views/window_delegate.h b/chrome/views/window_delegate.h index d10dbf6..d1d76f7 100644 --- a/chrome/views/window_delegate.h +++ b/chrome/views/window_delegate.h @@ -143,7 +143,7 @@ class WindowDelegate { void ReleaseWindow(); private: - friend Window; + friend class Window; // This is a little unusual. We use a scoped_ptr here because it's // initialized to NULL automatically. We do this because we want to allow // people using this helper to not have to call a ctor on this object. |