// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/renderer_host/render_view_host.h" #include #include #include "app/resource_bundle.h" #include "base/command_line.h" #include "base/gfx/native_widget_types.h" #include "base/string_util.h" #include "base/time.h" #include "base/waitable_event.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/child_process_security_policy.h" #include "chrome/browser/cross_site_request_manager.h" #include "chrome/browser/debugger/debugger_wrapper.h" #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/renderer_host/render_widget_host.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/site_instance.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/bindings_policy.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" #include "chrome/common/render_messages.h" #include "chrome/common/result_codes.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/thumbnail_score.h" #include "chrome/common/url_constants.h" #include "net/base/net_util.h" #include "third_party/skia/include/core/SkBitmap.h" #include "webkit/api/public/WebFindOptions.h" #include "webkit/glue/autofill_form.h" #if defined(OS_WIN) // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. #include "chrome/browser/browser_accessibility_manager.h" #endif using base::TimeDelta; using webkit_glue::AutofillForm; using webkit_glue::PasswordFormDomManager; using WebKit::WebConsoleMessage; using WebKit::WebFindOptions; using WebKit::WebInputEvent; namespace { void FilterURL(ChildProcessSecurityPolicy* policy, int renderer_id, GURL* url) { if (!url->is_valid()) return; // We don't need to block invalid URLs. if (url->SchemeIs(chrome::kAboutScheme)) { // The renderer treats all URLs in the about: scheme as being about:blank. // Canonicalize about: URLs to about:blank. *url = GURL(chrome::kAboutBlankURL); } 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), delegate_(delegate), waiting_for_drag_context_response_(false), debugger_attached_(false), enabled_bindings_(0), pending_request_id_(0), modal_dialog_count_(0), navigations_suspended_(false), suspended_nav_message_(NULL), run_modal_reply_msg_(NULL), is_waiting_for_unload_ack_(false), are_javascript_messages_suppressed_(false), sudden_termination_allowed_(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); } RenderViewHost::~RenderViewHost() { OnDebugDisconnect(); // Be sure to clean up any leftover state from cross-site requests. Singleton()->SetHasPendingCrossSiteRequest( process()->pid(), routing_id(), false); NotificationService::current()->Notify( NotificationType::RENDER_VIEW_HOST_DELETED, Source(this), NotificationService::NoDetails()); } 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()); if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) { ChildProcessSecurityPolicy::GetInstance()->GrantDOMUIBindings( process()->pid()); } if (BindingsPolicy::is_extension_enabled(enabled_bindings_)) { ChildProcessSecurityPolicy::GetInstance()->GrantExtensionBindings( process()->pid()); } renderer_initialized_ = true; #if defined(OS_WIN) HANDLE modal_dialog_event_handle; 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_handle, SYNCHRONIZE, FALSE, 0); DCHECK(result) << "Couldn't duplicate the modal dialog handle for the renderer."; #endif ModalDialogEvent modal_dialog_event; #if defined(OS_WIN) modal_dialog_event.event = modal_dialog_event_handle; #endif Send(new ViewMsg_New(GetNativeViewId(), modal_dialog_event, delegate_->GetRendererPrefs(), 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(), enabled_bindings_)); // Let our delegate know that we created a RenderView. delegate_->RenderViewCreated(this); return true; } bool RenderViewHost::IsRenderViewLive() const { return process()->channel() && renderer_initialized_; } void RenderViewHost::SetRendererPrefs( const RendererPreferences& renderer_prefs) { Send(new ViewMsg_SetRendererPrefs(routing_id(), renderer_prefs)); } void RenderViewHost::NavigateToEntry(const NavigationEntry& entry, bool is_reload) { ViewMsg_Navigate_Params params; MakeNavigateParams(entry, is_reload, ¶ms); ChildProcessSecurityPolicy::GetInstance()->GrantRequestURL( process()->pid(), params.url); DoNavigate(entry.url(), 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; ChildProcessSecurityPolicy::GetInstance()->GrantRequestURL( process()->pid(), params.url); DoNavigate(url, new ViewMsg_Navigate(routing_id(), params)); } void RenderViewHost::DoNavigate(const GURL& url, 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, TabContents 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); // Force the throbber to start. We do this because WebKit's "started // loading" message will be received asynchronously from the UI of the // browser. But we want to keep the throbber in sync with what's happening // in the UI. For example, we want to start throbbing immediately when the // user naivgates even if the renderer is delayed. There is also an issue // with the throbber starting because the DOMUI (which controls whether the // favicon is displayed) happens synchronously. If the start loading // messages was asynchronous, then the default favicon would flash in. // // WebKit doesn't send throb notifications for JavaScript URLs, so we // don't want to either. if (!url.SchemeIs(chrome::kJavaScriptScheme)) delegate_->DidStartLoading(this); } } 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) { // This should only be called to toggle the state. DCHECK(navigations_suspended_ != suspend); navigations_suspended_ = suspend; if (!suspend && suspended_nav_message_.get()) { // There's a navigation message waiting to be sent. Now that we're not // suspended anymore, resume navigation by sending it. 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 then 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(process()->pid(), 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->set_sudden_termination_allowed(true); 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()->pid(), 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::PrintPages() { return Send(new ViewMsg_PrintPages(routing_id())); } void RenderViewHost::PrintingDone(int document_cookie, bool success) { Send(new ViewMsg_PrintingDone(routing_id(), document_cookie, success)); } void RenderViewHost::StartFinding(int request_id, const string16& search_text, bool forward, bool match_case, bool find_next) { if (search_text.empty()) return; WebFindOptions options; options.forward = forward; options.matchCase = match_case; options.findNext = find_next; Send(new ViewMsg_Find(routing_id(), request_id, search_text, options)); // 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. ChildProcessSecurityPolicy* policy = ChildProcessSecurityPolicy::GetInstance(); policy->GrantRequestURL(process()->pid(), drop_data.url); for (std::vector::const_iterator iter(drop_data.filenames.begin()); iter != drop_data.filenames.end(); ++iter) { FilePath path = FilePath::FromWStringHack(UTF16ToWideHack(*iter)); policy->GrantRequestURL(process()->pid(), net::FilePathToFileURL(path)); policy->GrantUploadFile(process()->pid(), path); } 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::InsertCSSInWebFrame( const std::wstring& frame_xpath, const std::string& css) { Send(new ViewMsg_CSSInsertRequest(routing_id(), frame_xpath, css)); } void RenderViewHost::AddMessageToConsole( const string16& frame_xpath, const string16& message, const WebConsoleMessage::Level& level) { Send(new ViewMsg_AddMessageToConsole( routing_id(), frame_xpath, message, 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)); } ViewHostMsg_RunJavaScriptMessage::WriteReplyParams(reply_msg, success, prompt); Send(reply_msg); } void RenderViewHost::JavaScriptMessageBoxWindowDestroyed() { if (--modal_dialog_count_ == 0) modal_dialog_event_->Reset(); } 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) { if (!CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableOutOfProcessDevTools)) { DevToolsManager* manager = g_browser_process->devtools_manager(); manager->InspectElement(this, x, y); } else { ChildProcessSecurityPolicy::GetInstance()-> GrantInspectElement(process()->pid()); Send(new ViewMsg_InspectElement(routing_id(), x, y)); } } void RenderViewHost::ShowJavaScriptConsole() { if (!CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableOutOfProcessDevTools)) { DevToolsManager* manager = g_browser_process->devtools_manager(); manager->OpenDevToolsWindow(this); } else { ChildProcessSecurityPolicy::GetInstance()-> GrantInspectElement(process()->pid()); 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(), gfx::Point(client_x, client_y), gfx::Point(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(), gfx::Point(client_x, client_y), gfx::Point(screen_x, screen_y), false)); } void RenderViewHost::DragSourceSystemDragEnded() { Send(new ViewMsg_DragSourceSystemDragEnded(routing_id())); } void RenderViewHost::AllowDomAutomationBindings() { DCHECK(!renderer_initialized_); enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION; } void RenderViewHost::AllowExternalHostBindings() { DCHECK(!renderer_initialized_); enabled_bindings_ |= BindingsPolicy::EXTERNAL_HOST; } void RenderViewHost::AllowDOMUIBindings() { DCHECK(!renderer_initialized_); enabled_bindings_ |= BindingsPolicy::DOM_UI; } void RenderViewHost::AllowExtensionBindings() { DCHECK(!renderer_initialized_); enabled_bindings_ |= BindingsPolicy::EXTENSION; } void RenderViewHost::SetDOMUIProperty(const std::string& name, const std::string& value) { DCHECK(BindingsPolicy::is_dom_ui_enabled(enabled_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; params->request_time = base::Time::Now(); } void RenderViewHost::GotFocus() { RenderWidgetHost::GotFocus(); // Notifies the renderer it got focus. RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (view) view->GotFocus(); } bool RenderViewHost::CanBlur() const { return delegate_->CanBlur(); } void RenderViewHost::SetInitialFocus(bool reverse) { Send(new ViewMsg_SetInitialFocus(routing_id(), reverse)); } void RenderViewHost::ClearFocusedNode() { Send(new ViewMsg_ClearFocusedNode(routing_id())); } 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 FilePath& path) { ChildProcessSecurityPolicy::GetInstance()->GrantUploadFile(process()->pid(), 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) { ChildProcessSecurityPolicy::GetInstance()->GrantUploadFile( process()->pid(), *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::SuddenTerminationAllowed() const { return sudden_termination_allowed_ || process()->sudden_termination_allowed(); } /////////////////////////////////////////////////////////////////////////////// // 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! (message type " << msg.type() << ")"; 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_ShowView, OnMsgShowView) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnMsgShowWidget) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunModal, OnMsgRunModal) IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnMsgRenderViewReady) IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewGone, OnMsgRenderViewGone) 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(ViewHostMsg_Thumbnail, OnMsgThumbnail) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateInspectorSettings, OnUpdateInspectorSettings); 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_DidContentsPreferredWidthChange, OnMsgDidContentsPreferredWidthChange) IPC_MESSAGE_HANDLER(ViewHostMsg_DomOperationResponse, OnMsgDomOperationResponse) IPC_MESSAGE_HANDLER(ViewHostMsg_DOMUISend, OnMsgDOMUISend) IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardMessageToExternalHost, OnMsgForwardMessageToExternalHost) IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentLoadedInFrame, OnMsgDocumentLoadedInFrame) 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_ForwardToDevToolsAgent, OnForwardToDevToolsAgent); IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToDevToolsClient, OnForwardToDevToolsClient); 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_QueryFormFieldAutofill, OnQueryFormFieldAutofill) IPC_MESSAGE_HANDLER(ViewHostMsg_RemoveAutofillEntry, OnRemoveAutofillEntry) IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionRequest, OnExtensionRequest) IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionChanged, OnMsgSelectionChanged) IPC_MESSAGE_HANDLER(ViewHostMsg_PasteFromSelectionClipboard, OnMsgPasteFromSelectionClipboard) IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionPostMessage, OnExtensionPostMessage) IPC_MESSAGE_HANDLER(ViewHostMsg_AccessibilityFocusChange, OnAccessibilityFocusChange) IPC_MESSAGE_HANDLER(ViewHostMsg_OnCSSInserted, OnCSSInserted) // 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::CreateNewWindow(int route_id, ModalDialogEvent modal_dialog_event) { RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (!view) return; base::WaitableEvent* waitable_event = new base::WaitableEvent( #if defined(OS_WIN) modal_dialog_event.event); #else true, false); #endif view->CreateNewWindow(route_id, waitable_event); } void RenderViewHost::CreateNewWidget(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, const GURL& creator_url) { RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (view) { view->ShowCreatedWindow(route_id, disposition, initial_pos, user_gesture, creator_url); Send(new ViewMsg_Move_ACK(route_id)); } } void RenderViewHost::OnMsgShowWidget(int route_id, const gfx::Rect& initial_pos) { RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (view) { view->ShowCreatedWidget(route_id, initial_pos); Send(new ViewMsg_Move_ACK(route_id)); } } 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::OnMsgRenderViewReady() { WasResized(); delegate_->RenderViewReady(this); } void RenderViewHost::OnMsgRenderViewGone() { // Our base class RenderWidgetHost needs to reset some stuff. RendererExited(); delegate_->RenderViewGone(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()->pid(); ChildProcessSecurityPolicy* policy = ChildProcessSecurityPolicy::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); if (PageTransition::IsMainFrame(validated_params.transition)) { ExtensionFunctionDispatcher* new_efd = NULL; if (validated_params.url.SchemeIs(chrome::kExtensionScheme)) { new_efd = delegate()->CreateExtensionFunctionDispatcher(this, validated_params.url.host()); } extension_function_dispatcher_.reset(new_efd); } 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) { if (title.length() > chrome::kMaxTitleChars) { NOTREACHED() << "Renderer sent too many characters in title."; return; } 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 GURL& url, const ThumbnailScore& score, const SkBitmap& bitmap) { delegate_->UpdateThumbnail(url, bitmap, score); } void RenderViewHost::OnUpdateInspectorSettings( const std::wstring& raw_settings) { delegate_->UpdateInspectorSettings(raw_settings); } void RenderViewHost::OnMsgClose() { delegate_->Close(this); } void RenderViewHost::OnMsgRequestMove(const gfx::Rect& pos) { delegate_->RequestMove(pos); Send(new ViewMsg_Move_ACK(routing_id())); } 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() { delegate_->DidStartLoading(this); } void RenderViewHost::OnMsgDidStopLoading() { delegate_->DidStopLoading(this); } void RenderViewHost::OnMsgDidLoadResourceFromMemoryCache( const GURL& url, const std::string& frame_origin, const std::string& main_frame_origin, const std::string& security_info) { delegate_->DidLoadResourceFromMemoryCache( url, frame_origin, main_frame_origin, security_info); } void RenderViewHost::OnMsgDidStartProvisionalLoadForFrame(bool is_main_frame, const GURL& url) { GURL validated_url(url); FilterURL(ChildProcessSecurityPolicy::GetInstance(), process()->pid(), &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(ChildProcessSecurityPolicy::GetInstance(), process()->pid(), &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_->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 ContextMenuParams& 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. ContextMenuParams validated_params(params); const int renderer_id = process()->pid(); ChildProcessSecurityPolicy* policy = ChildProcessSecurityPolicy::GetInstance(); // We don't validate |unfiltered_link_url| so that this field can be used // when users want to copy the original link URL. 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(ChildProcessSecurityPolicy::GetInstance(), process()->pid(), &validated_url); delegate_->RequestOpenURL(validated_url, referrer, disposition); } void RenderViewHost::OnMsgDidContentsPreferredWidthChange(int pref_width) { RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (!view) return; view->UpdatePreferredWidth(pref_width); } 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 (!ChildProcessSecurityPolicy::GetInstance()-> HasDOMUIBindings(process()->pid())) { NOTREACHED() << "Blocked unauthorized use of DOMUIBindings."; return; } delegate_->ProcessDOMUIMessage(message, content); } void RenderViewHost::OnMsgForwardMessageToExternalHost( const std::string& message, const std::string& origin, const std::string& target) { delegate_->ProcessExternalHostMessage(message, origin, target); } void RenderViewHost::OnMsgDocumentLoadedInFrame() { delegate_->DocumentLoadedInFrame(); } void RenderViewHost::DisassociateFromPopupCount() { Send(new ViewMsg_DisassociateFromPopupCount(routing_id())); } void RenderViewHost::PopupNotificationVisibilityChanged(bool visible) { Send(new ViewMsg_PopupNotificationVisibilityChanged(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::OnMsgSelectionChanged(const std::string& text) { if (view()) view()->SelectionChanged(text); } void RenderViewHost::OnMsgPasteFromSelectionClipboard() { if (view()) view()->PasteFromSelectionClipboard(); } void RenderViewHost::OnMsgRunFileChooser(bool multiple_files, const string16& title, const FilePath& default_file) { delegate_->RunFileChooser(multiple_files, title, default_file); } void RenderViewHost::OnMsgRunJavaScriptMessage( const std::wstring& message, const std::wstring& default_prompt, const GURL& frame_url, const int flags, IPC::Message* reply_msg) { StopHangMonitorTimeout(); if (modal_dialog_count_++ == 0) modal_dialog_event_->Signal(); delegate_->RunJavaScriptMessage(message, default_prompt, frame_url, flags, reply_msg, &are_javascript_messages_suppressed_); } void RenderViewHost::OnMsgRunBeforeUnloadConfirm(const GURL& frame_url, 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::OnForwardToDevToolsAgent(const IPC::Message& message) { g_browser_process->devtools_manager()->ForwardToDevToolsAgent(this, message); } void RenderViewHost::OnForwardToDevToolsClient(const IPC::Message& message) { g_browser_process->devtools_manager()->ForwardToDevToolsClient(this, message); } void RenderViewHost::OnUserMetricsRecordAction(const std::wstring& action) { UserMetrics::RecordComputedAction(action.c_str(), process()->profile()); } void RenderViewHost::UnhandledKeyboardEvent( const NativeWebKeyboardEvent& 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::RawKeyDown) || (event.type == WebInputEvent::KeyDown) || (event.type == WebInputEvent::Char)) { view->HandleKeyboardEvent(event); } } } void RenderViewHost::OnUserGesture() { delegate_->OnUserGesture(); } void RenderViewHost::OnMissingPluginStatus(int status) { delegate_->OnMissingPluginStatus(status); } void RenderViewHost::UpdateBackForwardListCount() { int back_list_count = 0, forward_list_count = 0; 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 FilePath& 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::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::OnRemoveAutofillEntry(const std::wstring& field_name, const std::wstring& value) { delegate_->RemoveAutofillEntry(field_name, value); } 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::WindowMoveOrResizeStarted() { Send(new ViewMsg_MoveOrResizeStarted(routing_id())); } 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); } gfx::Rect RenderViewHost::GetRootWindowResizerRect() const { return delegate_->GetRootWindowResizerRect(); } void RenderViewHost::ForwardMouseEvent( const WebKit::WebMouseEvent& mouse_event) { // We make a copy of the mouse event because // RenderWidgetHost::ForwardMouseEvent will delete |mouse_event|. WebKit::WebMouseEvent event_copy(mouse_event); RenderWidgetHost::ForwardMouseEvent(event_copy); RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (view) { switch (event_copy.type) { case WebInputEvent::MouseMove: view->HandleMouseEvent(); break; case WebInputEvent::MouseLeave: view->HandleMouseLeave(); break; default: // For now, we don't care about the rest. break; } } } void RenderViewHost::OnDebugDisconnect() { if (debugger_attached_) { debugger_attached_ = false; g_browser_process->debugger_wrapper()->OnDebugDisconnect(); } DevToolsManager* devtools_manager = g_browser_process->devtools_manager(); if (devtools_manager) // NULL in tests devtools_manager->UnregisterDevToolsClientHostFor(this); } void RenderViewHost::ForwardMessageFromExternalHost(const std::string& message, const std::string& origin, const std::string& target) { Send(new ViewMsg_HandleMessageFromExternalHost(routing_id(), message, origin, target)); } void RenderViewHost::OnExtensionRequest(const std::string& name, const std::string& args, int request_id, bool has_callback) { if (!ChildProcessSecurityPolicy::GetInstance()-> HasExtensionBindings(process()->pid())) { NOTREACHED() << "Blocked unauthorized use of extension bindings."; return; } DCHECK(extension_function_dispatcher_.get()); extension_function_dispatcher_->HandleRequest(name, args, request_id, has_callback); } void RenderViewHost::SendExtensionResponse(int request_id, bool success, const std::string& response, const std::string& error) { Send(new ViewMsg_ExtensionResponse(routing_id(), request_id, success, response, error)); } void RenderViewHost::OnExtensionPostMessage( int port_id, const std::string& message) { URLRequestContext* context = process()->profile()->GetRequestContext(); ExtensionMessageService::GetInstance(context)-> PostMessageFromRenderer(port_id, message); } void RenderViewHost::OnAccessibilityFocusChange(int acc_obj_id) { #if defined(OS_WIN) BrowserAccessibilityManager::GetInstance()-> ChangeAccessibilityFocus(acc_obj_id, process()->pid(), routing_id()); #else // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. #endif } void RenderViewHost::OnCSSInserted() { delegate_->DidInsertCSS(); }