From 6524b5f9cb595b601fe95396439508efc7ecc8b3 Mon Sep 17 00:00:00 2001 From: "brettw@chromium.org" Date: Thu, 22 Jan 2009 17:48:25 +0000 Subject: Move files out of browser and into either renderer_host or tab_contents. This also fixes a crash in the web contents unit test in a commented-out test and re-enable it. Review URL: http://codereview.chromium.org/18504 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8470 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/automation/automation_provider.cc | 2 +- chrome/browser/browser.scons | 40 +- chrome/browser/browser.vcproj | 526 ++------ chrome/browser/browser_about_handler.cc | 2 +- chrome/browser/browser_accessibility_manager.cc | 2 +- chrome/browser/browser_shutdown.cc | 4 +- chrome/browser/cert_store.cc | 2 +- chrome/browser/debugger/debugger_host_impl.cpp | 2 +- chrome/browser/debugger/debugger_node.cc | 2 +- chrome/browser/debugger/debugger_view.cc | 2 +- chrome/browser/dom_ui/dom_ui_contents.cc | 2 +- chrome/browser/dom_ui/dom_ui_host.cc | 2 +- chrome/browser/dom_ui/html_dialog_contents.cc | 2 +- chrome/browser/dom_ui/new_tab_ui.cc | 2 +- chrome/browser/download/download_manager.cc | 2 +- chrome/browser/download/save_package.cc | 4 +- chrome/browser/download/save_package.h | 2 +- chrome/browser/fav_icon_helper.cc | 2 +- chrome/browser/memory_details.cc | 2 +- chrome/browser/modal_html_dialog_delegate.cc | 2 +- chrome/browser/printing/print_view_manager.cc | 2 +- chrome/browser/render_view_context_menu.cc | 180 --- chrome/browser/render_view_context_menu.h | 44 - .../browser/render_view_context_menu_controller.cc | 516 -------- .../browser/render_view_context_menu_controller.h | 56 - chrome/browser/render_view_host.cc | 1310 -------------------- chrome/browser/render_view_host.h | 628 ---------- chrome/browser/render_view_host_delegate.h | 396 ------ chrome/browser/render_view_host_manager.cc | 503 -------- chrome/browser/render_view_host_manager.h | 234 ---- chrome/browser/render_widget_helper.cc | 235 ---- chrome/browser/render_widget_helper.h | 159 --- chrome/browser/render_widget_host.cc | 849 ------------- chrome/browser/render_widget_host.h | 369 ------ chrome/browser/render_widget_host_view.h | 121 -- chrome/browser/render_widget_host_view_win.cc | 925 -------------- chrome/browser/render_widget_host_view_win.h | 283 ----- .../renderer_host/browser_render_process_host.cc | 6 +- .../renderer_host/cross_site_resource_handler.cc | 2 +- chrome/browser/renderer_host/render_view_host.cc | 1310 ++++++++++++++++++++ chrome/browser/renderer_host/render_view_host.h | 628 ++++++++++ .../renderer_host/render_view_host_delegate.h | 396 ++++++ .../browser/renderer_host/render_widget_helper.cc | 235 ++++ .../browser/renderer_host/render_widget_helper.h | 159 +++ chrome/browser/renderer_host/render_widget_host.cc | 849 +++++++++++++ chrome/browser/renderer_host/render_widget_host.h | 369 ++++++ .../renderer_host/render_widget_host_view.h | 121 ++ .../renderer_host/render_widget_host_view_win.cc | 925 ++++++++++++++ .../renderer_host/render_widget_host_view_win.h | 283 +++++ .../renderer_host/renderer_security_policy.cc | 285 +++++ .../renderer_host/renderer_security_policy.h | 122 ++ .../renderer_security_policy_unittest.cc | 260 ++++ .../renderer_host/resource_dispatcher_host.cc | 6 +- .../browser/renderer_host/test_render_view_host.cc | 6 +- .../browser/renderer_host/test_render_view_host.h | 10 +- chrome/browser/renderer_security_policy.cc | 285 ----- chrome/browser/renderer_security_policy.h | 122 -- .../browser/renderer_security_policy_unittest.cc | 260 ---- chrome/browser/resource_message_filter.cc | 2 +- chrome/browser/site_instance_unittest.cc | 2 +- chrome/browser/ssl/ssl_manager.cc | 2 +- chrome/browser/ssl/ssl_policy.cc | 2 +- chrome/browser/tab_contents/interstitial_page.cc | 2 +- chrome/browser/tab_contents/interstitial_page.h | 2 +- .../tab_contents/render_view_context_menu.cc | 180 +++ .../tab_contents/render_view_context_menu.h | 44 + .../render_view_context_menu_controller.cc | 516 ++++++++ .../render_view_context_menu_controller.h | 56 + .../tab_contents/render_view_host_manager.cc | 503 ++++++++ .../tab_contents/render_view_host_manager.h | 234 ++++ chrome/browser/tab_contents/tab_util.cc | 2 +- .../browser/tab_contents/view_source_contents.cc | 2 +- chrome/browser/tab_contents/web_contents.cc | 4 +- chrome/browser/tab_contents/web_contents.h | 4 +- .../browser/tab_contents/web_contents_unittest.cc | 8 +- chrome/browser/tab_contents/web_contents_view.cc | 2 +- chrome/browser/tab_contents/web_contents_view.h | 2 +- .../browser/tab_contents/web_contents_view_win.cc | 8 +- chrome/browser/tab_contents/web_drag_source.cc | 2 +- chrome/browser/tab_contents/web_drop_target.cc | 2 +- chrome/browser/tabs/tab_strip_model.cc | 2 +- chrome/browser/views/find_bar_win.cc | 2 +- chrome/browser/views/find_bar_win.h | 2 +- chrome/browser/views/hung_renderer_view.cc | 2 +- .../browser/views/tab_contents_container_view.cc | 6 +- chrome/browser/web_app.cc | 2 +- 86 files changed, 7636 insertions(+), 8016 deletions(-) delete mode 100644 chrome/browser/render_view_context_menu.cc delete mode 100644 chrome/browser/render_view_context_menu.h delete mode 100644 chrome/browser/render_view_context_menu_controller.cc delete mode 100644 chrome/browser/render_view_context_menu_controller.h delete mode 100644 chrome/browser/render_view_host.cc delete mode 100644 chrome/browser/render_view_host.h delete mode 100644 chrome/browser/render_view_host_delegate.h delete mode 100644 chrome/browser/render_view_host_manager.cc delete mode 100644 chrome/browser/render_view_host_manager.h delete mode 100644 chrome/browser/render_widget_helper.cc delete mode 100644 chrome/browser/render_widget_helper.h delete mode 100644 chrome/browser/render_widget_host.cc delete mode 100644 chrome/browser/render_widget_host.h delete mode 100644 chrome/browser/render_widget_host_view.h delete mode 100644 chrome/browser/render_widget_host_view_win.cc delete mode 100644 chrome/browser/render_widget_host_view_win.h create mode 100644 chrome/browser/renderer_host/render_view_host.cc create mode 100644 chrome/browser/renderer_host/render_view_host.h create mode 100644 chrome/browser/renderer_host/render_view_host_delegate.h create mode 100644 chrome/browser/renderer_host/render_widget_helper.cc create mode 100644 chrome/browser/renderer_host/render_widget_helper.h create mode 100644 chrome/browser/renderer_host/render_widget_host.cc create mode 100644 chrome/browser/renderer_host/render_widget_host.h create mode 100644 chrome/browser/renderer_host/render_widget_host_view.h create mode 100644 chrome/browser/renderer_host/render_widget_host_view_win.cc create mode 100644 chrome/browser/renderer_host/render_widget_host_view_win.h create mode 100644 chrome/browser/renderer_host/renderer_security_policy.cc create mode 100644 chrome/browser/renderer_host/renderer_security_policy.h create mode 100644 chrome/browser/renderer_host/renderer_security_policy_unittest.cc delete mode 100644 chrome/browser/renderer_security_policy.cc delete mode 100644 chrome/browser/renderer_security_policy.h delete mode 100644 chrome/browser/renderer_security_policy_unittest.cc create mode 100644 chrome/browser/tab_contents/render_view_context_menu.cc create mode 100644 chrome/browser/tab_contents/render_view_context_menu.h create mode 100644 chrome/browser/tab_contents/render_view_context_menu_controller.cc create mode 100644 chrome/browser/tab_contents/render_view_context_menu_controller.h create mode 100644 chrome/browser/tab_contents/render_view_host_manager.cc create mode 100644 chrome/browser/tab_contents/render_view_host_manager.h (limited to 'chrome/browser') diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 5ec7ffd..f4bccc7 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -21,7 +21,7 @@ #include "chrome/browser/find_notification_details.h" #include "chrome/browser/login_prompt.h" #include "chrome/browser/printing/print_job.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/ssl/ssl_manager.h" #include "chrome/browser/ssl/ssl_blocking_page.h" #include "chrome/browser/tab_contents/navigation_entry.h" diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons index 84917e2..805f12d0 100644 --- a/chrome/browser/browser.scons +++ b/chrome/browser/browser.scons @@ -126,16 +126,6 @@ input_files = ChromeFileList([ 'profile.h', 'profile_manager.cc', 'profile_manager.h', - 'render_view_host.cc', - 'render_view_host.h', - 'render_view_host_delegate.h', - 'render_widget_helper.cc', - 'render_widget_helper.h', - 'render_widget_host.cc', - 'render_widget_host.h', - 'render_widget_host_view.h', - 'render_widget_host_view_win.cc', - 'render_widget_host_view_win.h', 'resource_message_filter.cc', 'resource_message_filter.h', 'resource_request_details.h', @@ -181,12 +171,6 @@ input_files = ChromeFileList([ 'bookmarks/bookmark_utils.h', ]), MSVSFilter('Tab Contents (Old)', [ - 'render_view_context_menu.cc', - 'render_view_context_menu.h', - 'render_view_context_menu_controller.cc', - 'render_view_context_menu_controller.h', - 'render_view_host_manager.cc', - 'render_view_host_manager.h', 'security_style.h', ]), MSVSFilter('Browser Window', [ @@ -224,10 +208,6 @@ input_files = ChromeFileList([ 'window_sizer.cc', 'window_sizer.h', ]), - MSVSFilter('Policy', [ - 'renderer_security_policy.cc', - 'renderer_security_policy.h', - ]), MSVSFilter('Destination', [ 'base_history_model.cc', 'base_history_model.h', @@ -550,6 +530,18 @@ input_files = ChromeFileList([ 'renderer_host/download_throttling_resource_handler.h', 'renderer_host/browser_render_process_host.cc', 'renderer_host/browser_render_process_host.h', + 'renderer_host/render_view_host.cc', + 'renderer_host/render_view_host.h', + 'renderer_host/render_view_host_delegate.h', + 'renderer_host/render_widget_helper.cc', + 'renderer_host/render_widget_helper.h', + 'renderer_host/render_widget_host.cc', + 'renderer_host/render_widget_host.h', + 'renderer_host/render_widget_host_view.h', + 'renderer_host/render_widget_host_view_win.cc', + 'renderer_host/render_widget_host_view_win.h', + 'renderer_host/renderer_security_policy.cc', + 'renderer_host/renderer_security_policy.h', 'renderer_host/resource_dispatcher_host.cc', 'renderer_host/resource_dispatcher_host.h', 'renderer_host/resource_handler.h', @@ -579,6 +571,12 @@ input_files = ChromeFileList([ 'tab_contents/page_navigator.h', 'tab_contents/provisional_load_details.cc', 'tab_contents/provisional_load_details.h', + 'tab_contents/render_view_context_menu.cc', + 'tab_contents/render_view_context_menu.h', + 'tab_contents/render_view_context_menu_controller.cc', + 'tab_contents/render_view_context_menu_controller.h', + 'tab_contents/render_view_host_manager.cc', + 'tab_contents/render_view_host_manager.h', 'tab_contents/site_instance.cc', 'tab_contents/site_instance.h', 'tab_contents/status_view.cc', @@ -778,8 +776,6 @@ if not env.Bit('windows'): 'printing/win_printing_context.cc', 'profile.cc', 'profile_manager.cc', - 'render_view_context_menu.cc', - 'render_view_context_menu_controller.cc', 'render_view_host.cc', 'render_view_host_manager.cc', 'render_widget_helper.cc', diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj index 19cc20a..7deb350 100644 --- a/chrome/browser/browser.vcproj +++ b/chrome/browser/browser.vcproj @@ -482,46 +482,6 @@ > - - - - - - - - - - - - - - - - - - - - @@ -694,30 +654,6 @@ Name="Tab Contents (Old)" > - - - - - - - - - - - - @@ -859,18 +795,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -2200,24 +2100,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/stl_util-inl.h" diff --git a/chrome/browser/debugger/debugger_host_impl.cpp b/chrome/browser/debugger/debugger_host_impl.cpp index 0d39964..2f46feb 100644 --- a/chrome/browser/debugger/debugger_host_impl.cpp +++ b/chrome/browser/debugger/debugger_host_impl.cpp @@ -8,7 +8,7 @@ #include "base/string_util.h" #include "chrome/browser/debugger/debugger_io.h" #include "chrome/browser/debugger/debugger_wrapper.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/notification_service.h" diff --git a/chrome/browser/debugger/debugger_node.cc b/chrome/browser/debugger/debugger_node.cc index 86587c5..8a28b49 100644 --- a/chrome/browser/debugger/debugger_node.cc +++ b/chrome/browser/debugger/debugger_node.cc @@ -10,7 +10,7 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/browser/debugger/debugger_shell.h" diff --git a/chrome/browser/debugger/debugger_view.cc b/chrome/browser/debugger/debugger_view.cc index 97cb229..662deef 100644 --- a/chrome/browser/debugger/debugger_view.cc +++ b/chrome/browser/debugger/debugger_view.cc @@ -15,7 +15,7 @@ #include "chrome/browser/debugger/debugger_view.h" #include "chrome/browser/debugger/debugger_wrapper.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/standard_layout.h" diff --git a/chrome/browser/dom_ui/dom_ui_contents.cc b/chrome/browser/dom_ui/dom_ui_contents.cc index 1f6f220..a32a4cd 100644 --- a/chrome/browser/dom_ui/dom_ui_contents.cc +++ b/chrome/browser/dom_ui/dom_ui_contents.cc @@ -6,7 +6,7 @@ #include "chrome/browser/dom_ui/dom_ui.h" #include "chrome/browser/dom_ui/history_ui.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/common/resource_bundle.h" diff --git a/chrome/browser/dom_ui/dom_ui_host.cc b/chrome/browser/dom_ui/dom_ui_host.cc index 91ba5f5..bcc22844 100644 --- a/chrome/browser/dom_ui/dom_ui_host.cc +++ b/chrome/browser/dom_ui/dom_ui_host.cc @@ -7,9 +7,9 @@ #include "base/json_reader.h" #include "base/json_writer.h" #include "chrome/browser/browser.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/tab_contents_type.h" -#include "chrome/browser/render_view_host.h" DOMUIHost::DOMUIHost(Profile* profile, SiteInstance* instance, diff --git a/chrome/browser/dom_ui/html_dialog_contents.cc b/chrome/browser/dom_ui/html_dialog_contents.cc index 0b4a7a9..0a419fb 100644 --- a/chrome/browser/dom_ui/html_dialog_contents.cc +++ b/chrome/browser/dom_ui/html_dialog_contents.cc @@ -4,7 +4,7 @@ #include "chrome/browser/dom_ui/html_dialog_contents.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" const char kGearsScheme[] = "gears"; diff --git a/chrome/browser/dom_ui/new_tab_ui.cc b/chrome/browser/dom_ui/new_tab_ui.cc index 8d11080..dfe2c1f 100644 --- a/chrome/browser/dom_ui/new_tab_ui.cc +++ b/chrome/browser/dom_ui/new_tab_ui.cc @@ -16,7 +16,7 @@ #include "chrome/browser/history/page_usage_data.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profile.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/sessions/session_types.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/search_engines/template_url.h" diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 96fe0dd..fde5103 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -23,7 +23,7 @@ #include "chrome/browser/download/download_util.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/tab_contents/web_contents.h" diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index 43096e0..ac3844e 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -19,8 +19,8 @@ #include "chrome/browser/download/save_page_model.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/render_view_host.h" -#include "chrome/browser/render_view_host_delegate.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/tab_contents/web_contents.h" diff --git a/chrome/browser/download/save_package.h b/chrome/browser/download/save_package.h index 3363df5..a047b3f 100644 --- a/chrome/browser/download/save_package.h +++ b/chrome/browser/download/save_package.h @@ -17,7 +17,7 @@ #include "chrome/common/pref_member.h" #include "chrome/browser/download/save_item.h" #include "chrome/browser/download/save_types.h" -#include "chrome/browser/render_view_host_delegate.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" class SaveFileManager; class SavePackage; diff --git a/chrome/browser/fav_icon_helper.cc b/chrome/browser/fav_icon_helper.cc index 2f5bd97..6722336fb 100644 --- a/chrome/browser/fav_icon_helper.cc +++ b/chrome/browser/fav_icon_helper.cc @@ -6,7 +6,7 @@ #include "base/gfx/png_decoder.h" #include "base/gfx/png_encoder.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc index 0a79f80..321d8cf 100644 --- a/chrome/browser/memory_details.cc +++ b/chrome/browser/memory_details.cc @@ -16,7 +16,7 @@ #include "chrome/browser/plugin_process_host.h" #include "chrome/browser/plugin_service.h" #include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/render_view_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" diff --git a/chrome/browser/modal_html_dialog_delegate.cc b/chrome/browser/modal_html_dialog_delegate.cc index 46489cc..4afdd47 100644 --- a/chrome/browser/modal_html_dialog_delegate.cc +++ b/chrome/browser/modal_html_dialog_delegate.cc @@ -5,7 +5,7 @@ #include "chrome/browser/modal_html_dialog_delegate.h" #include "chrome/browser/browser_list.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" ModalHtmlDialogDelegate::ModalHtmlDialogDelegate( const GURL& url, int width, int height, const std::string& json_arguments, diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 9ae2efb..6813a15 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc @@ -9,7 +9,7 @@ #include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/printing/printed_document.h" #include "chrome/browser/printing/printer_query.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/gfx/emf.h" diff --git a/chrome/browser/render_view_context_menu.cc b/chrome/browser/render_view_context_menu.cc deleted file mode 100644 index 311ba27..0000000 --- a/chrome/browser/render_view_context_menu.cc +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2006-2008 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/render_view_context_menu.h" - -#include "base/logging.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/spellchecker.h" -#include "chrome/common/l10n_util.h" -#include "webkit/glue/context_node_types.h" - -#include "generated_resources.h" - -RenderViewContextMenu::RenderViewContextMenu( - Menu::Delegate* delegate, - HWND owner, - ContextNode::Type type, - const std::wstring& misspelled_word, - const std::vector& misspelled_word_suggestions, - Profile* profile) - : Menu(delegate, Menu::TOPLEFT, owner), - misspelled_word_(misspelled_word), - misspelled_word_suggestions_(misspelled_word_suggestions), - profile_(profile) { - InitMenu(type); -} - -RenderViewContextMenu::~RenderViewContextMenu() { -} - -void RenderViewContextMenu::InitMenu(ContextNode::Type type) { - switch (type) { - case ContextNode::PAGE: - AppendPageItems(); - break; - case ContextNode::FRAME: - AppendFrameItems(); - break; - case ContextNode::LINK: - AppendLinkItems(); - break; - case ContextNode::IMAGE: - AppendImageItems(); - break; - case ContextNode::IMAGE_LINK: - AppendLinkItems(); - AppendSeparator(); - AppendImageItems(); - break; - case ContextNode::SELECTION: - AppendSelectionItems(); - break; - case ContextNode::EDITABLE: - AppendEditableItems(); - break; - default: - NOTREACHED() << "Unknown ContextNode::Type"; - } - AppendSeparator(); - AppendDeveloperItems(); -} - -void RenderViewContextMenu::AppendDeveloperItems() { - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_INSPECTELEMENT); -} - -void RenderViewContextMenu::AppendLinkItems() { - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKNEWTAB); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVELINKAS); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYLINKLOCATION); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY); -} - -void RenderViewContextMenu::AppendImageItems() { - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEIMAGEAS); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYIMAGELOCATION); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYIMAGE); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB); -} - -void RenderViewContextMenu::AppendPageItems() { - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_BACK); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_FORWARD); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_RELOAD); - AppendSeparator(); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEPAGEAS); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PRINT); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWPAGESOURCE); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWPAGEINFO); -} - -void RenderViewContextMenu::AppendFrameItems() { - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_BACK); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_FORWARD); - AppendSeparator(); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMENEWTAB); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMENEWWINDOW); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMEOFFTHERECORD); - AppendSeparator(); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEFRAMEAS); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PRINTFRAME); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMEINFO); -} - -void RenderViewContextMenu::AppendSelectionItems() { - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY); - DCHECK(profile_); - if (profile_->GetTemplateURLModel()->GetDefaultSearchProvider() != NULL) - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SEARCHWEBFOR); -} - -void RenderViewContextMenu::AppendEditableItems() { - // Append Dictionary spell check suggestions. - for (size_t i = 0; i < misspelled_word_suggestions_.size() && - IDC_SPELLCHECK_SUGGESTION_0 + i <= IDC_SPELLCHECK_SUGGESTION_LAST; - i ++) { - AppendMenuItemWithLabel(IDC_SPELLCHECK_SUGGESTION_0 + static_cast(i), - misspelled_word_suggestions_[i]); - } - if (misspelled_word_suggestions_.size() > 0) - AppendSeparator(); - - // If word is misspelled, give option for "Add to dictionary" - if (!misspelled_word_.empty()) { - if (misspelled_word_suggestions_.size() == 0) { - AppendMenuItemWithLabel(0, - l10n_util::GetString(IDS_CONTENT_CONTEXT_NO_SPELLING_SUGGESTIONS)); - } - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY); - AppendSeparator(); - } - - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_UNDO); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_REDO); - AppendSeparator(); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_CUT); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PASTE); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_DELETE); - AppendSeparator(); - - // Add Spell Check options sub menu. - spellchecker_sub_menu_ = AppendSubMenu(IDC_SPELLCHECK_MENU, - l10n_util::GetString(IDS_CONTENT_CONTEXT_SPELLCHECK_MENU)); - - // Add Spell Check languages to sub menu. - SpellChecker::Languages display_languages; - SpellChecker::GetSpellCheckLanguagesToDisplayInContextMenu(profile_, - &display_languages); - DCHECK(display_languages.size() < - IDC_SPELLCHECK_LANGUAGES_LAST - IDC_SPELLCHECK_LANGUAGES_FIRST); - const std::wstring app_locale = g_browser_process->GetApplicationLocale(); - for (size_t i = 0; i < display_languages.size(); ++i) { - std::wstring local_language(l10n_util::GetLocalName( - display_languages[i], app_locale, true)); - spellchecker_sub_menu_->AppendMenuItem( - IDC_SPELLCHECK_LANGUAGES_FIRST + i, local_language, RADIO); - } - - // Add item in the sub menu to pop up the fonts and languages options menu. - spellchecker_sub_menu_->AppendSeparator(); - spellchecker_sub_menu_->AppendDelegateMenuItem( - IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS); - - // Add 'Check the spelling of this field' item in the sub menu. - spellchecker_sub_menu_->AppendMenuItem( - IDC_CHECK_SPELLING_OF_THIS_FIELD, - l10n_util::GetString(IDS_CONTENT_CONTEXT_CHECK_SPELLING_OF_THIS_FIELD), - CHECKBOX); - - AppendSeparator(); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SELECTALL); -} diff --git a/chrome/browser/render_view_context_menu.h b/chrome/browser/render_view_context_menu.h deleted file mode 100644 index a38cbe8..0000000 --- a/chrome/browser/render_view_context_menu.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2006-2008 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_RENDER_VIEW_CONTEXT_MENU_H__ -#define CHROME_BROWSER_RENDER_VIEW_CONTEXT_MENU_H__ - -#include "chrome/views/menu.h" -#include "webkit/glue/context_node_types.h" - -class Profile; - -class RenderViewContextMenu : public Menu { - public: - RenderViewContextMenu( - Menu::Delegate* delegate, - HWND owner, - ContextNode::Type type, - const std::wstring& misspelled_word, - const std::vector& misspelled_word_suggestions, - Profile* profile); - - virtual ~RenderViewContextMenu(); - - private: - void InitMenu(ContextNode::Type type); - void AppendDeveloperItems(); - void AppendLinkItems(); - void AppendImageItems(); - void AppendPageItems(); - void AppendFrameItems(); - void AppendSelectionItems(); - void AppendEditableItems(); - - std::wstring misspelled_word_; - std::vector misspelled_word_suggestions_; - Profile* profile_; - Menu* spellchecker_sub_menu_; - - DISALLOW_EVIL_CONSTRUCTORS(RenderViewContextMenu); -}; - -#endif // CHROME_BROWSER_RENDER_VIEW_CONTEXT_MENU_H__ - diff --git a/chrome/browser/render_view_context_menu_controller.cc b/chrome/browser/render_view_context_menu_controller.cc deleted file mode 100644 index 307bae4..0000000 --- a/chrome/browser/render_view_context_menu_controller.cc +++ /dev/null @@ -1,516 +0,0 @@ -// Copyright (c) 2006-2008 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/render_view_context_menu_controller.h" - -#include "base/command_line.h" -#include "base/path_service.h" -#include "base/scoped_clipboard_writer.h" -#include "base/string_util.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/views/options/fonts_languages_window_view.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/pref_service.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/spellchecker.h" -#include "chrome/browser/download/download_manager.h" -#include "chrome/browser/download/save_package.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/views/page_info_window.h" -#include "chrome/browser/tab_contents/navigation_controller.h" -#include "chrome/browser/tab_contents/navigation_entry.h" -#include "chrome/browser/tab_contents/web_contents.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/clipboard_service.h" -#include "chrome/common/l10n_util.h" -#include "chrome/common/win_util.h" -#include "net/base/escape.h" -#include "net/base/net_util.h" -#include "net/url_request/url_request.h" - -#include "generated_resources.h" - -RenderViewContextMenuController::RenderViewContextMenuController( - WebContents* source_web_contents, - const ViewHostMsg_ContextMenu_Params& params) - : source_web_contents_(source_web_contents), - params_(params) { -} - -RenderViewContextMenuController::~RenderViewContextMenuController() { -} - -/////////////////////////////////////////////////////////////////////////////// -// Controller methods - -void RenderViewContextMenuController::OpenURL( - const GURL& url, - WindowOpenDisposition disposition, - PageTransition::Type transition) { - source_web_contents_->OpenURL(url, GURL(), disposition, transition); -} - -void RenderViewContextMenuController::CopyImageAt(int x, int y) { - source_web_contents_->render_view_host()->CopyImageAt(x, y); -} - -void RenderViewContextMenuController::Inspect(int x, int y) { - source_web_contents_->render_view_host()->InspectElementAt(x, y); -} - -void RenderViewContextMenuController::WriteTextToClipboard( - const std::wstring& text) { - ClipboardService* clipboard = g_browser_process->clipboard_service(); - - if (!clipboard) - return; - - ScopedClipboardWriter scw(clipboard); - scw.WriteText(text); -} - -void RenderViewContextMenuController::WriteURLToClipboard(const GURL& url) { - if (url.SchemeIs("mailto")) - WriteTextToClipboard(UTF8ToWide(url.path())); - else - WriteTextToClipboard(UTF8ToWide(url.spec())); -} - -/////////////////////////////////////////////////////////////////////////////// -// Menu::Delegate methods - -std::wstring RenderViewContextMenuController::GetLabel(int id) const { - switch (id) { - case IDS_CONTENT_CONTEXT_SEARCHWEBFOR: { - const TemplateURL* const default_provider = source_web_contents_-> - profile()->GetTemplateURLModel()->GetDefaultSearchProvider(); - DCHECK(default_provider); // The context menu should not contain this - // item when there is no provider. - return l10n_util::GetStringF(id, default_provider->short_name(), - l10n_util::TruncateString(params_.selection_text, 50)); - } - - case IDS_CONTENT_CONTEXT_COPYLINKLOCATION: - if (params_.link_url.SchemeIs("mailto")) - return l10n_util::GetString(IDS_CONTENT_CONTEXT_COPYEMAILADDRESS); - - default: - return l10n_util::GetString(id); - } -} - -bool RenderViewContextMenuController::IsCommandEnabled(int id) const { - // Allow Spell Check language items on sub menu for text area context menu. - if ((id >= IDC_SPELLCHECK_LANGUAGES_FIRST) && - (id < IDC_SPELLCHECK_LANGUAGES_LAST)) { - return true; - } - - switch (id) { - case IDS_CONTENT_CONTEXT_BACK: - return source_web_contents_->controller()->CanGoBack(); - - case IDS_CONTENT_CONTEXT_FORWARD: - return source_web_contents_->controller()->CanGoForward(); - - case IDS_CONTENT_CONTEXT_VIEWPAGESOURCE: - case IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE: - case IDS_CONTENT_CONTEXT_INSPECTELEMENT: - return IsDevCommandEnabled(id); - - case IDS_CONTENT_CONTEXT_OPENLINKNEWTAB: - case IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW: - case IDS_CONTENT_CONTEXT_COPYLINKLOCATION: - return params_.link_url.is_valid(); - - case IDS_CONTENT_CONTEXT_SAVELINKAS: - return params_.link_url.is_valid() && - URLRequest::IsHandledURL(params_.link_url); - - case IDS_CONTENT_CONTEXT_SAVEIMAGEAS: - return params_.image_url.is_valid() && - URLRequest::IsHandledURL(params_.image_url); - - case IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB: - case IDS_CONTENT_CONTEXT_COPYIMAGELOCATION: - return params_.image_url.is_valid(); - - case IDS_CONTENT_CONTEXT_SAVEPAGEAS: - return SavePackage::IsSavableURL(source_web_contents_->GetURL()); - - case IDS_CONTENT_CONTEXT_OPENFRAMENEWTAB: - case IDS_CONTENT_CONTEXT_OPENFRAMENEWWINDOW: - return params_.frame_url.is_valid(); - - case IDS_CONTENT_CONTEXT_UNDO: - return !!(params_.edit_flags & ContextNode::CAN_UNDO); - - case IDS_CONTENT_CONTEXT_REDO: - return !!(params_.edit_flags & ContextNode::CAN_REDO); - - case IDS_CONTENT_CONTEXT_CUT: - return !!(params_.edit_flags & ContextNode::CAN_CUT); - - case IDS_CONTENT_CONTEXT_COPY: - return !!(params_.edit_flags & ContextNode::CAN_COPY); - - case IDS_CONTENT_CONTEXT_PASTE: - return !!(params_.edit_flags & ContextNode::CAN_PASTE); - - case IDS_CONTENT_CONTEXT_DELETE: - return !!(params_.edit_flags & ContextNode::CAN_DELETE); - - case IDS_CONTENT_CONTEXT_SELECTALL: - return !!(params_.edit_flags & ContextNode::CAN_SELECT_ALL); - - case IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD: - return !source_web_contents_->profile()->IsOffTheRecord() && - params_.link_url.is_valid(); - - case IDS_CONTENT_CONTEXT_OPENFRAMEOFFTHERECORD: - return !source_web_contents_->profile()->IsOffTheRecord() && - params_.frame_url.is_valid(); - - case IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY: - return !params_.misspelled_word.empty(); - - case IDS_CONTENT_CONTEXT_VIEWPAGEINFO: - return (source_web_contents_->controller()->GetActiveEntry() != NULL); - - case IDS_CONTENT_CONTEXT_RELOAD: - case IDS_CONTENT_CONTEXT_COPYIMAGE: - case IDS_CONTENT_CONTEXT_PRINT: - case IDS_CONTENT_CONTEXT_SEARCHWEBFOR: - case IDC_SPELLCHECK_SUGGESTION_0: - case IDC_SPELLCHECK_SUGGESTION_1: - case IDC_SPELLCHECK_SUGGESTION_2: - case IDC_SPELLCHECK_SUGGESTION_3: - case IDC_SPELLCHECK_SUGGESTION_4: - case IDC_SPELLCHECK_MENU: - case IDC_CHECK_SPELLING_OF_THIS_FIELD: - case IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS: - case IDS_CONTENT_CONTEXT_VIEWFRAMEINFO: - return true; - - case IDS_CONTENT_CONTEXT_SAVEFRAMEAS: - case IDS_CONTENT_CONTEXT_PRINTFRAME: - case IDS_CONTENT_CONTEXT_ADDSEARCHENGINE: // Not implemented. - default: - return false; - } -} - -bool RenderViewContextMenuController::IsItemChecked(int id) const { - // Check box for 'Check the Spelling of this field'. - if (id == IDC_CHECK_SPELLING_OF_THIS_FIELD) - return params_.spellcheck_enabled; - - // Don't bother getting the display language vector if this isn't a spellcheck - // language. - if ((id < IDC_SPELLCHECK_LANGUAGES_FIRST) || - (id >= IDC_SPELLCHECK_LANGUAGES_LAST)) - return false; - - SpellChecker::Languages display_languages; - return SpellChecker::GetSpellCheckLanguagesToDisplayInContextMenu( - source_web_contents_->profile(), &display_languages) == - (id - IDC_SPELLCHECK_LANGUAGES_FIRST); -} - -bool RenderViewContextMenuController::GetAcceleratorInfo( - int id, - views::Accelerator* accel) { - // There are no formally defined accelerators we can query so we assume - // that Ctrl+C, Ctrl+V, Ctrl+X, Ctrl-A, etc do what they normally do. - switch (id) { - case IDS_CONTENT_CONTEXT_UNDO: - *accel = views::Accelerator(L'Z', false, true, false); - return true; - - case IDS_CONTENT_CONTEXT_REDO: - *accel = views::Accelerator(L'Z', true, true, false); - return true; - - case IDS_CONTENT_CONTEXT_CUT: - *accel = views::Accelerator(L'X', false, true, false); - return true; - - case IDS_CONTENT_CONTEXT_COPY: - *accel = views::Accelerator(L'C', false, true, false); - return true; - - case IDS_CONTENT_CONTEXT_PASTE: - *accel = views::Accelerator(L'V', false, true, false); - return true; - - case IDS_CONTENT_CONTEXT_SELECTALL: - *accel = views::Accelerator(L'A', false, true, false); - - default: - return false; - } -} - -void RenderViewContextMenuController::ExecuteCommand(int id) { - // Check to see if one of the spell check language ids have been clicked. - if (id >= IDC_SPELLCHECK_LANGUAGES_FIRST && - id < IDC_SPELLCHECK_LANGUAGES_LAST) { - const size_t language_number = id - IDC_SPELLCHECK_LANGUAGES_FIRST; - SpellChecker::Languages display_languages; - SpellChecker::GetSpellCheckLanguagesToDisplayInContextMenu( - source_web_contents_->profile(), &display_languages); - if (language_number < display_languages.size()) { - StringPrefMember dictionary_language; - dictionary_language.Init(prefs::kSpellCheckDictionary, - source_web_contents_->profile()->GetPrefs(), NULL); - dictionary_language.SetValue(display_languages[language_number]); - } - - return; - } - - switch (id) { - case IDS_CONTENT_CONTEXT_OPENLINKNEWTAB: - OpenURL(params_.link_url, NEW_BACKGROUND_TAB, PageTransition::LINK); - break; - - case IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW: - OpenURL(params_.link_url, NEW_WINDOW, PageTransition::LINK); - break; - - case IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD: - OpenURL(params_.link_url, OFF_THE_RECORD, PageTransition::LINK); - break; - - // TODO(paulg): Prompt the user for file name when saving links and images. - case IDS_CONTENT_CONTEXT_SAVEIMAGEAS: - case IDS_CONTENT_CONTEXT_SAVELINKAS: { - const GURL& referrer = - params_.frame_url.is_empty() ? params_.page_url : params_.frame_url; - const GURL& url = id == IDS_CONTENT_CONTEXT_SAVELINKAS ? params_.link_url : - params_.image_url; - DownloadManager* dlm = - source_web_contents_->profile()->GetDownloadManager(); - dlm->DownloadUrl(url, referrer, source_web_contents_); - break; - } - - case IDS_CONTENT_CONTEXT_COPYLINKLOCATION: - WriteURLToClipboard(params_.link_url); - break; - - case IDS_CONTENT_CONTEXT_COPYIMAGELOCATION: - WriteURLToClipboard(params_.image_url); - break; - - case IDS_CONTENT_CONTEXT_COPYIMAGE: - CopyImageAt(params_.x, params_.y); - break; - - case IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB: - OpenURL(params_.image_url, NEW_BACKGROUND_TAB, PageTransition::LINK); - break; - - case IDS_CONTENT_CONTEXT_BACK: - source_web_contents_->controller()->GoBack(); - break; - - case IDS_CONTENT_CONTEXT_FORWARD: - source_web_contents_->controller()->GoForward(); - break; - - case IDS_CONTENT_CONTEXT_SAVEPAGEAS: - source_web_contents_->OnSavePage(); - break; - - case IDS_CONTENT_CONTEXT_RELOAD: - source_web_contents_->controller()->Reload(true); - break; - - case IDS_CONTENT_CONTEXT_PRINT: - source_web_contents_->PrintPreview(); - break; - - case IDS_CONTENT_CONTEXT_VIEWPAGESOURCE: - OpenURL(GURL("view-source:" + params_.page_url.spec()), - NEW_FOREGROUND_TAB, PageTransition::GENERATED); - break; - - case IDS_CONTENT_CONTEXT_INSPECTELEMENT: - Inspect(params_.x, params_.y); - break; - - case IDS_CONTENT_CONTEXT_VIEWPAGEINFO: { - NavigationEntry* nav_entry = - source_web_contents_->controller()->GetActiveEntry(); - PageInfoWindow::CreatePageInfo(source_web_contents_->profile(), - nav_entry, - source_web_contents_->GetContentHWND(), - PageInfoWindow::SECURITY); - break; - } - - case IDS_CONTENT_CONTEXT_OPENFRAMENEWTAB: - OpenURL(params_.frame_url, NEW_BACKGROUND_TAB, PageTransition::LINK); - break; - - case IDS_CONTENT_CONTEXT_OPENFRAMENEWWINDOW: - OpenURL(params_.frame_url, NEW_WINDOW, PageTransition::LINK); - break; - - case IDS_CONTENT_CONTEXT_OPENFRAMEOFFTHERECORD: - OpenURL(params_.frame_url, OFF_THE_RECORD, PageTransition::LINK); - break; - - case IDS_CONTENT_CONTEXT_SAVEFRAMEAS: - win_util::MessageBox(NULL, L"Context Menu Action", L"Save Frame As", - MB_OK); - break; - - case IDS_CONTENT_CONTEXT_PRINTFRAME: - win_util::MessageBox(NULL, L"Context Menu Action", L"Print Frame", - MB_OK); - break; - - case IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE: - OpenURL(GURL("view-source:" + params_.frame_url.spec()), - NEW_FOREGROUND_TAB, PageTransition::GENERATED); - break; - - case IDS_CONTENT_CONTEXT_VIEWFRAMEINFO: { - // Deserialize the SSL info. - NavigationEntry::SSLStatus ssl; - if (!params_.security_info.empty()) { - int cert_id, cert_status, security_bits; - SSLManager::DeserializeSecurityInfo(params_.security_info, - &cert_id, - &cert_status, - &security_bits); - ssl.set_cert_id(cert_id); - ssl.set_cert_status(cert_status); - ssl.set_security_bits(security_bits); - } - PageInfoWindow::CreateFrameInfo(source_web_contents_->profile(), - params_.frame_url, - ssl, - source_web_contents_->GetContentHWND(), - PageInfoWindow::SECURITY); - break; - } - - case IDS_CONTENT_CONTEXT_UNDO: - source_web_contents_->render_view_host()->Undo(); - break; - - case IDS_CONTENT_CONTEXT_REDO: - source_web_contents_->render_view_host()->Redo(); - break; - - case IDS_CONTENT_CONTEXT_CUT: - source_web_contents_->render_view_host()->Cut(); - break; - - case IDS_CONTENT_CONTEXT_COPY: - source_web_contents_->render_view_host()->Copy(); - break; - - case IDS_CONTENT_CONTEXT_PASTE: - source_web_contents_->render_view_host()->Paste(); - break; - - case IDS_CONTENT_CONTEXT_DELETE: - source_web_contents_->render_view_host()->Delete(); - break; - - case IDS_CONTENT_CONTEXT_SELECTALL: - source_web_contents_->render_view_host()->SelectAll(); - break; - - case IDS_CONTENT_CONTEXT_SEARCHWEBFOR: { - const TemplateURL* const default_provider = source_web_contents_-> - profile()->GetTemplateURLModel()->GetDefaultSearchProvider(); - DCHECK(default_provider); // The context menu should not contain this - // item when there is no provider. - const TemplateURLRef* const search_url = default_provider->url(); - DCHECK(search_url->SupportsReplacement()); - OpenURL(GURL(search_url->ReplaceSearchTerms(*default_provider, - params_.selection_text, TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, - std::wstring())), NEW_FOREGROUND_TAB, PageTransition::GENERATED); - break; - } - - case IDC_SPELLCHECK_SUGGESTION_0: - case IDC_SPELLCHECK_SUGGESTION_1: - case IDC_SPELLCHECK_SUGGESTION_2: - case IDC_SPELLCHECK_SUGGESTION_3: - case IDC_SPELLCHECK_SUGGESTION_4: - source_web_contents_->render_view_host()->Replace( - params_.dictionary_suggestions[id - IDC_SPELLCHECK_SUGGESTION_0]); - break; - - case IDC_CHECK_SPELLING_OF_THIS_FIELD: - source_web_contents_->render_view_host()->ToggleSpellCheck(); - break; - case IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY: - source_web_contents_->render_view_host()->AddToDictionary( - params_.misspelled_word); - break; - - case IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS: { - FontsLanguagesWindowView* window_ = new FontsLanguagesWindowView( - source_web_contents_->profile()); - views::Window::CreateChromeWindow(source_web_contents_->GetContentHWND(), - gfx::Rect(), window_)->Show(); - window_->SelectLanguagesTab(); - break; - } - - case IDS_CONTENT_CONTEXT_ADDSEARCHENGINE: // Not implemented. - default: - break; - } -} - -bool RenderViewContextMenuController::IsDevCommandEnabled(int id) const { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kAlwaysEnableDevTools)) - return true; - - NavigationEntry *active_entry = - source_web_contents_->controller()->GetActiveEntry(); - if (!active_entry) - return false; - - // Don't inspect HTML dialogs. - if (source_web_contents_->type() == TAB_CONTENTS_HTML_DIALOG) - return false; - - // Don't inspect view source. - if (source_web_contents_->type() == TAB_CONTENTS_VIEW_SOURCE) - return false; - - // Don't inspect inspector, new tab UI, etc. - if (active_entry->url().SchemeIs("chrome")) - return false; - - // Don't inspect about:network, about:memory, etc. - // However, we do want to inspect about:blank, which is often - // used by ordinary web pages. - if (active_entry->display_url().SchemeIs("about") && - !LowerCaseEqualsASCII(active_entry->display_url().path(), "blank")) - return false; - - // Don't enable the web inspector if JavaScript is disabled - if (id == IDS_CONTENT_CONTEXT_INSPECTELEMENT) { - PrefService* prefs = source_web_contents_->profile()->GetPrefs(); - if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled) || - command_line.HasSwitch(switches::kDisableJavaScript)) - return false; - } - - return true; -} - diff --git a/chrome/browser/render_view_context_menu_controller.h b/chrome/browser/render_view_context_menu_controller.h deleted file mode 100644 index b03fd3b..0000000 --- a/chrome/browser/render_view_context_menu_controller.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2006-2008 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_RENDER_VIEW_CONTEXT_MENU_CONTROLLER_H__ -#define CHROME_BROWSER_RENDER_VIEW_CONTEXT_MENU_CONTROLLER_H__ - -#include "chrome/common/pref_member.h" -#include "chrome/views/menu.h" -#include "chrome/common/render_messages.h" - -class WebContents; - -class RenderViewContextMenuController : public Menu::Delegate { - public: - RenderViewContextMenuController(WebContents* source_web_contents, - const ViewHostMsg_ContextMenu_Params& params); - virtual ~RenderViewContextMenuController(); - - // Overridden from Menu::Delegate - virtual std::wstring GetLabel(int id) const; - virtual bool IsCommandEnabled(int id) const; - virtual bool IsItemChecked(int id) const; - virtual void ExecuteCommand(int id); - virtual bool GetAcceleratorInfo(int id, views::Accelerator* accel); - - private: - // Opens the specified URL string in a new tab. If |in_current_window| is - // false, a new window is created to hold the new tab. - void OpenURL(const GURL& url, - WindowOpenDisposition disposition, - PageTransition::Type transition); - - // Copy to the clipboard an image located at a point in the RenderView - void CopyImageAt(int x, int y); - - // Launch the inspector targeting a point in the RenderView - void Inspect(int x, int y); - - // Writes the specified text/url to the system clipboard - void WriteTextToClipboard(const std::wstring& text); - void WriteURLToClipboard(const GURL& url); - - bool IsDevCommandEnabled(int id) const; - - DISALLOW_EVIL_CONSTRUCTORS(RenderViewContextMenuController); - - private: - WebContents* source_web_contents_; - ViewHostMsg_ContextMenu_Params params_; - StringPrefMember dictionary_language_; - int current_dictionary_language_index_; -}; - -#endif // CHROME_BROWSER_RENDER_VIEW_CONTEXT_MENU_CONTROLLER_H__ - diff --git a/chrome/browser/render_view_host.cc b/chrome/browser/render_view_host.cc deleted file mode 100644 index 152c3d6..0000000 --- a/chrome/browser/render_view_host.cc +++ /dev/null @@ -1,1310 +0,0 @@ -// Copyright (c) 2006-2008 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/render_view_host.h" - -#include -#include - -#include "base/string_util.h" -#include "base/waitable_event.h" -#include "chrome/app/result_codes.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/cross_site_request_manager.h" -#include "chrome/browser/debugger/debugger_wrapper.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/render_widget_host.h" -#include "chrome/browser/render_widget_host_view.h" -#include "chrome/browser/render_view_host_delegate.h" -#include "chrome/browser/renderer_security_policy.h" -#include "chrome/browser/tab_contents/navigation_entry.h" -#include "chrome/browser/tab_contents/site_instance.h" -#include "chrome/browser/tab_contents/web_contents.h" -#include "chrome/common/resource_bundle.h" -#include "chrome/common/thumbnail_score.h" -#include "net/base/net_util.h" -#include "skia/include/SkBitmap.h" - -using base::TimeDelta; - -namespace { - -void FilterURL(RendererSecurityPolicy* policy, int renderer_id, GURL* url) { - if (!url->is_valid()) - return; // We don't need to block invalid URLs. - - if (url->SchemeIs("about")) { - // The renderer treats all URLs in the about: scheme as being about:blank. - // Canonicalize about: URLs to about:blank. - *url = GURL("about:blank"); - } - - if (!policy->CanRequestURL(renderer_id, *url)) { - // If this renderer is not permitted to request this URL, we invalidate the - // URL. This prevents us from storing the blocked URL and becoming confused - // later. - LOG(INFO) << "Blocked URL " << url->spec(); - *url = GURL(); - } -} - -// Delay to wait on closing the tab for a beforeunload/unload handler to fire. -const int kUnloadTimeoutMS = 1000; - -} // namespace - -/////////////////////////////////////////////////////////////////////////////// -// RenderViewHost, public: - -// static -RenderViewHost* RenderViewHost::FromID(int render_process_id, - int render_view_id) { - RenderProcessHost* process = RenderProcessHost::FromID(render_process_id); - if (!process) - return NULL; - RenderWidgetHost* widget = static_cast( - process->GetListenerByID(render_view_id)); - if (!widget || !widget->IsRenderView()) - return NULL; - return static_cast(widget); -} - -RenderViewHost::RenderViewHost(SiteInstance* instance, - RenderViewHostDelegate* delegate, - int routing_id, - base::WaitableEvent* modal_dialog_event) - : RenderWidgetHost(instance->GetProcess(), routing_id), - instance_(instance), - enable_dom_ui_bindings_(false), - enable_external_host_bindings_(false), - delegate_(delegate), - renderer_initialized_(false), - waiting_for_drag_context_response_(false), - debugger_attached_(false), - modal_dialog_count_(0), - navigations_suspended_(false), - suspended_nav_message_(NULL), - run_modal_reply_msg_(NULL), - has_unload_listener_(false), - is_waiting_for_unload_ack_(false), - are_javascript_messages_suppressed_(false) { - DCHECK(instance_); - DCHECK(delegate_); - if (modal_dialog_event == NULL) - modal_dialog_event = new base::WaitableEvent(true, false); - - modal_dialog_event_.reset(modal_dialog_event); -#ifdef CHROME_PERSONALIZATION - personalization_ = Personalization::CreateHostPersonalization(this); -#endif -} - -RenderViewHost::~RenderViewHost() { - OnDebugDisconnect(); - -#ifdef CHROME_PERSONALIZATION - Personalization::CleanupHostPersonalization(personalization_); - personalization_ = NULL; -#endif - - // Be sure to clean up any leftover state from cross-site requests. - Singleton()->SetHasPendingCrossSiteRequest( - process()->host_id(), routing_id_, false); -} - -bool RenderViewHost::CreateRenderView() { - DCHECK(!IsRenderViewLive()) << "Creating view twice"; - - // The process may (if we're sharing a process with another host that already - // initialized it) or may not (we have our own process or the old process - // crashed) have been initialized. Calling Init multiple times will be - // ignored, so this is safe. - if (!process_->Init()) - return false; - DCHECK(process_->channel()); - DCHECK(process_->profile()); - - renderer_initialized_ = true; - - HANDLE modal_dialog_event; - HANDLE renderer_process_handle = process()->process().handle(); - if (renderer_process_handle == NULL) - renderer_process_handle = GetCurrentProcess(); - - BOOL result = DuplicateHandle(GetCurrentProcess(), - modal_dialog_event_->handle(), - renderer_process_handle, - &modal_dialog_event, - SYNCHRONIZE, - FALSE, - 0); - DCHECK(result) << "Couldn't duplicate the modal dialog handle for the renderer."; - - DCHECK(view_); - Send(new ViewMsg_New(view_->GetPluginHWND(), - modal_dialog_event, - delegate_->GetWebkitPrefs(), - routing_id_)); - - // Set the alternate error page, which is profile specific, in the renderer. - GURL url = delegate_->GetAlternateErrorPageURL(); - SetAlternateErrorPageURL(url); - - // If it's enabled, tell the renderer to set up the Javascript bindings for - // sending messages back to the browser. - Send(new ViewMsg_AllowBindings( - routing_id_, enable_dom_ui_bindings_, enable_external_host_bindings_)); - - // Let our delegate know that we created a RenderView. - delegate_->RendererCreated(this); - - return true; -} - -bool RenderViewHost::IsRenderViewLive() const { - return process_->channel() && renderer_initialized_; -} - -void RenderViewHost::Init() { - RenderWidgetHost::Init(); - renderer_initialized_ = true; -} - -void RenderViewHost::NavigateToEntry(const NavigationEntry& entry, - bool is_reload) { - ViewMsg_Navigate_Params params; - MakeNavigateParams(entry, is_reload, ¶ms); - - RendererSecurityPolicy::GetInstance()->GrantRequestURL( - process()->host_id(), params.url); - - DoNavigate(new ViewMsg_Navigate(routing_id_, params)); -} - -void RenderViewHost::NavigateToURL(const GURL& url) { - ViewMsg_Navigate_Params params; - params.page_id = -1; - params.url = url; - params.transition = PageTransition::LINK; - params.reload = false; - - RendererSecurityPolicy::GetInstance()->GrantRequestURL( - process()->host_id(), params.url); - - DoNavigate(new ViewMsg_Navigate(routing_id_, params)); -} - -void RenderViewHost::DoNavigate(ViewMsg_Navigate* nav_message) { - // Only send the message if we aren't suspended at the start of a cross-site - // request. - if (navigations_suspended_) { - // Shouldn't be possible to have a second navigation while suspended, since - // navigations will only be suspended during a cross-site request. If a - // second navigation occurs, WebContents will cancel this pending RVH - // create a new pending RVH. - DCHECK(!suspended_nav_message_.get()); - suspended_nav_message_.reset(nav_message); - } else { - Send(nav_message); - } -} - -void RenderViewHost::LoadAlternateHTMLString(const std::string& html_text, - bool new_navigation, - const GURL& display_url, - const std::string& security_info) { - Send(new ViewMsg_LoadAlternateHTMLText(routing_id_, html_text, - new_navigation, display_url, - security_info)); -} - -void RenderViewHost::SetNavigationsSuspended(bool suspend) { - DCHECK(navigations_suspended_ != suspend); - navigations_suspended_ = suspend; - if (!suspend && suspended_nav_message_.get()) { - // Resume navigation - Send(suspended_nav_message_.release()); - } -} - -void RenderViewHost::FirePageBeforeUnload() { - if (!IsRenderViewLive()) { - // This RenderViewHost doesn't have a live renderer, so just skip running - // the onbeforeunload handler. - OnMsgShouldCloseACK(true); - return; - } - - // This may be called more than once (if the user clicks the tab close button - // several times, or if she clicks the tab close button than the browser close - // button), so this test makes sure we only send the message once. - if (!is_waiting_for_unload_ack_) { - // Start the hang monitor in case the renderer hangs in the beforeunload - // handler. - is_waiting_for_unload_ack_ = true; - StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); - Send(new ViewMsg_ShouldClose(routing_id_)); - } -} - -void RenderViewHost::FirePageUnload() { - ClosePage(site_instance()->process_host_id(), - routing_id()); -} - -// static -void RenderViewHost::ClosePageIgnoringUnloadEvents(int render_process_host_id, - int request_id) { - RenderViewHost* rvh = RenderViewHost::FromID(render_process_host_id, - request_id); - if (!rvh) - return; - - rvh->StopHangMonitorTimeout(); - rvh->is_waiting_for_unload_ack_ = false; - - rvh->UnloadListenerHasFired(); - rvh->delegate()->Close(rvh); -} - -void RenderViewHost::ClosePage(int new_render_process_host_id, - int new_request_id) { - // Start the hang monitor in case the renderer hangs in the unload handler. - is_waiting_for_unload_ack_ = true; - StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); - - if (IsRenderViewLive()) { - Send(new ViewMsg_ClosePage(routing_id_, - new_render_process_host_id, - new_request_id)); - } else { - // This RenderViewHost doesn't have a live renderer, so just skip closing - // the page. We must notify the ResourceDispatcherHost on the IO thread, - // which we will do through the RenderProcessHost's widget helper. - process()->CrossSiteClosePageACK(new_render_process_host_id, - new_request_id); - } -} - -void RenderViewHost::SetHasPendingCrossSiteRequest(bool has_pending_request, - int request_id) { - Singleton()->SetHasPendingCrossSiteRequest( - process()->host_id(), routing_id_, has_pending_request); - pending_request_id_ = request_id; -} - -int RenderViewHost::GetPendingRequestId() { - return pending_request_id_; -} - -void RenderViewHost::OnCrossSiteResponse(int new_render_process_host_id, - int new_request_id) { - delegate_->OnCrossSiteResponse(new_render_process_host_id, new_request_id); -} - -void RenderViewHost::Stop() { - Send(new ViewMsg_Stop(routing_id_)); -} - -bool RenderViewHost::GetPrintedPagesCount(const ViewMsg_Print_Params& params) { - return Send(new ViewMsg_GetPrintedPagesCount(routing_id_, params)); -} - -bool RenderViewHost::PrintPages(const ViewMsg_PrintPages_Params& params) { - return Send(new ViewMsg_PrintPages(routing_id_, params)); -} - -void RenderViewHost::StartFinding(int request_id, - const std::wstring& search_string, - bool forward, - bool match_case, - bool find_next) { - if (search_string.empty()) - return; - - FindInPageRequest request; - request.request_id = request_id; - request.search_string = search_string; - request.forward = forward; - request.match_case = match_case; - request.find_next = find_next; - Send(new ViewMsg_Find(routing_id_, request)); - - // This call is asynchronous and returns immediately. - // The result of the search is sent as a notification message by the renderer. -} - -void RenderViewHost::StopFinding(bool clear_selection) { - Send(new ViewMsg_StopFinding(routing_id_, clear_selection)); -} - -void RenderViewHost::Zoom(PageZoom::Function function) { - Send(new ViewMsg_Zoom(routing_id_, function)); -} - -void RenderViewHost::SetPageEncoding(const std::wstring& encoding_name) { - Send(new ViewMsg_SetPageEncoding(routing_id_, encoding_name)); -} - -void RenderViewHost::SetAlternateErrorPageURL(const GURL& url) { - Send(new ViewMsg_SetAltErrorPageURL(routing_id_, url)); -} - -void RenderViewHost::FillForm(const FormData& form_data) { - Send(new ViewMsg_FormFill(routing_id_, form_data)); -} - -void RenderViewHost::FillPasswordForm( - const PasswordFormDomManager::FillData& form_data) { - Send(new ViewMsg_FillPasswordForm(routing_id_, form_data)); -} - -void RenderViewHost::DragTargetDragEnter(const WebDropData& drop_data, - const gfx::Point& client_pt, const gfx::Point& screen_pt) { - // Grant the renderer the ability to load the drop_data. - RendererSecurityPolicy* policy = RendererSecurityPolicy::GetInstance(); - policy->GrantRequestURL(process()->host_id(), drop_data.url); - for (std::vector::const_iterator iter(drop_data.filenames.begin()); - iter != drop_data.filenames.end(); ++iter) { - policy->GrantRequestURL(process()->host_id(), - net::FilePathToFileURL(*iter)); - policy->GrantUploadFile(process()->host_id(), *iter); - } - Send(new ViewMsg_DragTargetDragEnter(routing_id_, drop_data, client_pt, - screen_pt)); -} - -void RenderViewHost::DragTargetDragOver( - const gfx::Point& client_pt, const gfx::Point& screen_pt) { - Send(new ViewMsg_DragTargetDragOver(routing_id_, client_pt, screen_pt)); -} - -void RenderViewHost::DragTargetDragLeave() { - Send(new ViewMsg_DragTargetDragLeave(routing_id_)); -} - -void RenderViewHost::DragTargetDrop( - const gfx::Point& client_pt, const gfx::Point& screen_pt) { - Send(new ViewMsg_DragTargetDrop(routing_id_, client_pt, screen_pt)); -} - -void RenderViewHost::ReservePageIDRange(int size) { - Send(new ViewMsg_ReservePageIDRange(routing_id_, size)); -} - -void RenderViewHost::ExecuteJavascriptInWebFrame( - const std::wstring& frame_xpath, const std::wstring& jscript) { - Send(new ViewMsg_ScriptEvalRequest(routing_id_, frame_xpath, jscript)); -} - -void RenderViewHost::AddMessageToConsole( - const std::wstring& frame_xpath, const std::wstring& msg, - ConsoleMessageLevel level) { - Send(new ViewMsg_AddMessageToConsole(routing_id_, frame_xpath, msg, level)); -} - -void RenderViewHost::DebugCommand(const std::wstring& cmd) { - Send(new ViewMsg_DebugCommand(routing_id_, cmd)); -} - -void RenderViewHost::DebugAttach() { - if (!debugger_attached_) - Send(new ViewMsg_DebugAttach(routing_id_)); -} - -void RenderViewHost::DebugDetach() { - if (debugger_attached_) { - Send(new ViewMsg_DebugDetach(routing_id_)); - debugger_attached_ = false; - } -} - -void RenderViewHost::DebugBreak(bool force) { - if (debugger_attached_) - Send(new ViewMsg_DebugBreak(routing_id_, force)); -} - -void RenderViewHost::Undo() { - Send(new ViewMsg_Undo(routing_id_)); -} - -void RenderViewHost::Redo() { - Send(new ViewMsg_Redo(routing_id_)); -} - -void RenderViewHost::Cut() { - Send(new ViewMsg_Cut(routing_id_)); -} - -void RenderViewHost::Copy() { - Send(new ViewMsg_Copy(routing_id_)); -} - -void RenderViewHost::Paste() { - Send(new ViewMsg_Paste(routing_id_)); -} - -void RenderViewHost::Replace(const std::wstring& text_to_replace) { - Send(new ViewMsg_Replace(routing_id_, text_to_replace)); -} - -void RenderViewHost::ToggleSpellCheck() { - Send(new ViewMsg_ToggleSpellCheck(routing_id_)); -} - -void RenderViewHost::AddToDictionary(const std::wstring& word) { - process_->AddWord(word); -} - -void RenderViewHost::Delete() { - Send(new ViewMsg_Delete(routing_id_)); -} - -void RenderViewHost::SelectAll() { - Send(new ViewMsg_SelectAll(routing_id_)); -} - -int RenderViewHost::DownloadImage(const GURL& url, int image_size) { - if (!url.is_valid()) { - NOTREACHED(); - return 0; - } - static int next_id = 1; - int id = next_id++; - Send(new ViewMsg_DownloadImage(routing_id_, id, url, image_size)); - return id; -} - -void RenderViewHost::GetApplicationInfo(int32 page_id) { - Send(new ViewMsg_GetApplicationInfo(routing_id_, page_id)); -} - -void RenderViewHost::CaptureThumbnail() { - Send(new ViewMsg_CaptureThumbnail(routing_id_)); -} - -void RenderViewHost::JavaScriptMessageBoxClosed(IPC::Message* reply_msg, - bool success, - const std::wstring& prompt) { - if (is_waiting_for_unload_ack_) { - if (are_javascript_messages_suppressed_) { - delegate_->RendererUnresponsive(this, is_waiting_for_unload_ack_); - return; - } - - StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); - } - - if (--modal_dialog_count_ == 0) - modal_dialog_event_->Reset(); - ViewHostMsg_RunJavaScriptMessage::WriteReplyParams(reply_msg, success, prompt); - Send(reply_msg); -} - -void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg, - const std::string& json_retval) { - if (is_waiting_for_unload_ack_) - StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); - - if (--modal_dialog_count_ == 0) - modal_dialog_event_->Reset(); - - ViewHostMsg_ShowModalHTMLDialog::WriteReplyParams(reply_msg, json_retval); - Send(reply_msg); -} - -void RenderViewHost::CopyImageAt(int x, int y) { - Send(new ViewMsg_CopyImageAt(routing_id_, x, y)); -} - -void RenderViewHost::InspectElementAt(int x, int y) { - RendererSecurityPolicy::GetInstance()->GrantInspectElement( - process()->host_id()); - Send(new ViewMsg_InspectElement(routing_id_, x, y)); -} - -void RenderViewHost::ShowJavaScriptConsole() { - RendererSecurityPolicy::GetInstance()->GrantInspectElement( - process()->host_id()); - - Send(new ViewMsg_ShowJavaScriptConsole(routing_id_)); -} - -void RenderViewHost::DragSourceEndedAt( - int client_x, int client_y, int screen_x, int screen_y) { - Send(new ViewMsg_DragSourceEndedOrMoved( - routing_id_, client_x, client_y, screen_x, screen_y, true)); -} - -void RenderViewHost::DragSourceMovedTo( - int client_x, int client_y, int screen_x, int screen_y) { - Send(new ViewMsg_DragSourceEndedOrMoved( - routing_id_, client_x, client_y, screen_x, screen_y, false)); -} - -void RenderViewHost::DragSourceSystemDragEnded() { - Send(new ViewMsg_DragSourceSystemDragEnded(routing_id_)); -} - -void RenderViewHost::AllowDomAutomationBindings() { - // Expose the binding that allows the DOM to send messages here. - Send(new ViewMsg_AllowDomAutomationBindings(routing_id_, true)); -} - -void RenderViewHost::AllowDOMUIBindings() { - DCHECK(!renderer_initialized_); - enable_dom_ui_bindings_ = true; - RendererSecurityPolicy::GetInstance()->GrantDOMUIBindings(process()->host_id()); -} - -void RenderViewHost::AllowExternalHostBindings() { - enable_external_host_bindings_ = true; -} - -void RenderViewHost::SetDOMUIProperty(const std::string& name, - const std::string& value) { - DCHECK(enable_dom_ui_bindings_); - Send(new ViewMsg_SetDOMUIProperty(routing_id_, name, value)); -} - -// static -void RenderViewHost::MakeNavigateParams(const NavigationEntry& entry, - bool reload, - ViewMsg_Navigate_Params* params) { - params->page_id = entry.page_id(); - params->url = entry.url(); - params->referrer = entry.referrer(); - params->transition = entry.transition_type(); - params->state = entry.content_state(); - params->reload = reload; -} - -bool RenderViewHost::CanBlur() const { - return delegate_->CanBlur(); -} - -void RenderViewHost::SetInitialFocus(bool reverse) { - Send(new ViewMsg_SetInitialFocus(routing_id_, reverse)); -} - -void RenderViewHost::UpdateWebPreferences(const WebPreferences& prefs) { - Send(new ViewMsg_UpdateWebPreferences(routing_id_, prefs)); -} - -void RenderViewHost::InstallMissingPlugin() { - Send(new ViewMsg_InstallMissingPlugin(routing_id_)); -} - -void RenderViewHost::FileSelected(const std::wstring& path) { - RendererSecurityPolicy::GetInstance()->GrantUploadFile(process()->host_id(), - path); - std::vector files; - files.push_back(path); - Send(new ViewMsg_RunFileChooserResponse(routing_id_, files)); -} - -void RenderViewHost::MultiFilesSelected( - const std::vector& files) { - for (std::vector::const_iterator file = files.begin(); - file != files.end(); ++file) { - RendererSecurityPolicy::GetInstance()->GrantUploadFile( - process()->host_id(), *file); - } - Send(new ViewMsg_RunFileChooserResponse(routing_id_, files)); -} - -void RenderViewHost::LoadStateChanged(const GURL& url, - net::LoadState load_state) { - delegate_->LoadStateChanged(url, load_state); -} - -bool RenderViewHost::CanTerminate() const { - if (!delegate_->CanTerminate()) - return false; - - return has_unload_listener_; -} - -/////////////////////////////////////////////////////////////////////////////// -// RenderViewHost, IPC message handlers: - -void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { - if (msg.is_sync() && !msg.is_caller_pumping_messages()) { - NOTREACHED() << "Can't send sync messages to UI thread without pumping " \ - "messages in the renderer or else deadlocks can occur if the page" \ - "has windowed plugins!"; - IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg); - reply->set_reply_error(); - Send(reply); - return; - } - - bool msg_is_ok = true; - IPC_BEGIN_MESSAGE_MAP_EX(RenderViewHost, msg, msg_is_ok) - IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindowWithRoute, OnMsgCreateWindow) - IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidgetWithRoute, OnMsgCreateWidget) - IPC_MESSAGE_HANDLER(ViewHostMsg_ShowView, OnMsgShowView) - IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnMsgShowWidget) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunModal, OnMsgRunModal) - IPC_MESSAGE_HANDLER(ViewHostMsg_RendererReady, OnMsgRendererReady) - IPC_MESSAGE_HANDLER(ViewHostMsg_RendererGone, OnMsgRendererGone) - IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_FrameNavigate, OnMsgNavigate(msg)) - IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateState, OnMsgUpdateState) - IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTitle, OnMsgUpdateTitle) - IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateEncoding, OnMsgUpdateEncoding) - IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnMsgUpdateTargetURL) - IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_Thumbnail, OnMsgThumbnail(msg)) - IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnMsgClose) - IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnMsgRequestMove) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidStartLoading, OnMsgDidStartLoading) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnMsgDidStopLoading) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache, - OnMsgDidLoadResourceFromMemoryCache) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidRedirectProvisionalLoad, - OnMsgDidRedirectProvisionalLoad) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidStartProvisionalLoadForFrame, - OnMsgDidStartProvisionalLoadForFrame) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidFailProvisionalLoadWithError, - OnMsgDidFailProvisionalLoadWithError) - IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnMsgFindReply) - IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFavIconURL, OnMsgUpdateFavIconURL) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidDownloadImage, OnMsgDidDownloadImage) - IPC_MESSAGE_HANDLER(ViewHostMsg_ContextMenu, OnMsgContextMenu) - IPC_MESSAGE_HANDLER(ViewHostMsg_OpenURL, OnMsgOpenURL) - IPC_MESSAGE_HANDLER(ViewHostMsg_DomOperationResponse, - OnMsgDomOperationResponse) - IPC_MESSAGE_HANDLER(ViewHostMsg_DOMUISend, - OnMsgDOMUISend) - IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardMessageToExternalHost, - OnMsgForwardMessageToExternalHost) -#ifdef CHROME_PERSONALIZATION - IPC_MESSAGE_HANDLER(ViewHostMsg_PersonalizationEvent, - OnPersonalizationEvent) -#endif - IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, - OnMsgGoToEntryAtOffset) - IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnMsgSetTooltipText) - IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnMsgRunFileChooser) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunJavaScriptMessage, - OnMsgRunJavaScriptMessage) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunBeforeUnloadConfirm, - OnMsgRunBeforeUnloadConfirm) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ShowModalHTMLDialog, - OnMsgShowModalHTMLDialog) - IPC_MESSAGE_HANDLER(ViewHostMsg_PasswordFormsSeen, OnMsgPasswordFormsSeen) - IPC_MESSAGE_HANDLER(ViewHostMsg_AutofillFormSubmitted, - OnMsgAutofillFormSubmitted) - IPC_MESSAGE_HANDLER(ViewHostMsg_StartDragging, OnMsgStartDragging) - IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateDragCursor, OnUpdateDragCursor) - IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus) - IPC_MESSAGE_HANDLER(ViewHostMsg_PageHasOSDD, OnMsgPageHasOSDD) - IPC_MESSAGE_HANDLER(ViewHostMsg_InspectElement_Reply, - OnMsgInspectElementReply) - IPC_MESSAGE_FORWARD(ViewHostMsg_DidGetPrintedPagesCount, - delegate_, - RenderViewHostDelegate::DidGetPrintedPagesCount) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidPrintPage, DidPrintPage) - IPC_MESSAGE_HANDLER(ViewHostMsg_AddMessageToConsole, OnAddMessageToConsole) - IPC_MESSAGE_HANDLER(ViewHostMsg_DebuggerOutput, OnDebuggerOutput); - IPC_MESSAGE_HANDLER(ViewHostMsg_DidDebugAttach, DidDebugAttach); - IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction, - OnUserMetricsRecordAction) - IPC_MESSAGE_HANDLER(ViewHostMsg_MissingPluginStatus, OnMissingPluginStatus); - IPC_MESSAGE_FORWARD(ViewHostMsg_CrashedPlugin, delegate_, - RenderViewHostDelegate::OnCrashedPlugin); - IPC_MESSAGE_HANDLER(ViewHostMsg_SendCurrentPageAllSavableResourceLinks, - OnReceivedSavableResourceLinksForCurrentPage); - IPC_MESSAGE_HANDLER(ViewHostMsg_SendSerializedHtmlData, - OnReceivedSerializedHtmlData); - IPC_MESSAGE_HANDLER(ViewHostMsg_DidGetApplicationInfo, - OnDidGetApplicationInfo); - IPC_MESSAGE_FORWARD(ViewHostMsg_JSOutOfMemory, delegate_, - RenderViewHostDelegate::OnJSOutOfMemory); - IPC_MESSAGE_HANDLER(ViewHostMsg_ShouldClose_ACK, OnMsgShouldCloseACK); - IPC_MESSAGE_HANDLER(ViewHostMsg_UnloadListenerChanged, - OnUnloadListenerChanged); - IPC_MESSAGE_HANDLER(ViewHostMsg_QueryFormFieldAutofill, - OnQueryFormFieldAutofill) - // Have the super handle all other messages. - IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg)) - IPC_END_MESSAGE_MAP_EX() - - if (!msg_is_ok) { - // The message had a handler, but its de-serialization failed. - // Kill the renderer. - process()->ReceivedBadMessage(msg.type()); - } -} - -void RenderViewHost::Shutdown() { - // If we are being run modally (see RunModal), then we need to cleanup. - if (run_modal_reply_msg_) { - if (--modal_dialog_count_ == 0) - modal_dialog_event_->Reset(); - Send(run_modal_reply_msg_); - run_modal_reply_msg_ = NULL; - } - RenderWidgetHost::Shutdown(); -} - -void RenderViewHost::OnMsgCreateWindow(int route_id, - HANDLE modal_dialog_event) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) - view->CreateNewWindow(route_id, - new base::WaitableEvent(modal_dialog_event)); -} - -void RenderViewHost::OnMsgCreateWidget(int route_id, bool activatable) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) - view->CreateNewWidget(route_id, activatable); -} - -void RenderViewHost::OnMsgShowView(int route_id, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) - view->ShowCreatedWindow(route_id, disposition, initial_pos, user_gesture); -} - -void RenderViewHost::OnMsgShowWidget(int route_id, - const gfx::Rect& initial_pos) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) - view->ShowCreatedWidget(route_id, initial_pos); -} - -void RenderViewHost::OnMsgRunModal(IPC::Message* reply_msg) { - DCHECK(!run_modal_reply_msg_); - if (modal_dialog_count_++ == 0) - modal_dialog_event_->Reset(); - run_modal_reply_msg_ = reply_msg; - - // TODO(darin): Bug 1107929: Need to inform our delegate to show this view in - // an app-modal fashion. -} - -void RenderViewHost::OnMsgRendererReady() { - WasResized(); - delegate_->RendererReady(this); -} - -void RenderViewHost::OnMsgRendererGone() { - // Must reset these to ensure that mouse move events work with a new renderer. - mouse_move_pending_ = false; - next_mouse_move_.reset(); - - // Clearing this flag causes us to re-create the renderer when recovering - // from a crashed renderer. - renderer_initialized_ = false; - - // Reset some fields in preparation for recovering from a crash. - resize_ack_pending_ = false; - current_size_ = gfx::Size(); - is_hidden_ = false; - - RendererExited(); - - if (view_) { - view_->RendererGone(); - view_ = NULL; // The View should be deleted by RendererGone. - } - delegate_->RendererGone(this); - OnDebugDisconnect(); -} - -// Called when the renderer navigates. For every frame loaded, we'll get this -// notification containing parameters identifying the navigation. -// -// Subframes are identified by the page transition type. For subframes loaded -// as part of a wider page load, the page_id will be the same as for the top -// level frame. If the user explicitly requests a subframe navigation, we will -// get a new page_id because we need to create a new navigation entry for that -// action. -void RenderViewHost::OnMsgNavigate(const IPC::Message& msg) { - // Read the parameters out of the IPC message directly to avoid making another - // copy when we filter the URLs. - void* iter = NULL; - ViewHostMsg_FrameNavigate_Params validated_params; - if (!IPC::ParamTraits:: - Read(&msg, &iter, &validated_params)) - return; - - const int renderer_id = process()->host_id(); - RendererSecurityPolicy* policy = RendererSecurityPolicy::GetInstance(); - // Without this check, an evil renderer can trick the browser into creating - // a navigation entry for a banned URL. If the user clicks the back button - // followed by the forward button (or clicks reload, or round-trips through - // session restore, etc), we'll think that the browser commanded the - // renderer to load the URL and grant the renderer the privileges to request - // the URL. To prevent this attack, we block the renderer from inserting - // banned URLs into the navigation controller in the first place. - FilterURL(policy, renderer_id, &validated_params.url); - FilterURL(policy, renderer_id, &validated_params.referrer); - for (std::vector::iterator it(validated_params.redirects.begin()); - it != validated_params.redirects.end(); ++it) { - FilterURL(policy, renderer_id, &(*it)); - } - FilterURL(policy, renderer_id, &validated_params.searchable_form_url); - FilterURL(policy, renderer_id, &validated_params.password_form.origin); - FilterURL(policy, renderer_id, &validated_params.password_form.action); - - delegate_->DidNavigate(this, validated_params); - - UpdateBackForwardListCount(); -} - -void RenderViewHost::OnMsgUpdateState(int32 page_id, - const std::string& state) { - delegate_->UpdateState(this, page_id, state); -} - -void RenderViewHost::OnMsgUpdateTitle(int32 page_id, - const std::wstring& title) { - delegate_->UpdateTitle(this, page_id, title); -} - -void RenderViewHost::OnMsgUpdateEncoding(const std::wstring& encoding_name) { - delegate_->UpdateEncoding(this, encoding_name); -} - -void RenderViewHost::OnMsgUpdateTargetURL(int32 page_id, - const GURL& url) { - delegate_->UpdateTargetURL(page_id, url); - - // Send a notification back to the renderer that we are ready to - // receive more target urls. - Send(new ViewMsg_UpdateTargetURL_ACK(routing_id_)); -} - -void RenderViewHost::OnMsgThumbnail(const IPC::Message& msg) { - // crack the message - void* iter = NULL; - GURL url; - if (!IPC::ParamTraits::Read(&msg, &iter, &url)) - return; - - ThumbnailScore score; - if (!IPC::ParamTraits::Read(&msg, &iter, &score)) - return; - - // thumbnail data - SkBitmap bitmap; - if (!IPC::ParamTraits::Read(&msg, &iter, &bitmap)) - return; - - delegate_->UpdateThumbnail(url, bitmap, score); -} - -void RenderViewHost::OnMsgClose() { - delegate_->Close(this); -} - -void RenderViewHost::OnMsgRequestMove(const gfx::Rect& pos) { - delegate_->RequestMove(pos); -} - -void RenderViewHost::OnMsgDidRedirectProvisionalLoad(int32 page_id, - const GURL& source_url, - const GURL& target_url) { - delegate_->DidRedirectProvisionalLoad(page_id, source_url, target_url); -} - -void RenderViewHost::OnMsgDidStartLoading(int32 page_id) { - delegate_->DidStartLoading(this, page_id); - - if (view_) { - view_->UpdateCursorIfOverSelf(); - } -} - -void RenderViewHost::OnMsgDidStopLoading(int32 page_id) { - delegate_->DidStopLoading(this, page_id); - - if (view_) { - view_->UpdateCursorIfOverSelf(); - } -} - -void RenderViewHost::OnMsgDidLoadResourceFromMemoryCache( - const GURL& url, - const std::string& security_info) { - delegate_->DidLoadResourceFromMemoryCache(url, security_info); -} - -void RenderViewHost::OnMsgDidStartProvisionalLoadForFrame(bool is_main_frame, - const GURL& url) { - GURL validated_url(url); - FilterURL(RendererSecurityPolicy::GetInstance(), - process()->host_id(), &validated_url); - - delegate_->DidStartProvisionalLoadForFrame(this, is_main_frame, validated_url); -} - -void RenderViewHost::OnMsgDidFailProvisionalLoadWithError( - bool is_main_frame, - int error_code, - const GURL& url, - bool showing_repost_interstitial) { - GURL validated_url(url); - FilterURL(RendererSecurityPolicy::GetInstance(), - process()->host_id(), &validated_url); - - delegate_->DidFailProvisionalLoadWithError(this, is_main_frame, - error_code, validated_url, - showing_repost_interstitial); -} - -void RenderViewHost::OnMsgFindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (!view) - return; - view->OnFindReply(request_id, number_of_matches, selection_rect, - active_match_ordinal, final_update); - - // Send a notification to the renderer that we are ready to receive more - // results from the scoping effort of the Find operation. The FindInPage - // scoping is asynchronous and periodically sends results back up to the - // browser using IPC. In an effort to not spam the browser we have the - // browser send an ACK for each FindReply message and have the renderer - // queue up the latest status message while waiting for this ACK. - Send(new ViewMsg_FindReplyACK(routing_id_)); -} - -void RenderViewHost::OnMsgUpdateFavIconURL(int32 page_id, - const GURL& icon_url) { - delegate_->UpdateFavIconURL(this, page_id, icon_url); -} - -void RenderViewHost::OnMsgDidDownloadImage( - int id, - const GURL& image_url, - bool errored, - const SkBitmap& image) { - delegate_->DidDownloadImage(this, id, image_url, errored, image); -} - -void RenderViewHost::OnMsgContextMenu( - const ViewHostMsg_ContextMenu_Params& params) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (!view) - return; - - // Validate the URLs in |params|. If the renderer can't request the URLs - // directly, don't show them in the context menu. - ViewHostMsg_ContextMenu_Params validated_params(params); - const int renderer_id = process()->host_id(); - RendererSecurityPolicy* policy = RendererSecurityPolicy::GetInstance(); - - FilterURL(policy, renderer_id, &validated_params.link_url); - FilterURL(policy, renderer_id, &validated_params.image_url); - FilterURL(policy, renderer_id, &validated_params.page_url); - FilterURL(policy, renderer_id, &validated_params.frame_url); - - view->ShowContextMenu(validated_params); -} - -void RenderViewHost::OnMsgOpenURL(const GURL& url, - const GURL& referrer, - WindowOpenDisposition disposition) { - GURL validated_url(url); - FilterURL(RendererSecurityPolicy::GetInstance(), - process()->host_id(), &validated_url); - - delegate_->RequestOpenURL(validated_url, referrer, disposition); -} - -void RenderViewHost::OnMsgDomOperationResponse( - const std::string& json_string, int automation_id) { - delegate_->DomOperationResponse(json_string, automation_id); -} - -void RenderViewHost::OnMsgDOMUISend( - const std::string& message, const std::string& content) { - if (!RendererSecurityPolicy::GetInstance()-> - HasDOMUIBindings(process()->host_id())) { - NOTREACHED() << "Blocked unauthorized use of DOMUIBindings."; - return; - } - delegate_->ProcessDOMUIMessage(message, content); -} - -void RenderViewHost::OnMsgForwardMessageToExternalHost( - const std::string& receiver, - const std::string& message) { - delegate_->ProcessExternalHostMessage(receiver, message); -} - -#ifdef CHROME_PERSONALIZATION -void RenderViewHost::OnPersonalizationEvent(const std::string& message, - const std::string& content) { - Personalization::HandlePersonalizationEvent(this, message, content); -} -#endif - -void RenderViewHost::DisassociateFromPopupCount() { - Send(new ViewMsg_DisassociateFromPopupCount(routing_id_)); -} - -void RenderViewHost::PopupNotificationVisibilityChanged(bool visible) { - Send(new ViewMsg_PopupNotificationVisiblityChanged(routing_id_, visible)); -} - -void RenderViewHost::OnMsgGoToEntryAtOffset(int offset) { - delegate_->GoToEntryAtOffset(offset); -} - -void RenderViewHost::OnMsgSetTooltipText(const std::wstring& tooltip_text) { - if (view_) { - view_->SetTooltipText(tooltip_text); - } -} - -void RenderViewHost::OnMsgRunFileChooser(bool multiple_files, - const std::wstring& title, - const std::wstring& default_file, - const std::wstring& filter) { - std::wstring real_filter = filter; - std::replace(real_filter.begin(), real_filter.end(), '|', '\0'); - delegate_->RunFileChooser(multiple_files, title, default_file, real_filter); -} - -void RenderViewHost::OnMsgRunJavaScriptMessage( - const std::wstring& message, - const std::wstring& default_prompt, - const int flags, - IPC::Message* reply_msg) { - StopHangMonitorTimeout(); - if (modal_dialog_count_++ == 0) - modal_dialog_event_->Signal(); - bool did_suppress_message = false; - delegate_->RunJavaScriptMessage(message, default_prompt, flags, reply_msg, - &are_javascript_messages_suppressed_); -} - -void RenderViewHost::OnMsgRunBeforeUnloadConfirm(const std::wstring& message, - IPC::Message* reply_msg) { - StopHangMonitorTimeout(); - if (modal_dialog_count_++ == 0) - modal_dialog_event_->Signal(); - delegate_->RunBeforeUnloadConfirm(message, reply_msg); -} - -void RenderViewHost::OnMsgShowModalHTMLDialog( - const GURL& url, int width, int height, const std::string& json_arguments, - IPC::Message* reply_msg) { - StopHangMonitorTimeout(); - if (modal_dialog_count_++ == 0) - modal_dialog_event_->Signal(); - delegate_->ShowModalHTMLDialog(url, width, height, json_arguments, reply_msg); -} - -void RenderViewHost::OnMsgPasswordFormsSeen( - const std::vector& forms) { - delegate_->PasswordFormsSeen(forms); -} - -void RenderViewHost::OnMsgAutofillFormSubmitted( - const AutofillForm& form) { - delegate_->AutofillFormSubmitted(form); -} - -void RenderViewHost::OnMsgStartDragging( - const WebDropData& drop_data) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) - view->StartDragging(drop_data); -} - -void RenderViewHost::OnUpdateDragCursor(bool is_drop_target) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) - view->UpdateDragCursor(is_drop_target); -} - -void RenderViewHost::OnTakeFocus(bool reverse) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) - view->TakeFocus(reverse); -} - -void RenderViewHost::OnMsgPageHasOSDD(int32 page_id, const GURL& doc_url, - bool autodetected) { - delegate_->PageHasOSDD(this, page_id, doc_url, autodetected); -} - -void RenderViewHost::OnMsgInspectElementReply(int num_resources) { - delegate_->InspectElementReply(num_resources); -} - -void RenderViewHost::DidPrintPage( - const ViewHostMsg_DidPrintPage_Params& params) { - delegate_->DidPrintPage(params); -} - -void RenderViewHost::OnAddMessageToConsole(const std::wstring& message, - int32 line_no, - const std::wstring& source_id) { - std::wstring msg = StringPrintf(L"\"%ls,\" source: %ls (%d)", message.c_str(), - source_id.c_str(), line_no); - logging::LogMessage("CONSOLE", 0).stream() << msg; - if (debugger_attached_) - g_browser_process->debugger_wrapper()->DebugMessage(msg); -} - -void RenderViewHost::OnDebuggerOutput(const std::wstring& output) { - if (debugger_attached_) - g_browser_process->debugger_wrapper()->DebugMessage(output); -} - -void RenderViewHost::DidDebugAttach() { - if (!debugger_attached_) { - debugger_attached_ = true; - g_browser_process->debugger_wrapper()->OnDebugAttach(); - } -} - -void RenderViewHost::OnUserMetricsRecordAction(const std::wstring& action) { - UserMetrics::RecordComputedAction(action.c_str(), process_->profile()); -} - -void RenderViewHost::UnhandledInputEvent(const WebInputEvent& event) { - RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) { - // TODO(brettw) why do we have to filter these types of events here. Can't - // the renderer just send us the ones we care abount, or maybe the view - // should be able to decide which ones it wants or not? - if ((event.type == WebInputEvent::KEY_DOWN) || - (event.type == WebInputEvent::CHAR)) { - view->HandleKeyboardEvent( - static_cast(event)); - } - } -} - -void RenderViewHost::ForwardKeyboardEvent(const WebKeyboardEvent& key_event) { - if (key_event.type == WebKeyboardEvent::CHAR && - (key_event.key_code == VK_RETURN || key_event.key_code == VK_SPACE)) { - delegate_->OnEnterOrSpace(); - } - RenderWidgetHost::ForwardKeyboardEvent(key_event); -} - -void RenderViewHost::OnMissingPluginStatus(int status) { - delegate_->OnMissingPluginStatus(status); -} - -void RenderViewHost::UpdateBackForwardListCount() { - int back_list_count, forward_list_count; - delegate_->GetHistoryListCount(&back_list_count, &forward_list_count); - Send(new ViewMsg_UpdateBackForwardListCount( - routing_id_, back_list_count, forward_list_count)); -} - -void RenderViewHost::GetAllSavableResourceLinksForCurrentPage( - const GURL& page_url) { - Send(new ViewMsg_GetAllSavableResourceLinksForCurrentPage(routing_id_, - page_url)); -} - -void RenderViewHost::OnReceivedSavableResourceLinksForCurrentPage( - const std::vector& resources_list, - const std::vector& referrers_list, - const std::vector& frames_list) { - RenderViewHostDelegate::Save* save_delegate = delegate_->GetSaveDelegate(); - if (save_delegate) { - save_delegate->OnReceivedSavableResourceLinksForCurrentPage( - resources_list, referrers_list, frames_list); - } -} - -void RenderViewHost::OnDidGetApplicationInfo( - int32 page_id, - const webkit_glue::WebApplicationInfo& info) { - delegate_->OnDidGetApplicationInfo(page_id, info); -} - -void RenderViewHost::GetSerializedHtmlDataForCurrentPageWithLocalLinks( - const std::vector& links, - const std::vector& local_paths, - const std::wstring& local_directory_name) { - Send(new ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks( - routing_id_, links, local_paths, local_directory_name)); -} - -void RenderViewHost::OnReceivedSerializedHtmlData(const GURL& frame_url, - const std::string& data, - int32 status) { - RenderViewHostDelegate::Save* save_delegate = delegate_->GetSaveDelegate(); - if (save_delegate) - save_delegate->OnReceivedSerializedHtmlData(frame_url, data, status); -} - -void RenderViewHost::OnMsgShouldCloseACK(bool proceed) { - StopHangMonitorTimeout(); - DCHECK(is_waiting_for_unload_ack_); - is_waiting_for_unload_ack_ = false; - delegate_->ShouldClosePage(proceed); -} - -void RenderViewHost::OnUnloadListenerChanged(bool has_listener) { - has_unload_listener_ = has_listener; -} - -void RenderViewHost::OnQueryFormFieldAutofill(const std::wstring& field_name, - const std::wstring& user_text, - int64 node_id, - int request_id) { - delegate_->GetAutofillSuggestions(field_name, user_text, node_id, request_id); -} - -void RenderViewHost::AutofillSuggestionsReturned( - const std::vector& suggestions, - int64 node_id, int request_id, int default_suggestion_index) { - Send(new ViewMsg_AutofillSuggestions(routing_id_, node_id, - request_id, suggestions, -1)); - // Default index -1 means no default suggestion. -} - -void RenderViewHost::NotifyRendererUnresponsive() { - // If the debugger is attached, we're going to be unresponsive anytime it's - // stopped at a breakpoint. - if (!debugger_attached_) { - delegate_->RendererUnresponsive(this, is_waiting_for_unload_ack_); - } -} - -void RenderViewHost::NotifyRendererResponsive() { - delegate_->RendererResponsive(this); -} - -void RenderViewHost::OnDebugDisconnect() { - if (debugger_attached_) { - debugger_attached_ = false; - g_browser_process->debugger_wrapper()->OnDebugDisconnect(); - } -} - -#ifdef CHROME_PERSONALIZATION -void RenderViewHost::RaisePersonalizationEvent(std::string event_name, - std::string event_arg) { - Send(new ViewMsg_PersonalizationEvent(routing_id_, - event_name, - event_arg)); -} -#endif - -void RenderViewHost::ForwardMessageFromExternalHost( - const std::string& target, const std::string& message) { - Send(new ViewMsg_HandleMessageFromExternalHost(routing_id_, target, message)); -} diff --git a/chrome/browser/render_view_host.h b/chrome/browser/render_view_host.h deleted file mode 100644 index 7b0ef7a..0000000 --- a/chrome/browser/render_view_host.h +++ /dev/null @@ -1,628 +0,0 @@ -// Copyright (c) 2006-2008 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_RENDER_VIEW_HOST_H__ -#define CHROME_BROWSER_RENDER_VIEW_HOST_H__ - -#include -#include - -#include "base/scoped_ptr.h" -#include "chrome/browser/render_view_host_delegate.h" -#include "chrome/browser/render_widget_host.h" -#include "chrome/common/page_zoom.h" -#ifdef CHROME_PERSONALIZATION -#include "chrome/personalization/personalization.h" -#endif -#include "webkit/glue/password_form_dom_manager.h" -#include "webkit/glue/autofill_form.h" - -enum ConsoleMessageLevel; -class NavigationEntry; -class RenderViewHostDelegate; -class SiteInstance; -class SkBitmap; -struct ViewHostMsg_ContextMenu_Params; -struct ViewHostMsg_DidPrintPage_Params; -class ViewMsg_Navigate; -struct ViewMsg_Navigate_Params; -struct ViewMsg_Print_Params; -struct ViewMsg_PrintPages_Params; -struct WebDropData; -struct WebPreferences; -enum WindowOpenDisposition; - -namespace base { -class WaitableEvent; -} - -namespace gfx { -class Point; -} - -namespace net { -enum LoadState; -} - -namespace webkit_glue { -struct WebApplicationInfo; -} - -// -// RenderViewHost -// -// A RenderViewHost is responsible for creating and talking to a RenderView -// object in a child process. It exposes a high level API to users, for things -// like loading pages, adjusting the display and other browser functionality, -// which it translates into IPC messages sent over the IPC channel with the -// RenderView. It responds to all IPC messages sent by that RenderView and -// cracks them, calling a delegate object back with higher level types where -// possible. -// -// The intent of this class is to provide a view-agnostic communication -// conduit with a renderer. This is so we can build HTML views not only as -// TabContents (see WebContents for an example) but also as views, etc. -// -// The exact API of this object needs to be more thoroughly designed. Right -// now it mimics what WebContents exposed, which is a fairly large API and may -// contain things that are not relevant to a common subset of views. See also -// the comment in render_view_host_delegate.h about the size and scope of the -// delegate API. -// -// Right now, the concept of page navigation (both top level and frame) exists -// in the WebContents still, so if you instantiate one of these elsewhere, you -// will not be able to traverse pages back and forward. We need to determine -// if we want to bring that and other functionality down into this object so -// it can be shared by others. -// -class RenderViewHost : public RenderWidgetHost { - public: - // Returns the RenderViewHost given its ID and the ID of its render process. - // Returns NULL if the IDs do not correspond to a live RenderViewHost. - static RenderViewHost* FromID(int render_process_id, int render_view_id); - - // routing_id could be a valid route id, or it could be MSG_ROUTING_NONE, in - // which case RenderWidgetHost will create a new one. modal_dialog_event is - // the event that's set when showing a modal dialog so that the renderer and - // plugin processes know to pump messages. An existing event can be passed - // in, otherwise if it's NULL a new event will be created. - explicit RenderViewHost(SiteInstance* instance, - RenderViewHostDelegate* delegate, - int routing_id, - base::WaitableEvent* modal_dialog_event); - virtual ~RenderViewHost(); - - SiteInstance* site_instance() const { return instance_; } - RenderViewHostDelegate* delegate() const { return delegate_; } - - // Set up the RenderView child process. - virtual bool CreateRenderView(); - // Returns true if the RenderView is active and has not crashed. - virtual bool IsRenderViewLive() const; - // Create a new RenderViewHost but recycle an existing RenderView child - // process. - virtual void Init(); - - // Load the specified entry, optionally reloading. - virtual void NavigateToEntry(const NavigationEntry& entry, bool is_reload); - - // Load the specified URL. - void NavigateToURL(const GURL& url); - - // Loads the specified html (must be UTF8) in the main frame. If - // |new_navigation| is true, it simulates a navigation to |display_url|. - // |security_info| is the security state that will be reported when the page - // load commits. It is useful for mocking SSL errors. Provide an empty - // string if no secure connection state should be simulated. - // Note that if |new_navigation| is false, |display_url| and |security_info| - // are not used. - virtual void LoadAlternateHTMLString(const std::string& html_text, - bool new_navigation, - const GURL& display_url, - const std::string& security_info); - - // Suspends (or unsuspends) any navigation messages from being sent from this - // RenderViewHost. This is called when a pending RenderViewHost is created - // for a cross-site navigation, because we must suspend any navigations until - // we hear back from the old renderer's onbeforeunload handler. Note that it - // is important that only one navigation event happen after calling this - // method with |suspend| equal to true. If |suspend| is false and there is - // a suspended_nav_message_, this will send the message. - void SetNavigationsSuspended(bool suspend); - - // Causes the renderer to invoke the onbeforeunload event handler. The - // result will be returned via ViewMsg_ShouldClose. - virtual void FirePageBeforeUnload(); - - // Close the page after the page has responded that it can be closed via - // ViewMsg_ShouldClose. This is where the page itself is closed. The - // unload handler is triggered here, which can block with a dialog, but cannot - // cancel the close of the page. - void FirePageUnload(); - - // Close the page ignoring whether it has unload events registers. - // This is called after the beforeunload and unload events have fired - // and the user has agreed to continue with closing the page. - static void ClosePageIgnoringUnloadEvents(int render_process_host_id, - int request_id); - - // Causes the renderer to close the current page, including running its - // onunload event handler. A ClosePage_ACK message will be sent to the - // ResourceDispatcherHost when it is finished. |new_render_process_host_id| - // and |new_request_id| will help the ResourceDispatcherHost identify which - // response is associated with this event. - virtual void ClosePage(int new_render_process_host_id, - int new_request_id); - - // Sets whether this RenderViewHost has an outstanding cross-site request, - // for which another renderer will need to run an onunload event handler. - // This is called before the first navigation event for this RenderViewHost, - // and again after the corresponding OnCrossSiteResponse. - void SetHasPendingCrossSiteRequest(bool has_pending_request, int request_id); - - // Returns the request_id for the pending cross-site request. - // This is just needed in case the unload of the current page - // hangs, in which case we need to swap to the pending RenderViewHost. - int GetPendingRequestId(); - - // Called by ResourceDispatcherHost when a response for a pending cross-site - // request is received. The ResourceDispatcherHost will pause the response - // until the onunload handler of the previous renderer is run. - void OnCrossSiteResponse(int new_render_process_host_id, int new_request_id); - - // Stops the current load. - void Stop(); - - - // Retrieves the number of printed pages that would result for the current web - // page and the specified settings. The response is a - // ViewHostMsg_DidGetPrintedPagesCount. - bool GetPrintedPagesCount(const ViewMsg_Print_Params& params); - - // Asks the renderer to "render" printed pages. - bool PrintPages(const ViewMsg_PrintPages_Params& params); - - // Start looking for a string within the content of the page, with the - // specified options. - void StartFinding(int request_id, - const std::wstring& search_string, - bool forward, - bool match_case, - bool find_next); - - // Cancel a pending find operation. If |clear_selection| is true, it will also - // clear the selection on the focused frame. - void StopFinding(bool clear_selection); - - // Change the zoom level of a page. - void Zoom(PageZoom::Function function); - - // Change the encoding of the page. - void SetPageEncoding(const std::wstring& encoding); - - // Change the alternate error page URL. An empty GURL disables the use of - // alternate error pages. - void SetAlternateErrorPageURL(const GURL& url); - - // Fill out a form within the page with the specified data. - void FillForm(const FormData& form_data); - - // Fill out a password form and trigger DOM autocomplete in the case - // of multiple matching logins. - void FillPasswordForm(const PasswordFormDomManager::FillData& form_data); - - // D&d drop target messages that get sent to WebKit. - void DragTargetDragEnter(const WebDropData& drop_data, - const gfx::Point& client_pt, - const gfx::Point& screen_pt); - void DragTargetDragOver(const gfx::Point& client_pt, - const gfx::Point& screen_pt); - void DragTargetDragLeave(); - void DragTargetDrop(const gfx::Point& client_pt, - const gfx::Point& screen_pt); - - // Tell the RenderView to reserve a range of page ids of the given size. - void ReservePageIDRange(int size); - - // Runs some javascript within the context of a frame in the page. - void ExecuteJavascriptInWebFrame(const std::wstring& frame_xpath, - const std::wstring& jscript); - - // Logs a message to the console of a frame in the page. - void AddMessageToConsole(const std::wstring& frame_xpath, - const std::wstring& msg, - ConsoleMessageLevel level); - - // Send command to the debugger - void DebugCommand(const std::wstring& cmd); - - // Attach to the V8 instance for debugging - void DebugAttach(); - - // Detach from the V8 instance for debugging - void DebugDetach(); - - // Cause the V8 debugger to trigger a debug break. If the force flag is set - // force a debug break even if no JS code is running (this actually causes a - // simple JS script to be executed). - void DebugBreak(bool force); - - // Edit operations. - void Undo(); - void Redo(); - void Cut(); - void Copy(); - void Paste(); - void Replace(const std::wstring& text); - void ToggleSpellCheck(); - void AddToDictionary(const std::wstring& word); - void Delete(); - void SelectAll(); - - // Downloads an image notifying the delegate appropriately. The returned - // integer uniquely identifies the download for the lifetime of the browser. - int DownloadImage(const GURL& url, int image_size); - - // Requests application info for the specified page. This is an asynchronous - // request. The delegate is notified by way of OnDidGetApplicationInfo when - // the data is available. - void GetApplicationInfo(int32 page_id); - - // Captures a thumbnail representation of the page. - void CaptureThumbnail(); - - // Notifies the RenderView that the JavaScript message that was shown was - // closed by the user. - void JavaScriptMessageBoxClosed(IPC::Message* reply_msg, - bool success, - const std::wstring& prompt); - - // Notifies the RenderView that the modal html dialog has been closed. - void ModalHTMLDialogClosed(IPC::Message* reply_msg, - const std::string& json_retval); - - // Copies the image at the specified point. - void CopyImageAt(int x, int y); - - // Inspects the element at the specified point using the Web Inspector. - void InspectElementAt(int x, int y); - - // Show the JavaScript console. - void ShowJavaScriptConsole(); - - // Notifies the renderer that a drop occurred. This is necessary because the - // render may be the one that started the drag. - void DragSourceEndedAt( - int client_x, int client_y, int screen_x, int screen_y); - - // Notifies the renderer that a drag and drop operation is in progress, with - // droppable items positioned over the renderer's view. - void DragSourceMovedTo( - int client_x, int client_y, int screen_x, int screen_y); - - // Notifies the renderer that we're done with the drag and drop operation. - // This allows the renderer to reset some state. - void DragSourceSystemDragEnded(); - - // Tell the render view to expose DOM automation bindings so that the js - // content can send JSON-encoded data back to automation in the parent - // process. - void AllowDomAutomationBindings(); - - // Tell the render view to allow the javascript access to - // the external host via automation. - void AllowExternalHostBindings(); - - // Tell the render view to expose DOM bindings so that the JS content - // can send JSON-encoded data back to the browser process. - // This is used for HTML-based UI. - // Must be called before CreateRenderView(). - void AllowDOMUIBindings(); - - // 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); - - // Fill in a ViewMsg_Navigate_Params struct from a NavigationEntry. - static void MakeNavigateParams(const NavigationEntry& entry, - bool reload, - ViewMsg_Navigate_Params* params); - - // Overridden from RenderWidgetHost: We are hosting a web page. - virtual bool IsRenderView() { return true; } - virtual bool CanBlur() const; - - // IPC::Channel::Listener - virtual void OnMessageReceived(const IPC::Message& msg); - - // Override the RenderWidgetHost's Shutdown method. - virtual void Shutdown(); - - // Tells the renderer view to focus the first (last if reverse is true) node. - void SetInitialFocus(bool reverse); - - // Update render view specific (WebKit) preferences. - void UpdateWebPreferences(const WebPreferences& prefs); - - // Request the Renderer to ask the default plugin to start installation of - // missing plugin. Called by PluginInstaller. - void InstallMissingPlugin(); - - // Get all savable resource links from current webpage, include main - // frame and sub-frame. - void GetAllSavableResourceLinksForCurrentPage(const GURL& page_url); - - // Get html data by serializing all frames of current page with lists - // which contain all resource links that have local copy. - // The parameter links contain original URLs of all saved links. - // The parameter local_paths contain corresponding local file paths of - // all saved links, which matched with vector:links one by one. - // The parameter local_directory_name is relative path of directory which - // contain all saved auxiliary files included all sub frames and resouces. - void GetSerializedHtmlDataForCurrentPageWithLocalLinks( - const std::vector& links, - const std::vector& local_paths, - const std::wstring& local_directory_name); - - // Notifies the RenderViewHost that a file has been chosen by the user from - // an Open File dialog for the form. - void FileSelected(const std::wstring& path); - - // Notifies the Listener that many files have been chosen by the user from - // an Open File dialog for the form. - void MultiFilesSelected(const std::vector& files); - - // Notifies the RenderViewHost that its load state changed. - void LoadStateChanged(const GURL& url, net::LoadState load_state); - - // Does the associated view have an onunload or onbeforeunload handler? - bool HasUnloadListener() { return has_unload_listener_; } - - // If the associated view can be terminated without any side effects - bool CanTerminate() const; - - // Clears the has_unload_listener_ bit since the unload handler has fired - // and we're necessarily leaving the page. - void UnloadListenerHasFired() { has_unload_listener_ = false; } - -#ifdef CHROME_PERSONALIZATION - // Tells the RenderView to raise an personalization event with the given name - // and argument. - void RaisePersonalizationEvent(std::string event_name, std::string event_arg); - - HostPersonalization personalization() { - return personalization_; - } -#endif - - // Forward a message from external host to chrome renderer. - void ForwardMessageFromExternalHost(const std::string& target, - const std::string& message); - - // Message the renderer that we should be counted as a new document and not - // as a popup. - void DisassociateFromPopupCount(); - - // Notifies the Renderer that we've either displayed or hidden the popup - // notification. - void PopupNotificationVisibilityChanged(bool visible); - - // Called by the AutofillManager when the list of suggestions is ready. - void AutofillSuggestionsReturned(const std::vector& suggestions, - int64 node_id, - int request_id, - int default_suggestion_index); - - protected: - // Overridden from RenderWidgetHost: - virtual void UnhandledInputEvent(const WebInputEvent& event); - virtual void ForwardKeyboardEvent(const WebKeyboardEvent& key_event); - - // IPC message handlers: - void OnMsgCreateWindow(int route_id, HANDLE modal_dialog_event); - void OnMsgCreateWidget(int route_id, bool activatable); - void OnMsgShowView(int route_id, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture); - void OnMsgShowWidget(int route_id, const gfx::Rect& initial_pos); - void OnMsgRunModal(IPC::Message* reply_msg); - void OnMsgRendererReady(); - void OnMsgRendererGone(); - void OnMsgNavigate(const IPC::Message& msg); - void OnMsgUpdateState(int32 page_id, - const std::string& state); - void OnMsgUpdateTitle(int32 page_id, const std::wstring& title); - void OnMsgUpdateEncoding(const std::wstring& encoding); - void OnMsgUpdateTargetURL(int32 page_id, const GURL& url); - void OnMsgThumbnail(const IPC::Message& msg); - void OnMsgClose(); - void OnMsgRequestMove(const gfx::Rect& pos); - void OnMsgDidRedirectProvisionalLoad(int32 page_id, - const GURL& source_url, - const GURL& target_url); - void OnMsgDidStartLoading(int32 page_id); - void OnMsgDidStopLoading(int32 page_id); - void OnMsgDidLoadResourceFromMemoryCache(const GURL& url, - const std::string& security_info); - void OnMsgDidStartProvisionalLoadForFrame(bool main_frame, - const GURL& url); - void OnMsgDidFailProvisionalLoadWithError(bool main_frame, - int error_code, - const GURL& url, - bool showing_repost_interstitial); - void OnMsgFindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update); - void OnMsgUpdateFavIconURL(int32 page_id, const GURL& icon_url); - void OnMsgDidDownloadImage(int id, - const GURL& image_url, - bool errored, - const SkBitmap& image_data); - void OnMsgContextMenu(const ViewHostMsg_ContextMenu_Params& params); - void OnMsgOpenURL(const GURL& url, const GURL& referrer, - WindowOpenDisposition disposition); - void OnMsgDomOperationResponse(const std::string& json_string, - int automation_id); - void OnMsgDOMUISend(const std::string& message, - const std::string& content); - void OnMsgForwardMessageToExternalHost(const std::string& receiver, - const std::string& message); -#ifdef CHROME_PERSONALIZATION - void OnPersonalizationEvent(const std::string& message, - const std::string& content); -#endif - void OnMsgGoToEntryAtOffset(int offset); - void OnMsgSetTooltipText(const std::wstring& tooltip_text); - void OnMsgRunFileChooser(bool multiple_files, - const std::wstring& title, - const std::wstring& default_file, - const std::wstring& filter); - void OnMsgRunJavaScriptMessage(const std::wstring& message, - const std::wstring& default_prompt, - const int flags, - IPC::Message* reply_msg); - void OnMsgRunBeforeUnloadConfirm(const std::wstring& message, - IPC::Message* reply_msg); - void OnMsgShowModalHTMLDialog(const GURL& url, int width, int height, - const std::string& json_arguments, - IPC::Message* reply_msg); - void OnMsgPasswordFormsSeen(const std::vector& forms); - void OnMsgAutofillFormSubmitted(const AutofillForm& forms); - void OnMsgStartDragging(const WebDropData& drop_data); - void OnUpdateDragCursor(bool is_drop_target); - void OnTakeFocus(bool reverse); - void OnMsgPageHasOSDD(int32 page_id, const GURL& doc_url, bool autodetected); - void OnMsgInspectElementReply(int num_resources); - void DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params); - void OnDebugMessage(const std::string& message); - void OnAddMessageToConsole(const std::wstring& message, - int32 line_no, - const std::wstring& source_id); - void OnDebuggerOutput(const std::wstring& output); - void DidDebugAttach(); - void OnUserMetricsRecordAction(const std::wstring& action); - void OnMissingPluginStatus(int status); - void OnMessageReceived(IPC::Message* msg) { } - - void OnReceivedSavableResourceLinksForCurrentPage( - const std::vector& resources_list, - const std::vector& referrers_list, - const std::vector& frames_list); - - void OnReceivedSerializedHtmlData(const GURL& frame_url, - const std::string& data, - int32 status); - - void OnDidGetApplicationInfo(int32 page_id, - const webkit_glue::WebApplicationInfo& info); - void OnMsgShouldCloseACK(bool proceed); - void OnUnloadListenerChanged(bool has_handler); - void OnQueryFormFieldAutofill(const std::wstring& field_name, - const std::wstring& user_text, - int64 node_id, - int request_id); - virtual void NotifyRendererUnresponsive(); - virtual void NotifyRendererResponsive(); - - // Helper function to send a navigation message. If a cross-site request is - // in progress, we may be suspended while waiting for the onbeforeunload - // handler, so this function might buffer the message rather than sending it. - void DoNavigate(ViewMsg_Navigate* nav_message); - - private: - friend class TestRenderViewHost; - - void UpdateBackForwardListCount(); - - void OnDebugDisconnect(); - - // The SiteInstance associated with this RenderViewHost. All pages drawn - // in this RenderViewHost are part of this SiteInstance. Should not change - // over time. - scoped_refptr instance_; - - // Our delegate, which wants to know about changes in the RenderView. - RenderViewHostDelegate* delegate_; - -#ifdef CHROME_PERSONALIZATION - HostPersonalization personalization_; -#endif - - // true if a renderer has once been valid. We use this flag to display a sad - // tab only when we lose our renderer and not if a paint occurs during - // initialization. - bool renderer_initialized_; - - // true if we are currently waiting for a response for drag context - // information. - bool waiting_for_drag_context_response_; - - // is the debugger attached to us or not - bool debugger_attached_; - - // 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_; - - // The request_id for the pending cross-site request. Set to -1 if - // there is a pending request, but we have not yet started the unload - // for the current page. Set to the request_id value of the pending - // request once we have gotten the some data for the pending page - // and thus started the unload process. - int pending_request_id_; - - // True if javascript access to the external host (through - // automation) is allowed. - bool enable_external_host_bindings_; - - // Handle to an event that's set when the page is showing a modal dialog box - // (or equivalent constrained window). The renderer and plugin processes - // check this to know if they should pump messages/tasks then. - scoped_ptr modal_dialog_event_; - - // Multiple dialog boxes can be shown before the first one is finished, - // so we keep a counter to know when we can reset the modal dialog event. - int modal_dialog_count_; - - // Whether we should buffer outgoing Navigate messages rather than sending - // them. This will be true when a RenderViewHost is created for a cross-site - // request, until we hear back from the onbeforeunload handler of the old - // RenderViewHost. - bool navigations_suspended_; - - // We only buffer a suspended navigation message while we a pending RVH for a - // WebContents. There will only ever be one suspended navigation, because - // WebContents will destroy the pending RVH and create a new one if a second - // navigation occurs. - scoped_ptr suspended_nav_message_; - - // If we were asked to RunModal, then this will hold the reply_msg that we - // must return to the renderer to unblock it. - IPC::Message* run_modal_reply_msg_; - - bool has_unload_listener_; - - bool is_waiting_for_unload_ack_; - - bool are_javascript_messages_suppressed_; - - DISALLOW_EVIL_CONSTRUCTORS(RenderViewHost); -}; - -// Factory for creating RenderViewHosts. Useful for unit tests. -class RenderViewHostFactory { - public: - virtual ~RenderViewHostFactory() {} - - virtual RenderViewHost* CreateRenderViewHost( - SiteInstance* instance, - RenderViewHostDelegate* delegate, - int routing_id, - base::WaitableEvent* modal_dialog_event) = 0; -}; - -#endif // CHROME_BROWSER_RENDER_VIEW_HOST_H__ diff --git a/chrome/browser/render_view_host_delegate.h b/chrome/browser/render_view_host_delegate.h deleted file mode 100644 index 34aba46..0000000 --- a/chrome/browser/render_view_host_delegate.h +++ /dev/null @@ -1,396 +0,0 @@ -// Copyright (c) 2006-2008 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_RENDER_VIEW_HOST_DELEGATE_H__ -#define CHROME_BROWSER_RENDER_VIEW_HOST_DELEGATE_H__ - -#include -#include - -#include "base/basictypes.h" -#include "chrome/browser/autofill_manager.h" -#include "chrome/common/render_messages.h" -#include "webkit/glue/webpreferences.h" - -class NavigationEntry; -class Profile; -class RenderProcessHost; -class RenderViewHost; -class SkBitmap; -class WebContents; -struct WebDropData; -enum WindowOpenDisposition; - -namespace base { -class WaitableEvent; -} - -namespace IPC { -class Message; -} - -namespace gfx { -class Rect; -} - -namespace net { -enum LoadState; -} - -// -// RenderViewHostDelegate -// -// An interface implemented by an object interested in knowing about the state -// of the RenderViewHost. -// -// This interface currently encompasses every type of message that was -// previously being sent by WebContents itself. Some of these notifications -// may not be relevant to all users of RenderViewHost and we should consider -// exposing a more generic Send function on RenderViewHost and a response -// listener here to serve that need. -// -class RenderViewHostDelegate { - public: - class View { - public: - // The page is trying to open a new page (e.g. a popup window). The - // window should be created associated with the given route, but it should - // not be shown yet. That should happen in response to ShowCreatedWindow. - // - // Note: this is not called "CreateWindow" because that will clash with - // the Windows function which is actually a #define. - // - // NOTE: this takes ownership of @modal_dialog_event - virtual void CreateNewWindow(int route_id, - base::WaitableEvent* modal_dialog_event) = 0; - - // The page is trying to open a new widget (e.g. a select popup). The - // widget should be created associated with the given route, but it should - // not be shown yet. That should happen in response to ShowCreatedWidget. - // If |activatable| is false, the widget cannot be activated or get focus. - virtual void CreateNewWidget(int route_id, bool activatable) = 0; - - // Show a previously created page with the specified disposition and bounds. - // The window is identified by the route_id passed to CreateNewWindow. - // - // Note: this is not called "ShowWindow" because that will clash with - // the Windows function which is actually a #define. - virtual void ShowCreatedWindow(int route_id, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) = 0; - - // Show the newly created widget with the specified bounds. - // The widget is identified by the route_id passed to CreateNewWidget. - virtual void ShowCreatedWidget(int route_id, - const gfx::Rect& initial_pos) = 0; - - // A context menu should be shown, to be built using the context information - // provided in the supplied params. - virtual void ShowContextMenu( - const ViewHostMsg_ContextMenu_Params& params) = 0; - - // The user started dragging content of the specified type within the - // RenderView. Contextual information about the dragged content is supplied - // by WebDropData. - virtual void StartDragging(const WebDropData& drop_data) = 0; - - // The page wants to update the mouse cursor during a drag & drop operation. - // |is_drop_target| is true if the mouse is over a valid drop target. - virtual void UpdateDragCursor(bool is_drop_target) = 0; - - // Callback to inform the browser it should take back focus. If reverse is - // true, it means the focus was retrieved by doing a Shift-Tab. - virtual void TakeFocus(bool reverse) = 0; - - // Callback to inform the browser that the renderer did not process the - // specified events. This gives an opportunity to the browser to process the - // event (used for keyboard shortcuts). - virtual void HandleKeyboardEvent(const WebKeyboardEvent& event) = 0; - - // A find operation in the current page completed. - virtual void OnFindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) = 0; - }; - - // Interface for saving web pages. - class Save { - public: - // Notification that we get when we receive all savable links of - // sub-resources for the current page, their referrers and list of frames - // (include main frame and sub frames). - virtual void OnReceivedSavableResourceLinksForCurrentPage( - const std::vector& resources_list, - const std::vector& referrers_list, - const std::vector& frames_list) = 0; - - // Notification that we get when we receive serialized html content data of - // a specified web page from render process. The parameter frame_url - // specifies what frame the data belongs. The parameter data contains the - // available data for sending. The parameter status indicates the - // serialization status, See - // webkit_glue::DomSerializerDelegate::PageSavingSerializationStatus for - // the detail meaning of status. - virtual void OnReceivedSerializedHtmlData(const GURL& frame_url, - const std::string& data, - int32 status) = 0; - }; - - // Returns the current delegate associated with a feature. May be NULL. - virtual View* GetViewDelegate() const { return NULL; } - virtual Save* GetSaveDelegate() const { return NULL; } - - // Retrieves the profile to be used. - virtual Profile* GetProfile() const = 0; - - // The RenderView is being constructed (message sent to the renderer process - // to construct a RenderView). Now is a good time to send other setup events - // to the RenderView. This precedes any other commands to the RenderView. - virtual void RendererCreated(RenderViewHost* render_view_host) { } - - // The RenderView has been constructed. - virtual void RendererReady(RenderViewHost* render_view_host) { } - - // The RenderView died somehow (crashed or was killed by the user). - virtual void RendererGone(RenderViewHost* render_view_host) { } - - // The RenderView was navigated to a different page. - virtual void DidNavigate(RenderViewHost* render_view_host, - const ViewHostMsg_FrameNavigate_Params& params) { } - - // The state for the page changed and should be updated. - virtual void UpdateState(RenderViewHost* render_view_host, - int32 page_id, - const std::string& state) { } - - // The page's title was changed and should be updated. - virtual void UpdateTitle(RenderViewHost* render_view_host, - int32 page_id, - const std::wstring& title) { } - - // The page's encoding was changed and should be updated. - virtual void UpdateEncoding(RenderViewHost* render_view_host, - const std::wstring& encoding) { } - - // The destination URL has changed should be updated - virtual void UpdateTargetURL(int32 page_id, const GURL& url) { } - - // The thumbnail representation of the page changed and should be updated. - virtual void UpdateThumbnail(const GURL& url, - const SkBitmap& bitmap, - const ThumbnailScore& score) { } - - // The page is trying to close the RenderView's representation in the client. - virtual void Close(RenderViewHost* render_view_host) { } - - // The page is trying to move the RenderView's representation in the client. - virtual void RequestMove(const gfx::Rect& new_bounds) { } - - // The RenderView began loading a new page. - virtual void DidStartLoading(RenderViewHost* render_view_host, - int32 page_id) { } - - // The RenderView stopped loading a page. - virtual void DidStopLoading(RenderViewHost* render_view_host, - int32 page_id) { } - - // The RenderView is starting a provisional load. - virtual void DidStartProvisionalLoadForFrame(RenderViewHost* render_view_host, - bool is_main_frame, - const GURL& url) { } - - // Sent when a provisional load is redirected. - virtual void DidRedirectProvisionalLoad(int32 page_id, - const GURL& source_url, - const GURL& target_url) { } - - // The RenderView loaded a resource from an in-memory cache. - // |security_info| contains the security info if this resource was originally - // loaded over a secure connection. - virtual void DidLoadResourceFromMemoryCache(const GURL& url, - const std::string& security_info) { } - - // The RenderView failed a provisional load with an error. - virtual void DidFailProvisionalLoadWithError( - RenderViewHost* render_view_host, - bool is_main_frame, - int error_code, - const GURL& url, - bool showing_repost_interstitial) { } - - // The URL for the FavIcon of a page has changed. - virtual void UpdateFavIconURL(RenderViewHost* render_view_host, - int32 page_id, const GURL& icon_url) { } - - // An image that was requested to be downloaded by DownloadImage has - // completed. - virtual void DidDownloadImage(RenderViewHost* render_view_host, - int id, - const GURL& image_url, - bool errored, - const SkBitmap& image) { } - - // The page wants to open a URL with the specified disposition. - virtual void RequestOpenURL(const GURL& url, - const GURL& referrer, - WindowOpenDisposition disposition) { } - - // A DOM automation operation completed. The result of the operation is - // expressed in a json string. - virtual void DomOperationResponse(const std::string& json_string, - int automation_id) { } - - // A message was sent from HTML-based UI. - // By default we ignore such messages. - virtual void ProcessDOMUIMessage(const std::string& message, - const std::string& content) { } - - // A message for external host. By default we ignore such messages. - // |receiver| can be a receiving script and |message| is any - // arbitrary string that makes sense to the receiver. - virtual void ProcessExternalHostMessage(const std::string& receiver, - const std::string& message) { } - - // Navigate to the history entry for the given offset from the current - // position within the NavigationController. Makes no change if offset is - // not valid. - virtual void GoToEntryAtOffset(int offset) { } - - // The page requests the size of the back and forward lists - // within the NavigationController. - virtual void GetHistoryListCount(int* back_list_count, - int* forward_list_count) { } - - // A file chooser should be shown. - virtual void RunFileChooser(bool multiple_files, - const std::wstring& title, - const std::wstring& default_file, - const std::wstring& filter) { } - - // A javascript message, confirmation or prompt should be shown. - virtual void RunJavaScriptMessage(const std::wstring& message, - const std::wstring& default_prompt, - const int flags, - IPC::Message* reply_msg, - bool* did_suppress_message) { } - - virtual void RunBeforeUnloadConfirm(const std::wstring& message, - IPC::Message* reply_msg) { } - - // Display this RenderViewHost in a modal fashion. - virtual void RunModal(IPC::Message* reply_msg) { } - - virtual void ShowModalHTMLDialog(const GURL& url, int width, int height, - const std::string& json_arguments, - IPC::Message* reply_msg) { } - - // Password forms have been detected in the page. - virtual void PasswordFormsSeen(const std::vector& forms) { } - - // Forms fillable by autofill have been detected in the page. - virtual void AutofillFormSubmitted(const AutofillForm& form) { } - - // Called to retrieve a list of suggestions from the web database given - // the name of the field |field_name| and what the user has already typed in - // the field |user_text|. Appeals to the database thead to perform the query. - // When the database thread is finished, the autofill manager retrieves the - // calling RenderViewHost and then passes the vector of suggestions to - // RenderViewHost::AutofillSuggestionsReturned. - virtual void GetAutofillSuggestions(const std::wstring& field_name, - const std::wstring& user_text, - int64 node_id, - int request_id) { } - - // Notification that the page has an OpenSearch description document. - virtual void PageHasOSDD(RenderViewHost* render_view_host, - int32 page_id, const GURL& doc_url, - bool autodetected) { } - - // Notification that the inspect element window has been opened - virtual void InspectElementReply(int num_resources) { } - - // Notification that the render view has calculated the number of printed - // pages. - virtual void DidGetPrintedPagesCount(int cookie, int number_pages) { - NOTREACHED(); - } - - // Notification that the render view is done rendering one printed page. This - // call is synchronous, the renderer is waiting on us because of the EMF - // memory mapped data. - virtual void DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params) { - NOTREACHED(); - } - - // |url| is assigned to a server that can provide alternate error pages. If - // unchanged, just use the error pages built into our webkit. - virtual GURL GetAlternateErrorPageURL() const { - return GURL(); - } - - // Returns a WebPreferences object that will be used by the renderer - // associated with the owning render view host. - virtual WebPreferences GetWebkitPrefs() { - NOTREACHED(); - return WebPreferences(); - } - - // Notification when default plugin updates status of the missing plugin. - virtual void OnMissingPluginStatus(int status) { } - - // Notification from the renderer that a plugin instance has crashed. - virtual void OnCrashedPlugin(const FilePath& plugin_path) { } - - // Notification from the renderer that JS runs out of memory. - virtual void OnJSOutOfMemory() { } - - // Notification whether we should close the page, after an explicit call to - // AttemptToClosePage. This is called before a cross-site request or before - // a tab/window is closed, to allow the appropriate renderer to approve or - // deny the request. |proceed| indicates whether the user chose to proceed. - virtual void ShouldClosePage(bool proceed) { } - - // Called by ResourceDispatcherHost when a response for a pending cross-site - // request is received. The ResourceDispatcherHost will pause the response - // until the onunload handler of the previous renderer is run. - virtual void OnCrossSiteResponse(int new_render_process_host_id, - int new_request_id) { } - - // Whether this object can be blurred through a javascript - // obj.blur() call. ConstrainedWindows shouldn't be able to be - // blurred. - virtual bool CanBlur() const { return true; } - - // Notification that the renderer has become unresponsive. The - // delegate can use this notification to show a warning to the user. - virtual void RendererUnresponsive(RenderViewHost* render_view_host, - bool is_during_unload) { } - - // Notification that a previously unresponsive renderer has become - // responsive again. The delegate can use this notification to end the - // warning shown to the user. - virtual void RendererResponsive(RenderViewHost* render_view_host) { } - - // Notification that the RenderViewHost's load state changed. - virtual void LoadStateChanged(const GURL& url, net::LoadState load_state) { } - - // Notification that a request for install info has completed. - virtual void OnDidGetApplicationInfo( - int32 page_id, - const webkit_glue::WebApplicationInfo& app_info) { } - - // Notification the user has pressed enter or space while focus was on the - // page. This is used to avoid uninitiated user downloads (aka carpet - // bombing), see DownloadRequestManager for details. - virtual void OnEnterOrSpace() { } - - // If this view can be terminated without any side effects - virtual bool CanTerminate() const { return true; } -}; - -#endif // CHROME_BROWSER_RENDER_VIEW_HOST_DELEGATE_H__ - diff --git a/chrome/browser/render_view_host_manager.cc b/chrome/browser/render_view_host_manager.cc deleted file mode 100644 index 05d07f5..0000000 --- a/chrome/browser/render_view_host_manager.cc +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright (c) 2006-2008 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/render_view_host_manager.h" - -#include "base/command_line.h" -#include "base/logging.h" -#include "chrome/browser/render_widget_host_view.h" -#include "chrome/browser/render_view_host.h" -#include "chrome/browser/render_view_host_delegate.h" -#include "chrome/browser/tab_contents/navigation_controller.h" -#include "chrome/browser/tab_contents/navigation_entry.h" -#include "chrome/browser/tab_contents/site_instance.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/notification_service.h" - -namespace base { -class WaitableEvent; -} - -RenderViewHostManager::RenderViewHostManager( - RenderViewHostFactory* render_view_factory, - RenderViewHostDelegate* render_view_delegate, - Delegate* delegate) - : delegate_(delegate), - cross_navigation_pending_(false), - render_view_factory_(render_view_factory), - render_view_delegate_(render_view_delegate), - render_view_host_(NULL), - pending_render_view_host_(NULL), - interstitial_page_(NULL) { -} - -RenderViewHostManager::~RenderViewHostManager() { - // Shutdown should have been called which should have cleaned these up. - DCHECK(!render_view_host_); - DCHECK(!pending_render_view_host_); -} - -void RenderViewHostManager::Init(Profile* profile, - SiteInstance* site_instance, - int routing_id, - base::WaitableEvent* modal_dialog_event) { - // Create a RenderViewHost, once we have an instance. It is important to - // immediately give this SiteInstance to a RenderViewHost so that it is - // ref counted. - if (!site_instance) - site_instance = SiteInstance::CreateSiteInstance(profile); - render_view_host_ = CreateRenderViewHost( - site_instance, routing_id, modal_dialog_event); -} - -void RenderViewHostManager::Shutdown() { - if (pending_render_view_host_) - CancelPendingRenderView(); - - // We should always have a main RenderViewHost. - render_view_host_->Shutdown(); - render_view_host_ = NULL; -} - -RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { - RenderViewHost* dest_render_view_host = UpdateRendererStateNavigate(entry); - if (!dest_render_view_host) - return NULL; // We weren't able to create a pending render view host. - - // If the current render_view_host_ isn't live, we should create it so - // that we don't show a sad tab while the dest_render_view_host fetches - // its first page. (Bug 1145340) - if (dest_render_view_host != render_view_host_ && - !render_view_host_->IsRenderViewLive()) { - delegate_->CreateRenderViewForRenderManager(render_view_host_); - } - - // If the renderer crashed, then try to create a new one to satisfy this - // navigation request. - if (!dest_render_view_host->IsRenderViewLive()) { - if (!delegate_->CreateRenderViewForRenderManager(dest_render_view_host)) - return NULL; - - // Now that we've created a new renderer, be sure to hide it if it isn't - // our primary one. Otherwise, we might crash if we try to call Show() - // on it later. - if (dest_render_view_host != render_view_host_ && - dest_render_view_host->view()) { - dest_render_view_host->view()->Hide(); - } else { - // This is our primary renderer, notify here as we won't be calling - // SwapToRenderView (which does the notify). - RenderViewHostSwitchedDetails details; - details.new_host = render_view_host_; - details.old_host = NULL; - NotificationService::current()->Notify( - NOTIFY_RENDER_VIEW_HOST_CHANGED, - Source( - delegate_->GetControllerForRenderManager()), - Details(&details)); - } - } - - return dest_render_view_host; -} - -void RenderViewHostManager::Stop() { - render_view_host_->Stop(); - - // If we are cross-navigating, we should stop the pending renderers. This - // will lead to a DidFailProvisionalLoad, which will properly destroy them. - if (cross_navigation_pending_) { - pending_render_view_host_->Stop(); - - } -} - -void RenderViewHostManager::SetIsLoading(bool is_loading) { - render_view_host_->SetIsLoading(is_loading); - if (pending_render_view_host_) - pending_render_view_host_->SetIsLoading(is_loading); -} - -bool RenderViewHostManager::ShouldCloseTabOnUnresponsiveRenderer() { - if (!cross_navigation_pending_) - return true; - - // If the tab becomes unresponsive during unload while doing a - // crosssite navigation, proceed with the navigation. - int pending_request_id = pending_render_view_host_->GetPendingRequestId(); - if (pending_request_id == -1) { - // Haven't gotten around to starting the request. - pending_render_view_host_->SetNavigationsSuspended(false); - } else { - current_host()->process()->CrossSiteClosePageACK( - pending_render_view_host_->site_instance()->process_host_id(), - pending_request_id); - DidNavigateMainFrame(pending_render_view_host_); - } - return false; -} - -void RenderViewHostManager::DidNavigateMainFrame( - RenderViewHost* render_view_host) { - if (!cross_navigation_pending_) { - // We should only hear this from our current renderer. - DCHECK(render_view_host == render_view_host_); - return; - } - - if (render_view_host == pending_render_view_host_) { - // The pending cross-site navigation completed, so show the renderer. - SwapToRenderView(&pending_render_view_host_, true); - cross_navigation_pending_ = false; - } else if (render_view_host == render_view_host_) { - // A navigation in the original page has taken place. Cancel the pending - // one. - CancelPendingRenderView(); - cross_navigation_pending_ = false; - } else { - // No one else should be sending us DidNavigate in this state. - DCHECK(false); - } -} - -void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id, - int new_request_id) { - // Should only see this while we have a pending renderer. - if (!cross_navigation_pending_) - return; - DCHECK(pending_render_view_host_); - - // Tell the old renderer to run its onunload handler. When it finishes, it - // will send a ClosePage_ACK to the ResourceDispatcherHost with the given - // IDs (of the pending RVH's request), allowing the pending RVH's response to - // resume. - render_view_host_->ClosePage(new_render_process_host_id, new_request_id); - - // ResourceDispatcherHost has told us to run the onunload handler, which - // means it is not a download or unsafe page, and we are going to perform the - // navigation. Thus, we no longer need to remember that the RenderViewHost - // is part of a pending cross-site request. - pending_render_view_host_->SetHasPendingCrossSiteRequest(false, - new_request_id); -} - -void RenderViewHostManager::RendererAbortedProvisionalLoad( - RenderViewHost* render_view_host) { - // We used to cancel the pending renderer here for cross-site downloads. - // However, it's not safe to do that because the download logic repeatedly - // looks for this TabContents based on a render view ID. Instead, we just - // leave the pending renderer around until the next navigation event - // (Navigate, DidNavigate, etc), which will clean it up properly. - // TODO(creis): All of this will go away when we move the cross-site logic - // to ResourceDispatcherHost, so that we intercept responses rather than - // navigation events. (That's necessary to support onunload anyway.) Once - // we've made that change, we won't create a pending renderer until we know - // the response is not a download. -} - -void RenderViewHostManager::ShouldClosePage(bool proceed) { - // Should only see this while we have a pending renderer. Otherwise, we - // should ignore. - if (!pending_render_view_host_) { - bool proceed_to_fire_unload; - delegate_->BeforeUnloadFiredFromRenderManager(proceed, - &proceed_to_fire_unload); - - if (proceed_to_fire_unload) { - // This is not a cross-site navigation, the tab is being closed. - render_view_host_->FirePageUnload(); - } - return; - } - - if (proceed) { - // Ok to unload the current page, so proceed with the cross-site navigate. - pending_render_view_host_->SetNavigationsSuspended(false); - } else { - // Current page says to cancel. - CancelPendingRenderView(); - cross_navigation_pending_ = false; - } -} - -void RenderViewHostManager::OnJavaScriptMessageBoxClosed( - IPC::Message* reply_msg, - bool success, - const std::wstring& prompt) { - render_view_host_->JavaScriptMessageBoxClosed(reply_msg, success, prompt); -} - - -bool RenderViewHostManager::ShouldTransitionCrossSite() { - // True if we are using process-per-site-instance (default) or - // process-per-site (kProcessPerSite). - return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); -} - -SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( - const NavigationEntry& entry, - SiteInstance* curr_instance) { - // NOTE: This is only called when ShouldTransitionCrossSite is true. - - // If the entry has an instance already, we should use it. - if (entry.site_instance()) - return entry.site_instance(); - - // (UGLY) HEURISTIC, process-per-site only: - // - // If this navigation is generated, then it probably corresponds to a search - // query. Given that search results typically lead to users navigating to - // other sites, we don't really want to use the search engine hostname to - // determine the site instance for this navigation. - // - // NOTE: This can be removed once we have a way to transition between - // RenderViews in response to a link click. - // - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && - entry.transition_type() == PageTransition::GENERATED) - return curr_instance; - - const GURL& dest_url = entry.url(); - - // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it - // for this entry. We won't commit the SiteInstance to this site until the - // navigation commits (in DidNavigate), unless the navigation entry was - // restored. As session restore loads all the pages immediately we need to set - // the site first, otherwise after a restore none of the pages would share - // renderers. - if (!curr_instance->has_site()) { - // If we've already created a SiteInstance for our destination, we don't - // want to use this unused SiteInstance; use the existing one. (We don't - // do this check if the curr_instance has a site, because for now, we want - // to compare against the current URL and not the SiteInstance's site. In - // this case, there is no current URL, so comparing against the site is ok. - // See additional comments below.) - if (curr_instance->HasRelatedSiteInstance(dest_url)) { - return curr_instance->GetRelatedSiteInstance(dest_url); - } else { - if (entry.restored()) - curr_instance->SetSite(dest_url); - return curr_instance; - } - } - - // Otherwise, only create a new SiteInstance for cross-site navigation. - - // TODO(creis): Once we intercept links and script-based navigations, we - // will be able to enforce that all entries in a SiteInstance actually have - // the same site, and it will be safe to compare the URL against the - // SiteInstance's site, as follows: - // const GURL& current_url = curr_instance->site(); - // For now, though, we're in a hybrid model where you only switch - // SiteInstances if you type in a cross-site URL. This means we have to - // compare the entry's URL to the last committed entry's URL. - NavigationController* controller = delegate_->GetControllerForRenderManager(); - NavigationEntry* curr_entry = controller->GetLastCommittedEntry(); - if (interstitial_page_) { - // The interstitial is currently the last committed entry, but we want to - // compare against the last non-interstitial entry. - curr_entry = controller->GetEntryAtOffset(-1); - } - // If there is no last non-interstitial entry (and curr_instance already - // has a site), then we must have been opened from another tab. We want - // to compare against the URL of the page that opened us, but we can't - // get to it directly. The best we can do is check against the site of - // the SiteInstance. This will be correct when we intercept links and - // script-based navigations, but for now, it could place some pages in a - // new process unnecessarily. We should only hit this case if a page tries - // to open a new tab to an interstitial-inducing URL, and then navigates - // the page to a different same-site URL. (This seems very unlikely in - // practice.) - const GURL& current_url = (curr_entry) ? curr_entry->url() : - curr_instance->site(); - - if (SiteInstance::IsSameWebSite(current_url, dest_url)) { - return curr_instance; - } else { - // Start the new renderer in a new SiteInstance, but in the current - // BrowsingInstance. It is important to immediately give this new - // SiteInstance to a RenderViewHost (if it is different than our current - // SiteInstance), so that it is ref counted. This will happen in - // CreatePendingRenderView. - return curr_instance->GetRelatedSiteInstance(dest_url); - } -} - -bool RenderViewHostManager::CreatePendingRenderView(SiteInstance* instance) { - NavigationEntry* curr_entry = - delegate_->GetControllerForRenderManager()->GetLastCommittedEntry(); - if (curr_entry && curr_entry->tab_type() == TAB_CONTENTS_WEB) { - DCHECK(!curr_entry->content_state().empty()); - - // TODO(creis): Should send a message to the RenderView to let it know - // we're about to switch away, so that it sends an UpdateState message. - } - - pending_render_view_host_ = - CreateRenderViewHost(instance, MSG_ROUTING_NONE, NULL); - - bool success = delegate_->CreateRenderViewForRenderManager( - pending_render_view_host_); - if (success) { - // Don't show the view until we get a DidNavigate from it. - pending_render_view_host_->view()->Hide(); - } else { - CancelPendingRenderView(); - } - return success; -} - -RenderViewHost* RenderViewHostManager::CreateRenderViewHost( - SiteInstance* instance, - int routing_id, - base::WaitableEvent* modal_dialog_event) { - if (render_view_factory_) { - return render_view_factory_->CreateRenderViewHost( - instance, render_view_delegate_, routing_id, modal_dialog_event); - } else { - return new RenderViewHost(instance, render_view_delegate_, routing_id, - modal_dialog_event); - } -} - -void RenderViewHostManager::SwapToRenderView( - RenderViewHost** new_render_view_host, - bool destroy_after) { - // Remember if the page was focused so we can focus the new renderer in - // that case. - bool focus_render_view = render_view_host_->view() && - render_view_host_->view()->HasFocus(); - - // Hide the current view and prepare to destroy it. - // TODO(creis): Get the old RenderViewHost to send us an UpdateState message - // before we destroy it. - if (render_view_host_->view()) - render_view_host_->view()->Hide(); - RenderViewHost* old_render_view_host = render_view_host_; - - // Swap in the pending view and make it active. - render_view_host_ = (*new_render_view_host); - (*new_render_view_host) = NULL; - - // If the view is gone, then this RenderViewHost died while it was hidden. - // We ignored the RendererGone call at the time, so we should send it now - // to make sure the sad tab shows up, etc. - if (render_view_host_->view()) - render_view_host_->view()->Show(); - else - delegate_->RendererGoneFromRenderManager(render_view_host_); - - // Make sure the size is up to date. (Fix for bug 1079768.) - delegate_->UpdateRenderViewSizeForRenderManager(); - - if (focus_render_view && render_view_host_->view()) - render_view_host_->view()->Focus(); - - RenderViewHostSwitchedDetails details; - details.new_host = render_view_host_; - details.old_host = old_render_view_host; - NotificationService::current()->Notify( - NOTIFY_RENDER_VIEW_HOST_CHANGED, - Source(delegate_->GetControllerForRenderManager()), - Details(&details)); - - if (destroy_after) - old_render_view_host->Shutdown(); - - // Let the task manager know that we've swapped RenderViewHosts, since it - // might need to update its process groupings. - delegate_->NotifySwappedFromRenderManager(); -} - -RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate( - const NavigationEntry& entry) { - // If we are cross-navigating, then we want to get back to normal and navigate - // as usual. - if (cross_navigation_pending_) { - if (pending_render_view_host_) - CancelPendingRenderView(); - cross_navigation_pending_ = false; - } - - // render_view_host_ will not be deleted before the end of this method, so we - // don't have to worry about this SiteInstance's ref count dropping to zero. - SiteInstance* curr_instance = render_view_host_->site_instance(); - - // Determine if we need a new SiteInstance for this entry. - // Again, new_instance won't be deleted before the end of this method, so it - // is safe to use a normal pointer here. - SiteInstance* new_instance = curr_instance; - if (ShouldTransitionCrossSite()) - new_instance = GetSiteInstanceForEntry(entry, curr_instance); - - if (new_instance != curr_instance) { - // New SiteInstance. - DCHECK(!cross_navigation_pending_); - - // Create a pending RVH and navigate it. - bool success = CreatePendingRenderView(new_instance); - if (!success) - return NULL; - - // Check if our current RVH is live before we set up a transition. - if (!render_view_host_->IsRenderViewLive()) { - if (!cross_navigation_pending_) { - // The current RVH is not live. There's no reason to sit around with a - // sad tab or a newly created RVH while we wait for the pending RVH to - // navigate. Just switch to the pending RVH now and go back to non - // cross-navigating (Note that we don't care about on{before}unload - // handlers if the current RVH isn't live.) - SwapToRenderView(&pending_render_view_host_, true); - return render_view_host_; - } else { - NOTREACHED(); - return render_view_host_; - } - } - // Otherwise, it's safe to treat this as a pending cross-site transition. - - // Make sure the old render view stops, in case a load is in progress. - render_view_host_->Stop(); - - // Suspend the new render view (i.e., don't let it send the cross-site - // Navigate message) until we hear back from the old renderer's - // onbeforeunload handler. If it returns false, we'll have to cancel the - // request. - pending_render_view_host_->SetNavigationsSuspended(true); - - // Tell the CrossSiteRequestManager that this RVH has a pending cross-site - // request, so that ResourceDispatcherHost will know to tell us to run the - // old page's onunload handler before it sends the response. - pending_render_view_host_->SetHasPendingCrossSiteRequest(true, -1); - - // We now have a pending RVH. - DCHECK(!cross_navigation_pending_); - cross_navigation_pending_ = true; - - // Tell the old render view to run its onbeforeunload handler, since it - // doesn't otherwise know that the cross-site request is happening. This - // will trigger a call to ShouldClosePage with the reply. - render_view_host_->FirePageBeforeUnload(); - - return pending_render_view_host_; - } - - // Same SiteInstance can be used. Navigate render_view_host_ if we are not - // cross navigating. - DCHECK(!cross_navigation_pending_); - return render_view_host_; -} - -void RenderViewHostManager::CancelPendingRenderView() { - pending_render_view_host_->Shutdown(); - pending_render_view_host_ = NULL; -} - -void RenderViewHostManager::CrossSiteNavigationCanceled() { - DCHECK(cross_navigation_pending_); - cross_navigation_pending_ = false; - if (pending_render_view_host_) - CancelPendingRenderView(); -} - diff --git a/chrome/browser/render_view_host_manager.h b/chrome/browser/render_view_host_manager.h deleted file mode 100644 index ee0e16b..0000000 --- a/chrome/browser/render_view_host_manager.h +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) 2006-2008 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_RENDER_VIEW_HOST_MANAGER_H_ -#define CHROME_BROWSER_RENDER_VIEW_HOST_MANAGER_H_ - -#include - -#include - -#include "base/basictypes.h" -#include "chrome/browser/render_view_host.h" - -class InterstitialPage; -class NavigationController; -class NavigationEntry; -class Profile; -class RenderViewHostDelegate; -class RenderViewHostFactory; -class RenderWidgetHostView; -class SiteInstance; - -// Manages RenderViewHosts for a WebContents. Normally there is only one and -// it is easy to do. But we can also have transitions of processes (and hence -// RenderViewHosts) that can get complex. -class RenderViewHostManager { - public: - // Functions implemented by our owner that we need. - // - // TODO(brettw) Clean this up! These are all the functions in WebContents that - // are required to run this class. The design should probably be better such - // that these are more clear. - // - // There is additional complexity that some of the functions we need in - // WebContents are inherited and non-virtual. These are named with - // "RenderManager" so that the duplicate implementation of them will be clear. - class Delegate { - public: - // See web_contents.h's implementation for more. - virtual bool CreateRenderViewForRenderManager( - RenderViewHost* render_view_host) = 0; - virtual void BeforeUnloadFiredFromRenderManager( - bool proceed, bool* proceed_to_fire_unload) = 0; - virtual void DidStartLoadingFromRenderManager( - RenderViewHost* render_view_host, int32 page_id) = 0; - virtual void RendererGoneFromRenderManager( - RenderViewHost* render_view_host) = 0; - virtual void UpdateRenderViewSizeForRenderManager() = 0; - virtual void NotifySwappedFromRenderManager() = 0; - virtual NavigationController* GetControllerForRenderManager() = 0; - }; - - // The factory is optional. It is used by unit tests to supply custom render - // view hosts. When NULL, the regular RenderViewHost will be created. - // - // Both delegate pointers must be non-NULL and are not owned by this class. - // They must outlive this class. The RenderViewHostDelegate is what will be - // installed into all RenderViewHosts that are created. - // - // You must call Init() before using this class and Shutdown() before - // deleting it. - RenderViewHostManager(RenderViewHostFactory* render_view_factory, - RenderViewHostDelegate* render_view_delegate, - Delegate* delegate); - ~RenderViewHostManager(); - - // For arguments, see WebContents constructor. - void Init(Profile* profile, - SiteInstance* site_instance, - int routing_id, - base::WaitableEvent* modal_dialog_event); - - // Schedules all RenderViewHosts for destruction. - void Shutdown(); - - // Returns the currently actuive RenderViewHost. - // - // This will be non-NULL between Init() and Shutdown(). You may want to NULL - // check it in many cases, however. Windows can send us messages during the - // destruction process after it has been shut down. - RenderViewHost* current_host() const { - return render_view_host_; - } - - // Returns the view associated with the current RenderViewHost, or NULL if - // there is no current one. - RenderWidgetHostView* current_view() const { - if (!render_view_host_) - return NULL; - return render_view_host_->view(); - } - - // Called when we want to instruct the renderer to navigate to the given - // navigation entry. It may create a new RenderViewHost or re-use an existing - // one. The RenderViewHost to navigate will be returned. Returns NULL if one - // could not be created. - RenderViewHost* Navigate(const NavigationEntry& entry); - - // Instructs the various live views to stop. Called when the user directed the - // page to stop loading. - void Stop(); - - // Notifies the regular and pending RenderViewHosts that a load is or is not - // happening. Even though the message is only for one of them, we don't know - // which one so we tell both. - void SetIsLoading(bool is_loading); - - // Whether to close the tab or not when there is a hang during an unload - // handler. If we are mid-crosssite navigation, then we should proceed - // with the navigation instead of closing the tab. - bool ShouldCloseTabOnUnresponsiveRenderer(); - - // Called when a renderer's main frame navigates. - void DidNavigateMainFrame(RenderViewHost* render_view_host); - - // Allows the WebContents to react when a cross-site response is ready to be - // delivered to a pending RenderViewHost. We must first run the onunload - // handler of the old RenderViewHost before we can allow it to proceed. - void OnCrossSiteResponse(int new_render_process_host_id, - int new_request_id); - - // Notifies that the navigation that initiated a cross-site transition has - // been canceled. - void CrossSiteNavigationCanceled(); - - // Called when a provisional load on the given renderer is aborted. - void RendererAbortedProvisionalLoad(RenderViewHost* render_view_host); - - // Actually implements this RenderViewHostDelegate function for the - // WebContents. - void ShouldClosePage(bool proceed); - - // Forwards the message to the RenderViewHost, which is the original one. - void OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, - bool success, - const std::wstring& prompt); - - // Sets the passed passed interstitial as the currently showing interstitial. - // |interstitial_page| should be non NULL (use the remove_interstitial_page - // method to unset the interstitial) and no interstitial page should be set - // when there is already a non NULL interstitial page set. - void set_interstitial_page(InterstitialPage* interstitial_page) { - DCHECK(!interstitial_page_ && interstitial_page); - interstitial_page_ = interstitial_page; - } - - // Unsets the currently showing interstitial. - void remove_interstitial_page() { - DCHECK(interstitial_page_); - interstitial_page_ = NULL; - } - - // Returns the currently showing interstitial, NULL if no interstitial is - // showing. - InterstitialPage* interstitial_page() const { - return interstitial_page_; - } - - private: - friend class TestWebContents; - - // Returns whether this tab should transition to a new renderer for - // cross-site URLs. Enabled unless we see the --process-per-tab command line - // switch. Can be overridden in unit tests. - bool ShouldTransitionCrossSite(); - - // Returns an appropriate SiteInstance object for the given NavigationEntry, - // possibly reusing the current SiteInstance. - // Never called if --process-per-tab is used. - SiteInstance* GetSiteInstanceForEntry(const NavigationEntry& entry, - SiteInstance* curr_instance); - - // Helper method to create a pending RenderViewHost for a cross-site - // navigation. - bool CreatePendingRenderView(SiteInstance* instance); - - // Creates a RenderViewHost using render_view_factory_ (or directly, if the - // factory is NULL). - RenderViewHost* CreateRenderViewHost(SiteInstance* instance, - int routing_id, - base::WaitableEvent* modal_dialog_event); - - // Replaces the currently shown render_view_host_ with the RenderViewHost in - // the field pointed to by |new_render_view_host|, and then NULLs the field. - // Callers should only pass pointers to the pending_render_view_host_, - // interstitial_render_view_host_, or original_render_view_host_ fields of - // this object. If |destroy_after|, this method will call - // ScheduleDeferredDestroy on the previous render_view_host_. - void SwapToRenderView(RenderViewHost** new_render_view_host, - bool destroy_after); - - // Helper method to terminate the pending RenderViewHost. - void CancelPendingRenderView(); - - RenderViewHost* UpdateRendererStateNavigate(const NavigationEntry& entry); - - // Our delegate, not owned by us. Guaranteed non-NULL. - Delegate* delegate_; - - // Allows tests to create their own render view host types. - RenderViewHostFactory* render_view_factory_; - - // Implemented by the owner of this class, this delegate is installed into all - // the RenderViewHosts that we create. - RenderViewHostDelegate* render_view_delegate_; - - // Our RenderView host. This object is responsible for all communication with - // a child RenderView instance. - RenderViewHost* render_view_host_; - - // A RenderViewHost used to load a cross-site page. This remains hidden - // while a cross-site request is pending until it calls DidNavigate. - RenderViewHost* pending_render_view_host_; - - // The intersitial page currently shown if any, not own by this class - // (the InterstitialPage is self-owned, it deletes itself when hidden). - InterstitialPage* interstitial_page_; - - // Whether a cross-site request is pending (in the new process model). - bool cross_navigation_pending_; - - DISALLOW_COPY_AND_ASSIGN(RenderViewHostManager); -}; - -// The "details" for a NOTIFY_RENDER_VIEW_HOST_CHANGED notification. The old -// host can be NULL when the first RenderViewHost is set. -struct RenderViewHostSwitchedDetails { - RenderViewHost* old_host; - RenderViewHost* new_host; -}; - -#endif // CHROME_BROWSER_RENDER_VIEW_HOST_MANAGER_H_ - diff --git a/chrome/browser/render_widget_helper.cc b/chrome/browser/render_widget_helper.cc deleted file mode 100644 index 7542d27..0000000 --- a/chrome/browser/render_widget_helper.cc +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (c) 2006-2008 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/render_widget_helper.h" - -#include "base/thread.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/renderer_host/resource_dispatcher_host.h" - -using base::TimeDelta; -using base::TimeTicks; - -// A Task used with InvokeLater that we hold a pointer to in pending_paints_. -// Instances are deleted by MessageLoop after it calls their Run method. -class RenderWidgetHelper::PaintMsgProxy : public Task { - public: - explicit PaintMsgProxy(RenderWidgetHelper* h, const IPC::Message& m) - : helper(h), - message(m), - cancelled(false) { - } - - ~PaintMsgProxy() { - // If the paint message was never dispatched, then we need to let the - // helper know that we are going away. - if (!cancelled && helper) - helper->OnDiscardPaintMsg(this); - } - - virtual void Run() { - if (!cancelled) { - helper->OnDispatchPaintMsg(this); - helper = NULL; - } - } - - scoped_refptr helper; - IPC::Message message; - bool cancelled; // If true, then the message will not be dispatched. - - DISALLOW_EVIL_CONSTRUCTORS(PaintMsgProxy); -}; - -RenderWidgetHelper::RenderWidgetHelper(int render_process_id) - : render_process_id_(render_process_id), - ui_loop_(MessageLoop::current()), - event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)), - block_popups_(false) { -} - -RenderWidgetHelper::~RenderWidgetHelper() { - // The elements of pending_paints_ each hold an owning reference back to this - // object, so we should not be destroyed unless pending_paints_ is empty! - DCHECK(pending_paints_.empty()); - - CloseHandle(event_); -} - -int RenderWidgetHelper::GetNextRoutingID() { - return next_routing_id_.GetNext() + 1; -} - -void RenderWidgetHelper::CancelResourceRequests(int render_widget_id) { - if (g_browser_process->io_thread()) - g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, - NewRunnableMethod(this, - &RenderWidgetHelper::OnCancelResourceRequests, - g_browser_process->resource_dispatcher_host(), - render_widget_id)); -} - -void RenderWidgetHelper::CrossSiteClosePageACK(int new_render_process_host_id, - int new_request_id) { - if (g_browser_process->io_thread()) - g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, - NewRunnableMethod(this, - &RenderWidgetHelper::OnCrossSiteClosePageACK, - g_browser_process->resource_dispatcher_host(), - new_render_process_host_id, - new_request_id)); -} - -bool RenderWidgetHelper::WaitForPaintMsg(int render_widget_id, - const TimeDelta& max_delay, - IPC::Message* msg) { - TimeTicks time_start = TimeTicks::Now(); - - for (;;) { - PaintMsgProxy* proxy = NULL; - { - AutoLock lock(pending_paints_lock_); - - PaintMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); - if (it != pending_paints_.end()) { - proxy = it->second; - - // Flag the proxy as cancelled so that when it is run as a task it will - // do nothing. - proxy->cancelled = true; - - pending_paints_.erase(it); - } - } - - if (proxy) { - *msg = proxy->message; - DCHECK(msg->routing_id() == render_widget_id); - return true; - } - - // Calculate the maximum amount of time that we are willing to sleep. - TimeDelta max_sleep_time = - max_delay - (TimeTicks::Now() - time_start); - if (max_sleep_time <= TimeDelta::FromMilliseconds(0)) - break; - - WaitForSingleObject(event_, - static_cast(max_sleep_time.InMilliseconds())); - } - - return false; -} - -void RenderWidgetHelper::DidReceivePaintMsg(const IPC::Message& msg) { - int render_widget_id = msg.routing_id(); - - PaintMsgProxy* proxy; - { - AutoLock lock(pending_paints_lock_); - - PaintMsgProxyMap::value_type new_value(render_widget_id, NULL); - - // We expect only a single PaintRect message at a time. Optimize for the - // case that we don't already have an entry by using the 'insert' method. - std::pair result = - pending_paints_.insert(new_value); - if (!result.second) { - NOTREACHED() << "Unexpected PaintRect message!"; - return; - } - - result.first->second = (proxy = new PaintMsgProxy(this, msg)); - } - - // Notify anyone waiting on the UI thread that there is a new entry in the - // proxy map. If they don't find the entry they are looking for, then they - // will just continue waiting. - SetEvent(event_); - - // The proxy will be deleted when it is run as a task. - ui_loop_->PostTask(FROM_HERE, proxy); -} - -void RenderWidgetHelper::OnDiscardPaintMsg(PaintMsgProxy* proxy) { - const IPC::Message& msg = proxy->message; - - // Remove the proxy from the map now that we are going to handle it normally. - { - AutoLock lock(pending_paints_lock_); - - PaintMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); - DCHECK(it != pending_paints_.end()); - DCHECK(it->second == proxy); - - pending_paints_.erase(it); - } -} - -void RenderWidgetHelper::OnDispatchPaintMsg(PaintMsgProxy* proxy) { - OnDiscardPaintMsg(proxy); - - // It is reasonable for the host to no longer exist. - RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_); - if (host) - host->OnMessageReceived(proxy->message); -} - -void RenderWidgetHelper::OnCancelResourceRequests( - ResourceDispatcherHost* dispatcher, - int render_widget_id) { - dispatcher->CancelRequestsForRenderView(render_process_id_, render_widget_id); -} - -void RenderWidgetHelper::OnCrossSiteClosePageACK( - ResourceDispatcherHost* dispatcher, - int new_render_process_host_id, - int new_request_id) { - dispatcher->OnClosePageACK(new_render_process_host_id, new_request_id); -} - -void RenderWidgetHelper::CreateNewWindow(int opener_id, - bool user_gesture, - int* route_id, - HANDLE* modal_dialog_event, - HANDLE render_process) { - if (!user_gesture && block_popups_) { - *route_id = MSG_ROUTING_NONE; - *modal_dialog_event = NULL; - return; - } - - *route_id = GetNextRoutingID(); - HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); - BOOL result = DuplicateHandle(GetCurrentProcess(), - event, - render_process, - modal_dialog_event, - SYNCHRONIZE, - FALSE, - 0); - DCHECK(result) << "Couldn't duplicate modal dialog event for the renderer."; - - // The easiest way to reach RenderViewHost is just to send a routed message. - ViewHostMsg_CreateWindowWithRoute msg(opener_id, *route_id, event); - ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &RenderWidgetHelper::OnSimulateReceivedMessage, msg)); -} - -void RenderWidgetHelper::CreateNewWidget(int opener_id, - bool activatable, - int* route_id) { - *route_id = GetNextRoutingID(); - ViewHostMsg_CreateWidgetWithRoute msg(opener_id, *route_id, activatable); - ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &RenderWidgetHelper::OnSimulateReceivedMessage, msg)); -} - -void RenderWidgetHelper::OnSimulateReceivedMessage( - const IPC::Message& message) { - RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_); - if (host) - host->OnMessageReceived(message); -} diff --git a/chrome/browser/render_widget_helper.h b/chrome/browser/render_widget_helper.h deleted file mode 100644 index 9ec75e0..0000000 --- a/chrome/browser/render_widget_helper.h +++ /dev/null @@ -1,159 +0,0 @@ - -// Copyright (c) 2006-2008 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_RENDER_WIDGET_HELPER_H__ -#define CHROME_BROWSER_RENDER_WIDGET_HELPER_H__ - -#include "base/atomic_sequence_num.h" -#include "base/hash_tables.h" -#include "base/ref_counted.h" -#include "base/lock.h" - -namespace IPC { -class Message; -} - -namespace base { -class TimeDelta; -} - -class MessageLoop; -class ResourceDispatcherHost; - -// Instantiated per RenderProcessHost to provide various optimizations on -// behalf of a RenderWidgetHost. This class bridges between the IO thread -// where the RenderProcessHost's MessageFilter lives and the UI thread where -// the RenderWidgetHost lives. -// -// -// OPTIMIZED RESIZE -// -// RenderWidgetHelper is used to implement optimized resize. When the -// RenderWidgetHost is resized, it sends a Resize message to its RenderWidget -// counterpart in the renderer process. The RenderWidget generates a -// PaintRect message in response to the Resize message, and it sets the -// IS_RESIZE_ACK flag in the PaintRect message to true. -// -// Back in the browser process, when the RenderProcessHost's MessageFilter -// sees a PaintRect message, it directs it to the RenderWidgetHelper by -// calling the DidReceivePaintMsg method. That method stores the data for -// the PaintRect message in a map, where it can be directly accessed by the -// RenderWidgetHost on the UI thread during a call to RenderWidgetHost's -// GetBackingStore method. -// -// When the RenderWidgetHost's GetBackingStore method is called, it first -// checks to see if it is waiting for a resize ack. If it is, then it calls -// the RenderWidgetHelper's WaitForPaintMsg to check if there is already a -// resulting PaintRect message (or to wait a short amount of time for one to -// arrive). The main goal of this mechanism is to short-cut the usual way in -// which IPC messages are proxied over to the UI thread via InvokeLater. -// This approach is necessary since window resize is followed up immediately -// by a request to repaint the window. -// -// -// OPTIMIZED TAB SWITCHING -// -// When a RenderWidgetHost is in a background tab, it is flagged as hidden. -// This causes the corresponding RenderWidget to stop sending PaintRect -// messages. The RenderWidgetHost also discards its backingstore when it is -// hidden, which helps free up memory. As a result, when a RenderWidgetHost -// is restored, it can be momentarily without a backingstore. (Restoring a -// RenderWidgetHost results in a WasRestored message being sent to the -// RenderWidget, which triggers a full PaintRect message.) This can lead to -// an observed rendering glitch as the WebContents will just have to fill -// white overtop the RenderWidgetHost until the RenderWidgetHost receives a -// PaintRect message to refresh its backingstore. -// -// To avoid this 'white flash', the RenderWidgetHost again makes use of the -// RenderWidgetHelper's WaitForPaintMsg method. When the RenderWidgetHost's -// GetBackingStore method is called, it will call WaitForPaintMsg if it has -// no backingstore. -// -class RenderWidgetHelper : - public base::RefCountedThreadSafe { - public: - RenderWidgetHelper(int render_process_id); - ~RenderWidgetHelper(); - - // Gets the next available routing id. This is thread safe. - int GetNextRoutingID(); - - // Sets whether popup blocking is enabled or not. - void set_block_popups(bool block) { block_popups_ = block; } - - - // UI THREAD ONLY ----------------------------------------------------------- - - // These three functions provide the backend implementation of the - // corresponding functions in RenderProcessHost. See those declarations - // for documentation. - void CancelResourceRequests(int render_widget_id); - void CrossSiteClosePageACK(int new_render_process_host_id, - int new_request_id); - bool WaitForPaintMsg(int render_widget_id, - const base::TimeDelta& max_delay, - IPC::Message* msg); - - - // IO THREAD ONLY ----------------------------------------------------------- - - // Called on the IO thread when a PaintRect message is received. - void DidReceivePaintMsg(const IPC::Message& msg); - - MessageLoop* ui_loop() { return ui_loop_; } - - void CreateNewWindow(int opener_id, bool user_gesture, int* route_id, - HANDLE* modal_dialog_event, HANDLE render_process); - void CreateNewWidget(int opener_id, bool activatable, int* route_id); - - private: - // A class used to proxy a paint message. PaintMsgProxy objects are created - // on the IO thread and destroyed on the UI thread. - class PaintMsgProxy; - friend class PaintMsgProxy; - - // Map from render_widget_id to live PaintMsgProxy instance. - typedef base::hash_map PaintMsgProxyMap; - - // Called on the UI thread to discard a paint message. - void OnDiscardPaintMsg(PaintMsgProxy* proxy); - - // Called on the UI thread to dispatch a paint message if necessary. - void OnDispatchPaintMsg(PaintMsgProxy* proxy); - - // Called on the UI thread to send a message to the RenderProcessHost. - void OnSimulateReceivedMessage(const IPC::Message& message); - - // Called on the IO thread to cancel resource requests for the render widget. - void OnCancelResourceRequests(ResourceDispatcherHost* dispatcher, - int render_widget_id); - - // Called on the IO thread to resume a cross-site response. - void OnCrossSiteClosePageACK(ResourceDispatcherHost* dispatcher, - int new_render_process_host_id, - int new_request_id); - - // A map of live paint messages. Must hold pending_paints_lock_ to access. - // The PaintMsgProxy objects are not owned by this map. (See PaintMsgProxy - // for details about how the lifetime of instances are managed.) - PaintMsgProxyMap pending_paints_; - Lock pending_paints_lock_; - - int render_process_id_; - MessageLoop* ui_loop_; - - // Event used to implement WaitForPaintMsg. - HANDLE event_; - - // The next routing id to use. - base::AtomicSequenceNumber next_routing_id_; - - // Whether popup blocking is enabled or not. - bool block_popups_; - - DISALLOW_EVIL_CONSTRUCTORS(RenderWidgetHelper); -}; - -#endif // CHROME_BROWSER_RENDER_WIDGET_HELPER_H__ diff --git a/chrome/browser/render_widget_host.cc b/chrome/browser/render_widget_host.cc deleted file mode 100644 index fdbec92..0000000 --- a/chrome/browser/render_widget_host.cc +++ /dev/null @@ -1,849 +0,0 @@ -// Copyright (c) 2006-2008 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/render_widget_host.h" - -#include "base/gfx/gdi_util.h" -#include "base/message_loop.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/render_widget_helper.h" -#include "chrome/browser/render_widget_host_view.h" -#include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/common/mru_cache.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/win_util.h" -#include "chrome/views/view.h" -#include "webkit/glue/webcursor.h" -#include "webkit/glue/webinputevent.h" - -using base::Time; -using base::TimeDelta; -using base::TimeTicks; - -// How long to (synchronously) wait for the renderer to respond with a -// PaintRect message, when our backing-store is invalid, before giving up and -// returning a null or incorrectly sized backing-store from GetBackingStore. -// This timeout impacts the "choppiness" of our window resize perf. -static const int kPaintMsgTimeoutMS = 40; - -// How long to wait before we consider a renderer hung. -static const int kHungRendererDelayMs = 20000; - -/////////////////////////////////////////////////////////////////////////////// -// RenderWidget::BackingStore - -RenderWidgetHost::BackingStore::BackingStore(const gfx::Size& size) - : size_(size), - backing_store_dib_(NULL), - original_bitmap_(NULL) { - HDC screen_dc = ::GetDC(NULL); - hdc_ = CreateCompatibleDC(screen_dc); - ReleaseDC(NULL, screen_dc); -} - -RenderWidgetHost::BackingStore::~BackingStore() { - DCHECK(hdc_); - - DeleteDC(hdc_); - - if (backing_store_dib_) { - DeleteObject(backing_store_dib_); - backing_store_dib_ = NULL; - } -} - -bool RenderWidgetHost::BackingStore::Refresh(HANDLE process, - HANDLE bitmap_section, - const gfx::Rect& bitmap_rect) { - // The bitmap received is valid only in the renderer process. - HANDLE valid_bitmap = - win_util::GetSectionFromProcess(bitmap_section, process, false); - if (!valid_bitmap) - return false; - - if (!backing_store_dib_) { - backing_store_dib_ = CreateDIB(hdc_, size_.width(), size_.height(), true, - NULL); - DCHECK(backing_store_dib_ != NULL); - original_bitmap_ = SelectObject(hdc_, backing_store_dib_); - } - - // TODO(darin): protect against integer overflow - DWORD size = 4 * bitmap_rect.width() * bitmap_rect.height(); - void* backing_store_data = MapViewOfFile(valid_bitmap, FILE_MAP_READ, 0, 0, - size); - // These values are shared with gfx::PlatformDevice - BITMAPINFOHEADER hdr; - gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr); - // Account for a bitmap_rect that exceeds the bounds of our view - gfx::Rect view_rect(0, 0, size_.width(), size_.height()); - gfx::Rect paint_rect = view_rect.Intersect(bitmap_rect); - - StretchDIBits(hdc_, - paint_rect.x(), - paint_rect.y(), - paint_rect.width(), - paint_rect.height(), - 0, 0, // source x,y - paint_rect.width(), - paint_rect.height(), - backing_store_data, - reinterpret_cast(&hdr), - DIB_RGB_COLORS, - SRCCOPY); - - UnmapViewOfFile(backing_store_data); - CloseHandle(valid_bitmap); - return true; -} - -HANDLE RenderWidgetHost::BackingStore::CreateDIB(HDC dc, int width, int height, - bool use_system_color_depth, - HANDLE section) { - BITMAPINFOHEADER hdr; - - if (use_system_color_depth) { - HDC screen_dc = ::GetDC(NULL); - int color_depth = GetDeviceCaps(screen_dc, BITSPIXEL); - ::ReleaseDC(NULL, screen_dc); - - // Color depths less than 16 bpp require a palette to be specified in the - // BITMAPINFO structure passed to CreateDIBSection. Instead of creating - // the palette, we specify the desired color depth as 16 which allows the - // OS to come up with an approximation. Tested this with 8bpp. - if (color_depth < 16) - color_depth = 16; - - gfx::CreateBitmapHeaderWithColorDepth(width, height, color_depth, &hdr); - } else { - gfx::CreateBitmapHeader(width, height, &hdr); - } - void* data = NULL; - HANDLE dib = - CreateDIBSection(hdc_, reinterpret_cast(&hdr), - 0, &data, section, 0); - return dib; -} - - -/////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHost::BackingStoreManager - -// This class manages backing stores in the browsr. Every RenderWidgetHost -// is associated with a backing store which it requests from this class. -// The hosts don't maintain any references to the backing stores. -// These backing stores are maintained in a cache which can be trimmed as -// needed. -class RenderWidgetHost::BackingStoreManager { - public: - // Returns a backing store which matches the desired dimensions. - // Parameters: - // host - // A pointer to the RenderWidgetHost. - // backing_store_rect - // The desired backing store dimensions. - // Returns a pointer to the backing store on success, NULL on failure. - static BackingStore* GetBackingStore(RenderWidgetHost* host, - const gfx::Size& desired_size) { - BackingStore* backing_store = Lookup(host); - if (backing_store) { - // If we already have a backing store, then make sure it is the correct - // size. - if (backing_store->size() == desired_size) - return backing_store; - backing_store = NULL; - } - - return backing_store; - } - - // Returns a backing store which is fully ready for consumption, - // i.e. the bitmap from the renderer has been copied into the - // backing store dc, or the bitmap in the backing store dc references - // the renderer bitmap. - // Parameters: - // host - // A pointer to the RenderWidgetHost. - // backing_store_rect - // The desired backing store dimensions. - // process_handle - // The renderer process handle. - // bitmap_section - // The bitmap section from the renderer. - // bitmap_rect - // The rect to be painted into the backing store - // needs_full_paint - // Set if we need to send out a request to paint the view - // to the renderer. - static BackingStore* PrepareBackingStore(RenderWidgetHost* host, - const gfx::Rect& backing_store_rect, - HANDLE process_handle, - HANDLE bitmap_section, - const gfx::Rect& bitmap_rect, - bool* needs_full_paint) { - BackingStore* backing_store = GetBackingStore(host, - backing_store_rect.size()); - if (!backing_store) { - // We need to get Webkit to generate a new paint here, as we - // don't have a previous snapshot. - if (bitmap_rect != backing_store_rect) { - DCHECK(needs_full_paint != NULL); - *needs_full_paint = true; - } - backing_store = CreateBackingStore(host, backing_store_rect); - } - - DCHECK(backing_store != NULL); - backing_store->Refresh(process_handle, bitmap_section, bitmap_rect); - return backing_store; - } - - // Returns a matching backing store for the host. - // Returns NULL if we fail to find one. - static BackingStore* Lookup(RenderWidgetHost* host) { - if (cache_) { - BackingStoreCache::iterator it = cache_->Peek(host); - if (it != cache_->end()) - return it->second; - } - return NULL; - } - - // Removes the backing store for the host. - static void RemoveBackingStore(RenderWidgetHost* host) { - if (!cache_) - return; - - BackingStoreCache::iterator it = cache_->Peek(host); - if (it == cache_->end()) - return; - - cache_->Erase(it); - - if (cache_->empty()) { - delete cache_; - cache_ = NULL; - } - } - - private: - // Not intended for instantiation. - ~BackingStoreManager(); - - typedef OwningMRUCache BackingStoreCache; - static BackingStoreCache* cache_; - - // Returns the size of the backing store cache. - // TODO(iyengar) Make this dynamic, i.e. based on the available resources - // on the machine. - static int GetBackingStoreCacheSize() { - const int kMaxSize = 5; - return kMaxSize; - } - - // Creates the backing store for the host based on the dimensions passed in. - // Removes the existing backing store if there is one. - static BackingStore* CreateBackingStore( - RenderWidgetHost* host, const gfx::Rect& backing_store_rect) { - RemoveBackingStore(host); - - BackingStore* backing_store = new BackingStore(backing_store_rect.size()); - int backing_store_cache_size = GetBackingStoreCacheSize(); - if (backing_store_cache_size > 0) { - if (!cache_) - cache_ = new BackingStoreCache(backing_store_cache_size); - cache_->Put(host, backing_store); - } - return backing_store; - } - - DISALLOW_EVIL_CONSTRUCTORS(BackingStoreManager); -}; - -RenderWidgetHost::BackingStoreManager::BackingStoreCache* - RenderWidgetHost::BackingStoreManager::cache_ = NULL; - - -/////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHost - -RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, - int routing_id) - : process_(process), - routing_id_(routing_id), - resize_ack_pending_(false), - mouse_move_pending_(false), - view_(NULL), - is_loading_(false), - is_hidden_(false), - suppress_view_updating_(false), - needs_repainting_on_restore_(false), - is_unresponsive_(false), - view_being_painted_(false), - repaint_ack_pending_(false) { - if (routing_id_ == MSG_ROUTING_NONE) - routing_id_ = process_->GetNextRoutingID(); - - process_->Attach(this, routing_id_); - // Because the widget initializes as is_hidden_ == false, - // tell the process host that we're alive. - process_->WidgetRestored(); -} - -RenderWidgetHost::~RenderWidgetHost() { - // Clear our current or cached backing store if either remains. - BackingStoreManager::RemoveBackingStore(this); - - process_->Release(routing_id_); -} - -void RenderWidgetHost::Init() { - DCHECK(process_->channel()); - - // Send the ack along with the information on placement. - HWND plugin_hwnd = view_->GetPluginHWND(); - Send(new ViewMsg_CreatingNew_ACK(routing_id_, plugin_hwnd)); - - WasResized(); -} - -/////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHost, protected: - -IPC_DEFINE_MESSAGE_MAP(RenderWidgetHost) - IPC_MESSAGE_HANDLER(ViewHostMsg_RendererReady, OnMsgRendererReady) - IPC_MESSAGE_HANDLER(ViewHostMsg_RendererGone, OnMsgRendererGone) - IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnMsgClose) - IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnMsgRequestMove) - IPC_MESSAGE_HANDLER(ViewHostMsg_PaintRect, OnMsgPaintRect) - IPC_MESSAGE_HANDLER(ViewHostMsg_ScrollRect, OnMsgScrollRect) - IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnMsgInputEventAck) - IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnMsgFocus) - IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur) - IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) - IPC_MESSAGE_HANDLER(ViewHostMsg_ImeUpdateStatus, OnMsgImeUpdateStatus) - IPC_MESSAGE_UNHANDLED_ERROR() -IPC_END_MESSAGE_MAP() - -void RenderWidgetHost::OnMsgRendererReady() { - WasResized(); -} - -void RenderWidgetHost::OnMsgRendererGone() { - // TODO(evanm): This synchronously ends up calling "delete this". - // Is that really what we want in response to this message? I'm matching - // previous behavior of the code here. - Destroy(); -} - -void RenderWidgetHost::OnMsgClose() { - Shutdown(); -} - -void RenderWidgetHost::OnMsgRequestMove(const gfx::Rect& pos) { - // Note that we ignore the position. - view_->SetSize(pos.size()); -} - -void RenderWidgetHost::OnMsgPaintRect( - const ViewHostMsg_PaintRect_Params& params) { - TimeTicks paint_start = TimeTicks::Now(); - - // Update our knowledge of the RenderWidget's size. - current_size_ = params.view_size; - - bool is_resize_ack = - ViewHostMsg_PaintRect_Flags::is_resize_ack(params.flags); - - // resize_ack_pending_ needs to be cleared before we call DidPaintRect, since - // that will end up reaching GetBackingStore. - if (is_resize_ack) { - DCHECK(resize_ack_pending_); - resize_ack_pending_ = false; - } - - bool is_repaint_ack = - ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags); - if (is_repaint_ack) { - repaint_ack_pending_ = false; - TimeDelta delta = TimeTicks::Now() - repaint_start_time_; - UMA_HISTOGRAM_TIMES(L"MPArch.RWH_RepaintDelta", delta); - } - - DCHECK(params.bitmap); - DCHECK(!params.bitmap_rect.IsEmpty()); - DCHECK(!params.view_size.IsEmpty()); - - PaintRect(params.bitmap, params.bitmap_rect, params.view_size); - - // ACK early so we can prefetch the next PaintRect if there is a next one. - Send(new ViewMsg_PaintRect_ACK(routing_id_)); - - // TODO(darin): This should really be done by the view_! - MovePluginWindows(params.plugin_window_moves); - - // The view might be destroyed already. Check for this case. - if (view_ && !suppress_view_updating_) { - view_being_painted_ = true; - view_->DidPaintRect(params.bitmap_rect); - view_being_painted_ = false; - } - - if (paint_observer_.get()) - paint_observer_->RenderWidgetHostDidPaint(this); - - // If we got a resize ack, then perhaps we have another resize to send? - if (is_resize_ack && view_) { - gfx::Rect view_bounds = view_->GetViewBounds(); - if (current_size_.width() != view_bounds.width() || - current_size_.height() != view_bounds.height()) { - WasResized(); - } - } - - // Log the time delta for processing a paint message. - TimeDelta delta = TimeTicks::Now() - paint_start; - UMA_HISTOGRAM_TIMES(L"MPArch.RWH_OnMsgPaintRect", delta); -} - -void RenderWidgetHost::OnMsgScrollRect( - const ViewHostMsg_ScrollRect_Params& params) { - TimeTicks scroll_start = TimeTicks::Now(); - - DCHECK(!params.view_size.IsEmpty()); - - ScrollRect(params.bitmap, params.bitmap_rect, params.dx, params.dy, - params.clip_rect, params.view_size); - - // ACK early so we can prefetch the next ScrollRect if there is a next one. - Send(new ViewMsg_ScrollRect_ACK(routing_id_)); - - // TODO(darin): This should really be done by the view_! - MovePluginWindows(params.plugin_window_moves); - - // The view might be destroyed already. Check for this case - if (view_) { - view_being_painted_ = true; - view_->DidScrollRect(params.clip_rect, params.dx, params.dy); - view_being_painted_ = false; - } - - // Log the time delta for processing a scroll message. - TimeDelta delta = TimeTicks::Now() - scroll_start; - UMA_HISTOGRAM_TIMES(L"MPArch.RWH_OnMsgScrollRect", delta); -} - -void RenderWidgetHost::MovePluginWindows( - const std::vector& plugin_window_moves) { - if (plugin_window_moves.empty()) - return; - - HDWP defer_window_pos_info = - ::BeginDeferWindowPos(static_cast(plugin_window_moves.size())); - - if (!defer_window_pos_info) { - NOTREACHED(); - return; - } - - for (size_t i = 0; i < plugin_window_moves.size(); ++i) { - unsigned long flags = 0; - const WebPluginGeometry& move = plugin_window_moves[i]; - - if (move.visible) - flags |= SWP_SHOWWINDOW; - else - flags |= SWP_HIDEWINDOW; - - HRGN hrgn = ::CreateRectRgn(move.clip_rect.x(), - move.clip_rect.y(), - move.clip_rect.right(), - move.clip_rect.bottom()); - gfx::SubtractRectanglesFromRegion(hrgn, move.cutout_rects); - - // Note: System will own the hrgn after we call SetWindowRgn, - // so we don't need to call DeleteObject(hrgn) - ::SetWindowRgn(move.window, hrgn, !move.clip_rect.IsEmpty()); - - defer_window_pos_info = ::DeferWindowPos(defer_window_pos_info, - move.window, NULL, - move.window_rect.x(), - move.window_rect.y(), - move.window_rect.width(), - move.window_rect.height(), flags); - if (!defer_window_pos_info) { - return; - } - } - - ::EndDeferWindowPos(defer_window_pos_info); -} - -void RenderWidgetHost::OnMsgInputEventAck(const IPC::Message& message) { - // Log the time delta for processing an input event. - TimeDelta delta = TimeTicks::Now() - input_event_start_time_; - UMA_HISTOGRAM_TIMES(L"MPArch.RWH_InputEventDelta", delta); - - // Cancel pending hung renderer checks since the renderer is responsive. - StopHangMonitorTimeout(); - - void* iter = NULL; - int type = 0; - bool r = message.ReadInt(&iter, &type); - DCHECK(r); - - if (type == WebInputEvent::MOUSE_MOVE) { - mouse_move_pending_ = false; - - // now, we can send the next mouse move event - if (next_mouse_move_.get()) { - DCHECK(next_mouse_move_->type == WebInputEvent::MOUSE_MOVE); - ForwardMouseEvent(*next_mouse_move_); - } - } - - const char* data = NULL; - int length = 0; - if (message.ReadData(&iter, &data, &length)) { - const WebInputEvent* input_event = - reinterpret_cast(data); - UnhandledInputEvent(*input_event); - } -} - -void RenderWidgetHost::OnMsgFocus() { - // Only the user can focus a RenderWidgetHost. - NOTREACHED(); -} - -void RenderWidgetHost::OnMsgBlur() { - if (view_) { - view_->Blur(); - } -} - -void RenderWidgetHost::OnMsgSetCursor(const WebCursor& cursor) { - if (!view_) { - return; - } - view_->UpdateCursor(cursor); -} - -void RenderWidgetHost::OnMsgImeUpdateStatus(ViewHostMsg_ImeControl control, - const gfx::Rect& caret_rect) { - if (view_) { - view_->IMEUpdateStatus(control, caret_rect); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -void RenderWidgetHost::WasHidden() { - is_hidden_ = true; - - // Don't bother reporting hung state when we aren't the active tab. - StopHangMonitorTimeout(); - - // If we have a renderer, then inform it that we are being hidden so it can - // reduce its resource utilization. - Send(new ViewMsg_WasHidden(routing_id_)); - - // TODO(darin): what about constrained windows? it doesn't look like they - // see a message when their parent is hidden. maybe there is something more - // generic we can do at the TabContents API level instead of relying on - // Windows messages. - - // Tell the RenderProcessHost we were hidden. - process_->WidgetHidden(); -} - -void RenderWidgetHost::WasRestored() { - // When we create the widget, it is created as *not* hidden. - if (!is_hidden_) - return; - is_hidden_ = false; - - BackingStore* backing_store = BackingStoreManager::Lookup(this); - // If we already have a backing store for this widget, then we don't need to - // repaint on restore _unless_ we know that our backing store is invalid. - bool needs_repainting; - if (needs_repainting_on_restore_ || !backing_store) { - needs_repainting = true; - needs_repainting_on_restore_ = false; - } else { - needs_repainting = false; - } - Send(new ViewMsg_WasRestored(routing_id_, needs_repainting)); - - process_->WidgetRestored(); -} - -void RenderWidgetHost::WasResized() { - if (resize_ack_pending_ || !process_->channel() || !view_) - return; - - gfx::Rect view_bounds = view_->GetViewBounds(); - gfx::Size new_size(view_bounds.width(), view_bounds.height()); - - // Avoid asking the RenderWidget to resize to its current size, since it - // won't send us a PaintRect message in that case. - if (new_size == current_size_) - return; - - // We don't expect to receive an ACK when the requested size is empty. - if (!new_size.IsEmpty()) - resize_ack_pending_ = true; - - if (!Send(new ViewMsg_Resize(routing_id_, new_size))) - resize_ack_pending_ = false; -} - -void RenderWidgetHost::ForwardMouseEvent(const WebMouseEvent& mouse_event) { - // Avoid spamming the renderer with mouse move events. It is important - // to note that WM_MOUSEMOVE events are anyways synthetic, but since our - // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way - // more WM_MOUSEMOVE events than we wish to send to the renderer. - if (mouse_event.type == WebInputEvent::MOUSE_MOVE) { - if (mouse_move_pending_) { - next_mouse_move_.reset(new WebMouseEvent(mouse_event)); - return; - } - mouse_move_pending_ = true; - } - - ForwardInputEvent(mouse_event, sizeof(WebMouseEvent)); -} - -void RenderWidgetHost::ForwardKeyboardEvent( - const WebKeyboardEvent& key_event) { - ForwardInputEvent(key_event, sizeof(WebKeyboardEvent)); -} - -void RenderWidgetHost::ForwardWheelEvent( - const WebMouseWheelEvent& wheel_event) { - ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent)); -} - -void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event, - int event_size) { - if (!process_->channel()) - return; - - IPC::Message* message = new ViewMsg_HandleInputEvent(routing_id_); - message->WriteData( - reinterpret_cast(&input_event), event_size); - input_event_start_time_ = TimeTicks::Now(); - Send(message); - - // any input event cancels a pending mouse move event - next_mouse_move_.reset(); - - StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs)); -} - -void RenderWidgetHost::Shutdown() { - if (process_->channel()) { - // Tell the renderer object to close. - process_->ReportExpectingClose(routing_id_); - bool rv = Send(new ViewMsg_Close(routing_id_)); - DCHECK(rv); - } - - Destroy(); -} - -void RenderWidgetHost::Focus() { - Send(new ViewMsg_SetFocus(routing_id_, true)); -} - -void RenderWidgetHost::Blur() { - Send(new ViewMsg_SetFocus(routing_id_, false)); -} - -void RenderWidgetHost::LostCapture() { - Send(new ViewMsg_MouseCaptureLost(routing_id_)); -} - -void RenderWidgetHost::ViewDestroyed() { - // TODO(evanm): tracking this may no longer be necessary; - // eliminate this function if so. - view_ = NULL; -} - -void RenderWidgetHost::Destroy() { - NotificationService::current()->Notify( - NOTIFY_RENDER_WIDGET_HOST_DESTROYED, - Source(this), - NotificationService::NoDetails()); - - // Tell the view to die. - // Note that in the process of the view shutting down, it can call a ton - // of other messages on us. So if you do any other deinitialization here, - // do it after this call to view_->Destroy(). - if (view_) - view_->Destroy(); - - delete this; -} - -void RenderWidgetHost::CheckRendererIsUnresponsive() { - // If we received a call to StopHangMonitorTimeout. - if (time_when_considered_hung_.is_null()) - return; - - // If we have not waited long enough, then wait some more. - Time now = Time::Now(); - if (now < time_when_considered_hung_) { - StartHangMonitorTimeout(time_when_considered_hung_ - now); - return; - } - - // OK, looks like we have a hung renderer! - NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_HANG, - Source(this), - NotificationService::NoDetails()); - is_unresponsive_ = true; - NotifyRendererUnresponsive(); -} - -void RenderWidgetHost::RendererIsResponsive() { - if (is_unresponsive_) { - is_unresponsive_ = false; - NotifyRendererResponsive(); - } -} - -bool RenderWidgetHost::Send(IPC::Message* msg) { - return process_->Send(msg); -} - -void RenderWidgetHost::SetIsLoading(bool is_loading) { - is_loading_ = is_loading; - if (!view_) - return; - view_->SetIsLoading(is_loading); -} - -RenderWidgetHost::BackingStore* RenderWidgetHost::GetBackingStore() { - // We should not be asked to paint while we are hidden. If we are hidden, - // then it means that our consumer failed to call WasRestored. - DCHECK(!is_hidden_) << "GetBackingStore called while hidden!"; - - // We might have a cached backing store that we can reuse! - BackingStore* backing_store = - BackingStoreManager::GetBackingStore(this, current_size_); - // If we fail to find a backing store in the cache, send out a request - // to the renderer to paint the view if required. - if (!backing_store && !repaint_ack_pending_ && !resize_ack_pending_ && - !view_being_painted_) { - repaint_start_time_ = TimeTicks::Now(); - repaint_ack_pending_ = true; - Send(new ViewMsg_Repaint(routing_id_, current_size_)); - } - - // When we have asked the RenderWidget to resize, and we are still waiting on - // a response, block for a little while to see if we can't get a response - // before returning the old (incorrectly sized) backing store. - if (resize_ack_pending_ || !backing_store) { - IPC::Message msg; - TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS); - if (process_->WaitForPaintMsg(routing_id_, max_delay, &msg)) { - suppress_view_updating_ = true; - ViewHostMsg_PaintRect::Dispatch( - &msg, this, &RenderWidgetHost::OnMsgPaintRect); - suppress_view_updating_ = false; - backing_store = BackingStoreManager::GetBackingStore(this, current_size_); - } - } - - return backing_store; -} - -void RenderWidgetHost::PaintRect(HANDLE bitmap, const gfx::Rect& bitmap_rect, - const gfx::Size& view_size) { - if (is_hidden_) { - needs_repainting_on_restore_ = true; - return; - } - - // We use the view size according to the render view, which may not be - // quite the same as the size of our window. - gfx::Rect view_rect(0, 0, view_size.width(), view_size.height()); - - bool needs_full_paint = false; - BackingStore* backing_store = - BackingStoreManager::PrepareBackingStore(this, view_rect, - process_->process().handle(), - bitmap, bitmap_rect, - &needs_full_paint); - DCHECK(backing_store != NULL); - if (needs_full_paint) { - repaint_start_time_ = TimeTicks::Now(); - repaint_ack_pending_ = true; - Send(new ViewMsg_Repaint(routing_id_, view_size)); - } -} - -void RenderWidgetHost::ScrollRect(HANDLE bitmap, const gfx::Rect& bitmap_rect, - int dx, int dy, const gfx::Rect& clip_rect, - const gfx::Size& view_size) { - if (is_hidden_) { - needs_repainting_on_restore_ = true; - return; - } - - // TODO(darin): do we need to do something else if our backing store is not - // the same size as the advertised view? maybe we just assume there is a - // full paint on its way? - BackingStore* backing_store = BackingStoreManager::Lookup(this); - if (!backing_store || (backing_store->size() != view_size)) - return; - - RECT damaged_rect, r = clip_rect.ToRECT(); - ScrollDC(backing_store->dc(), dx, dy, NULL, &r, NULL, &damaged_rect); - - // TODO(darin): this doesn't work if dx and dy are both non-zero! - DCHECK(dx == 0 || dy == 0); - - // We expect that damaged_rect should equal bitmap_rect. - DCHECK(gfx::Rect(damaged_rect) == bitmap_rect); - - backing_store->Refresh(process_->process().handle(), bitmap, bitmap_rect); -} - -void RenderWidgetHost::RestartHangMonitorTimeout() { - StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs)); -} - -void RenderWidgetHost::StopHangMonitorTimeout() { - time_when_considered_hung_ = Time(); - RendererIsResponsive(); - - // We do not bother to stop the hung_renderer_timer_ here in case it will be - // started again shortly, which happens to be the common use case. -} - -void RenderWidgetHost::StartHangMonitorTimeout(TimeDelta delay) { - time_when_considered_hung_ = Time::Now() + delay; - - // If we already have a timer that will expire at or before the given delay, - // then we have nothing more to do now. - if (hung_renderer_timer_.IsRunning() && - hung_renderer_timer_.GetCurrentDelay() <= delay) - return; - - // Either the timer is not yet running, or we need to adjust the timer to - // fire sooner. - hung_renderer_timer_.Stop(); - hung_renderer_timer_.Start(delay, this, - &RenderWidgetHost::CheckRendererIsUnresponsive); -} - -void RenderWidgetHost::RendererExited() { - BackingStoreManager::RemoveBackingStore(this); -} - -void RenderWidgetHost::SystemThemeChanged() { - Send(new ViewMsg_ThemeChanged(routing_id_)); -} diff --git a/chrome/browser/render_widget_host.h b/chrome/browser/render_widget_host.h deleted file mode 100644 index dbaccd5c..0000000 --- a/chrome/browser/render_widget_host.h +++ /dev/null @@ -1,369 +0,0 @@ -// Copyright (c) 2006-2008 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_RENDER_WIDGET_HOST_H_ -#define CHROME_BROWSER_RENDER_WIDGET_HOST_H_ - -#include - -#include - -#include "base/gfx/size.h" -#include "base/timer.h" -#include "chrome/common/ipc_channel.h" - -namespace gfx { -class Rect; -} - -class BackingStore; -class PaintObserver; -class RenderProcessHost; -class RenderWidgetHostView; -class WebInputEvent; -class WebKeyboardEvent; -class WebMouseEvent; -class WebMouseWheelEvent; -class WebCursor; -enum ViewHostMsg_ImeControl; -struct ViewHostMsg_PaintRect_Params; -struct ViewHostMsg_ScrollRect_Params; -struct WebPluginGeometry; - -// This class manages the browser side of a browser<->renderer HWND connection. -// The HWND lives in the browser process, and windows events are sent over -// IPC to the corresponding object in the renderer. The renderer paints into -// shared memory, which we transfer to a backing store and blit to the screen -// when Windows sends us a WM_PAINT message. -// -// How Shutdown Works -// -// There are two situations in which this object, a RenderWidgetHost, can be -// instantiated: -// -// 1. By a WebContents as the communication conduit for a rendered web page. -// The WebContents instantiates a derived class: RenderViewHost. -// 2. By a WebContents as the communication conduit for a select widget. The -// WebContents instantiates the RenderWidgetHost directly. -// -// For every WebContents there are several objects in play that need to be -// properly destroyed or cleaned up when certain events occur. -// -// - WebContents - the TabContents itself, and its associated HWND. -// - RenderViewHost - representing the communication conduit with the child -// process. -// - RenderWidgetHostView - the view of the web page content, message handler, -// and plugin root. -// -// Normally, the WebContents contains a child RenderWidgetHostView that renders -// the contents of the loaded page. It has a WS_CLIPCHILDREN style so that it -// does no painting of its own. -// -// The lifetime of the RenderWidgetHostView is tied to the render process. If -// the render process dies, the RenderWidgetHostView goes away and all -// references to it must become NULL. If the WebContents finds itself without a -// RenderWidgetHostView, it paints Sad Tab instead. -// -// RenderViewHost (a RenderWidgetHost subclass) is the conduit used to -// communicate with the RenderView and is owned by the WebContents. If the -// render process crashes, the RenderViewHost remains and restarts the render -// process if needed to continue navigation. -// -// The WebContents is itself owned by the NavigationController in which it -// resides. -// -// Some examples of how shutdown works: -// -// When a tab is closed (either by the user, the web page calling window.close, -// etc) the TabStrip destroys the associated NavigationController, which calls -// Destroy on each TabContents it owns. -// -// For a WebContents, its Destroy method tells the RenderViewHost to -// shut down the render process and die. -// -// When the render process is destroyed it destroys the View: the -// RenderWidgetHostView, which destroys its HWND and deletes that object. -// -// For select popups, the situation is a little different. The RenderWidgetHost -// associated with the select popup owns the view and itself (is responsible -// for destroying itself when the view is closed). The WebContents's only -// responsibility is to select popups is to create them when it is told to. When -// the View is destroyed via an IPC message (for when WebCore destroys the -// popup, e.g. if the user selects one of the options), or because -// WM_CANCELMODE is received by the view, the View schedules the destruction of -// the render process. However in this case since there's no WebContents -// container, when the render process is destroyed, the RenderWidgetHost just -// deletes itself, which is safe because no one else should have any references -// to it (the WebContents does not). -// -// It should be noted that the RenderViewHost, not the RenderWidgetHost, -// handles IPC messages relating to the render process going away, since the -// way a RenderViewHost (WebContents) handles the process dying is different to -// the way a select popup does. As such the RenderWidgetHostView handles these -// messages for select popups. This placement is more out of convenience than -// anything else. When the view is live, these messages are forwarded to it by -// the RenderWidgetHost's IPC message map. -// -class RenderWidgetHost : public IPC::Channel::Listener { - public: - // routing_id can be MSG_ROUTING_NONE, in which case the next available - // routing id is taken from the RenderProcessHost. - RenderWidgetHost(RenderProcessHost* process, int routing_id); - virtual ~RenderWidgetHost(); - - // Gets/Sets the View of this RenderWidgetHost. Can be NULL, e.g. if the - // RenderWidget is being destroyed or the render process crashed. You should - // never cache this pointer since it can become NULL if the renderer crashes, - // instead you should always ask for it using the accessor. - void set_view(RenderWidgetHostView* view) { view_ = view; } - RenderWidgetHostView* view() const { return view_; } - - RenderProcessHost* process() const { return process_; } - int routing_id() const { return routing_id_; } - - // Manual RTTI FTW. We are not hosting a web page. - virtual bool IsRenderView() { return false; } - - // Called when a renderer object already been created for this host, and we - // just need to be attached to it. Used for window.open, dropdown + // menus, and other times when the renderer initiates creating an object. + virtual void Init(); + + // IPC::Channel::Listener + virtual void OnMessageReceived(const IPC::Message& msg); + + // Sends a message to the corresponding object in the renderer. + bool Send(IPC::Message* msg); + + // Called to notify the RenderWidget that it has been hidden or restored from + // having been hidden. + void WasHidden(); + void WasRestored(); + + // Called to notify the RenderWidget that it has been resized. + void WasResized(); + + // Tells the renderer to die and then calls Destroy(). + virtual void Shutdown(); + + void Focus(); + void Blur(); + void LostCapture(); + + // Notifies the RenderWidgetHost that the View was destroyed. + void ViewDestroyed(); + + // Indicates if the page has finished loading. + virtual void SetIsLoading(bool is_loading); + + // Represents a device-dependent drawing surface used to hold the rendering + // of a RenderWidgetHost. + class BackingStore; + + // Manages a set of backing stores. + class BackingStoreManager; + + // Get access to the widget's backing store. If a resize is in progress, + // then the current size of the backing store may be less than the size of + // the widget's view. This method returns NULL if the backing store could + // not be created. + BackingStore* GetBackingStore(); + + // An interface that gets called when paints happen. + // Used in performance tests. + class PaintObserver; + // Set the PaintObserver on this object. Takes ownership. + void SetPaintObserver(PaintObserver* paint_observer) { + paint_observer_.reset(paint_observer); + } + + // Checks to see if we can give up focus to this widget through a + // javascript call. + virtual bool CanBlur() const { return true; } + + // Restart the active hang monitor timeout. Clears all existing timeouts and + // starts with a new one. This can be because the renderer has become + // active, the tab is being hidden, or the user has chosen to wait some more + // to give the tab a chance to become active and we don't want to display a + // warning too soon. + void RestartHangMonitorTimeout(); + + // Stops all existing hang monitor timeouts and assumes the renderer is + // responsive. + void StopHangMonitorTimeout(); + + // Starts a hang monitor timeout. If there's already a hang monitor timeout + // the new one will only fire if it has a shorter delay than the time + // left on the existing timeouts. + void StartHangMonitorTimeout(base::TimeDelta delay); + + // Called when we receive a notification indicating that the renderer + // process has gone. + void RendererExited(); + + // Called when the system theme changes. At this time all existing native + // theme handles are invalid and the renderer must obtain new ones and + // repaint. + void SystemThemeChanged(); + + protected: + // Called when we an InputEvent was not processed by the renderer. + virtual void UnhandledInputEvent(const WebInputEvent& event) { } + + // IPC message handlers + void OnMsgRendererReady(); + void OnMsgRendererGone(); + void OnMsgClose(); + void OnMsgRequestMove(const gfx::Rect& pos); + void OnMsgResizeAck(); + void OnMsgPaintRect(const ViewHostMsg_PaintRect_Params& params); + void OnMsgScrollRect(const ViewHostMsg_ScrollRect_Params& params); + void OnMsgInputEventAck(const IPC::Message& message); + void OnMsgFocus(); + void OnMsgBlur(); + void OnMsgSetCursor(const WebCursor& cursor); + void OnMsgImeUpdateStatus(ViewHostMsg_ImeControl control, + const gfx::Rect& caret_rect); + + void MovePluginWindows( + const std::vector& plugin_window_moves); + + // TODO(beng): (Cleanup) remove this friendship once we expose a clean API to + // RenderWidgetHost Views. This exists only to give RenderWidgetHostView + // access to Forward*Event. + friend class RenderWidgetHostViewWin; + + void ForwardMouseEvent(const WebMouseEvent& mouse_event); + virtual void ForwardKeyboardEvent(const WebKeyboardEvent& key_event); + void ForwardWheelEvent(const WebMouseWheelEvent& wheel_event); + void ForwardInputEvent(const WebInputEvent& input_event, int event_size); + + // Called to paint a region of the backing store + void PaintRect(HANDLE bitmap, const gfx::Rect& bitmap_rect, + const gfx::Size& view_size); + + // Called to scroll a region of the backing store + void ScrollRect(HANDLE bitmap, const gfx::Rect& bitmap_rect, int dx, int dy, + const gfx::Rect& clip_rect, const gfx::Size& view_size); + + // Tell this object to destroy itself. + void Destroy(); + + // Callbacks for notification when the renderer becomes unresponsive to user + // input events, and subsequently responsive again. The delegate can use + // these notifications to show a warning. + void CheckRendererIsUnresponsive(); + virtual void NotifyRendererUnresponsive() {} + void RendererIsResponsive(); + virtual void NotifyRendererResponsive() {} + + // Created during construction but initialized during Init*(). Therefore, it + // is guaranteed never to be NULL, but its channel may be NULL if the + // renderer crashed, so you must always check that. + RenderProcessHost* process_; + + // The ID of the corresponding object in the Renderer Instance. + int routing_id_; + + bool resize_ack_pending_; // True when waiting for RESIZE_ACK. + gfx::Size current_size_; // The current size of the RenderWidget. + + // True if a mouse move event was sent to the render view and we are waiting + // for a corresponding ViewHostMsg_HandleInputEvent_ACK message. + bool mouse_move_pending_; + + // The next mouse move event to send (only non-null while mouse_move_pending_ + // is true). + scoped_ptr next_mouse_move_; + + // The View associated with the RenderViewHost. The lifetime of this object + // is associated with the lifetime of the Render process. If the Renderer + // crashes, its View is destroyed and this pointer becomes NULL, even though + // render_view_host_ lives on to load another URL (creating a new View while + // doing so). + RenderWidgetHostView* view_; + + // The time when an input event was sent to the RenderWidget. + base::TimeTicks input_event_start_time_; + + // Indicates whether a page is loading or not. + bool is_loading_; + // Indicates whether a page is hidden or not. + bool is_hidden_; + // If true, then we should not ask our view to repaint when our backingstore + // is updated. + bool suppress_view_updating_; + + // If true, then we should repaint when restoring even if we have a + // backingstore. This flag is set to true if we receive a paint message + // while is_hidden_ to true. Even though we tell the render widget to hide + // itself, a paint message could already be in flight at that point. + bool needs_repainting_on_restore_; + + // The following value indicates a time in the future when we would consider + // the renderer hung if it does not generate an appropriate response message. + base::Time time_when_considered_hung_; + + // This timer runs to check if time_when_considered_hung_ has past. + base::OneShotTimer hung_renderer_timer_; + + // This is true if the renderer is currently unresponsive. + bool is_unresponsive_; + + // Optional observer that listens for notifications of painting. + scoped_ptr paint_observer_; + + // Set when we call DidPaintRect/DidScrollRect on the view. + bool view_being_painted_; + + // Set if we are waiting for a repaint ack for the view. + bool repaint_ack_pending_; + + // Used for UMA histogram logging to measure the time for a repaint view + // operation to finish. + base::TimeTicks repaint_start_time_; + + DISALLOW_EVIL_CONSTRUCTORS(RenderWidgetHost); +}; + +class RenderWidgetHost::BackingStore { + public: + BackingStore(const gfx::Size& size); + ~BackingStore(); + + HDC dc() { return hdc_; } + const gfx::Size& size() { return size_; } + + // Paints the bitmap from the renderer onto the backing store. + bool Refresh(HANDLE process, HANDLE bitmap_section, + const gfx::Rect& bitmap_rect); + + private: + // Creates a dib conforming to the height/width/section parameters passed + // in. The use_os_color_depth parameter controls whether we use the color + // depth to create an appropriate dib or not. + HANDLE CreateDIB(HDC dc, int width, int height, bool use_os_color_depth, + HANDLE section); + + // The backing store dc. + HDC hdc_; + // The size of the backing store. + gfx::Size size_; + // Handle to the backing store dib. + HANDLE backing_store_dib_; + // Handle to the original bitmap in the dc. + HANDLE original_bitmap_; + + DISALLOW_COPY_AND_ASSIGN(BackingStore); +}; + +class RenderWidgetHost::PaintObserver { + public: + virtual ~PaintObserver() {} + + // Called each time the RenderWidgetHost paints. + virtual void RenderWidgetHostDidPaint(RenderWidgetHost* rwh) = 0; +}; + +#endif // #ifndef CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_H_ diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h new file mode 100644 index 0000000..8e6152f --- /dev/null +++ b/chrome/browser/renderer_host/render_widget_host_view.h @@ -0,0 +1,121 @@ +// Copyright (c) 2006-2008 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_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_H_ +#define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_H_ + +#include + +#include "base/shared_memory.h" +#include "chrome/common/render_messages.h" + +namespace gfx { +class Rect; +class Size; +} +namespace IPC { +class Message; +} + +class RenderProcessHost; +class RenderWidgetHost; +class WebCursor; + +/////////////////////////////////////////////////////////////////////////////// +// +// RenderWidgetHostView +// +// RenderWidgetHostView is an interface implemented by an object that acts as +// the "View" portion of a RenderWidgetHost. The RenderWidgetHost and its +// associated RenderProcessHost own the "Model" in this case which is the +// child renderer process. The View is responsible for receiving events from +// the surrounding environment and passing them to the RenderWidgetHost, and +// for actually displaying the content of the RenderWidgetHost when it +// changes. +// +/////////////////////////////////////////////////////////////////////////////// +class RenderWidgetHostView { + public: + // Platform-specific creator. Use this to construct new RenderWidgetHostViews + // rather than using RenderWidgetHostViewWin & friends. + // + // The RenderWidgetHost must already be created (because we can't know if it's + // going to be a regular RenderWidgetHost or a RenderViewHost (a subclass). + static RenderWidgetHostView* CreateViewForWidget(RenderWidgetHost* widget); + + // Returns the associated RenderWidgetHost. + virtual RenderWidgetHost* GetRenderWidgetHost() const = 0; + + // Notifies the View that it has become visible. + virtual void DidBecomeSelected() = 0; + + // Notifies the View that it has been hidden. + virtual void WasHidden() = 0; + + // Tells the View to size itself to the specified size. + virtual void SetSize(const gfx::Size& size) = 0; + + // Retrieves the HWND used to contain plugin HWNDs. + virtual HWND GetPluginHWND() = 0; + + // Sends the specified mouse event to the renderer. + virtual void ForwardMouseEventToRenderer(UINT message, + WPARAM wparam, + LPARAM lparam) = 0; + + // Actually set/take focus to/from the associated View component. + virtual void Focus() = 0; + virtual void Blur() = 0; + + // Returns true if the View currently has the focus. + virtual bool HasFocus() = 0; + + // Shows/hides the view. + virtual void Show() = 0; + virtual void Hide() = 0; + + // Retrieve the bounds of the View, in screen coordinates. + virtual gfx::Rect GetViewBounds() const = 0; + + // Sets the cursor to the one associated with the specified cursor_type + virtual void UpdateCursor(const WebCursor& cursor) = 0; + + // Updates the displayed cursor to the current one. + virtual void UpdateCursorIfOverSelf() = 0; + + // Indicates whether the page has finished loading. + virtual void SetIsLoading(bool is_loading) = 0; + + // Enable or disable IME for the view. + virtual void IMEUpdateStatus(ViewHostMsg_ImeControl control, + const gfx::Rect& caret_rect) = 0; + + // Informs the view that a portion of the widget's backing store was painted. + virtual void DidPaintRect(const gfx::Rect& rect) = 0; + + // Informs the view that a portion of the widget's backing store was scrolled + // by dx pixels horizontally and dy pixels vertically. + virtual void DidScrollRect( + const gfx::Rect& rect, int dx, int dy) = 0; + + // Notifies the View that the renderer has ceased to exist. + virtual void RendererGone() = 0; + + // Tells the View to destroy itself. + virtual void Destroy() = 0; + + // Tells the View that the tooltip text for the current mouse position over + // the page has changed. + virtual void SetTooltipText(const std::wstring& tooltip_text) = 0; + + protected: + // Interface class only, do not construct. + RenderWidgetHostView() {} + + private: + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostView); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_H_ + diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc new file mode 100644 index 0000000..f628809 --- /dev/null +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -0,0 +1,925 @@ +// Copyright (c) 2006-2008 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/renderer_host/render_widget_host_view_win.h" + +#include "base/command_line.h" +#include "base/gfx/gdi_util.h" +#include "base/gfx/rect.h" +#include "base/histogram.h" +#include "base/win_util.h" +#include "chrome/browser/browser_accessibility.h" +#include "chrome/browser/browser_accessibility_manager.h" +#include "chrome/browser/browser_trial.h" +#include "chrome/browser/renderer_host/render_process_host.h" +// TODO(beng): (Cleanup) we should not need to include this file... see comment +// in |DidBecomeSelected|. +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_widget_host.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/l10n_util.h" +#include "chrome/common/plugin_messages.h" +#include "chrome/common/win_util.h" +// Included for views::kReflectedMessage - TODO(beng): move this to win_util.h! +#include "chrome/views/widget_win.h" +#include "webkit/glue/plugins/plugin_constants_win.h" +#include "webkit/glue/plugins/webplugin_delegate_impl.h" +#include "webkit/glue/webcursor.h" + +using base::TimeDelta; +using base::TimeTicks; + +namespace { + +// Tooltips will wrap after this width. Yes, wrap. Imagine that! +const int kTooltipMaxWidthPixels = 300; + +// Maximum number of characters we allow in a tooltip. +const int kMaxTooltipLength = 1024; + +// A callback function for EnumThreadWindows to enumerate and dismiss +// any owned popop windows +BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { + const HWND toplevel_hwnd = reinterpret_cast(arg); + + if (::IsWindowVisible(window)) { + const HWND owner = ::GetWindow(window, GW_OWNER); + if (toplevel_hwnd == owner) { + ::PostMessage(window, WM_CANCELMODE, 0, 0); + } + } + + return TRUE; +} + +} // namespace + +// RenderWidgetHostView -------------------------------------------------------- + +// static +RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( + RenderWidgetHost* widget) { + return new RenderWidgetHostViewWin(widget); +} + +/////////////////////////////////////////////////////////////////////////////// +// RenderWidgetHostViewWin, public: + +RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) + : render_widget_host_(widget), + track_mouse_leave_(false), + ime_notification_(false), + is_hidden_(false), + close_on_deactivate_(false), + tooltip_hwnd_(NULL), + tooltip_showing_(false), + shutdown_factory_(this), + parent_hwnd_(NULL), + is_loading_(false), + activatable_(true) { + render_widget_host_->set_view(this); + renderer_accessible_ = + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableRendererAccessibility); +} + +RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { + ResetTooltip(); +} + +/////////////////////////////////////////////////////////////////////////////// +// RenderWidgetHostViewWin, RenderWidgetHostView implementation: + +RenderWidgetHost* RenderWidgetHostViewWin::GetRenderWidgetHost() const { + return render_widget_host_; +} + +void RenderWidgetHostViewWin::DidBecomeSelected() { + if (!is_hidden_) + return; + + is_hidden_ = false; + EnsureTooltip(); + render_widget_host_->WasRestored(); +} + +void RenderWidgetHostViewWin::WasHidden() { + if (is_hidden_) + return; + + // If we receive any more paint messages while we are hidden, we want to + // ignore them so we don't re-allocate the backing store. We will paint + // everything again when we become selected again. + is_hidden_ = true; + + ResetTooltip(); + + // If we have a renderer, then inform it that we are being hidden so it can + // reduce its resource utilization. + render_widget_host_->WasHidden(); + + // TODO(darin): what about constrained windows? it doesn't look like they + // see a message when their parent is hidden. maybe there is something more + // generic we can do at the TabContents API level instead of relying on + // Windows messages. +} + +void RenderWidgetHostViewWin::SetSize(const gfx::Size& size) { + if (is_hidden_) + return; + + // No SWP_NOREDRAW as autofill popups can resize and the underneath window + // should redraw in that case. + UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS | + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE; + SetWindowPos(NULL, 0, 0, size.width(), size.height(), swp_flags); + render_widget_host_->WasResized(); + EnsureTooltip(); +} + +HWND RenderWidgetHostViewWin::GetPluginHWND() { + return m_hWnd; +} + +void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, + WPARAM wparam, + LPARAM lparam) { + WebMouseEvent event(m_hWnd, message, wparam, lparam); + switch (event.type) { + case WebInputEvent::MOUSE_MOVE: + TrackMouseLeave(true); + break; + case WebInputEvent::MOUSE_LEAVE: + TrackMouseLeave(false); + break; + case WebInputEvent::MOUSE_DOWN: + SetCapture(); + break; + case WebInputEvent::MOUSE_UP: + if (GetCapture() == m_hWnd) + ReleaseCapture(); + break; + } + + render_widget_host_->ForwardMouseEvent(event); + + if (activatable_ && event.type == WebInputEvent::MOUSE_DOWN) { + // This is a temporary workaround for bug 765011 to get focus when the + // mouse is clicked. This happens after the mouse down event is sent to + // the renderer because normally Windows does a WM_SETFOCUS after + // WM_LBUTTONDOWN. + SetFocus(); + } +} + +void RenderWidgetHostViewWin::Focus() { + if (IsWindow()) + SetFocus(); +} + +void RenderWidgetHostViewWin::Blur() { + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManager(GetParent()); + // We don't have a FocusManager if we are hidden. + if (focus_manager && render_widget_host_->CanBlur()) + focus_manager->ClearFocus(); +} + +bool RenderWidgetHostViewWin::HasFocus() { + return ::GetFocus() == m_hWnd; +} + +void RenderWidgetHostViewWin::Show() { + DCHECK(parent_hwnd_); + SetParent(parent_hwnd_); + ShowWindow(SW_SHOW); + + DidBecomeSelected(); +} + +void RenderWidgetHostViewWin::Hide() { + if (::GetFocus() == m_hWnd) + ::SetFocus(NULL); + ShowWindow(SW_HIDE); + parent_hwnd_ = GetParent(); + // Orphan the window so we stop receiving messages. + SetParent(NULL); + + WasHidden(); +} + +gfx::Rect RenderWidgetHostViewWin::GetViewBounds() const { + CRect window_rect; + GetWindowRect(&window_rect); + return gfx::Rect(window_rect); +} + +void RenderWidgetHostViewWin::UpdateCursor(const WebCursor& cursor) { + current_cursor_ = cursor; + UpdateCursorIfOverSelf(); +} + +void RenderWidgetHostViewWin::UpdateCursorIfOverSelf() { + static HCURSOR kCursorArrow = LoadCursor(NULL, IDC_ARROW); + static HCURSOR kCursorAppStarting = LoadCursor(NULL, IDC_APPSTARTING); + static HINSTANCE module_handle = + GetModuleHandle(chrome::kBrowserResourcesDll); + + // We cannot pass in NULL as the module handle as this would only work for + // standard win32 cursors. We can also receive cursor types which are defined + // as webkit resources. We need to specify the module handle of chrome.dll + // while loading these cursors. + HCURSOR display_cursor = current_cursor_.GetCursor(module_handle); + + // If a page is in the loading state, we want to show the Arrow+Hourglass + // cursor only when the current cursor is the ARROW cursor. In all other + // cases we should continue to display the current cursor. + if (is_loading_ && display_cursor == kCursorArrow) + display_cursor = kCursorAppStarting; + + // If the mouse is over our HWND, then update the cursor state immediately. + CPoint pt; + GetCursorPos(&pt); + if (WindowFromPoint(pt) == m_hWnd) + SetCursor(display_cursor); +} + +void RenderWidgetHostViewWin::SetIsLoading(bool is_loading) { + is_loading_ = is_loading; + UpdateCursorIfOverSelf(); +} + +void RenderWidgetHostViewWin::IMEUpdateStatus(ViewHostMsg_ImeControl control, + const gfx::Rect& caret_rect) { + if (control == IME_DISABLE) { + ime_input_.DisableIME(m_hWnd); + } else { + ime_input_.EnableIME(m_hWnd, caret_rect, + control == IME_COMPLETE_COMPOSITION); + } +} + +BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam) { + if (!WebPluginDelegateImpl::IsPluginDelegateWindow(hwnd)) + return TRUE; + + gfx::Rect* rect = reinterpret_cast(lparam); + static UINT msg = RegisterWindowMessage(kPaintMessageName); + WPARAM wparam = rect->x() << 16 | rect->y(); + lparam = rect->width() << 16 | rect->height(); + + // SendMessage gets the message across much quicker than PostMessage, since it + // doesn't get queued. When the plugin thread calls PeekMessage or other + // Win32 APIs, sent messages are dispatched automatically. + SendNotifyMessage(hwnd, msg, wparam, lparam); + + return TRUE; +} + +void RenderWidgetHostViewWin::Redraw(const gfx::Rect& rect) { + // Paint the invalid region synchronously. Our caller will not paint again + // until we return, so by painting to the screen here, we ensure effective + // rate-limiting of backing store updates. This helps a lot on pages that + // have animations or fairly expensive layout (e.g., google maps). + // + // We paint this window synchronously, however child windows (i.e. plugins) + // are painted asynchronously. By avoiding synchronous cross-process window + // message dispatching we allow scrolling to be smooth, and also avoid the + // browser process locking up if the plugin process is hung. + // + RedrawWindow( + &rect.ToRECT(), NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN); + + // Send the invalid rect in screen coordinates. + gfx::Rect screen_rect = GetViewBounds(); + gfx::Rect invalid_screen_rect = rect; + invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y()); + + LPARAM lparam = reinterpret_cast(&invalid_screen_rect); + EnumChildWindows(m_hWnd, EnumChildProc, lparam); +} + +void RenderWidgetHostViewWin::DidPaintRect(const gfx::Rect& rect) { + if (is_hidden_) + return; + + Redraw(rect); +} + +void RenderWidgetHostViewWin::DidScrollRect( + const gfx::Rect& rect, int dx, int dy) { + if (is_hidden_) + return; + + // We need to pass in SW_INVALIDATE to ScrollWindowEx. The MSDN + // documentation states that it only applies to the HRGN argument, which is + // wrong. Not passing in this flag does not invalidate the region which was + // scrolled from, thus causing painting issues. + RECT clip_rect = rect.ToRECT(); + ScrollWindowEx(dx, dy, NULL, &clip_rect, NULL, NULL, SW_INVALIDATE); + + RECT invalid_rect = {0}; + GetUpdateRect(&invalid_rect); + Redraw(gfx::Rect(invalid_rect)); +} + +void RenderWidgetHostViewWin::RendererGone() { + // TODO(darin): keep this around, and draw sad-tab into it. + UpdateCursorIfOverSelf(); + DestroyWindow(); +} + +void RenderWidgetHostViewWin::Destroy() { + // We've been told to destroy. + // By clearing close_on_deactivate_, we prevent further deactivations + // (caused by windows messages resulting from the DestroyWindow) from + // triggering further destructions. The deletion of this is handled by + // OnFinalMessage(); + close_on_deactivate_ = false; + DestroyWindow(); +} + +void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) { + if (tooltip_text != tooltip_text_) { + tooltip_text_ = tooltip_text; + + // Clamp the tooltip length to kMaxTooltipLength so that we don't + // accidentally DOS the user with a mega tooltip (since Windows doesn't seem + // to do this itself). + if (tooltip_text_.length() > kMaxTooltipLength) + tooltip_text_ = tooltip_text_.substr(0, kMaxTooltipLength); + + // Need to check if the tooltip is already showing so that we don't + // immediately show the tooltip with no delay when we move the mouse from + // a region with no tooltip to a region with a tooltip. + if (::IsWindow(tooltip_hwnd_) && tooltip_showing_) { + ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); + ::SendMessage(tooltip_hwnd_, TTM_POPUP, 0, 0); + } + } else { + // Make sure the tooltip gets closed after TTN_POP gets sent. For some + // reason this doesn't happen automatically, so moving the mouse around + // within the same link/image/etc doesn't cause the tooltip to re-appear. + if (!tooltip_showing_) { + if (::IsWindow(tooltip_hwnd_)) + ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// RenderWidgetHostViewWin, private: + +LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) { + // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale + // of a browser process. + OnInputLangChange(0, 0); + return 0; +} + +void RenderWidgetHostViewWin::OnActivate(UINT action, BOOL minimized, + HWND window) { + // If the container is a popup, clicking elsewhere on screen should close the + // popup. + if (close_on_deactivate_ && action == WA_INACTIVE) { + // Send a windows message so that any derived classes + // will get a change to override the default handling + SendMessage(WM_CANCELMODE); + } +} + +void RenderWidgetHostViewWin::OnDestroy() { + ResetTooltip(); + TrackMouseLeave(false); +} + +void RenderWidgetHostViewWin::OnPaint(HDC dc) { + DCHECK(render_widget_host_->process()->channel()); + + CPaintDC paint_dc(m_hWnd); + HBRUSH white_brush = reinterpret_cast(GetStockObject(WHITE_BRUSH)); + + RenderWidgetHost::BackingStore* backing_store = + render_widget_host_->GetBackingStore(); + + if (backing_store) { + gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint); + + gfx::Rect bitmap_rect( + 0, 0, backing_store->size().width(), backing_store->size().height()); + + gfx::Rect paint_rect = bitmap_rect.Intersect(damaged_rect); + if (!paint_rect.IsEmpty()) { + BitBlt(paint_dc.m_hDC, + paint_rect.x(), + paint_rect.y(), + paint_rect.width(), + paint_rect.height(), + backing_store->dc(), + paint_rect.x(), + paint_rect.y(), + SRCCOPY); + } + + // Fill the remaining portion of the damaged_rect with white + if (damaged_rect.right() > bitmap_rect.right()) { + RECT r; + r.left = std::max(bitmap_rect.right(), damaged_rect.x()); + r.right = damaged_rect.right(); + r.top = damaged_rect.y(); + r.bottom = std::min(bitmap_rect.bottom(), damaged_rect.bottom()); + paint_dc.FillRect(&r, white_brush); + } + if (damaged_rect.bottom() > bitmap_rect.bottom()) { + RECT r; + r.left = damaged_rect.x(); + r.right = damaged_rect.right(); + r.top = std::max(bitmap_rect.bottom(), damaged_rect.y()); + r.bottom = damaged_rect.bottom(); + paint_dc.FillRect(&r, white_brush); + } + if (!whiteout_start_time_.is_null()) { + TimeDelta whiteout_duration = TimeTicks::Now() - whiteout_start_time_; + + // If field trial is active, report results in special histogram. + static scoped_refptr trial( + FieldTrialList::Find(BrowserTrial::kMemoryModelFieldTrial)); + if (trial.get()) { + if (trial->boolean_value()) + UMA_HISTOGRAM_TIMES(L"MPArch.RWHH_WhiteoutDuration_trial_high_memory", + whiteout_duration); + else + UMA_HISTOGRAM_TIMES(L"MPArch.RWHH_WhiteoutDuration_trial_med_memory", + whiteout_duration); + } else { + UMA_HISTOGRAM_TIMES(L"MPArch.RWHH_WhiteoutDuration", whiteout_duration); + } + + // Reset the start time to 0 so that we start recording again the next + // time the backing store is NULL... + whiteout_start_time_ = TimeTicks(); + } + } else { + paint_dc.FillRect(&paint_dc.m_ps.rcPaint, white_brush); + if (whiteout_start_time_.is_null()) + whiteout_start_time_ = TimeTicks::Now(); + } +} + +void RenderWidgetHostViewWin::OnNCPaint(HRGN update_region) { + // Do nothing. This suppresses the resize corner that Windows would + // otherwise draw for us. +} + +LRESULT RenderWidgetHostViewWin::OnEraseBkgnd(HDC dc) { + return 1; +} + +LRESULT RenderWidgetHostViewWin::OnSetCursor(HWND window, UINT hittest_code, + UINT mouse_message_id) { + UpdateCursorIfOverSelf(); + return 0; +} + +void RenderWidgetHostViewWin::OnSetFocus(HWND window) { + render_widget_host_->Focus(); +} + +void RenderWidgetHostViewWin::OnKillFocus(HWND window) { + render_widget_host_->Blur(); +} + +void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) { + render_widget_host_->LostCapture(); +} + +void RenderWidgetHostViewWin::OnCancelMode() { + render_widget_host_->LostCapture(); + + if (close_on_deactivate_ && shutdown_factory_.empty()) { + // Dismiss popups and menus. We do this asynchronously to avoid changing + // activation within this callstack, which may interfere with another window + // being activated. We can synchronously hide the window, but we need to + // not change activation while doing so. + SetWindowPos(NULL, 0, 0, 0, 0, + SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | + SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER); + MessageLoop::current()->PostTask(FROM_HERE, + shutdown_factory_.NewRunnableMethod( + &RenderWidgetHostViewWin::ShutdownHost)); + } +} + +void RenderWidgetHostViewWin::OnInputLangChange(DWORD character_set, + HKL input_language_id) { + // Send the given Locale ID to the ImeInput object and retrieves whether + // or not the current input context has IMEs. + // If the current input context has IMEs, a browser process has to send a + // request to a renderer process that it needs status messages about + // the focused edit control from the renderer process. + // On the other hand, if the current input context does not have IMEs, the + // browser process also has to send a request to the renderer process that + // it does not need the status messages any longer. + // To minimize the number of this notification request, we should check if + // the browser process is actually retrieving the status messages (this + // state is stored in ime_notification_) and send a request only if the + // browser process has to update this status, its details are listed below: + // * If a browser process is not retrieving the status messages, + // (i.e. ime_notification_ == false), + // send this request only if the input context does have IMEs, + // (i.e. ime_status == true); + // When it successfully sends the request, toggle its notification status, + // (i.e.ime_notification_ = !ime_notification_ = true). + // * If a browser process is retrieving the status messages + // (i.e. ime_notification_ == true), + // send this request only if the input context does not have IMEs, + // (i.e. ime_status == false). + // When it successfully sends the request, toggle its notification status, + // (i.e.ime_notification_ = !ime_notification_ = false). + // To analyze the above actions, we can optimize them into the ones + // listed below: + // 1 Sending a request only if ime_status_ != ime_notification_, and; + // 2 Copying ime_status to ime_notification_ if it sends the request + // successfully (because Action 1 shows ime_status = !ime_notification_.) + bool ime_status = ime_input_.SetInputLanguage(); + if (ime_status != ime_notification_) { + if (Send(new ViewMsg_ImeSetInputMode(render_widget_host_->routing_id(), + ime_status))) { + ime_notification_ = ime_status; + } + } +} + +void RenderWidgetHostViewWin::OnThemeChanged() { + render_widget_host_->SystemThemeChanged(); +} + +LRESULT RenderWidgetHostViewWin::OnNotify(int w_param, NMHDR* header) { + if (tooltip_hwnd_ == NULL) + return 0; + + switch (header->code) { + case TTN_GETDISPINFO: { + NMTTDISPINFOW* tooltip_info = reinterpret_cast(header); + tooltip_info->szText[0] = L'\0'; + tooltip_info->lpszText = const_cast(tooltip_text_.c_str()); + ::SendMessage( + tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, kTooltipMaxWidthPixels); + SetMsgHandled(TRUE); + break; + } + case TTN_POP: + tooltip_showing_ = false; + SetMsgHandled(TRUE); + break; + case TTN_SHOW: + tooltip_showing_ = true; + SetMsgHandled(TRUE); + break; + } + return 0; +} + +LRESULT RenderWidgetHostViewWin::OnImeSetContext( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { + // We need status messages about the focused input control from a + // renderer process when: + // * the current input context has IMEs, and; + // * an application is activated. + // This seems to tell we should also check if the current input context has + // IMEs before sending a request, however, this WM_IME_SETCONTEXT is + // fortunately sent to an application only while the input context has IMEs. + // Therefore, we just start/stop status messages according to the activation + // status of this application without checks. + bool activated = (wparam == TRUE); + if (Send(new ViewMsg_ImeSetInputMode( + render_widget_host_->routing_id(), activated))) { + ime_notification_ = activated; + } + + if (ime_notification_) + ime_input_.CreateImeWindow(m_hWnd); + + ime_input_.CleanupComposition(m_hWnd); + ime_input_.SetImeWindowStyle(m_hWnd, message, wparam, lparam, &handled); + return 0; +} + +LRESULT RenderWidgetHostViewWin::OnImeStartComposition( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { + // Reset the composition status and create IME windows. + ime_input_.CreateImeWindow(m_hWnd); + ime_input_.ResetComposition(m_hWnd); + // We have to prevent WTL from calling ::DefWindowProc() because the function + // calls ::ImmSetCompositionWindow() and ::ImmSetCandidateWindow() to + // over-write the position of IME windows. + handled = TRUE; + return 0; +} + +LRESULT RenderWidgetHostViewWin::OnImeComposition( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { + // At first, update the position of the IME window. + ime_input_.UpdateImeWindow(m_hWnd); + + // Retrieve the result string and its attributes of the ongoing composition + // and send it to a renderer process. + ImeComposition composition; + if (ime_input_.GetResult(m_hWnd, lparam, &composition)) { + Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(), + composition.string_type, + composition.cursor_position, + composition.target_start, + composition.target_end, + composition.ime_string)); + ime_input_.ResetComposition(m_hWnd); + // Fall though and try reading the composition string. + // Japanese IMEs send a message containing both GCS_RESULTSTR and + // GCS_COMPSTR, which means an ongoing composition has been finished + // by the start of another composition. + } + // Retrieve the composition string and its attributes of the ongoing + // composition and send it to a renderer process. + if (ime_input_.GetComposition(m_hWnd, lparam, &composition)) { + Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(), + composition.string_type, + composition.cursor_position, + composition.target_start, + composition.target_end, + composition.ime_string)); + } + // We have to prevent WTL from calling ::DefWindowProc() because we do not + // want for the IMM (Input Method Manager) to send WM_IME_CHAR messages. + handled = TRUE; + return 0; +} + +LRESULT RenderWidgetHostViewWin::OnImeEndComposition( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { + if (ime_input_.is_composing()) { + // A composition has been ended while there is an ongoing composition, + // i.e. the ongoing composition has been canceled. + // We need to reset the composition status both of the ImeInput object and + // of the renderer process. + std::wstring empty_string; + Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(), + 0, -1, -1, -1, empty_string)); + ime_input_.ResetComposition(m_hWnd); + } + ime_input_.DestroyImeWindow(m_hWnd); + // Let WTL call ::DefWindowProc() and release its resources. + handled = FALSE; + return 0; +} + +LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam, + LPARAM lparam, BOOL& handled) { + handled = TRUE; + + if (::IsWindow(tooltip_hwnd_)) { + // Forward mouse events through to the tooltip window + MSG msg; + msg.hwnd = m_hWnd; + msg.message = message; + msg.wParam = wparam; + msg.lParam = lparam; + SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, NULL, + reinterpret_cast(&msg)); + } + + // TODO(jcampan): I am not sure if we should forward the message to the + // WebContents first in the case of popups. If we do, we would need to + // convert the click from the popup window coordinates to the WebContents' + // window coordinates. For now we don't forward the message in that case to + // address bug #907474. + // Note: GetParent() on popup windows returns the top window and not the + // parent the window was created with (the parent and the owner of the popup + // is the first non-child view of the view that was specified to the create + // call). So the WebContents window would have to be specified to the + // RenderViewHostHWND as there is no way to retrieve it from the HWND. + if (!close_on_deactivate_) { // Don't forward if the container is a popup. + switch (message) { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_MOUSEMOVE: + case WM_MOUSELEAVE: + case WM_RBUTTONDOWN: { + // Give the WebContents first crack at the message. It may want to + // prevent forwarding to the renderer if some higher level browser + // functionality is invoked. + if (SendMessage(GetParent(), message, wparam, lparam) != 0) + return 1; + } + } + } + + ForwardMouseEventToRenderer(message, wparam, lparam); + return 0; +} + +LRESULT RenderWidgetHostViewWin::OnKeyEvent(UINT message, WPARAM wparam, + LPARAM lparam, BOOL& handled) { + handled = TRUE; + + // If we are a pop-up, forward tab related messages to our parent HWND, so + // that we are dismissed appropriately and so that the focus advance in our + // parent. + // TODO(jcampan): http://b/issue?id=1192881 Could be abstracted in the + // FocusManager. + if (close_on_deactivate_ && + (((message == WM_KEYDOWN || message == WM_KEYUP) && (wparam == VK_TAB)) || + (message == WM_CHAR && wparam == L'\t'))) { + DCHECK(parent_hwnd_); + // First close the pop-up. + SendMessage(WM_CANCELMODE); + // Then move the focus by forwarding the tab key to the parent. + return ::SendMessage(parent_hwnd_, message, wparam, lparam); + } + + render_widget_host_->ForwardKeyboardEvent( + WebKeyboardEvent(m_hWnd, message, wparam, lparam)); + return 0; +} + +LRESULT RenderWidgetHostViewWin::OnWheelEvent(UINT message, WPARAM wparam, + LPARAM lparam, BOOL& handled) { + // Workaround for Thinkpad mousewheel driver. We get mouse wheel/scroll + // messages even if we are not in the foreground. So here we check if + // we have any owned popup windows in the foreground and dismiss them. + if (m_hWnd != GetForegroundWindow()) { + HWND toplevel_hwnd = ::GetAncestor(m_hWnd, GA_ROOT); + EnumThreadWindows( + GetCurrentThreadId(), + DismissOwnedPopups, + reinterpret_cast(toplevel_hwnd)); + } + + // This is a bit of a hack, but will work for now since we don't want to + // pollute this object with WebContents-specific functionality... + bool handled_by_webcontents = false; + if (GetParent()) { + // Use a special reflected message to break recursion. If we send + // WM_MOUSEWHEEL, the focus manager subclass of web contents will + // route it back here. + MSG new_message = {0}; + new_message.hwnd = m_hWnd; + new_message.message = message; + new_message.wParam = wparam; + new_message.lParam = lparam; + + handled_by_webcontents = + !!::SendMessage(GetParent(), views::kReflectedMessage, 0, + reinterpret_cast(&new_message)); + } + + if (!handled_by_webcontents) { + render_widget_host_->ForwardWheelEvent( + WebMouseWheelEvent(m_hWnd, message, wparam, lparam)); + } + handled = TRUE; + return 0; +} + +LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT, WPARAM, LPARAM, + BOOL& handled) { + if (!activatable_) + return MA_NOACTIVATE; + + HWND focus_window = GetFocus(); + if (!::IsWindow(focus_window) || !IsChild(focus_window)) { + // We handle WM_MOUSEACTIVATE to set focus to the underlying plugin + // child window. This is to ensure that keyboard events are received + // by the plugin. The correct way to fix this would be send over + // an event to the renderer which would then eventually send over + // a setFocus call to the plugin widget. This would ensure that + // the renderer (webkit) knows about the plugin widget receiving + // focus. + // TODO(iyengar) Do the right thing as per the above comment. + POINT cursor_pos = {0}; + ::GetCursorPos(&cursor_pos); + ::ScreenToClient(m_hWnd, &cursor_pos); + HWND child_window = ::RealChildWindowFromPoint(m_hWnd, cursor_pos); + if (::IsWindow(child_window)) { + ::SetFocus(child_window); + return MA_NOACTIVATE; + } + } + handled = FALSE; + return MA_ACTIVATE; +} + +LRESULT RenderWidgetHostViewWin::OnGetObject(UINT message, WPARAM wparam, + LPARAM lparam, BOOL& handled) { + LRESULT reference_result = static_cast(0L); + // TODO(jcampan): http://b/issue?id=1432077 Disabling accessibility in the + // renderer is a temporary work-around until that bug is fixed. + if (!renderer_accessible_) + return reference_result; + + // Accessibility readers will send an OBJID_CLIENT message. + if (OBJID_CLIENT == lparam) { + // If our MSAA DOM root is already created, reuse that pointer. Otherwise, + // create a new one. + if (!browser_accessibility_root_) { + CComObject* accessibility = NULL; + + if (!SUCCEEDED(CComObject::CreateInstance( + &accessibility)) || !accessibility) { + // Return with failure. + return static_cast(0L); + } + + CComPtr accessibility_comptr(accessibility); + + // Root id is always 0, to distinguish this particular instance when + // mapping to the render-side IAccessible. + accessibility->set_iaccessible_id(0); + + // Set the unique member variables of this particular process. + accessibility->set_instance_id( + BrowserAccessibilityManager::GetInstance()-> + SetMembers(accessibility, m_hWnd, render_widget_host_)); + + // All is well, assign the temp instance to the class smart pointer. + browser_accessibility_root_.Attach(accessibility_comptr.Detach()); + + if (!browser_accessibility_root_) { + // Paranoia check. Return with failure. + NOTREACHED(); + return static_cast(0L); + } + + // Notify that an instance of IAccessible was allocated for m_hWnd. + ::NotifyWinEvent(EVENT_OBJECT_CREATE, m_hWnd, OBJID_CLIENT, + CHILDID_SELF); + } + + // Create a reference to ViewAccessibility that MSAA will marshall + // to the client. + reference_result = LresultFromObject(IID_IAccessible, wparam, + static_cast(browser_accessibility_root_)); + } + return reference_result; +} + +void RenderWidgetHostViewWin::OnFinalMessage(HWND window) { + render_widget_host_->ViewDestroyed(); + delete this; +} + +void RenderWidgetHostViewWin::TrackMouseLeave(bool track) { + if (track == track_mouse_leave_) + return; + track_mouse_leave_ = track; + + DCHECK(m_hWnd); + + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = TME_LEAVE; + if (!track_mouse_leave_) + tme.dwFlags |= TME_CANCEL; + tme.hwndTrack = m_hWnd; + + TrackMouseEvent(&tme); +} + +bool RenderWidgetHostViewWin::Send(IPC::Message* message) { + return render_widget_host_->Send(message); +} + +void RenderWidgetHostViewWin::EnsureTooltip() { + UINT message = TTM_NEWTOOLRECT; + + TOOLINFO ti; + ti.cbSize = sizeof(ti); + ti.hwnd = m_hWnd; + ti.uId = 0; + if (!::IsWindow(tooltip_hwnd_)) { + message = TTM_ADDTOOL; + tooltip_hwnd_ = CreateWindowEx( + WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(), + TOOLTIPS_CLASS, NULL, TTS_NOPREFIX, 0, 0, 0, 0, m_hWnd, NULL, + NULL, NULL); + ti.uFlags = TTF_TRANSPARENT; + ti.lpszText = LPSTR_TEXTCALLBACK; + } + + CRect cr; + GetClientRect(&ti.rect); + SendMessage(tooltip_hwnd_, message, NULL, reinterpret_cast(&ti)); +} + +void RenderWidgetHostViewWin::ResetTooltip() { + if (::IsWindow(tooltip_hwnd_)) + ::DestroyWindow(tooltip_hwnd_); + tooltip_hwnd_ = NULL; +} + +void RenderWidgetHostViewWin::ShutdownHost() { + shutdown_factory_.RevokeAll(); + render_widget_host_->Shutdown(); + // Do not touch any members at this point, |this| has been deleted. +} diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h new file mode 100644 index 0000000..a735ab0 --- /dev/null +++ b/chrome/browser/renderer_host/render_widget_host_view_win.h @@ -0,0 +1,283 @@ +// Copyright (c) 2006-2008 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_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_WIN_H_ +#define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_WIN_H_ + +#include +#include +#include +#include + +#include "base/basictypes.h" +#include "base/gfx/size.h" +#include "base/scoped_handle.h" +#include "base/shared_memory.h" +#include "base/task.h" +#include "chrome/browser/ime_input.h" +#include "chrome/browser/renderer_host/render_widget_host_view.h" +#include "chrome/common/render_messages.h" +#include "chrome/views/focus_manager.h" + +namespace gfx { +class Rect; +} +namespace IPC { +class Message; +} +class RenderWidgetHost; +class WebMouseEvent; +class WebCursor; + +typedef CWinTraits + RenderWidgetHostHWNDTraits; + +static const wchar_t* const kRenderWidgetHostHWNDClass = + L"Chrome_RenderWidgetHostHWND"; + +/////////////////////////////////////////////////////////////////////////////// +// RenderWidgetHostViewWin +// +// An object representing the "View" of a rendered web page. This object is +// responsible for displaying the content of the web page, receiving windows +// messages, and containing plugins HWNDs. It is the implementation of the +// RenderWidgetHostView that the cross-platform RenderWidgetHost object uses +// to display the data. +// +// Comment excerpted from render_widget_host.h: +// +// "The lifetime of the RenderWidgetHostHWND is tied to the render process. +// If the render process dies, the RenderWidgetHostHWND goes away and all +// references to it must become NULL." +// +class RenderWidgetHostViewWin : + public CWindowImpl, + public RenderWidgetHostView { + public: + // The view will associate itself with the given widget. + explicit RenderWidgetHostViewWin(RenderWidgetHost* widget); + virtual ~RenderWidgetHostViewWin(); + + void set_close_on_deactivate(bool close_on_deactivate) { + close_on_deactivate_ = close_on_deactivate; + } + + void set_activatable(bool activatable) { + activatable_ = activatable; + } + bool activatable() const { return activatable_; } + + void set_parent_hwnd(HWND parent) { parent_hwnd_ = parent; } + + DECLARE_WND_CLASS_EX(kRenderWidgetHostHWNDClass, CS_DBLCLKS, 0); + + BEGIN_MSG_MAP(RenderWidgetHostHWND) + MSG_WM_CREATE(OnCreate) + MSG_WM_ACTIVATE(OnActivate) + MSG_WM_DESTROY(OnDestroy) + MSG_WM_PAINT(OnPaint) + MSG_WM_NCPAINT(OnNCPaint) + MSG_WM_ERASEBKGND(OnEraseBkgnd) + MSG_WM_SETCURSOR(OnSetCursor) + MSG_WM_SETFOCUS(OnSetFocus) + MSG_WM_KILLFOCUS(OnKillFocus) + MSG_WM_CAPTURECHANGED(OnCaptureChanged) + MSG_WM_CANCELMODE(OnCancelMode) + MSG_WM_INPUTLANGCHANGE(OnInputLangChange) + MSG_WM_THEMECHANGED(OnThemeChanged) + MSG_WM_NOTIFY(OnNotify) + MESSAGE_HANDLER(WM_IME_SETCONTEXT, OnImeSetContext) + MESSAGE_HANDLER(WM_IME_STARTCOMPOSITION, OnImeStartComposition) + MESSAGE_HANDLER(WM_IME_COMPOSITION, OnImeComposition) + MESSAGE_HANDLER(WM_IME_ENDCOMPOSITION, OnImeEndComposition) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseEvent) + MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseEvent) + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnMouseEvent) + MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMouseEvent) + MESSAGE_HANDLER(WM_RBUTTONDOWN, OnMouseEvent) + MESSAGE_HANDLER(WM_LBUTTONUP, OnMouseEvent) + MESSAGE_HANDLER(WM_MBUTTONUP, OnMouseEvent) + MESSAGE_HANDLER(WM_RBUTTONUP, OnMouseEvent) + MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnMouseEvent) + MESSAGE_HANDLER(WM_MBUTTONDBLCLK, OnMouseEvent) + MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnMouseEvent) + MESSAGE_HANDLER(WM_SYSKEYDOWN, OnKeyEvent) + MESSAGE_HANDLER(WM_SYSKEYUP, OnKeyEvent) + MESSAGE_HANDLER(WM_KEYDOWN, OnKeyEvent) + MESSAGE_HANDLER(WM_KEYUP, OnKeyEvent) + MESSAGE_HANDLER(WM_MOUSEWHEEL, OnWheelEvent) + MESSAGE_HANDLER(WM_MOUSEHWHEEL, OnWheelEvent) + MESSAGE_HANDLER(WM_HSCROLL, OnWheelEvent) + MESSAGE_HANDLER(WM_VSCROLL, OnWheelEvent) + MESSAGE_HANDLER(WM_CHAR, OnKeyEvent) + MESSAGE_HANDLER(WM_SYSCHAR, OnKeyEvent) + MESSAGE_HANDLER(WM_IME_CHAR, OnKeyEvent) + MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate) + MESSAGE_HANDLER(WM_GETOBJECT, OnGetObject) + END_MSG_MAP() + + // Implementation of RenderWidgetHostView: + virtual RenderWidgetHost* GetRenderWidgetHost() const; + virtual void DidBecomeSelected(); + virtual void WasHidden(); + virtual void SetSize(const gfx::Size& size); + virtual HWND GetPluginHWND(); + virtual void ForwardMouseEventToRenderer(UINT message, + WPARAM wparam, + LPARAM lparam); + virtual void Focus(); + virtual void Blur(); + virtual bool HasFocus(); + virtual void Show(); + virtual void Hide(); + virtual gfx::Rect GetViewBounds() const; + virtual void UpdateCursor(const WebCursor& cursor); + virtual void UpdateCursorIfOverSelf(); + virtual void SetIsLoading(bool is_loading); + virtual void IMEUpdateStatus(ViewHostMsg_ImeControl control, + const gfx::Rect& caret_rect); + virtual void DidPaintRect(const gfx::Rect& rect); + virtual void DidScrollRect(const gfx::Rect& rect, int dx, int dy); + virtual void RendererGone(); + virtual void Destroy(); + virtual void SetTooltipText(const std::wstring& tooltip_text); + + protected: + // Windows Message Handlers + LRESULT OnCreate(CREATESTRUCT* create_struct); + void OnActivate(UINT, BOOL, HWND); + void OnDestroy(); + void OnPaint(HDC dc); + void OnNCPaint(HRGN update_region); + LRESULT OnEraseBkgnd(HDC dc); + LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT mouse_message_id); + void OnSetFocus(HWND window); + void OnKillFocus(HWND window); + void OnCaptureChanged(HWND window); + void OnCancelMode(); + void OnInputLangChange(DWORD character_set, HKL input_language_id); + void OnThemeChanged(); + LRESULT OnNotify(int w_param, NMHDR* header); + LRESULT OnImeSetContext( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); + LRESULT OnImeStartComposition( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); + LRESULT OnImeComposition( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); + LRESULT OnImeEndComposition( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); + LRESULT OnMouseEvent( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); + LRESULT OnKeyEvent( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); + LRESULT OnWheelEvent( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); + LRESULT OnMouseActivate(UINT, WPARAM, LPARAM, BOOL& handled); + // Handle MSAA requests for accessibility information. + LRESULT OnGetObject(UINT message, WPARAM wparam, LPARAM lparam, + BOOL& handled); + // Handle vertical scrolling + LRESULT OnVScroll(int code, short position, HWND scrollbar_control); + // Handle horizontal scrolling + LRESULT OnHScroll(int code, short position, HWND scrollbar_control); + + void OnFinalMessage(HWND window); + + private: + // Tells Windows that we want to hear about mouse exit messages. + void TrackMouseLeave(bool start_tracking); + + // Sends a message to the RenderView in the renderer process. + bool Send(IPC::Message* message); + + // Set the tooltip region to the size of the window, creating the tooltip + // hwnd if it has not been created yet. + void EnsureTooltip(); + + // Tooltips become invalid when the root ancestor changes. When the View + // becomes hidden, this method is called to reset the tooltip. + void ResetTooltip(); + + // Synthesize mouse wheel event. + LRESULT SynthesizeMouseWheel(bool is_vertical, int scroll_code, + short scroll_position); + + // Shuts down the render_widget_host_. This is a separate function so we can + // invoke it from the message loop. + void ShutdownHost(); + + // Redraws the window synchronously, and any child windows (i.e. plugins) + // asynchronously. + void Redraw(const gfx::Rect& invalid_rect); + + // The associated Model. + RenderWidgetHost* render_widget_host_; + + // The cursor for the page. This is passed up from the renderer. + WebCursor current_cursor_; + + // Indicates if the page is loading. + bool is_loading_; + + // true if we are currently tracking WM_MOUSEEXIT messages. + bool track_mouse_leave_; + + // Wrapper class for IME input. + // (See "chrome/browser/ime_input.h" for its details.) + ImeInput ime_input_; + + // Represents whether or not this browser process is receiving status + // messages about the focused edit control from a renderer process. + bool ime_notification_; + + // true if the View is not visible. + bool is_hidden_; + + // true if the View should be closed when its HWND is deactivated (used to + // support SELECT popups which are closed when they are deactivated). + bool close_on_deactivate_; + + // Tooltips + // The text to be shown in the tooltip, supplied by the renderer. + std::wstring tooltip_text_; + // The tooltip control hwnd + HWND tooltip_hwnd_; + // Whether or not a tooltip is currently visible. We use this to track + // whether or not we want to force-close the tooltip when we receive mouse + // move notifications from the renderer. See comment in OnMsgSetTooltipText. + bool tooltip_showing_; + + // Factory used to safely scope delayed calls to ShutdownHost(). + ScopedRunnableMethodFactory shutdown_factory_; + + // Our parent HWND. We keep a reference to it as we SetParent(NULL) when + // hidden to prevent getting messages (Paint, Resize...), and we reattach + // when shown again. + HWND parent_hwnd_; + + // Instance of accessibility information for the root of the MSAA + // tree representation of the WebKit render tree. + CComPtr browser_accessibility_root_; + + // The time at which this view started displaying white pixels as a result of + // not having anything to paint (empty backing store from renderer). This + // value returns true for is_null() if we are not recording whiteout times. + base::TimeTicks whiteout_start_time_; + + // Whether the window can be activated. Autocomplete popup windows for example + // cannot be activated. Default is true. + bool activatable_; + + // Whether the renderer is made accessible. + // TODO(jcampan): http://b/issue?id=1432077 This is a temporary work-around + // until that bug is fixed. + bool renderer_accessible_; + + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewWin); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_WIN_H_ + diff --git a/chrome/browser/renderer_host/renderer_security_policy.cc b/chrome/browser/renderer_host/renderer_security_policy.cc new file mode 100644 index 0000000..ccea740 --- /dev/null +++ b/chrome/browser/renderer_host/renderer_security_policy.cc @@ -0,0 +1,285 @@ +// Copyright (c) 2006-2008 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/renderer_host/renderer_security_policy.h" + +#include "base/logging.h" +#include "base/string_util.h" +#ifdef CHROME_PERSONALIZATION +#include "chrome/personalization/personalization.h" +#endif +#include "googleurl/src/gurl.h" +#include "net/url_request/url_request.h" + +// The SecurityState class is used to maintain per-renderer security state +// information. +class RendererSecurityPolicy::SecurityState { + public: + SecurityState() : has_dom_ui_bindings_(false) { } + + // Grant permission to request URLs with the specified scheme. + void GrantScheme(const std::string& scheme) { + scheme_policy_[scheme] = true; + } + + // Revoke permission to request URLs with the specified scheme. + void RevokeScheme(const std::string& scheme) { + scheme_policy_[scheme] = false; + } + + // Grant permission to upload the specified file to the web. + void GrantUploadFile(const std::wstring& file) { + uploadable_files_.insert(file); + } + + void GrantDOMUIBindings() { + has_dom_ui_bindings_ = true; + } + + // Determine whether permission has been granted to request url. + // Schemes that have not been granted default to being denied. + bool CanRequestURL(const GURL& url) { + SchemeMap::const_iterator judgment(scheme_policy_.find(url.scheme())); + + if (judgment == scheme_policy_.end()) + return false; // Unmentioned schemes are disallowed. + + return judgment->second; + } + + // Determine whether permission has been granted to upload file. + // Files that have not been granted default to being denied. + bool CanUploadFile(const std::wstring& file) { + return uploadable_files_.find(file) != uploadable_files_.end(); + } + + bool has_dom_ui_bindings() const { return has_dom_ui_bindings_; } + + private: + typedef std::map SchemeMap; + typedef std::set FileSet; + + // Maps URL schemes to whether permission has been granted or revoked: + // |true| means the scheme has been granted. + // |false| means the scheme has been revoked. + // If a scheme is not present in the map, then it has never been granted + // or revoked. + SchemeMap scheme_policy_; + + // The set of files the renderer is permited to upload to the web. + FileSet uploadable_files_; + + bool has_dom_ui_bindings_; + + DISALLOW_COPY_AND_ASSIGN(SecurityState); +}; + +RendererSecurityPolicy::RendererSecurityPolicy() { + // We know about these schemes and believe them to be safe. + RegisterWebSafeScheme("http"); + RegisterWebSafeScheme("https"); + RegisterWebSafeScheme("ftp"); + RegisterWebSafeScheme("data"); + RegisterWebSafeScheme("feed"); + + // We know about the following psuedo schemes and treat them specially. + RegisterPseudoScheme("about"); + RegisterPseudoScheme("javascript"); + RegisterPseudoScheme("view-source"); +} + +// static +RendererSecurityPolicy* RendererSecurityPolicy::GetInstance() { + return Singleton::get(); +} + +void RendererSecurityPolicy::Add(int renderer_id) { + AutoLock lock(lock_); + if (security_state_.count(renderer_id) != 0) { + NOTREACHED() << "Add renderers at most once."; + return; + } + + security_state_[renderer_id] = new SecurityState(); +} + +void RendererSecurityPolicy::Remove(int renderer_id) { + AutoLock lock(lock_); + if (security_state_.count(renderer_id) != 1) { + NOTREACHED() << "Remove renderers at most once."; + return; + } + + delete security_state_[renderer_id]; + security_state_.erase(renderer_id); +} + +void RendererSecurityPolicy::RegisterWebSafeScheme(const std::string& scheme) { + AutoLock lock(lock_); + DCHECK(web_safe_schemes_.count(scheme) == 0) << "Add schemes at most once."; + DCHECK(pseudo_schemes_.count(scheme) == 0) << "Web-safe implies not psuedo."; + + web_safe_schemes_.insert(scheme); +} + +bool RendererSecurityPolicy::IsWebSafeScheme(const std::string& scheme) { + AutoLock lock(lock_); + + return (web_safe_schemes_.find(scheme) != web_safe_schemes_.end()); +} + +void RendererSecurityPolicy::RegisterPseudoScheme(const std::string& scheme) { + AutoLock lock(lock_); + DCHECK(pseudo_schemes_.count(scheme) == 0) << "Add schemes at most once."; + DCHECK(web_safe_schemes_.count(scheme) == 0) << "Psuedo implies not web-safe."; + + pseudo_schemes_.insert(scheme); +} + +bool RendererSecurityPolicy::IsPseudoScheme(const std::string& scheme) { + AutoLock lock(lock_); + + return (pseudo_schemes_.find(scheme) != pseudo_schemes_.end()); +} + +void RendererSecurityPolicy::GrantRequestURL(int renderer_id, const GURL& url) { + + if (!url.is_valid()) + return; // Can't grant the capability to request invalid URLs. + + if (IsWebSafeScheme(url.scheme())) + return; // The scheme has already been white-listed for every renderer. + + if (IsPseudoScheme(url.scheme())) { + // The view-source scheme is a special case of a pseudo URL that eventually + // results in requesting its embedded URL. + if (url.SchemeIs("view-source")) { + // URLs with the view-source scheme typically look like: + // view-source:http://www.google.com/a + // In order to request these URLs, the renderer needs to be able to request + // the embedded URL. + GrantRequestURL(renderer_id, GURL(url.path())); + } + + return; // Can't grant the capability to request pseudo schemes. + } + + { + AutoLock lock(lock_); + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return; + + // If the renderer has been commanded to request a scheme, then we grant + // it the capability to request URLs of that scheme. + state->second->GrantScheme(url.scheme()); + } +} + +void RendererSecurityPolicy::GrantUploadFile(int renderer_id, + const std::wstring& file) { + AutoLock lock(lock_); + + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return; + + state->second->GrantUploadFile(file); +} + +void RendererSecurityPolicy::GrantInspectElement(int renderer_id) { + AutoLock lock(lock_); + + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return; + + // The inspector is served from a chrome: URL. In order to run the + // inspector, the renderer needs to be able to load chrome URLs. + state->second->GrantScheme("chrome"); +} + +void RendererSecurityPolicy::GrantDOMUIBindings(int renderer_id) { + AutoLock lock(lock_); + + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return; + + state->second->GrantDOMUIBindings(); + + // DOM UI bindings need the ability to request chrome URLs. + state->second->GrantScheme("chrome"); + + // DOM UI pages can contain links to file:// URLs. + state->second->GrantScheme("file"); +} + +bool RendererSecurityPolicy::CanRequestURL(int renderer_id, const GURL& url) { + if (!url.is_valid()) + return false; // Can't request invalid URLs. + + if (IsWebSafeScheme(url.scheme())) + return true; // The scheme has been white-listed for every renderer. + + if (IsPseudoScheme(url.scheme())) { + // There are a number of special cases for pseudo schemes. + + if (url.SchemeIs("view-source")) { + // A view-source URL is allowed if the renderer is permitted to request + // the embedded URL. + return CanRequestURL(renderer_id, GURL(url.path())); + } + + if (LowerCaseEqualsASCII(url.spec(), "about:blank")) + return true; // Every renderer can request . + + // URLs like and shouldn't be requestable by + // any renderer. Also, this case covers , which should be + // handled internally by the renderer and not kicked up to the browser. + return false; + } + +#ifdef CHROME_PERSONALIZATION + if (url.SchemeIs(kPersonalizationScheme)) + return true; +#endif + + if (!URLRequest::IsHandledURL(url)) + return true; // This URL request is destined for ShellExecute. + + { + AutoLock lock(lock_); + + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return false; + + // Otherwise, we consult the renderer's security state to see if it is + // allowed to request the URL. + return state->second->CanRequestURL(url); + } +} + +bool RendererSecurityPolicy::CanUploadFile(int renderer_id, + const std::wstring& file) { + AutoLock lock(lock_); + + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return false; + + return state->second->CanUploadFile(file); +} + +bool RendererSecurityPolicy::HasDOMUIBindings(int renderer_id) { + AutoLock lock(lock_); + + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return false; + + return state->second->has_dom_ui_bindings(); +} + diff --git a/chrome/browser/renderer_host/renderer_security_policy.h b/chrome/browser/renderer_host/renderer_security_policy.h new file mode 100644 index 0000000..646f783 --- /dev/null +++ b/chrome/browser/renderer_host/renderer_security_policy.h @@ -0,0 +1,122 @@ +// Copyright (c) 2006-2008 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_RENDERER_HOST_RENDERER_SECURITY_POLICY_H_ +#define CHROME_BROWSER_RENDERER_HOST_RENDERER_SECURITY_POLICY_H_ + +#include +#include +#include + +#include "base/basictypes.h" +#include "base/lock.h" +#include "base/singleton.h" + +class GURL; + +// The RendererSecurityPolicy class is used to grant and revoke security +// capabilities for renderers. For example, it restricts whether a renderer +// is permmitted to loaded file:// URLs based on whether the renderer has ever +// been commanded to load file:// URLs by the browser. +// +// RendererSecurityPolicy is a singleton that may be used on any thread. +// +class RendererSecurityPolicy { + public: + // There is one global RendererSecurityPolicy object for the entire browser + // processes. The object returned by this method may be accessed on any + // thread. + static RendererSecurityPolicy* GetInstance(); + + // Web-safe schemes can be requested by any renderer. Once a web-safe scheme + // has been registered, any renderer processes can request URLs with that + // scheme. There is no mechanism for revoking web-safe schemes. + void RegisterWebSafeScheme(const std::string& scheme); + + // Returns true iff |scheme| has been registered as a web-safe scheme. + bool IsWebSafeScheme(const std::string& scheme); + + // Pseudo schemes are treated differently than other schemes because they + // cannot be requested like normal URLs. There is no mechanism for revoking + // pseudo schemes. + void RegisterPseudoScheme(const std::string& scheme); + + // Returns true iff |scheme| has been registered as pseudo scheme. + bool IsPseudoScheme(const std::string& scheme); + + // Upon creation, render processes should register themselves by calling this + // this method exactly once. + void Add(int renderer_id); + + // Upon destruction, render processess should unregister themselves by caling + // this method exactly once. + void Remove(int renderer_id); + + // Whenever the browser processes commands the renderer to request a URL, it + // should call this method to grant the renderer process the capability to + // request the URL. + void GrantRequestURL(int renderer_id, const GURL& url); + + // Whenever the user picks a file from a element, the + // browser should call this function to grant the renderer the capability to + // upload the file to the web. + void GrantUploadFile(int renderer_id, const std::wstring& file); + + // Whenever the browser processes commands the renderer to run web inspector, + // it should call this method to grant the renderer process the capability to + // run the inspector. + void GrantInspectElement(int renderer_id); + + // Grant this renderer the ability to use DOM UI Bindings. + void GrantDOMUIBindings(int renderer_id); + + // Before servicing a renderer's request for a URL, the browser should call + // this method to determine whether the renderer has the capability to + // request the URL. + bool CanRequestURL(int renderer_id, const GURL& url); + + // Before servicing a renderer's request to upload a file to the web, the + // browser should call this method to determine whether the renderer has the + // capability to upload the requested file. + bool CanUploadFile(int renderer_id, const std::wstring& file); + + // Returns true of the specified renderer_id has been granted DOMUIBindings. + // The browser should check this property before assuming the renderer is + // allowed to use DOMUIBindings. + bool HasDOMUIBindings(int renderer_id); + + private: + class SecurityState; + + typedef std::set SchemeSet; + typedef std::map SecurityStateMap; + + // Obtain an instance of RendererSecurityPolicy via GetInstance(). + RendererSecurityPolicy(); + friend struct DefaultSingletonTraits; + + // You must acquire this lock before reading or writing any members of this + // class. You must not block while holding this lock. + Lock lock_; + + // These schemes are white-listed for all renderers. This set is protected + // by |lock_|. + SchemeSet web_safe_schemes_; + + // These schemes do not actually represent retrievable URLs. For example, + // the the URLs in the "about" scheme are aliases to other URLs. This set is + // protected by |lock_|. + SchemeSet pseudo_schemes_; + + // This map holds a SecurityState for each renderer process. The key for the + // map is the ID of the RenderProcessHost. The SecurityState objects are + // owned by this object and are protected by |lock_|. References to them must + // not escape this class. + SecurityStateMap security_state_; + + DISALLOW_COPY_AND_ASSIGN(RendererSecurityPolicy); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_RENDERER_SECURITY_POLICY_H_ + diff --git a/chrome/browser/renderer_host/renderer_security_policy_unittest.cc b/chrome/browser/renderer_host/renderer_security_policy_unittest.cc new file mode 100644 index 0000000..ae3ac52 --- /dev/null +++ b/chrome/browser/renderer_host/renderer_security_policy_unittest.cc @@ -0,0 +1,260 @@ +// Copyright (c) 2006-2008 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 + +#include "base/basictypes.h" +#include "chrome/browser/renderer_host/renderer_security_policy.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_test_job.h" +#include "testing/gtest/include/gtest/gtest.h" + +class RendererSecurityPolicyTest : public testing::Test { +protected: + // testing::Test + virtual void SetUp() { + // In the real world, "chrome" is a handled scheme. + URLRequest::RegisterProtocolFactory("chrome", + &URLRequestTestJob::Factory); + } + virtual void TearDown() { + URLRequest::RegisterProtocolFactory("chrome", NULL); + } +}; + +static int kRendererID = 42; + +TEST_F(RendererSecurityPolicyTest, IsWebSafeSchemeTest) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + EXPECT_TRUE(p->IsWebSafeScheme("http")); + EXPECT_TRUE(p->IsWebSafeScheme("https")); + EXPECT_TRUE(p->IsWebSafeScheme("ftp")); + EXPECT_TRUE(p->IsWebSafeScheme("data")); + EXPECT_TRUE(p->IsWebSafeScheme("feed")); + + EXPECT_FALSE(p->IsWebSafeScheme("registered-web-safe-scheme")); + p->RegisterWebSafeScheme("registered-web-safe-scheme"); + EXPECT_TRUE(p->IsWebSafeScheme("registered-web-safe-scheme")); +} + +TEST_F(RendererSecurityPolicyTest, IsPseudoSchemeTest) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + EXPECT_TRUE(p->IsPseudoScheme("about")); + EXPECT_TRUE(p->IsPseudoScheme("javascript")); + EXPECT_TRUE(p->IsPseudoScheme("view-source")); + + EXPECT_FALSE(p->IsPseudoScheme("registered-psuedo-scheme")); + p->RegisterPseudoScheme("registered-psuedo-scheme"); + EXPECT_TRUE(p->IsPseudoScheme("registered-psuedo-scheme")); +} + +TEST_F(RendererSecurityPolicyTest, StandardSchemesTest) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + p->Add(kRendererID); + + // Safe + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("http://www.google.com/"))); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("https://www.paypal.com/"))); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("ftp://ftp.gnu.org/"))); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("data:text/html,Hi"))); + EXPECT_TRUE(p->CanRequestURL(kRendererID, + GURL("view-source:http://www.google.com/"))); + + // Dangerous + EXPECT_FALSE(p->CanRequestURL(kRendererID, + GURL("file:///etc/passwd"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, + GURL("view-cache:http://www.google.com/"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, + GURL("chrome://foo/bar"))); + + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, AboutTest) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + p->Add(kRendererID); + + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:blank"))); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:BlAnK"))); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:BlAnK"))); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:blank"))); + + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:memory"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:cache"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:hang"))); + + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBoUt:memory"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:CrASh"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("abOuT:cAChe"))); + + p->GrantRequestURL(kRendererID, GURL("about:memory")); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:memory"))); + + p->GrantRequestURL(kRendererID, GURL("about:crash")); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash"))); + + p->GrantRequestURL(kRendererID, GURL("about:cache")); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:cache"))); + + p->GrantRequestURL(kRendererID, GURL("about:hang")); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:hang"))); + + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, JavaScriptTest) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + p->Add(kRendererID); + + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')"))); + p->GrantRequestURL(kRendererID, GURL("javascript:alert('xss')")); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')"))); + + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, RegisterWebSafeSchemeTest) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + p->Add(kRendererID); + + // Currently, "asdf" is destined for ShellExecute, so it is allowed. + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); + + // Once we register a ProtocolFactory for "asdf", we default to deny. + URLRequest::RegisterProtocolFactory("asdf", &URLRequestTestJob::Factory); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); + + // We can allow new schemes by adding them to the whitelist. + p->RegisterWebSafeScheme("asdf"); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); + + // Cleanup. + URLRequest::RegisterProtocolFactory("asdf", NULL); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); + + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, CanServiceCommandsTest) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + p->Add(kRendererID); + + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); + p->GrantRequestURL(kRendererID, GURL("file:///etc/passwd")); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); + + // We should forget our state if we repeat a renderer id. + p->Remove(kRendererID); + p->Add(kRendererID); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, ViewSource) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + p->Add(kRendererID); + + // View source is determined by the embedded scheme. + EXPECT_TRUE(p->CanRequestURL(kRendererID, + GURL("view-source:http://www.google.com/"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, + GURL("view-source:file:///etc/passwd"))); + EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); + + p->GrantRequestURL(kRendererID, GURL("view-source:file:///etc/passwd")); + // View source needs to be able to request the embedded scheme. + EXPECT_TRUE(p->CanRequestURL(kRendererID, + GURL("view-source:file:///etc/passwd"))); + EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); + + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, CanUploadFiles) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + p->Add(kRendererID); + + EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/passwd")); + p->GrantUploadFile(kRendererID, L"/etc/passwd"); + EXPECT_TRUE(p->CanUploadFile(kRendererID, L"/etc/passwd")); + EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/shadow")); + + p->Remove(kRendererID); + p->Add(kRendererID); + + EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/passwd")); + EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/shadow")); + + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, CanServiceInspectElement) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + GURL url("chrome://inspector/inspector.html"); + + p->Add(kRendererID); + + EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); + p->GrantInspectElement(kRendererID); + EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); + + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, CanServiceDOMUIBindings) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + GURL url("chrome://thumb/http://www.google.com/"); + + p->Add(kRendererID); + + EXPECT_FALSE(p->HasDOMUIBindings(kRendererID)); + EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); + p->GrantDOMUIBindings(kRendererID); + EXPECT_TRUE(p->HasDOMUIBindings(kRendererID)); + EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); + + p->Remove(kRendererID); +} + +TEST_F(RendererSecurityPolicyTest, RemoveRace) { + RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); + + GURL url("file:///etc/passwd"); + std::wstring file(L"/etc/passwd"); + + p->Add(kRendererID); + + p->GrantRequestURL(kRendererID, url); + p->GrantUploadFile(kRendererID, file); + p->GrantDOMUIBindings(kRendererID); + + EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); + EXPECT_TRUE(p->CanUploadFile(kRendererID, file)); + EXPECT_TRUE(p->HasDOMUIBindings(kRendererID)); + + p->Remove(kRendererID); + + // Renderers are added and removed on the UI thread, but the policy can be + // queried on the IO thread. The RendererSecurityPolicy needs to be prepared + // to answer policy questions about renderers who no longer exist. + + // In this case, we default to secure behavior. + EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); + EXPECT_FALSE(p->CanUploadFile(kRendererID, file)); + EXPECT_FALSE(p->HasDOMUIBindings(kRendererID)); +} + diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index 7c74420..261d1c1 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -20,16 +20,16 @@ #include "chrome/browser/external_protocol_handler.h" #include "chrome/browser/login_prompt.h" #include "chrome/browser/plugin_service.h" -#include "chrome/browser/render_view_host.h" -#include "chrome/browser/render_view_host_delegate.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/renderer_host/async_resource_handler.h" #include "chrome/browser/renderer_host/buffered_resource_handler.h" #include "chrome/browser/renderer_host/cross_site_resource_handler.h" #include "chrome/browser/renderer_host/download_resource_handler.h" +#include "chrome/browser/renderer_host/renderer_security_policy.h" #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" #include "chrome/browser/renderer_host/save_file_resource_handler.h" #include "chrome/browser/renderer_host/sync_resource_handler.h" -#include "chrome/browser/renderer_security_policy.h" #include "chrome/browser/resource_request_details.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/tab_contents/tab_util.h" diff --git a/chrome/browser/renderer_host/test_render_view_host.cc b/chrome/browser/renderer_host/test_render_view_host.cc index 7c47b53..1c77bb8 100644 --- a/chrome/browser/renderer_host/test_render_view_host.cc +++ b/chrome/browser/renderer_host/test_render_view_host.cc @@ -73,8 +73,10 @@ void RenderViewHostTestHarness::SetUp() { } void RenderViewHostTestHarness::TearDown() { - contents_->CloseContents(); - contents_ = NULL; + if (contents_) { + contents_->CloseContents(); + contents_ = NULL; + } controller_ = NULL; // Make sure that we flush any messages related to WebContents destruction diff --git a/chrome/browser/renderer_host/test_render_view_host.h b/chrome/browser/renderer_host/test_render_view_host.h index ba7c7ea..be7acfe 100644 --- a/chrome/browser/renderer_host/test_render_view_host.h +++ b/chrome/browser/renderer_host/test_render_view_host.h @@ -9,9 +9,9 @@ #include "base/message_loop.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/test_web_contents.h" -#include "chrome/browser/render_view_host.h" #include "chrome/browser/renderer_host/mock_render_process_host.h" -#include "chrome/browser/render_widget_host_view.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/test/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" @@ -183,6 +183,12 @@ class RenderViewHostTestHarness : public testing::Test { return profile_.get(); } + // Marks the contents as already cleaned up. If a test calls CloseContents, + // then our cleanup code shouldn't run. This function makes sure that happens. + void ContentsCleanedUp() { + contents_ = NULL; + } + protected: // testing::Test virtual void SetUp(); diff --git a/chrome/browser/renderer_security_policy.cc b/chrome/browser/renderer_security_policy.cc deleted file mode 100644 index 32d29f8..0000000 --- a/chrome/browser/renderer_security_policy.cc +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 2006-2008 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/renderer_security_policy.h" - -#include "base/logging.h" -#include "base/string_util.h" -#ifdef CHROME_PERSONALIZATION -#include "chrome/personalization/personalization.h" -#endif -#include "googleurl/src/gurl.h" -#include "net/url_request/url_request.h" - -// The SecurityState class is used to maintain per-renderer security state -// information. -class RendererSecurityPolicy::SecurityState { - public: - SecurityState() : has_dom_ui_bindings_(false) { } - - // Grant permission to request URLs with the specified scheme. - void GrantScheme(const std::string& scheme) { - scheme_policy_[scheme] = true; - } - - // Revoke permission to request URLs with the specified scheme. - void RevokeScheme(const std::string& scheme) { - scheme_policy_[scheme] = false; - } - - // Grant permission to upload the specified file to the web. - void GrantUploadFile(const std::wstring& file) { - uploadable_files_.insert(file); - } - - void GrantDOMUIBindings() { - has_dom_ui_bindings_ = true; - } - - // Determine whether permission has been granted to request url. - // Schemes that have not been granted default to being denied. - bool CanRequestURL(const GURL& url) { - SchemeMap::const_iterator judgment(scheme_policy_.find(url.scheme())); - - if (judgment == scheme_policy_.end()) - return false; // Unmentioned schemes are disallowed. - - return judgment->second; - } - - // Determine whether permission has been granted to upload file. - // Files that have not been granted default to being denied. - bool CanUploadFile(const std::wstring& file) { - return uploadable_files_.find(file) != uploadable_files_.end(); - } - - bool has_dom_ui_bindings() const { return has_dom_ui_bindings_; } - - private: - typedef std::map SchemeMap; - typedef std::set FileSet; - - // Maps URL schemes to whether permission has been granted or revoked: - // |true| means the scheme has been granted. - // |false| means the scheme has been revoked. - // If a scheme is not present in the map, then it has never been granted - // or revoked. - SchemeMap scheme_policy_; - - // The set of files the renderer is permited to upload to the web. - FileSet uploadable_files_; - - bool has_dom_ui_bindings_; - - DISALLOW_COPY_AND_ASSIGN(SecurityState); -}; - -RendererSecurityPolicy::RendererSecurityPolicy() { - // We know about these schemes and believe them to be safe. - RegisterWebSafeScheme("http"); - RegisterWebSafeScheme("https"); - RegisterWebSafeScheme("ftp"); - RegisterWebSafeScheme("data"); - RegisterWebSafeScheme("feed"); - - // We know about the following psuedo schemes and treat them specially. - RegisterPseudoScheme("about"); - RegisterPseudoScheme("javascript"); - RegisterPseudoScheme("view-source"); -} - -// static -RendererSecurityPolicy* RendererSecurityPolicy::GetInstance() { - return Singleton::get(); -} - -void RendererSecurityPolicy::Add(int renderer_id) { - AutoLock lock(lock_); - if (security_state_.count(renderer_id) != 0) { - NOTREACHED() << "Add renderers at most once."; - return; - } - - security_state_[renderer_id] = new SecurityState(); -} - -void RendererSecurityPolicy::Remove(int renderer_id) { - AutoLock lock(lock_); - if (security_state_.count(renderer_id) != 1) { - NOTREACHED() << "Remove renderers at most once."; - return; - } - - delete security_state_[renderer_id]; - security_state_.erase(renderer_id); -} - -void RendererSecurityPolicy::RegisterWebSafeScheme(const std::string& scheme) { - AutoLock lock(lock_); - DCHECK(web_safe_schemes_.count(scheme) == 0) << "Add schemes at most once."; - DCHECK(pseudo_schemes_.count(scheme) == 0) << "Web-safe implies not psuedo."; - - web_safe_schemes_.insert(scheme); -} - -bool RendererSecurityPolicy::IsWebSafeScheme(const std::string& scheme) { - AutoLock lock(lock_); - - return (web_safe_schemes_.find(scheme) != web_safe_schemes_.end()); -} - -void RendererSecurityPolicy::RegisterPseudoScheme(const std::string& scheme) { - AutoLock lock(lock_); - DCHECK(pseudo_schemes_.count(scheme) == 0) << "Add schemes at most once."; - DCHECK(web_safe_schemes_.count(scheme) == 0) << "Psuedo implies not web-safe."; - - pseudo_schemes_.insert(scheme); -} - -bool RendererSecurityPolicy::IsPseudoScheme(const std::string& scheme) { - AutoLock lock(lock_); - - return (pseudo_schemes_.find(scheme) != pseudo_schemes_.end()); -} - -void RendererSecurityPolicy::GrantRequestURL(int renderer_id, const GURL& url) { - - if (!url.is_valid()) - return; // Can't grant the capability to request invalid URLs. - - if (IsWebSafeScheme(url.scheme())) - return; // The scheme has already been white-listed for every renderer. - - if (IsPseudoScheme(url.scheme())) { - // The view-source scheme is a special case of a pseudo URL that eventually - // results in requesting its embedded URL. - if (url.SchemeIs("view-source")) { - // URLs with the view-source scheme typically look like: - // view-source:http://www.google.com/a - // In order to request these URLs, the renderer needs to be able to request - // the embedded URL. - GrantRequestURL(renderer_id, GURL(url.path())); - } - - return; // Can't grant the capability to request pseudo schemes. - } - - { - AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); - if (state == security_state_.end()) - return; - - // If the renderer has been commanded to request a scheme, then we grant - // it the capability to request URLs of that scheme. - state->second->GrantScheme(url.scheme()); - } -} - -void RendererSecurityPolicy::GrantUploadFile(int renderer_id, - const std::wstring& file) { - AutoLock lock(lock_); - - SecurityStateMap::iterator state = security_state_.find(renderer_id); - if (state == security_state_.end()) - return; - - state->second->GrantUploadFile(file); -} - -void RendererSecurityPolicy::GrantInspectElement(int renderer_id) { - AutoLock lock(lock_); - - SecurityStateMap::iterator state = security_state_.find(renderer_id); - if (state == security_state_.end()) - return; - - // The inspector is served from a chrome: URL. In order to run the - // inspector, the renderer needs to be able to load chrome URLs. - state->second->GrantScheme("chrome"); -} - -void RendererSecurityPolicy::GrantDOMUIBindings(int renderer_id) { - AutoLock lock(lock_); - - SecurityStateMap::iterator state = security_state_.find(renderer_id); - if (state == security_state_.end()) - return; - - state->second->GrantDOMUIBindings(); - - // DOM UI bindings need the ability to request chrome URLs. - state->second->GrantScheme("chrome"); - - // DOM UI pages can contain links to file:// URLs. - state->second->GrantScheme("file"); -} - -bool RendererSecurityPolicy::CanRequestURL(int renderer_id, const GURL& url) { - if (!url.is_valid()) - return false; // Can't request invalid URLs. - - if (IsWebSafeScheme(url.scheme())) - return true; // The scheme has been white-listed for every renderer. - - if (IsPseudoScheme(url.scheme())) { - // There are a number of special cases for pseudo schemes. - - if (url.SchemeIs("view-source")) { - // A view-source URL is allowed if the renderer is permitted to request - // the embedded URL. - return CanRequestURL(renderer_id, GURL(url.path())); - } - - if (LowerCaseEqualsASCII(url.spec(), "about:blank")) - return true; // Every renderer can request . - - // URLs like and shouldn't be requestable by - // any renderer. Also, this case covers , which should be - // handled internally by the renderer and not kicked up to the browser. - return false; - } - -#ifdef CHROME_PERSONALIZATION - if (url.SchemeIs(kPersonalizationScheme)) - return true; -#endif - - if (!URLRequest::IsHandledURL(url)) - return true; // This URL request is destined for ShellExecute. - - { - AutoLock lock(lock_); - - SecurityStateMap::iterator state = security_state_.find(renderer_id); - if (state == security_state_.end()) - return false; - - // Otherwise, we consult the renderer's security state to see if it is - // allowed to request the URL. - return state->second->CanRequestURL(url); - } -} - -bool RendererSecurityPolicy::CanUploadFile(int renderer_id, - const std::wstring& file) { - AutoLock lock(lock_); - - SecurityStateMap::iterator state = security_state_.find(renderer_id); - if (state == security_state_.end()) - return false; - - return state->second->CanUploadFile(file); -} - -bool RendererSecurityPolicy::HasDOMUIBindings(int renderer_id) { - AutoLock lock(lock_); - - SecurityStateMap::iterator state = security_state_.find(renderer_id); - if (state == security_state_.end()) - return false; - - return state->second->has_dom_ui_bindings(); -} - diff --git a/chrome/browser/renderer_security_policy.h b/chrome/browser/renderer_security_policy.h deleted file mode 100644 index 86d1e73..0000000 --- a/chrome/browser/renderer_security_policy.h +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) 2006-2008 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_RENDERER_SECURITY_POLICY_H__ -#define CHROME_BROWSER_RENDERER_SECURITY_POLICY_H__ - -#include -#include -#include - -#include "base/basictypes.h" -#include "base/lock.h" -#include "base/singleton.h" - -class GURL; - -// The RendererSecurityPolicy class is used to grant and revoke security -// capabilities for renderers. For example, it restricts whether a renderer -// is permmitted to loaded file:// URLs based on whether the renderer has ever -// been commanded to load file:// URLs by the browser. -// -// RendererSecurityPolicy is a singleton that may be used on any thread. -// -class RendererSecurityPolicy { - public: - // There is one global RendererSecurityPolicy object for the entire browser - // processes. The object returned by this method may be accessed on any - // thread. - static RendererSecurityPolicy* GetInstance(); - - // Web-safe schemes can be requested by any renderer. Once a web-safe scheme - // has been registered, any renderer processes can request URLs with that - // scheme. There is no mechanism for revoking web-safe schemes. - void RegisterWebSafeScheme(const std::string& scheme); - - // Returns true iff |scheme| has been registered as a web-safe scheme. - bool IsWebSafeScheme(const std::string& scheme); - - // Pseudo schemes are treated differently than other schemes because they - // cannot be requested like normal URLs. There is no mechanism for revoking - // pseudo schemes. - void RegisterPseudoScheme(const std::string& scheme); - - // Returns true iff |scheme| has been registered as pseudo scheme. - bool IsPseudoScheme(const std::string& scheme); - - // Upon creation, render processes should register themselves by calling this - // this method exactly once. - void Add(int renderer_id); - - // Upon destruction, render processess should unregister themselves by caling - // this method exactly once. - void Remove(int renderer_id); - - // Whenever the browser processes commands the renderer to request a URL, it - // should call this method to grant the renderer process the capability to - // request the URL. - void GrantRequestURL(int renderer_id, const GURL& url); - - // Whenever the user picks a file from a element, the - // browser should call this function to grant the renderer the capability to - // upload the file to the web. - void GrantUploadFile(int renderer_id, const std::wstring& file); - - // Whenever the browser processes commands the renderer to run web inspector, - // it should call this method to grant the renderer process the capability to - // run the inspector. - void GrantInspectElement(int renderer_id); - - // Grant this renderer the ability to use DOM UI Bindings. - void GrantDOMUIBindings(int renderer_id); - - // Before servicing a renderer's request for a URL, the browser should call - // this method to determine whether the renderer has the capability to - // request the URL. - bool CanRequestURL(int renderer_id, const GURL& url); - - // Before servicing a renderer's request to upload a file to the web, the - // browser should call this method to determine whether the renderer has the - // capability to upload the requested file. - bool CanUploadFile(int renderer_id, const std::wstring& file); - - // Returns true of the specified renderer_id has been granted DOMUIBindings. - // The browser should check this property before assuming the renderer is - // allowed to use DOMUIBindings. - bool HasDOMUIBindings(int renderer_id); - - private: - class SecurityState; - - typedef std::set SchemeSet; - typedef std::map SecurityStateMap; - - // Obtain an instance of RendererSecurityPolicy via GetInstance(). - RendererSecurityPolicy(); - friend struct DefaultSingletonTraits; - - // You must acquire this lock before reading or writing any members of this - // class. You must not block while holding this lock. - Lock lock_; - - // These schemes are white-listed for all renderers. This set is protected - // by |lock_|. - SchemeSet web_safe_schemes_; - - // These schemes do not actually represent retrievable URLs. For example, - // the the URLs in the "about" scheme are aliases to other URLs. This set is - // protected by |lock_|. - SchemeSet pseudo_schemes_; - - // This map holds a SecurityState for each renderer process. The key for the - // map is the ID of the RenderProcessHost. The SecurityState objects are - // owned by this object and are protected by |lock_|. References to them must - // not escape this class. - SecurityStateMap security_state_; - - DISALLOW_EVIL_CONSTRUCTORS(RendererSecurityPolicy); -}; - -#endif // CHROME_BROWSER_RENDERER_SECURITY_POLICY_H__ - diff --git a/chrome/browser/renderer_security_policy_unittest.cc b/chrome/browser/renderer_security_policy_unittest.cc deleted file mode 100644 index 7d4318d..0000000 --- a/chrome/browser/renderer_security_policy_unittest.cc +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright (c) 2006-2008 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 - -#include "base/basictypes.h" -#include "chrome/browser/renderer_security_policy.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_test_job.h" -#include "testing/gtest/include/gtest/gtest.h" - -class RendererSecurityPolicyTest : public testing::Test { -protected: - // testing::Test - virtual void SetUp() { - // In the real world, "chrome" is a handled scheme. - URLRequest::RegisterProtocolFactory("chrome", - &URLRequestTestJob::Factory); - } - virtual void TearDown() { - URLRequest::RegisterProtocolFactory("chrome", NULL); - } -}; - -static int kRendererID = 42; - -TEST_F(RendererSecurityPolicyTest, IsWebSafeSchemeTest) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - EXPECT_TRUE(p->IsWebSafeScheme("http")); - EXPECT_TRUE(p->IsWebSafeScheme("https")); - EXPECT_TRUE(p->IsWebSafeScheme("ftp")); - EXPECT_TRUE(p->IsWebSafeScheme("data")); - EXPECT_TRUE(p->IsWebSafeScheme("feed")); - - EXPECT_FALSE(p->IsWebSafeScheme("registered-web-safe-scheme")); - p->RegisterWebSafeScheme("registered-web-safe-scheme"); - EXPECT_TRUE(p->IsWebSafeScheme("registered-web-safe-scheme")); -} - -TEST_F(RendererSecurityPolicyTest, IsPseudoSchemeTest) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - EXPECT_TRUE(p->IsPseudoScheme("about")); - EXPECT_TRUE(p->IsPseudoScheme("javascript")); - EXPECT_TRUE(p->IsPseudoScheme("view-source")); - - EXPECT_FALSE(p->IsPseudoScheme("registered-psuedo-scheme")); - p->RegisterPseudoScheme("registered-psuedo-scheme"); - EXPECT_TRUE(p->IsPseudoScheme("registered-psuedo-scheme")); -} - -TEST_F(RendererSecurityPolicyTest, StandardSchemesTest) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - p->Add(kRendererID); - - // Safe - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("http://www.google.com/"))); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("https://www.paypal.com/"))); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("ftp://ftp.gnu.org/"))); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("data:text/html,Hi"))); - EXPECT_TRUE(p->CanRequestURL(kRendererID, - GURL("view-source:http://www.google.com/"))); - - // Dangerous - EXPECT_FALSE(p->CanRequestURL(kRendererID, - GURL("file:///etc/passwd"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, - GURL("view-cache:http://www.google.com/"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, - GURL("chrome://foo/bar"))); - - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, AboutTest) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - p->Add(kRendererID); - - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:blank"))); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:BlAnK"))); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:BlAnK"))); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:blank"))); - - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:memory"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:cache"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:hang"))); - - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBoUt:memory"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:CrASh"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("abOuT:cAChe"))); - - p->GrantRequestURL(kRendererID, GURL("about:memory")); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:memory"))); - - p->GrantRequestURL(kRendererID, GURL("about:crash")); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash"))); - - p->GrantRequestURL(kRendererID, GURL("about:cache")); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:cache"))); - - p->GrantRequestURL(kRendererID, GURL("about:hang")); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:hang"))); - - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, JavaScriptTest) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - p->Add(kRendererID); - - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')"))); - p->GrantRequestURL(kRendererID, GURL("javascript:alert('xss')")); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')"))); - - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, RegisterWebSafeSchemeTest) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - p->Add(kRendererID); - - // Currently, "asdf" is destined for ShellExecute, so it is allowed. - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); - - // Once we register a ProtocolFactory for "asdf", we default to deny. - URLRequest::RegisterProtocolFactory("asdf", &URLRequestTestJob::Factory); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); - - // We can allow new schemes by adding them to the whitelist. - p->RegisterWebSafeScheme("asdf"); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); - - // Cleanup. - URLRequest::RegisterProtocolFactory("asdf", NULL); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); - - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, CanServiceCommandsTest) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - p->Add(kRendererID); - - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); - p->GrantRequestURL(kRendererID, GURL("file:///etc/passwd")); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); - - // We should forget our state if we repeat a renderer id. - p->Remove(kRendererID); - p->Add(kRendererID); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, ViewSource) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - p->Add(kRendererID); - - // View source is determined by the embedded scheme. - EXPECT_TRUE(p->CanRequestURL(kRendererID, - GURL("view-source:http://www.google.com/"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, - GURL("view-source:file:///etc/passwd"))); - EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); - - p->GrantRequestURL(kRendererID, GURL("view-source:file:///etc/passwd")); - // View source needs to be able to request the embedded scheme. - EXPECT_TRUE(p->CanRequestURL(kRendererID, - GURL("view-source:file:///etc/passwd"))); - EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); - - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, CanUploadFiles) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - p->Add(kRendererID); - - EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/passwd")); - p->GrantUploadFile(kRendererID, L"/etc/passwd"); - EXPECT_TRUE(p->CanUploadFile(kRendererID, L"/etc/passwd")); - EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/shadow")); - - p->Remove(kRendererID); - p->Add(kRendererID); - - EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/passwd")); - EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/shadow")); - - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, CanServiceInspectElement) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - GURL url("chrome://inspector/inspector.html"); - - p->Add(kRendererID); - - EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); - p->GrantInspectElement(kRendererID); - EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); - - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, CanServiceDOMUIBindings) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - GURL url("chrome://thumb/http://www.google.com/"); - - p->Add(kRendererID); - - EXPECT_FALSE(p->HasDOMUIBindings(kRendererID)); - EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); - p->GrantDOMUIBindings(kRendererID); - EXPECT_TRUE(p->HasDOMUIBindings(kRendererID)); - EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); - - p->Remove(kRendererID); -} - -TEST_F(RendererSecurityPolicyTest, RemoveRace) { - RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance(); - - GURL url("file:///etc/passwd"); - std::wstring file(L"/etc/passwd"); - - p->Add(kRendererID); - - p->GrantRequestURL(kRendererID, url); - p->GrantUploadFile(kRendererID, file); - p->GrantDOMUIBindings(kRendererID); - - EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); - EXPECT_TRUE(p->CanUploadFile(kRendererID, file)); - EXPECT_TRUE(p->HasDOMUIBindings(kRendererID)); - - p->Remove(kRendererID); - - // Renderers are added and removed on the UI thread, but the policy can be - // queried on the IO thread. The RendererSecurityPolicy needs to be prepared - // to answer policy questions about renderers who no longer exist. - - // In this case, we default to secure behavior. - EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); - EXPECT_FALSE(p->CanUploadFile(kRendererID, file)); - EXPECT_FALSE(p->HasDOMUIBindings(kRendererID)); -} - diff --git a/chrome/browser/resource_message_filter.cc b/chrome/browser/resource_message_filter.cc index 5732ed9..c959ae7 100644 --- a/chrome/browser/resource_message_filter.cc +++ b/chrome/browser/resource_message_filter.cc @@ -15,7 +15,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/plugin_service.h" #include "chrome/browser/renderer_host/browser_render_process_host.h" -#include "chrome/browser/render_widget_helper.h" +#include "chrome/browser/renderer_host/render_widget_helper.h" #include "chrome/browser/spellchecker.h" #include "chrome/common/chrome_plugin_lib.h" #include "chrome/common/chrome_plugin_util.h" diff --git a/chrome/browser/site_instance_unittest.cc b/chrome/browser/site_instance_unittest.cc index 647a221..d1691fa 100644 --- a/chrome/browser/site_instance_unittest.cc +++ b/chrome/browser/site_instance_unittest.cc @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/render_view_host.h" #include "chrome/browser/renderer_host/browser_render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/render_messages.h" diff --git a/chrome/browser/ssl/ssl_manager.cc b/chrome/browser/ssl/ssl_manager.cc index b2fd246..49227e2 100644 --- a/chrome/browser/ssl/ssl_manager.cc +++ b/chrome/browser/ssl/ssl_manager.cc @@ -10,7 +10,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/load_notification_details.h" #include "chrome/browser/load_from_memory_cache_details.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/resource_request_details.h" #include "chrome/browser/ssl/ssl_error_info.h" #include "chrome/browser/ssl/ssl_policy.h" diff --git a/chrome/browser/ssl/ssl_policy.cc b/chrome/browser/ssl/ssl_policy.cc index e857244..61aada3 100644 --- a/chrome/browser/ssl/ssl_policy.cc +++ b/chrome/browser/ssl/ssl_policy.cc @@ -9,7 +9,7 @@ #include "base/string_util.h" #include "chrome/browser/browser_resources.h" #include "chrome/browser/cert_store.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/ssl/ssl_error_info.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/tab_contents.h" diff --git a/chrome/browser/tab_contents/interstitial_page.cc b/chrome/browser/tab_contents/interstitial_page.cc index 491b1cc..bc65504 100644 --- a/chrome/browser/tab_contents/interstitial_page.cc +++ b/chrome/browser/tab_contents/interstitial_page.cc @@ -8,7 +8,7 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_resources.h" #include "chrome/browser/dom_operation_notification_details.h" -#include "chrome/browser/render_widget_host_view_win.h" +#include "chrome/browser/renderer_host/render_widget_host_view_win.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/web_contents.h" diff --git a/chrome/browser/tab_contents/interstitial_page.h b/chrome/browser/tab_contents/interstitial_page.h index 9a68f95..755ec65 100644 --- a/chrome/browser/tab_contents/interstitial_page.h +++ b/chrome/browser/tab_contents/interstitial_page.h @@ -7,7 +7,7 @@ #include -#include "chrome/browser/render_view_host_delegate.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/common/notification_registrar.h" #include "googleurl/src/gurl.h" diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc new file mode 100644 index 0000000..4aecf00 --- /dev/null +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -0,0 +1,180 @@ +// Copyright (c) 2006-2008 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/tab_contents/render_view_context_menu.h" + +#include "base/logging.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/search_engines/template_url_model.h" +#include "chrome/browser/spellchecker.h" +#include "chrome/common/l10n_util.h" +#include "webkit/glue/context_node_types.h" + +#include "generated_resources.h" + +RenderViewContextMenu::RenderViewContextMenu( + Menu::Delegate* delegate, + HWND owner, + ContextNode::Type type, + const std::wstring& misspelled_word, + const std::vector& misspelled_word_suggestions, + Profile* profile) + : Menu(delegate, Menu::TOPLEFT, owner), + misspelled_word_(misspelled_word), + misspelled_word_suggestions_(misspelled_word_suggestions), + profile_(profile) { + InitMenu(type); +} + +RenderViewContextMenu::~RenderViewContextMenu() { +} + +void RenderViewContextMenu::InitMenu(ContextNode::Type type) { + switch (type) { + case ContextNode::PAGE: + AppendPageItems(); + break; + case ContextNode::FRAME: + AppendFrameItems(); + break; + case ContextNode::LINK: + AppendLinkItems(); + break; + case ContextNode::IMAGE: + AppendImageItems(); + break; + case ContextNode::IMAGE_LINK: + AppendLinkItems(); + AppendSeparator(); + AppendImageItems(); + break; + case ContextNode::SELECTION: + AppendSelectionItems(); + break; + case ContextNode::EDITABLE: + AppendEditableItems(); + break; + default: + NOTREACHED() << "Unknown ContextNode::Type"; + } + AppendSeparator(); + AppendDeveloperItems(); +} + +void RenderViewContextMenu::AppendDeveloperItems() { + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_INSPECTELEMENT); +} + +void RenderViewContextMenu::AppendLinkItems() { + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKNEWTAB); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVELINKAS); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYLINKLOCATION); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY); +} + +void RenderViewContextMenu::AppendImageItems() { + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEIMAGEAS); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYIMAGELOCATION); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYIMAGE); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB); +} + +void RenderViewContextMenu::AppendPageItems() { + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_BACK); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_FORWARD); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_RELOAD); + AppendSeparator(); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEPAGEAS); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PRINT); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWPAGESOURCE); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWPAGEINFO); +} + +void RenderViewContextMenu::AppendFrameItems() { + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_BACK); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_FORWARD); + AppendSeparator(); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMENEWTAB); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMENEWWINDOW); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMEOFFTHERECORD); + AppendSeparator(); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEFRAMEAS); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PRINTFRAME); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMEINFO); +} + +void RenderViewContextMenu::AppendSelectionItems() { + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY); + DCHECK(profile_); + if (profile_->GetTemplateURLModel()->GetDefaultSearchProvider() != NULL) + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SEARCHWEBFOR); +} + +void RenderViewContextMenu::AppendEditableItems() { + // Append Dictionary spell check suggestions. + for (size_t i = 0; i < misspelled_word_suggestions_.size() && + IDC_SPELLCHECK_SUGGESTION_0 + i <= IDC_SPELLCHECK_SUGGESTION_LAST; + i ++) { + AppendMenuItemWithLabel(IDC_SPELLCHECK_SUGGESTION_0 + static_cast(i), + misspelled_word_suggestions_[i]); + } + if (misspelled_word_suggestions_.size() > 0) + AppendSeparator(); + + // If word is misspelled, give option for "Add to dictionary" + if (!misspelled_word_.empty()) { + if (misspelled_word_suggestions_.size() == 0) { + AppendMenuItemWithLabel(0, + l10n_util::GetString(IDS_CONTENT_CONTEXT_NO_SPELLING_SUGGESTIONS)); + } + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY); + AppendSeparator(); + } + + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_UNDO); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_REDO); + AppendSeparator(); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_CUT); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PASTE); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_DELETE); + AppendSeparator(); + + // Add Spell Check options sub menu. + spellchecker_sub_menu_ = AppendSubMenu(IDC_SPELLCHECK_MENU, + l10n_util::GetString(IDS_CONTENT_CONTEXT_SPELLCHECK_MENU)); + + // Add Spell Check languages to sub menu. + SpellChecker::Languages display_languages; + SpellChecker::GetSpellCheckLanguagesToDisplayInContextMenu(profile_, + &display_languages); + DCHECK(display_languages.size() < + IDC_SPELLCHECK_LANGUAGES_LAST - IDC_SPELLCHECK_LANGUAGES_FIRST); + const std::wstring app_locale = g_browser_process->GetApplicationLocale(); + for (size_t i = 0; i < display_languages.size(); ++i) { + std::wstring local_language(l10n_util::GetLocalName( + display_languages[i], app_locale, true)); + spellchecker_sub_menu_->AppendMenuItem( + IDC_SPELLCHECK_LANGUAGES_FIRST + i, local_language, RADIO); + } + + // Add item in the sub menu to pop up the fonts and languages options menu. + spellchecker_sub_menu_->AppendSeparator(); + spellchecker_sub_menu_->AppendDelegateMenuItem( + IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS); + + // Add 'Check the spelling of this field' item in the sub menu. + spellchecker_sub_menu_->AppendMenuItem( + IDC_CHECK_SPELLING_OF_THIS_FIELD, + l10n_util::GetString(IDS_CONTENT_CONTEXT_CHECK_SPELLING_OF_THIS_FIELD), + CHECKBOX); + + AppendSeparator(); + AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SELECTALL); +} diff --git a/chrome/browser/tab_contents/render_view_context_menu.h b/chrome/browser/tab_contents/render_view_context_menu.h new file mode 100644 index 0000000..6c95f57 --- /dev/null +++ b/chrome/browser/tab_contents/render_view_context_menu.h @@ -0,0 +1,44 @@ +// Copyright (c) 2006-2008 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_RENDERER_HOST_RENDER_VIEW_CONTEXT_MENU_H_ +#define CHROME_BROWSER_RENDERER_HOST_RENDER_VIEW_CONTEXT_MENU_H_ + +#include "chrome/views/menu.h" +#include "webkit/glue/context_node_types.h" + +class Profile; + +class RenderViewContextMenu : public Menu { + public: + RenderViewContextMenu( + Menu::Delegate* delegate, + HWND owner, + ContextNode::Type type, + const std::wstring& misspelled_word, + const std::vector& misspelled_word_suggestions, + Profile* profile); + + virtual ~RenderViewContextMenu(); + + private: + void InitMenu(ContextNode::Type type); + void AppendDeveloperItems(); + void AppendLinkItems(); + void AppendImageItems(); + void AppendPageItems(); + void AppendFrameItems(); + void AppendSelectionItems(); + void AppendEditableItems(); + + std::wstring misspelled_word_; + std::vector misspelled_word_suggestions_; + Profile* profile_; + Menu* spellchecker_sub_menu_; + + DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenu); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_VIEW_CONTEXT_MENU_H_ + diff --git a/chrome/browser/tab_contents/render_view_context_menu_controller.cc b/chrome/browser/tab_contents/render_view_context_menu_controller.cc new file mode 100644 index 0000000..4b3a245 --- /dev/null +++ b/chrome/browser/tab_contents/render_view_context_menu_controller.cc @@ -0,0 +1,516 @@ +// Copyright (c) 2006-2008 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/tab_contents/render_view_context_menu_controller.h" + +#include "base/command_line.h" +#include "base/path_service.h" +#include "base/scoped_clipboard_writer.h" +#include "base/string_util.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/views/options/fonts_languages_window_view.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/spellchecker.h" +#include "chrome/browser/download/download_manager.h" +#include "chrome/browser/download/save_package.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/search_engines/template_url_model.h" +#include "chrome/browser/views/page_info_window.h" +#include "chrome/browser/tab_contents/navigation_controller.h" +#include "chrome/browser/tab_contents/navigation_entry.h" +#include "chrome/browser/tab_contents/web_contents.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/clipboard_service.h" +#include "chrome/common/l10n_util.h" +#include "chrome/common/win_util.h" +#include "net/base/escape.h" +#include "net/base/net_util.h" +#include "net/url_request/url_request.h" + +#include "generated_resources.h" + +RenderViewContextMenuController::RenderViewContextMenuController( + WebContents* source_web_contents, + const ViewHostMsg_ContextMenu_Params& params) + : source_web_contents_(source_web_contents), + params_(params) { +} + +RenderViewContextMenuController::~RenderViewContextMenuController() { +} + +/////////////////////////////////////////////////////////////////////////////// +// Controller methods + +void RenderViewContextMenuController::OpenURL( + const GURL& url, + WindowOpenDisposition disposition, + PageTransition::Type transition) { + source_web_contents_->OpenURL(url, GURL(), disposition, transition); +} + +void RenderViewContextMenuController::CopyImageAt(int x, int y) { + source_web_contents_->render_view_host()->CopyImageAt(x, y); +} + +void RenderViewContextMenuController::Inspect(int x, int y) { + source_web_contents_->render_view_host()->InspectElementAt(x, y); +} + +void RenderViewContextMenuController::WriteTextToClipboard( + const std::wstring& text) { + ClipboardService* clipboard = g_browser_process->clipboard_service(); + + if (!clipboard) + return; + + ScopedClipboardWriter scw(clipboard); + scw.WriteText(text); +} + +void RenderViewContextMenuController::WriteURLToClipboard(const GURL& url) { + if (url.SchemeIs("mailto")) + WriteTextToClipboard(UTF8ToWide(url.path())); + else + WriteTextToClipboard(UTF8ToWide(url.spec())); +} + +/////////////////////////////////////////////////////////////////////////////// +// Menu::Delegate methods + +std::wstring RenderViewContextMenuController::GetLabel(int id) const { + switch (id) { + case IDS_CONTENT_CONTEXT_SEARCHWEBFOR: { + const TemplateURL* const default_provider = source_web_contents_-> + profile()->GetTemplateURLModel()->GetDefaultSearchProvider(); + DCHECK(default_provider); // The context menu should not contain this + // item when there is no provider. + return l10n_util::GetStringF(id, default_provider->short_name(), + l10n_util::TruncateString(params_.selection_text, 50)); + } + + case IDS_CONTENT_CONTEXT_COPYLINKLOCATION: + if (params_.link_url.SchemeIs("mailto")) + return l10n_util::GetString(IDS_CONTENT_CONTEXT_COPYEMAILADDRESS); + + default: + return l10n_util::GetString(id); + } +} + +bool RenderViewContextMenuController::IsCommandEnabled(int id) const { + // Allow Spell Check language items on sub menu for text area context menu. + if ((id >= IDC_SPELLCHECK_LANGUAGES_FIRST) && + (id < IDC_SPELLCHECK_LANGUAGES_LAST)) { + return true; + } + + switch (id) { + case IDS_CONTENT_CONTEXT_BACK: + return source_web_contents_->controller()->CanGoBack(); + + case IDS_CONTENT_CONTEXT_FORWARD: + return source_web_contents_->controller()->CanGoForward(); + + case IDS_CONTENT_CONTEXT_VIEWPAGESOURCE: + case IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE: + case IDS_CONTENT_CONTEXT_INSPECTELEMENT: + return IsDevCommandEnabled(id); + + case IDS_CONTENT_CONTEXT_OPENLINKNEWTAB: + case IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW: + case IDS_CONTENT_CONTEXT_COPYLINKLOCATION: + return params_.link_url.is_valid(); + + case IDS_CONTENT_CONTEXT_SAVELINKAS: + return params_.link_url.is_valid() && + URLRequest::IsHandledURL(params_.link_url); + + case IDS_CONTENT_CONTEXT_SAVEIMAGEAS: + return params_.image_url.is_valid() && + URLRequest::IsHandledURL(params_.image_url); + + case IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB: + case IDS_CONTENT_CONTEXT_COPYIMAGELOCATION: + return params_.image_url.is_valid(); + + case IDS_CONTENT_CONTEXT_SAVEPAGEAS: + return SavePackage::IsSavableURL(source_web_contents_->GetURL()); + + case IDS_CONTENT_CONTEXT_OPENFRAMENEWTAB: + case IDS_CONTENT_CONTEXT_OPENFRAMENEWWINDOW: + return params_.frame_url.is_valid(); + + case IDS_CONTENT_CONTEXT_UNDO: + return !!(params_.edit_flags & ContextNode::CAN_UNDO); + + case IDS_CONTENT_CONTEXT_REDO: + return !!(params_.edit_flags & ContextNode::CAN_REDO); + + case IDS_CONTENT_CONTEXT_CUT: + return !!(params_.edit_flags & ContextNode::CAN_CUT); + + case IDS_CONTENT_CONTEXT_COPY: + return !!(params_.edit_flags & ContextNode::CAN_COPY); + + case IDS_CONTENT_CONTEXT_PASTE: + return !!(params_.edit_flags & ContextNode::CAN_PASTE); + + case IDS_CONTENT_CONTEXT_DELETE: + return !!(params_.edit_flags & ContextNode::CAN_DELETE); + + case IDS_CONTENT_CONTEXT_SELECTALL: + return !!(params_.edit_flags & ContextNode::CAN_SELECT_ALL); + + case IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD: + return !source_web_contents_->profile()->IsOffTheRecord() && + params_.link_url.is_valid(); + + case IDS_CONTENT_CONTEXT_OPENFRAMEOFFTHERECORD: + return !source_web_contents_->profile()->IsOffTheRecord() && + params_.frame_url.is_valid(); + + case IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY: + return !params_.misspelled_word.empty(); + + case IDS_CONTENT_CONTEXT_VIEWPAGEINFO: + return (source_web_contents_->controller()->GetActiveEntry() != NULL); + + case IDS_CONTENT_CONTEXT_RELOAD: + case IDS_CONTENT_CONTEXT_COPYIMAGE: + case IDS_CONTENT_CONTEXT_PRINT: + case IDS_CONTENT_CONTEXT_SEARCHWEBFOR: + case IDC_SPELLCHECK_SUGGESTION_0: + case IDC_SPELLCHECK_SUGGESTION_1: + case IDC_SPELLCHECK_SUGGESTION_2: + case IDC_SPELLCHECK_SUGGESTION_3: + case IDC_SPELLCHECK_SUGGESTION_4: + case IDC_SPELLCHECK_MENU: + case IDC_CHECK_SPELLING_OF_THIS_FIELD: + case IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS: + case IDS_CONTENT_CONTEXT_VIEWFRAMEINFO: + return true; + + case IDS_CONTENT_CONTEXT_SAVEFRAMEAS: + case IDS_CONTENT_CONTEXT_PRINTFRAME: + case IDS_CONTENT_CONTEXT_ADDSEARCHENGINE: // Not implemented. + default: + return false; + } +} + +bool RenderViewContextMenuController::IsItemChecked(int id) const { + // Check box for 'Check the Spelling of this field'. + if (id == IDC_CHECK_SPELLING_OF_THIS_FIELD) + return params_.spellcheck_enabled; + + // Don't bother getting the display language vector if this isn't a spellcheck + // language. + if ((id < IDC_SPELLCHECK_LANGUAGES_FIRST) || + (id >= IDC_SPELLCHECK_LANGUAGES_LAST)) + return false; + + SpellChecker::Languages display_languages; + return SpellChecker::GetSpellCheckLanguagesToDisplayInContextMenu( + source_web_contents_->profile(), &display_languages) == + (id - IDC_SPELLCHECK_LANGUAGES_FIRST); +} + +bool RenderViewContextMenuController::GetAcceleratorInfo( + int id, + views::Accelerator* accel) { + // There are no formally defined accelerators we can query so we assume + // that Ctrl+C, Ctrl+V, Ctrl+X, Ctrl-A, etc do what they normally do. + switch (id) { + case IDS_CONTENT_CONTEXT_UNDO: + *accel = views::Accelerator(L'Z', false, true, false); + return true; + + case IDS_CONTENT_CONTEXT_REDO: + *accel = views::Accelerator(L'Z', true, true, false); + return true; + + case IDS_CONTENT_CONTEXT_CUT: + *accel = views::Accelerator(L'X', false, true, false); + return true; + + case IDS_CONTENT_CONTEXT_COPY: + *accel = views::Accelerator(L'C', false, true, false); + return true; + + case IDS_CONTENT_CONTEXT_PASTE: + *accel = views::Accelerator(L'V', false, true, false); + return true; + + case IDS_CONTENT_CONTEXT_SELECTALL: + *accel = views::Accelerator(L'A', false, true, false); + + default: + return false; + } +} + +void RenderViewContextMenuController::ExecuteCommand(int id) { + // Check to see if one of the spell check language ids have been clicked. + if (id >= IDC_SPELLCHECK_LANGUAGES_FIRST && + id < IDC_SPELLCHECK_LANGUAGES_LAST) { + const size_t language_number = id - IDC_SPELLCHECK_LANGUAGES_FIRST; + SpellChecker::Languages display_languages; + SpellChecker::GetSpellCheckLanguagesToDisplayInContextMenu( + source_web_contents_->profile(), &display_languages); + if (language_number < display_languages.size()) { + StringPrefMember dictionary_language; + dictionary_language.Init(prefs::kSpellCheckDictionary, + source_web_contents_->profile()->GetPrefs(), NULL); + dictionary_language.SetValue(display_languages[language_number]); + } + + return; + } + + switch (id) { + case IDS_CONTENT_CONTEXT_OPENLINKNEWTAB: + OpenURL(params_.link_url, NEW_BACKGROUND_TAB, PageTransition::LINK); + break; + + case IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW: + OpenURL(params_.link_url, NEW_WINDOW, PageTransition::LINK); + break; + + case IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD: + OpenURL(params_.link_url, OFF_THE_RECORD, PageTransition::LINK); + break; + + // TODO(paulg): Prompt the user for file name when saving links and images. + case IDS_CONTENT_CONTEXT_SAVEIMAGEAS: + case IDS_CONTENT_CONTEXT_SAVELINKAS: { + const GURL& referrer = + params_.frame_url.is_empty() ? params_.page_url : params_.frame_url; + const GURL& url = id == IDS_CONTENT_CONTEXT_SAVELINKAS ? params_.link_url : + params_.image_url; + DownloadManager* dlm = + source_web_contents_->profile()->GetDownloadManager(); + dlm->DownloadUrl(url, referrer, source_web_contents_); + break; + } + + case IDS_CONTENT_CONTEXT_COPYLINKLOCATION: + WriteURLToClipboard(params_.link_url); + break; + + case IDS_CONTENT_CONTEXT_COPYIMAGELOCATION: + WriteURLToClipboard(params_.image_url); + break; + + case IDS_CONTENT_CONTEXT_COPYIMAGE: + CopyImageAt(params_.x, params_.y); + break; + + case IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB: + OpenURL(params_.image_url, NEW_BACKGROUND_TAB, PageTransition::LINK); + break; + + case IDS_CONTENT_CONTEXT_BACK: + source_web_contents_->controller()->GoBack(); + break; + + case IDS_CONTENT_CONTEXT_FORWARD: + source_web_contents_->controller()->GoForward(); + break; + + case IDS_CONTENT_CONTEXT_SAVEPAGEAS: + source_web_contents_->OnSavePage(); + break; + + case IDS_CONTENT_CONTEXT_RELOAD: + source_web_contents_->controller()->Reload(true); + break; + + case IDS_CONTENT_CONTEXT_PRINT: + source_web_contents_->PrintPreview(); + break; + + case IDS_CONTENT_CONTEXT_VIEWPAGESOURCE: + OpenURL(GURL("view-source:" + params_.page_url.spec()), + NEW_FOREGROUND_TAB, PageTransition::GENERATED); + break; + + case IDS_CONTENT_CONTEXT_INSPECTELEMENT: + Inspect(params_.x, params_.y); + break; + + case IDS_CONTENT_CONTEXT_VIEWPAGEINFO: { + NavigationEntry* nav_entry = + source_web_contents_->controller()->GetActiveEntry(); + PageInfoWindow::CreatePageInfo(source_web_contents_->profile(), + nav_entry, + source_web_contents_->GetContentHWND(), + PageInfoWindow::SECURITY); + break; + } + + case IDS_CONTENT_CONTEXT_OPENFRAMENEWTAB: + OpenURL(params_.frame_url, NEW_BACKGROUND_TAB, PageTransition::LINK); + break; + + case IDS_CONTENT_CONTEXT_OPENFRAMENEWWINDOW: + OpenURL(params_.frame_url, NEW_WINDOW, PageTransition::LINK); + break; + + case IDS_CONTENT_CONTEXT_OPENFRAMEOFFTHERECORD: + OpenURL(params_.frame_url, OFF_THE_RECORD, PageTransition::LINK); + break; + + case IDS_CONTENT_CONTEXT_SAVEFRAMEAS: + win_util::MessageBox(NULL, L"Context Menu Action", L"Save Frame As", + MB_OK); + break; + + case IDS_CONTENT_CONTEXT_PRINTFRAME: + win_util::MessageBox(NULL, L"Context Menu Action", L"Print Frame", + MB_OK); + break; + + case IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE: + OpenURL(GURL("view-source:" + params_.frame_url.spec()), + NEW_FOREGROUND_TAB, PageTransition::GENERATED); + break; + + case IDS_CONTENT_CONTEXT_VIEWFRAMEINFO: { + // Deserialize the SSL info. + NavigationEntry::SSLStatus ssl; + if (!params_.security_info.empty()) { + int cert_id, cert_status, security_bits; + SSLManager::DeserializeSecurityInfo(params_.security_info, + &cert_id, + &cert_status, + &security_bits); + ssl.set_cert_id(cert_id); + ssl.set_cert_status(cert_status); + ssl.set_security_bits(security_bits); + } + PageInfoWindow::CreateFrameInfo(source_web_contents_->profile(), + params_.frame_url, + ssl, + source_web_contents_->GetContentHWND(), + PageInfoWindow::SECURITY); + break; + } + + case IDS_CONTENT_CONTEXT_UNDO: + source_web_contents_->render_view_host()->Undo(); + break; + + case IDS_CONTENT_CONTEXT_REDO: + source_web_contents_->render_view_host()->Redo(); + break; + + case IDS_CONTENT_CONTEXT_CUT: + source_web_contents_->render_view_host()->Cut(); + break; + + case IDS_CONTENT_CONTEXT_COPY: + source_web_contents_->render_view_host()->Copy(); + break; + + case IDS_CONTENT_CONTEXT_PASTE: + source_web_contents_->render_view_host()->Paste(); + break; + + case IDS_CONTENT_CONTEXT_DELETE: + source_web_contents_->render_view_host()->Delete(); + break; + + case IDS_CONTENT_CONTEXT_SELECTALL: + source_web_contents_->render_view_host()->SelectAll(); + break; + + case IDS_CONTENT_CONTEXT_SEARCHWEBFOR: { + const TemplateURL* const default_provider = source_web_contents_-> + profile()->GetTemplateURLModel()->GetDefaultSearchProvider(); + DCHECK(default_provider); // The context menu should not contain this + // item when there is no provider. + const TemplateURLRef* const search_url = default_provider->url(); + DCHECK(search_url->SupportsReplacement()); + OpenURL(GURL(search_url->ReplaceSearchTerms(*default_provider, + params_.selection_text, TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, + std::wstring())), NEW_FOREGROUND_TAB, PageTransition::GENERATED); + break; + } + + case IDC_SPELLCHECK_SUGGESTION_0: + case IDC_SPELLCHECK_SUGGESTION_1: + case IDC_SPELLCHECK_SUGGESTION_2: + case IDC_SPELLCHECK_SUGGESTION_3: + case IDC_SPELLCHECK_SUGGESTION_4: + source_web_contents_->render_view_host()->Replace( + params_.dictionary_suggestions[id - IDC_SPELLCHECK_SUGGESTION_0]); + break; + + case IDC_CHECK_SPELLING_OF_THIS_FIELD: + source_web_contents_->render_view_host()->ToggleSpellCheck(); + break; + case IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY: + source_web_contents_->render_view_host()->AddToDictionary( + params_.misspelled_word); + break; + + case IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS: { + FontsLanguagesWindowView* window_ = new FontsLanguagesWindowView( + source_web_contents_->profile()); + views::Window::CreateChromeWindow(source_web_contents_->GetContentHWND(), + gfx::Rect(), window_)->Show(); + window_->SelectLanguagesTab(); + break; + } + + case IDS_CONTENT_CONTEXT_ADDSEARCHENGINE: // Not implemented. + default: + break; + } +} + +bool RenderViewContextMenuController::IsDevCommandEnabled(int id) const { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kAlwaysEnableDevTools)) + return true; + + NavigationEntry *active_entry = + source_web_contents_->controller()->GetActiveEntry(); + if (!active_entry) + return false; + + // Don't inspect HTML dialogs. + if (source_web_contents_->type() == TAB_CONTENTS_HTML_DIALOG) + return false; + + // Don't inspect view source. + if (source_web_contents_->type() == TAB_CONTENTS_VIEW_SOURCE) + return false; + + // Don't inspect inspector, new tab UI, etc. + if (active_entry->url().SchemeIs("chrome")) + return false; + + // Don't inspect about:network, about:memory, etc. + // However, we do want to inspect about:blank, which is often + // used by ordinary web pages. + if (active_entry->display_url().SchemeIs("about") && + !LowerCaseEqualsASCII(active_entry->display_url().path(), "blank")) + return false; + + // Don't enable the web inspector if JavaScript is disabled + if (id == IDS_CONTENT_CONTEXT_INSPECTELEMENT) { + PrefService* prefs = source_web_contents_->profile()->GetPrefs(); + if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled) || + command_line.HasSwitch(switches::kDisableJavaScript)) + return false; + } + + return true; +} + diff --git a/chrome/browser/tab_contents/render_view_context_menu_controller.h b/chrome/browser/tab_contents/render_view_context_menu_controller.h new file mode 100644 index 0000000..89270b5 --- /dev/null +++ b/chrome/browser/tab_contents/render_view_context_menu_controller.h @@ -0,0 +1,56 @@ +// Copyright (c) 2006-2008 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_RENDERER_HOST_RENDER_VIEW_CONTEXT_MENU_CONTROLLER_H_ +#define CHROME_BROWSER_RENDERER_HOST_RENDER_VIEW_CONTEXT_MENU_CONTROLLER_H_ + +#include "chrome/common/pref_member.h" +#include "chrome/views/menu.h" +#include "chrome/common/render_messages.h" + +class WebContents; + +class RenderViewContextMenuController : public Menu::Delegate { + public: + RenderViewContextMenuController(WebContents* source_web_contents, + const ViewHostMsg_ContextMenu_Params& params); + virtual ~RenderViewContextMenuController(); + + // Overridden from Menu::Delegate + virtual std::wstring GetLabel(int id) const; + virtual bool IsCommandEnabled(int id) const; + virtual bool IsItemChecked(int id) const; + virtual void ExecuteCommand(int id); + virtual bool GetAcceleratorInfo(int id, views::Accelerator* accel); + + private: + // Opens the specified URL string in a new tab. If |in_current_window| is + // false, a new window is created to hold the new tab. + void OpenURL(const GURL& url, + WindowOpenDisposition disposition, + PageTransition::Type transition); + + // Copy to the clipboard an image located at a point in the RenderView + void CopyImageAt(int x, int y); + + // Launch the inspector targeting a point in the RenderView + void Inspect(int x, int y); + + // Writes the specified text/url to the system clipboard + void WriteTextToClipboard(const std::wstring& text); + void WriteURLToClipboard(const GURL& url); + + bool IsDevCommandEnabled(int id) const; + + DISALLOW_EVIL_CONSTRUCTORS(RenderViewContextMenuController); + + private: + WebContents* source_web_contents_; + ViewHostMsg_ContextMenu_Params params_; + StringPrefMember dictionary_language_; + int current_dictionary_language_index_; +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_VIEW_CONTEXT_MENU_CONTROLLER_H_ + diff --git a/chrome/browser/tab_contents/render_view_host_manager.cc b/chrome/browser/tab_contents/render_view_host_manager.cc new file mode 100644 index 0000000..3e235e2 --- /dev/null +++ b/chrome/browser/tab_contents/render_view_host_manager.cc @@ -0,0 +1,503 @@ +// Copyright (c) 2006-2008 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/tab_contents/render_view_host_manager.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "chrome/browser/renderer_host/render_widget_host_view.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" +#include "chrome/browser/tab_contents/navigation_controller.h" +#include "chrome/browser/tab_contents/navigation_entry.h" +#include "chrome/browser/tab_contents/site_instance.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/notification_service.h" + +namespace base { +class WaitableEvent; +} + +RenderViewHostManager::RenderViewHostManager( + RenderViewHostFactory* render_view_factory, + RenderViewHostDelegate* render_view_delegate, + Delegate* delegate) + : delegate_(delegate), + cross_navigation_pending_(false), + render_view_factory_(render_view_factory), + render_view_delegate_(render_view_delegate), + render_view_host_(NULL), + pending_render_view_host_(NULL), + interstitial_page_(NULL) { +} + +RenderViewHostManager::~RenderViewHostManager() { + // Shutdown should have been called which should have cleaned these up. + DCHECK(!render_view_host_); + DCHECK(!pending_render_view_host_); +} + +void RenderViewHostManager::Init(Profile* profile, + SiteInstance* site_instance, + int routing_id, + base::WaitableEvent* modal_dialog_event) { + // Create a RenderViewHost, once we have an instance. It is important to + // immediately give this SiteInstance to a RenderViewHost so that it is + // ref counted. + if (!site_instance) + site_instance = SiteInstance::CreateSiteInstance(profile); + render_view_host_ = CreateRenderViewHost( + site_instance, routing_id, modal_dialog_event); +} + +void RenderViewHostManager::Shutdown() { + if (pending_render_view_host_) + CancelPendingRenderView(); + + // We should always have a main RenderViewHost. + render_view_host_->Shutdown(); + render_view_host_ = NULL; +} + +RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { + RenderViewHost* dest_render_view_host = UpdateRendererStateNavigate(entry); + if (!dest_render_view_host) + return NULL; // We weren't able to create a pending render view host. + + // If the current render_view_host_ isn't live, we should create it so + // that we don't show a sad tab while the dest_render_view_host fetches + // its first page. (Bug 1145340) + if (dest_render_view_host != render_view_host_ && + !render_view_host_->IsRenderViewLive()) { + delegate_->CreateRenderViewForRenderManager(render_view_host_); + } + + // If the renderer crashed, then try to create a new one to satisfy this + // navigation request. + if (!dest_render_view_host->IsRenderViewLive()) { + if (!delegate_->CreateRenderViewForRenderManager(dest_render_view_host)) + return NULL; + + // Now that we've created a new renderer, be sure to hide it if it isn't + // our primary one. Otherwise, we might crash if we try to call Show() + // on it later. + if (dest_render_view_host != render_view_host_ && + dest_render_view_host->view()) { + dest_render_view_host->view()->Hide(); + } else { + // This is our primary renderer, notify here as we won't be calling + // SwapToRenderView (which does the notify). + RenderViewHostSwitchedDetails details; + details.new_host = render_view_host_; + details.old_host = NULL; + NotificationService::current()->Notify( + NOTIFY_RENDER_VIEW_HOST_CHANGED, + Source( + delegate_->GetControllerForRenderManager()), + Details(&details)); + } + } + + return dest_render_view_host; +} + +void RenderViewHostManager::Stop() { + render_view_host_->Stop(); + + // If we are cross-navigating, we should stop the pending renderers. This + // will lead to a DidFailProvisionalLoad, which will properly destroy them. + if (cross_navigation_pending_) { + pending_render_view_host_->Stop(); + + } +} + +void RenderViewHostManager::SetIsLoading(bool is_loading) { + render_view_host_->SetIsLoading(is_loading); + if (pending_render_view_host_) + pending_render_view_host_->SetIsLoading(is_loading); +} + +bool RenderViewHostManager::ShouldCloseTabOnUnresponsiveRenderer() { + if (!cross_navigation_pending_) + return true; + + // If the tab becomes unresponsive during unload while doing a + // crosssite navigation, proceed with the navigation. + int pending_request_id = pending_render_view_host_->GetPendingRequestId(); + if (pending_request_id == -1) { + // Haven't gotten around to starting the request. + pending_render_view_host_->SetNavigationsSuspended(false); + } else { + current_host()->process()->CrossSiteClosePageACK( + pending_render_view_host_->site_instance()->process_host_id(), + pending_request_id); + DidNavigateMainFrame(pending_render_view_host_); + } + return false; +} + +void RenderViewHostManager::DidNavigateMainFrame( + RenderViewHost* render_view_host) { + if (!cross_navigation_pending_) { + // We should only hear this from our current renderer. + DCHECK(render_view_host == render_view_host_); + return; + } + + if (render_view_host == pending_render_view_host_) { + // The pending cross-site navigation completed, so show the renderer. + SwapToRenderView(&pending_render_view_host_, true); + cross_navigation_pending_ = false; + } else if (render_view_host == render_view_host_) { + // A navigation in the original page has taken place. Cancel the pending + // one. + CancelPendingRenderView(); + cross_navigation_pending_ = false; + } else { + // No one else should be sending us DidNavigate in this state. + DCHECK(false); + } +} + +void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id, + int new_request_id) { + // Should only see this while we have a pending renderer. + if (!cross_navigation_pending_) + return; + DCHECK(pending_render_view_host_); + + // Tell the old renderer to run its onunload handler. When it finishes, it + // will send a ClosePage_ACK to the ResourceDispatcherHost with the given + // IDs (of the pending RVH's request), allowing the pending RVH's response to + // resume. + render_view_host_->ClosePage(new_render_process_host_id, new_request_id); + + // ResourceDispatcherHost has told us to run the onunload handler, which + // means it is not a download or unsafe page, and we are going to perform the + // navigation. Thus, we no longer need to remember that the RenderViewHost + // is part of a pending cross-site request. + pending_render_view_host_->SetHasPendingCrossSiteRequest(false, + new_request_id); +} + +void RenderViewHostManager::RendererAbortedProvisionalLoad( + RenderViewHost* render_view_host) { + // We used to cancel the pending renderer here for cross-site downloads. + // However, it's not safe to do that because the download logic repeatedly + // looks for this TabContents based on a render view ID. Instead, we just + // leave the pending renderer around until the next navigation event + // (Navigate, DidNavigate, etc), which will clean it up properly. + // TODO(creis): All of this will go away when we move the cross-site logic + // to ResourceDispatcherHost, so that we intercept responses rather than + // navigation events. (That's necessary to support onunload anyway.) Once + // we've made that change, we won't create a pending renderer until we know + // the response is not a download. +} + +void RenderViewHostManager::ShouldClosePage(bool proceed) { + // Should only see this while we have a pending renderer. Otherwise, we + // should ignore. + if (!pending_render_view_host_) { + bool proceed_to_fire_unload; + delegate_->BeforeUnloadFiredFromRenderManager(proceed, + &proceed_to_fire_unload); + + if (proceed_to_fire_unload) { + // This is not a cross-site navigation, the tab is being closed. + render_view_host_->FirePageUnload(); + } + return; + } + + if (proceed) { + // Ok to unload the current page, so proceed with the cross-site navigate. + pending_render_view_host_->SetNavigationsSuspended(false); + } else { + // Current page says to cancel. + CancelPendingRenderView(); + cross_navigation_pending_ = false; + } +} + +void RenderViewHostManager::OnJavaScriptMessageBoxClosed( + IPC::Message* reply_msg, + bool success, + const std::wstring& prompt) { + render_view_host_->JavaScriptMessageBoxClosed(reply_msg, success, prompt); +} + + +bool RenderViewHostManager::ShouldTransitionCrossSite() { + // True if we are using process-per-site-instance (default) or + // process-per-site (kProcessPerSite). + return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); +} + +SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( + const NavigationEntry& entry, + SiteInstance* curr_instance) { + // NOTE: This is only called when ShouldTransitionCrossSite is true. + + // If the entry has an instance already, we should use it. + if (entry.site_instance()) + return entry.site_instance(); + + // (UGLY) HEURISTIC, process-per-site only: + // + // If this navigation is generated, then it probably corresponds to a search + // query. Given that search results typically lead to users navigating to + // other sites, we don't really want to use the search engine hostname to + // determine the site instance for this navigation. + // + // NOTE: This can be removed once we have a way to transition between + // RenderViews in response to a link click. + // + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && + entry.transition_type() == PageTransition::GENERATED) + return curr_instance; + + const GURL& dest_url = entry.url(); + + // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it + // for this entry. We won't commit the SiteInstance to this site until the + // navigation commits (in DidNavigate), unless the navigation entry was + // restored. As session restore loads all the pages immediately we need to set + // the site first, otherwise after a restore none of the pages would share + // renderers. + if (!curr_instance->has_site()) { + // If we've already created a SiteInstance for our destination, we don't + // want to use this unused SiteInstance; use the existing one. (We don't + // do this check if the curr_instance has a site, because for now, we want + // to compare against the current URL and not the SiteInstance's site. In + // this case, there is no current URL, so comparing against the site is ok. + // See additional comments below.) + if (curr_instance->HasRelatedSiteInstance(dest_url)) { + return curr_instance->GetRelatedSiteInstance(dest_url); + } else { + if (entry.restored()) + curr_instance->SetSite(dest_url); + return curr_instance; + } + } + + // Otherwise, only create a new SiteInstance for cross-site navigation. + + // TODO(creis): Once we intercept links and script-based navigations, we + // will be able to enforce that all entries in a SiteInstance actually have + // the same site, and it will be safe to compare the URL against the + // SiteInstance's site, as follows: + // const GURL& current_url = curr_instance->site(); + // For now, though, we're in a hybrid model where you only switch + // SiteInstances if you type in a cross-site URL. This means we have to + // compare the entry's URL to the last committed entry's URL. + NavigationController* controller = delegate_->GetControllerForRenderManager(); + NavigationEntry* curr_entry = controller->GetLastCommittedEntry(); + if (interstitial_page_) { + // The interstitial is currently the last committed entry, but we want to + // compare against the last non-interstitial entry. + curr_entry = controller->GetEntryAtOffset(-1); + } + // If there is no last non-interstitial entry (and curr_instance already + // has a site), then we must have been opened from another tab. We want + // to compare against the URL of the page that opened us, but we can't + // get to it directly. The best we can do is check against the site of + // the SiteInstance. This will be correct when we intercept links and + // script-based navigations, but for now, it could place some pages in a + // new process unnecessarily. We should only hit this case if a page tries + // to open a new tab to an interstitial-inducing URL, and then navigates + // the page to a different same-site URL. (This seems very unlikely in + // practice.) + const GURL& current_url = (curr_entry) ? curr_entry->url() : + curr_instance->site(); + + if (SiteInstance::IsSameWebSite(current_url, dest_url)) { + return curr_instance; + } else { + // Start the new renderer in a new SiteInstance, but in the current + // BrowsingInstance. It is important to immediately give this new + // SiteInstance to a RenderViewHost (if it is different than our current + // SiteInstance), so that it is ref counted. This will happen in + // CreatePendingRenderView. + return curr_instance->GetRelatedSiteInstance(dest_url); + } +} + +bool RenderViewHostManager::CreatePendingRenderView(SiteInstance* instance) { + NavigationEntry* curr_entry = + delegate_->GetControllerForRenderManager()->GetLastCommittedEntry(); + if (curr_entry && curr_entry->tab_type() == TAB_CONTENTS_WEB) { + DCHECK(!curr_entry->content_state().empty()); + + // TODO(creis): Should send a message to the RenderView to let it know + // we're about to switch away, so that it sends an UpdateState message. + } + + pending_render_view_host_ = + CreateRenderViewHost(instance, MSG_ROUTING_NONE, NULL); + + bool success = delegate_->CreateRenderViewForRenderManager( + pending_render_view_host_); + if (success) { + // Don't show the view until we get a DidNavigate from it. + pending_render_view_host_->view()->Hide(); + } else { + CancelPendingRenderView(); + } + return success; +} + +RenderViewHost* RenderViewHostManager::CreateRenderViewHost( + SiteInstance* instance, + int routing_id, + base::WaitableEvent* modal_dialog_event) { + if (render_view_factory_) { + return render_view_factory_->CreateRenderViewHost( + instance, render_view_delegate_, routing_id, modal_dialog_event); + } else { + return new RenderViewHost(instance, render_view_delegate_, routing_id, + modal_dialog_event); + } +} + +void RenderViewHostManager::SwapToRenderView( + RenderViewHost** new_render_view_host, + bool destroy_after) { + // Remember if the page was focused so we can focus the new renderer in + // that case. + bool focus_render_view = render_view_host_->view() && + render_view_host_->view()->HasFocus(); + + // Hide the current view and prepare to destroy it. + // TODO(creis): Get the old RenderViewHost to send us an UpdateState message + // before we destroy it. + if (render_view_host_->view()) + render_view_host_->view()->Hide(); + RenderViewHost* old_render_view_host = render_view_host_; + + // Swap in the pending view and make it active. + render_view_host_ = (*new_render_view_host); + (*new_render_view_host) = NULL; + + // If the view is gone, then this RenderViewHost died while it was hidden. + // We ignored the RendererGone call at the time, so we should send it now + // to make sure the sad tab shows up, etc. + if (render_view_host_->view()) + render_view_host_->view()->Show(); + else + delegate_->RendererGoneFromRenderManager(render_view_host_); + + // Make sure the size is up to date. (Fix for bug 1079768.) + delegate_->UpdateRenderViewSizeForRenderManager(); + + if (focus_render_view && render_view_host_->view()) + render_view_host_->view()->Focus(); + + RenderViewHostSwitchedDetails details; + details.new_host = render_view_host_; + details.old_host = old_render_view_host; + NotificationService::current()->Notify( + NOTIFY_RENDER_VIEW_HOST_CHANGED, + Source(delegate_->GetControllerForRenderManager()), + Details(&details)); + + if (destroy_after) + old_render_view_host->Shutdown(); + + // Let the task manager know that we've swapped RenderViewHosts, since it + // might need to update its process groupings. + delegate_->NotifySwappedFromRenderManager(); +} + +RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate( + const NavigationEntry& entry) { + // If we are cross-navigating, then we want to get back to normal and navigate + // as usual. + if (cross_navigation_pending_) { + if (pending_render_view_host_) + CancelPendingRenderView(); + cross_navigation_pending_ = false; + } + + // render_view_host_ will not be deleted before the end of this method, so we + // don't have to worry about this SiteInstance's ref count dropping to zero. + SiteInstance* curr_instance = render_view_host_->site_instance(); + + // Determine if we need a new SiteInstance for this entry. + // Again, new_instance won't be deleted before the end of this method, so it + // is safe to use a normal pointer here. + SiteInstance* new_instance = curr_instance; + if (ShouldTransitionCrossSite()) + new_instance = GetSiteInstanceForEntry(entry, curr_instance); + + if (new_instance != curr_instance) { + // New SiteInstance. + DCHECK(!cross_navigation_pending_); + + // Create a pending RVH and navigate it. + bool success = CreatePendingRenderView(new_instance); + if (!success) + return NULL; + + // Check if our current RVH is live before we set up a transition. + if (!render_view_host_->IsRenderViewLive()) { + if (!cross_navigation_pending_) { + // The current RVH is not live. There's no reason to sit around with a + // sad tab or a newly created RVH while we wait for the pending RVH to + // navigate. Just switch to the pending RVH now and go back to non + // cross-navigating (Note that we don't care about on{before}unload + // handlers if the current RVH isn't live.) + SwapToRenderView(&pending_render_view_host_, true); + return render_view_host_; + } else { + NOTREACHED(); + return render_view_host_; + } + } + // Otherwise, it's safe to treat this as a pending cross-site transition. + + // Make sure the old render view stops, in case a load is in progress. + render_view_host_->Stop(); + + // Suspend the new render view (i.e., don't let it send the cross-site + // Navigate message) until we hear back from the old renderer's + // onbeforeunload handler. If it returns false, we'll have to cancel the + // request. + pending_render_view_host_->SetNavigationsSuspended(true); + + // Tell the CrossSiteRequestManager that this RVH has a pending cross-site + // request, so that ResourceDispatcherHost will know to tell us to run the + // old page's onunload handler before it sends the response. + pending_render_view_host_->SetHasPendingCrossSiteRequest(true, -1); + + // We now have a pending RVH. + DCHECK(!cross_navigation_pending_); + cross_navigation_pending_ = true; + + // Tell the old render view to run its onbeforeunload handler, since it + // doesn't otherwise know that the cross-site request is happening. This + // will trigger a call to ShouldClosePage with the reply. + render_view_host_->FirePageBeforeUnload(); + + return pending_render_view_host_; + } + + // Same SiteInstance can be used. Navigate render_view_host_ if we are not + // cross navigating. + DCHECK(!cross_navigation_pending_); + return render_view_host_; +} + +void RenderViewHostManager::CancelPendingRenderView() { + pending_render_view_host_->Shutdown(); + pending_render_view_host_ = NULL; +} + +void RenderViewHostManager::CrossSiteNavigationCanceled() { + DCHECK(cross_navigation_pending_); + cross_navigation_pending_ = false; + if (pending_render_view_host_) + CancelPendingRenderView(); +} + diff --git a/chrome/browser/tab_contents/render_view_host_manager.h b/chrome/browser/tab_contents/render_view_host_manager.h new file mode 100644 index 0000000..29a9f8f --- /dev/null +++ b/chrome/browser/tab_contents/render_view_host_manager.h @@ -0,0 +1,234 @@ +// Copyright (c) 2006-2008 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_TAB_CONTENTS_RENDER_VIEW_HOST_MANAGER_H_ +#define CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_HOST_MANAGER_H_ + +#include + +#include + +#include "base/basictypes.h" +#include "chrome/browser/renderer_host/render_view_host.h" + +class InterstitialPage; +class NavigationController; +class NavigationEntry; +class Profile; +class RenderViewHostDelegate; +class RenderViewHostFactory; +class RenderWidgetHostView; +class SiteInstance; + +// Manages RenderViewHosts for a WebContents. Normally there is only one and +// it is easy to do. But we can also have transitions of processes (and hence +// RenderViewHosts) that can get complex. +class RenderViewHostManager { + public: + // Functions implemented by our owner that we need. + // + // TODO(brettw) Clean this up! These are all the functions in WebContents that + // are required to run this class. The design should probably be better such + // that these are more clear. + // + // There is additional complexity that some of the functions we need in + // WebContents are inherited and non-virtual. These are named with + // "RenderManager" so that the duplicate implementation of them will be clear. + class Delegate { + public: + // See web_contents.h's implementation for more. + virtual bool CreateRenderViewForRenderManager( + RenderViewHost* render_view_host) = 0; + virtual void BeforeUnloadFiredFromRenderManager( + bool proceed, bool* proceed_to_fire_unload) = 0; + virtual void DidStartLoadingFromRenderManager( + RenderViewHost* render_view_host, int32 page_id) = 0; + virtual void RendererGoneFromRenderManager( + RenderViewHost* render_view_host) = 0; + virtual void UpdateRenderViewSizeForRenderManager() = 0; + virtual void NotifySwappedFromRenderManager() = 0; + virtual NavigationController* GetControllerForRenderManager() = 0; + }; + + // The factory is optional. It is used by unit tests to supply custom render + // view hosts. When NULL, the regular RenderViewHost will be created. + // + // Both delegate pointers must be non-NULL and are not owned by this class. + // They must outlive this class. The RenderViewHostDelegate is what will be + // installed into all RenderViewHosts that are created. + // + // You must call Init() before using this class and Shutdown() before + // deleting it. + RenderViewHostManager(RenderViewHostFactory* render_view_factory, + RenderViewHostDelegate* render_view_delegate, + Delegate* delegate); + ~RenderViewHostManager(); + + // For arguments, see WebContents constructor. + void Init(Profile* profile, + SiteInstance* site_instance, + int routing_id, + base::WaitableEvent* modal_dialog_event); + + // Schedules all RenderViewHosts for destruction. + void Shutdown(); + + // Returns the currently actuive RenderViewHost. + // + // This will be non-NULL between Init() and Shutdown(). You may want to NULL + // check it in many cases, however. Windows can send us messages during the + // destruction process after it has been shut down. + RenderViewHost* current_host() const { + return render_view_host_; + } + + // Returns the view associated with the current RenderViewHost, or NULL if + // there is no current one. + RenderWidgetHostView* current_view() const { + if (!render_view_host_) + return NULL; + return render_view_host_->view(); + } + + // Called when we want to instruct the renderer to navigate to the given + // navigation entry. It may create a new RenderViewHost or re-use an existing + // one. The RenderViewHost to navigate will be returned. Returns NULL if one + // could not be created. + RenderViewHost* Navigate(const NavigationEntry& entry); + + // Instructs the various live views to stop. Called when the user directed the + // page to stop loading. + void Stop(); + + // Notifies the regular and pending RenderViewHosts that a load is or is not + // happening. Even though the message is only for one of them, we don't know + // which one so we tell both. + void SetIsLoading(bool is_loading); + + // Whether to close the tab or not when there is a hang during an unload + // handler. If we are mid-crosssite navigation, then we should proceed + // with the navigation instead of closing the tab. + bool ShouldCloseTabOnUnresponsiveRenderer(); + + // Called when a renderer's main frame navigates. + void DidNavigateMainFrame(RenderViewHost* render_view_host); + + // Allows the WebContents to react when a cross-site response is ready to be + // delivered to a pending RenderViewHost. We must first run the onunload + // handler of the old RenderViewHost before we can allow it to proceed. + void OnCrossSiteResponse(int new_render_process_host_id, + int new_request_id); + + // Notifies that the navigation that initiated a cross-site transition has + // been canceled. + void CrossSiteNavigationCanceled(); + + // Called when a provisional load on the given renderer is aborted. + void RendererAbortedProvisionalLoad(RenderViewHost* render_view_host); + + // Actually implements this RenderViewHostDelegate function for the + // WebContents. + void ShouldClosePage(bool proceed); + + // Forwards the message to the RenderViewHost, which is the original one. + void OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, + bool success, + const std::wstring& prompt); + + // Sets the passed passed interstitial as the currently showing interstitial. + // |interstitial_page| should be non NULL (use the remove_interstitial_page + // method to unset the interstitial) and no interstitial page should be set + // when there is already a non NULL interstitial page set. + void set_interstitial_page(InterstitialPage* interstitial_page) { + DCHECK(!interstitial_page_ && interstitial_page); + interstitial_page_ = interstitial_page; + } + + // Unsets the currently showing interstitial. + void remove_interstitial_page() { + DCHECK(interstitial_page_); + interstitial_page_ = NULL; + } + + // Returns the currently showing interstitial, NULL if no interstitial is + // showing. + InterstitialPage* interstitial_page() const { + return interstitial_page_; + } + + private: + friend class TestWebContents; + + // Returns whether this tab should transition to a new renderer for + // cross-site URLs. Enabled unless we see the --process-per-tab command line + // switch. Can be overridden in unit tests. + bool ShouldTransitionCrossSite(); + + // Returns an appropriate SiteInstance object for the given NavigationEntry, + // possibly reusing the current SiteInstance. + // Never called if --process-per-tab is used. + SiteInstance* GetSiteInstanceForEntry(const NavigationEntry& entry, + SiteInstance* curr_instance); + + // Helper method to create a pending RenderViewHost for a cross-site + // navigation. + bool CreatePendingRenderView(SiteInstance* instance); + + // Creates a RenderViewHost using render_view_factory_ (or directly, if the + // factory is NULL). + RenderViewHost* CreateRenderViewHost(SiteInstance* instance, + int routing_id, + base::WaitableEvent* modal_dialog_event); + + // Replaces the currently shown render_view_host_ with the RenderViewHost in + // the field pointed to by |new_render_view_host|, and then NULLs the field. + // Callers should only pass pointers to the pending_render_view_host_, + // interstitial_render_view_host_, or original_render_view_host_ fields of + // this object. If |destroy_after|, this method will call + // ScheduleDeferredDestroy on the previous render_view_host_. + void SwapToRenderView(RenderViewHost** new_render_view_host, + bool destroy_after); + + // Helper method to terminate the pending RenderViewHost. + void CancelPendingRenderView(); + + RenderViewHost* UpdateRendererStateNavigate(const NavigationEntry& entry); + + // Our delegate, not owned by us. Guaranteed non-NULL. + Delegate* delegate_; + + // Allows tests to create their own render view host types. + RenderViewHostFactory* render_view_factory_; + + // Implemented by the owner of this class, this delegate is installed into all + // the RenderViewHosts that we create. + RenderViewHostDelegate* render_view_delegate_; + + // Our RenderView host. This object is responsible for all communication with + // a child RenderView instance. + RenderViewHost* render_view_host_; + + // A RenderViewHost used to load a cross-site page. This remains hidden + // while a cross-site request is pending until it calls DidNavigate. + RenderViewHost* pending_render_view_host_; + + // The intersitial page currently shown if any, not own by this class + // (the InterstitialPage is self-owned, it deletes itself when hidden). + InterstitialPage* interstitial_page_; + + // Whether a cross-site request is pending (in the new process model). + bool cross_navigation_pending_; + + DISALLOW_COPY_AND_ASSIGN(RenderViewHostManager); +}; + +// The "details" for a NOTIFY_RENDER_VIEW_HOST_CHANGED notification. The old +// host can be NULL when the first RenderViewHost is set. +struct RenderViewHostSwitchedDetails { + RenderViewHost* old_host; + RenderViewHost* new_host; +}; + +#endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_HOST_MANAGER_H_ + diff --git a/chrome/browser/tab_contents/tab_util.cc b/chrome/browser/tab_contents/tab_util.cc index 8cea595..9943279 100644 --- a/chrome/browser/tab_contents/tab_util.cc +++ b/chrome/browser/tab_contents/tab_util.cc @@ -4,8 +4,8 @@ #include "chrome/browser/tab_contents/tab_util.h" -#include "chrome/browser/render_view_host.h" #include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/tab_contents/web_contents.h" #include "net/url_request/url_request.h" diff --git a/chrome/browser/tab_contents/view_source_contents.cc b/chrome/browser/tab_contents/view_source_contents.cc index 849a005..291b0c3 100644 --- a/chrome/browser/tab_contents/view_source_contents.cc +++ b/chrome/browser/tab_contents/view_source_contents.cc @@ -4,8 +4,8 @@ #include "chrome/browser/tab_contents/view_source_contents.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/navigation_entry.h" -#include "chrome/browser/render_view_host.h" ViewSourceContents::ViewSourceContents(Profile* profile, SiteInstance* instance) : WebContents(profile, instance, NULL, MSG_ROUTING_NONE, NULL) { diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc index 9062894..cf36173 100644 --- a/chrome/browser/tab_contents/web_contents.cc +++ b/chrome/browser/tab_contents/web_contents.cc @@ -28,8 +28,8 @@ #include "chrome/browser/plugin_installer.h" #include "chrome/browser/plugin_service.h" #include "chrome/browser/printing/print_job.h" -#include "chrome/browser/render_view_host.h" -#include "chrome/browser/render_widget_host_view_win.h" // TODO(brettw) delete me. +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_widget_host_view_win.h" // TODO(brettw) delete me. #include "chrome/browser/search_engines/template_url_fetcher.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/browser/tab_contents/navigation_entry.h" diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h index 9600a15..c3094a4 100644 --- a/chrome/browser/tab_contents/web_contents.h +++ b/chrome/browser/tab_contents/web_contents.h @@ -9,8 +9,8 @@ #include "chrome/browser/download/save_package.h" #include "chrome/browser/fav_icon_helper.h" #include "chrome/browser/printing/print_view_manager.h" -#include "chrome/browser/render_view_host_delegate.h" -#include "chrome/browser/render_view_host_manager.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" +#include "chrome/browser/tab_contents/render_view_host_manager.h" #include "chrome/browser/shell_dialogs.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/web_app.h" diff --git a/chrome/browser/tab_contents/web_contents_unittest.cc b/chrome/browser/tab_contents/web_contents_unittest.cc index 211d1e8..60f795e 100644 --- a/chrome/browser/tab_contents/web_contents_unittest.cc +++ b/chrome/browser/tab_contents/web_contents_unittest.cc @@ -3,9 +3,9 @@ // found in the LICENSE file. #include "base/logging.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/renderer_host/test_render_view_host.h" -#include "chrome/browser/render_widget_host_view.h" #include "chrome/browser/tab_contents/interstitial_page.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/navigation_entry.h" @@ -887,8 +887,6 @@ TEST_F(WebContentsTest, ShowInterstitialThenNavigate) { EXPECT_EQ(TestInterstitialPage::CANCELED, state); } -// TODO(brettw) fix this test. -#if 0 // Test navigating to a page that shows an interstitial, then close the tab. TEST_F(WebContentsTest, ShowInterstitialThenCloseTab) { // Show interstitial. @@ -904,10 +902,10 @@ TEST_F(WebContentsTest, ShowInterstitialThenCloseTab) { // Now close the tab. contents()->CloseContents(); + ContentsCleanedUp(); EXPECT_TRUE(deleted); EXPECT_EQ(TestInterstitialPage::CANCELED, state); } -#endif // Test that after Proceed is called and an interstitial is still shown, no more // commands get executed. diff --git a/chrome/browser/tab_contents/web_contents_view.cc b/chrome/browser/tab_contents/web_contents_view.cc index c3c8e8b..eee0d98 100644 --- a/chrome/browser/tab_contents/web_contents_view.cc +++ b/chrome/browser/tab_contents/web_contents_view.cc @@ -4,7 +4,7 @@ #include "chrome/browser/tab_contents/web_contents_view.h" -#include "chrome/browser/render_widget_host.h" +#include "chrome/browser/renderer_host/render_widget_host.h" void WebContentsView::RenderWidgetHostDestroyed(RenderWidgetHost* host) { for (PendingWidgetViews::iterator i = pending_widget_views_.begin(); diff --git a/chrome/browser/tab_contents/web_contents_view.h b/chrome/browser/tab_contents/web_contents_view.h index bec1064..12f4ab8 100644 --- a/chrome/browser/tab_contents/web_contents_view.h +++ b/chrome/browser/tab_contents/web_contents_view.h @@ -13,7 +13,7 @@ #include "base/basictypes.h" #include "base/gfx/rect.h" #include "base/gfx/size.h" -#include "chrome/browser/render_view_host_delegate.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" class Browser; class RenderViewHost; diff --git a/chrome/browser/tab_contents/web_contents_view_win.cc b/chrome/browser/tab_contents/web_contents_view_win.cc index 54eb162..5f1016a 100644 --- a/chrome/browser/tab_contents/web_contents_view_win.cc +++ b/chrome/browser/tab_contents/web_contents_view_win.cc @@ -10,10 +10,10 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_request_manager.h" -#include "chrome/browser/render_view_context_menu.h" -#include "chrome/browser/render_view_context_menu_controller.h" -#include "chrome/browser/render_view_host.h" -#include "chrome/browser/render_widget_host_view_win.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_widget_host_view_win.h" +#include "chrome/browser/tab_contents/render_view_context_menu.h" +#include "chrome/browser/tab_contents/render_view_context_menu_controller.h" #include "chrome/browser/tab_contents/interstitial_page.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/browser/tab_contents/web_contents.h" diff --git a/chrome/browser/tab_contents/web_drag_source.cc b/chrome/browser/tab_contents/web_drag_source.cc index b47913b..c1061ee 100644 --- a/chrome/browser/tab_contents/web_drag_source.cc +++ b/chrome/browser/tab_contents/web_drag_source.cc @@ -8,7 +8,7 @@ #include "chrome/browser/tab_contents/web_drag_source.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" namespace { diff --git a/chrome/browser/tab_contents/web_drop_target.cc b/chrome/browser/tab_contents/web_drop_target.cc index c3220e5..90ac002 100644 --- a/chrome/browser/tab_contents/web_drop_target.cc +++ b/chrome/browser/tab_contents/web_drop_target.cc @@ -9,7 +9,7 @@ #include "base/clipboard_util.h" #include "base/gfx/point.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/os_exchange_data.h" #include "googleurl/src/gurl.h" diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index 45a2246..2599382 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -11,7 +11,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profile.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/navigation_entry.h" diff --git a/chrome/browser/views/find_bar_win.cc b/chrome/browser/views/find_bar_win.cc index 867f341..d58cf6c 100644 --- a/chrome/browser/views/find_bar_win.cc +++ b/chrome/browser/views/find_bar_win.cc @@ -7,7 +7,7 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/find_notification_details.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/bookmark_bar_view.h" #include "chrome/browser/views/find_bar_view.h" diff --git a/chrome/browser/views/find_bar_win.h b/chrome/browser/views/find_bar_win.h index 6cc6029..f1727de 100644 --- a/chrome/browser/views/find_bar_win.h +++ b/chrome/browser/views/find_bar_win.h @@ -6,7 +6,7 @@ #define CHROME_BROWSER_VIEWS_FIND_BAR_WIN_H_ #include "base/gfx/rect.h" -#include "chrome/browser/render_view_host_delegate.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/common/animation.h" #include "chrome/views/widget_win.h" diff --git a/chrome/browser/views/hung_renderer_view.cc b/chrome/browser/views/hung_renderer_view.cc index 9c55a1b..bf35e50 100644 --- a/chrome/browser/views/hung_renderer_view.cc +++ b/chrome/browser/views/hung_renderer_view.cc @@ -7,7 +7,7 @@ #include "chrome/app/result_codes.h" #include "chrome/app/theme/theme_resources.h" #include "chrome/browser/browser_list.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/views/standard_layout.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/chrome_constants.h" diff --git a/chrome/browser/views/tab_contents_container_view.cc b/chrome/browser/views/tab_contents_container_view.cc index 01f449b..cfcb301 100644 --- a/chrome/browser/views/tab_contents_container_view.cc +++ b/chrome/browser/views/tab_contents_container_view.cc @@ -7,9 +7,9 @@ #include "chrome/browser/views/tab_contents_container_view.h" #include "base/logging.h" -#include "chrome/browser/render_view_host.h" -#include "chrome/browser/render_view_host_manager.h" -#include "chrome/browser/render_widget_host_view.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_widget_host_view.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/browser/view_ids.h" diff --git a/chrome/browser/web_app.cc b/chrome/browser/web_app.cc index 0d24874e..10f7e35 100644 --- a/chrome/browser/web_app.cc +++ b/chrome/browser/web_app.cc @@ -6,7 +6,7 @@ #include "base/gfx/png_decoder.h" #include "chrome/browser/profile.h" -#include "chrome/browser/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/gfx/favicon_size.h" #include "net/base/base64.h" -- cgit v1.1