summaryrefslogtreecommitdiffstats
path: root/chrome/browser/render_view_host.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/render_view_host.cc
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/render_view_host.cc')
-rw-r--r--chrome/browser/render_view_host.cc1178
1 files changed, 1178 insertions, 0 deletions
diff --git a/chrome/browser/render_view_host.cc b/chrome/browser/render_view_host.cc
new file mode 100644
index 0000000..3080705
--- /dev/null
+++ b/chrome/browser/render_view_host.cc
@@ -0,0 +1,1178 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/browser/render_view_host.h"
+
+#include <string>
+#include <vector>
+
+#include "base/string_util.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/cross_site_request_manager.h"
+#include "chrome/browser/navigation_entry.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/render_process_host.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/debugger/debugger_wrapper.h"
+#include "chrome/browser/site_instance.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/tab_contents_delegate.h"
+#include "chrome/browser/user_metrics.h"
+#include "chrome/browser/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"
+
+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();
+ }
+}
+
+} // 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<RenderWidgetHost*>(
+ process->GetListenerByID(render_view_id));
+ if (!widget || !widget->IsRenderView())
+ return NULL;
+ return static_cast<RenderViewHost*>(widget);
+}
+
+RenderViewHost::RenderViewHost(SiteInstance* instance,
+ RenderViewHostDelegate* delegate,
+ int routing_id,
+ HANDLE modal_dialog_event)
+ : RenderWidgetHost(instance->GetProcess(), routing_id),
+ instance_(instance),
+ enable_dom_ui_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) {
+ DCHECK(instance_);
+ DCHECK(delegate_);
+ if (modal_dialog_event == NULL)
+ modal_dialog_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ modal_dialog_event_.Set(modal_dialog_event);
+}
+
+RenderViewHost::~RenderViewHost() {
+ OnDebugDisconnect();
+
+ // Be sure to clean up any leftover state from cross-site requests.
+ Singleton<CrossSiteRequestManager>()->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();
+ if (renderer_process_handle == NULL)
+ renderer_process_handle = GetCurrentProcess();
+
+ BOOL result = DuplicateHandle(GetCurrentProcess(),
+ modal_dialog_event_.Get(),
+ 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.
+ if (enable_dom_ui_bindings_)
+ Send(new ViewMsg_AllowDOMUIBindings(routing_id_));
+
+ // 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, &params);
+
+ RendererSecurityPolicy::GetInstance()->GrantRequestURL(
+ process()->host_id(), params.url);
+
+ DoNavigate(new ViewMsg_Navigate(routing_id_, params));
+
+ UpdateBackForwardListCount();
+}
+
+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::AttemptToClosePage(bool is_closing_browser) {
+ if (IsRenderViewLive()) {
+ Send(new ViewMsg_ShouldClose(routing_id_, is_closing_browser));
+ } else {
+ // This RenderViewHost doesn't have a live renderer, so just skip running
+ // the onbeforeunload handler.
+ OnMsgShouldCloseACK(true, is_closing_browser);
+ }
+}
+
+void RenderViewHost::OnProceedWithClosePage(bool is_closing_browser) {
+ Send(new ViewMsg_ClosePage(routing_id_,
+ site_instance()->process_host_id(),
+ routing_id(),
+ is_closing_browser));
+}
+
+// static
+void RenderViewHost::ClosePageIgnoringUnloadEvents(int render_process_host_id,
+ int request_id,
+ bool is_closing_browser) {
+ RenderViewHost* rvh = RenderViewHost::FromID(render_process_host_id,
+ request_id);
+ if (!rvh)
+ return;
+
+ // The RenderViewHost's delegate is a WebContents.
+ TabContents* tab = static_cast<WebContents*>(rvh->delegate());
+ rvh->UnloadListenerHasFired();
+
+ if (is_closing_browser) {
+ tab->delegate()->UnloadFired(tab);
+ } else {
+ rvh->delegate()->Close(rvh);
+ }
+}
+
+void RenderViewHost::ClosePage(int new_render_process_host_id,
+ int new_request_id) {
+ if (IsRenderViewLive()) {
+ Send(new ViewMsg_ClosePage(routing_id_,
+ new_render_process_host_id,
+ new_request_id,
+ false)); // is_closing_browser
+ } 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) {
+ Singleton<CrossSiteRequestManager>()->SetHasPendingCrossSiteRequest(
+ process()->host_id(), routing_id_, has_pending_request);
+}
+
+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) {
+ 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::SendFindReplyAck() {
+ Send(new ViewMsg_FindReplyACK(routing_id_));
+}
+
+void RenderViewHost::AlterTextSize(text_zoom::TextSize size) {
+ Send(new ViewMsg_AlterTextSize(routing_id_, size));
+}
+
+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<std::wstring>::const_iterator iter(drop_data.filenames.begin());
+ iter != drop_data.filenames.end(); ++iter) {
+ policy->GrantRequestURL(process()->host_id(),
+ net_util::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::UploadFile(const std::wstring& file_path,
+ const std::wstring& form,
+ const std::wstring& file,
+ const std::wstring& submit,
+ const std::wstring& other_values) {
+ if (!process_->channel())
+ return;
+
+ RendererSecurityPolicy::GetInstance()->GrantUploadFile(process()->host_id(),
+ file);
+ ViewMsg_UploadFile_Params p;
+ p.file_path = file_path;
+ p.form = form;
+ p.file = file;
+ p.submit = submit;
+ p.other_values = other_values;
+ Send(new ViewMsg_UploadFile(routing_id_, p));
+}
+
+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::SendToDebugger(const std::wstring& cmd) {
+ Send(new ViewMsg_SendToDebugger(routing_id_, cmd));
+}
+
+void RenderViewHost::DebugAttach() {
+ if (!debugger_attached_)
+ Send(new ViewMsg_DebugAttach(routing_id_));
+}
+
+void RenderViewHost::DebugDetach() {
+ if (debugger_attached_) {
+ SendToDebugger(L"quit");
+ debugger_attached_ = false;
+ }
+}
+
+void RenderViewHost::DebugBreak() {
+ if (debugger_attached_)
+ SendToDebugger(L"break");
+}
+
+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::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 (--modal_dialog_count_ == 0)
+ ResetEvent(modal_dialog_event_.Get());
+ ViewHostMsg_RunJavaScriptMessage::WriteReplyParams(reply_msg, success, prompt);
+ Send(reply_msg);
+}
+
+void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg,
+ const std::string& json_retval) {
+ if (--modal_dialog_count_ == 0)
+ ResetEvent(modal_dialog_event_.Get());
+
+ 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::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.GetPageID();
+ params->url = entry.GetURL();
+ params->transition = entry.GetTransitionType();
+ params->state = entry.GetContentState();
+ 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);
+ Send(new ViewMsg_RunFileChooserResponse(routing_id_, path));
+}
+
+void RenderViewHost::LoadStateChanged(const GURL& url,
+ net::LoadState load_state) {
+ delegate_->LoadStateChanged(url, load_state);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 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_CreateViewWithRoute, OnMsgCreateView)
+ 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_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_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);
+ // 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)
+ ResetEvent(modal_dialog_event_.Get());
+ Send(run_modal_reply_msg_);
+ run_modal_reply_msg_ = NULL;
+ }
+ RenderWidgetHost::Shutdown();
+}
+
+void RenderViewHost::OnMsgCreateView(int route_id, HANDLE modal_dialog_event) {
+ delegate_->CreateView(route_id, modal_dialog_event);
+}
+
+void RenderViewHost::OnMsgCreateWidget(int route_id) {
+ delegate_->CreateWidget(route_id);
+}
+
+void RenderViewHost::OnMsgShowView(int route_id,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {
+ delegate_->ShowView(route_id, disposition, initial_pos, user_gesture);
+}
+
+void RenderViewHost::OnMsgShowWidget(int route_id,
+ const gfx::Rect& initial_pos) {
+ delegate_->ShowWidget(route_id, initial_pos);
+}
+
+void RenderViewHost::OnMsgRunModal(IPC::Message* reply_msg) {
+ DCHECK(!run_modal_reply_msg_);
+ if (modal_dialog_count_++ == 0)
+ SetEvent(modal_dialog_event_.Get());
+ 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;
+
+ backing_store_.reset();
+
+ 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<ViewHostMsg_FrameNavigate_Params>::
+ 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<GURL>::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 GURL& url,
+ const std::wstring& title,
+ const std::string& state) {
+ GURL validated_url(url);
+ FilterURL(RendererSecurityPolicy::GetInstance(),
+ process()->host_id(), &validated_url);
+
+ delegate_->UpdateState(this, page_id, validated_url, title, 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<GURL>::Read(&msg, &iter, &url))
+ return;
+
+ ThumbnailScore score;
+ if (!IPC::ParamTraits<ThumbnailScore>::Read(&msg, &iter, &score))
+ return;
+
+ // thumbnail data
+ SkBitmap bitmap;
+ if (!IPC::ParamTraits<SkBitmap>::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) {
+ delegate_->FindReply(request_id, number_of_matches,
+ selection_rect, active_match_ordinal, final_update);
+ SendFindReplyAck();
+}
+
+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) {
+ // 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);
+
+ delegate_->ShowContextMenu(validated_params);
+}
+
+void RenderViewHost::OnMsgOpenURL(const GURL& url,
+ WindowOpenDisposition disposition) {
+ GURL validated_url(url);
+ FilterURL(RendererSecurityPolicy::GetInstance(),
+ process()->host_id(), &validated_url);
+
+ delegate_->RequestOpenURL(validated_url, 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::OnMsgGoToEntryAtOffset(int offset) {
+ delegate_->GoToEntryAtOffset(offset);
+}
+
+void RenderViewHost::OnMsgSetTooltipText(const std::wstring& tooltip_text) {
+ if (view_) {
+ view_->SetTooltipText(tooltip_text);
+ }
+}
+
+void RenderViewHost::OnMsgRunFileChooser(const std::wstring& default_file) {
+ delegate_->RunFileChooser(default_file);
+}
+
+void RenderViewHost::OnMsgRunJavaScriptMessage(
+ const std::wstring& message,
+ const std::wstring& default_prompt,
+ const int flags,
+ IPC::Message* reply_msg) {
+ if (modal_dialog_count_++ == 0)
+ SetEvent(modal_dialog_event_.Get());
+ delegate_->RunJavaScriptMessage(message, default_prompt, flags, reply_msg);
+}
+
+void RenderViewHost::OnMsgRunBeforeUnloadConfirm(const std::wstring& message,
+ IPC::Message* reply_msg) {
+ if (modal_dialog_count_++ == 0)
+ SetEvent(modal_dialog_event_.Get());
+ delegate_->RunBeforeUnloadConfirm(message, reply_msg);
+}
+
+void RenderViewHost::OnMsgShowModalHTMLDialog(
+ const GURL& url, int width, int height, const std::string& json_arguments,
+ IPC::Message* reply_msg) {
+ if (modal_dialog_count_++ == 0)
+ SetEvent(modal_dialog_event_.Get());
+ delegate_->ShowModalHTMLDialog(url, width, height, json_arguments, reply_msg);
+}
+
+void RenderViewHost::OnMsgPasswordFormsSeen(
+ const std::vector<PasswordForm>& forms) {
+ delegate_->PasswordFormsSeen(forms);
+}
+
+void RenderViewHost::OnMsgStartDragging(
+ const WebDropData& drop_data) {
+ delegate_->StartDragging(drop_data);
+}
+
+void RenderViewHost::OnUpdateDragCursor(bool is_drop_target) {
+ delegate_->UpdateDragCursor(is_drop_target);
+}
+
+void RenderViewHost::OnTakeFocus(bool reverse) {
+ delegate_->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"\"%s,\" source: %s (%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;
+ SendToDebugger(L"attach");
+ }
+}
+
+void RenderViewHost::OnUserMetricsRecordAction(const std::wstring& action) {
+ UserMetrics::RecordComputedAction(action.c_str(), process_->profile());
+}
+
+void RenderViewHost::UnhandledInputEvent(const WebInputEvent& event) {
+ if ((event.type == WebInputEvent::KEY_DOWN) ||
+ (event.type == WebInputEvent::CHAR))
+ delegate_->HandleKeyboardEvent(
+ static_cast<const WebKeyboardEvent&>(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<GURL>& resources_list,
+ const std::vector<GURL>& referrers_list,
+ const std::vector<GURL>& frames_list) {
+ 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<std::wstring>& links,
+ const std::vector<std::wstring>& 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) {
+ delegate_->OnReceivedSerializedHtmlData(frame_url, data, status);
+}
+
+void RenderViewHost::OnMsgShouldCloseACK(bool proceed,
+ bool is_closing_browser) {
+ if (is_closing_browser) {
+ // The RenderViewHost's delegate is a WebContents.
+ TabContents* tab = static_cast<WebContents*>(delegate());
+ if (!tab)
+ return;
+
+ tab->delegate()->BeforeUnloadFired(tab, proceed);
+ } else {
+ delegate_->ShouldClosePage(proceed);
+ }
+}
+
+void RenderViewHost::OnUnloadListenerChanged(bool has_listener) {
+ has_unload_listener_ = has_listener;
+}
+
+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);
+}
+
+void RenderViewHost::NotifyRendererResponsive() {
+ delegate_->RendererResponsive(this);
+}
+
+void RenderViewHost::OnDebugDisconnect() {
+ if (debugger_attached_) {
+ debugger_attached_ = false;
+ g_browser_process->debugger_wrapper()->OnDebugDisconnect();
+ }
+}
+
+void RenderViewHost::OnThemeChanged() {
+ Send (new ViewMsg_ThemeChanged(routing_id_));
+}
+