blob: 8759231f8571d747aeb852319dcae6767182a7d9 [file] [log] [blame]
// 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 <string>
#include <vector>
#include "base/scoped_ptr.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/common/modal_dialog_event.h"
#include "chrome/common/page_zoom.h"
#include "webkit/api/public/WebConsoleMessage.h"
#include "webkit/glue/autofill_form.h"
#include "webkit/glue/password_form_dom_manager.h"
#include "webkit/glue/window_open_disposition.h"
class AutofillForm;
class NavigationEntry;
class RenderViewHostDelegate;
class SiteInstance;
class SkBitmap;
class ViewMsg_Navigate;
struct ContextMenuParams;
struct ViewHostMsg_DidPrintPage_Params;
struct ViewMsg_Navigate_Params;
struct WebDropData;
struct WebPreferences;
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 TabContents 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 TabContents 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 TabContents 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 {
// 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_; }
ExtensionFunctionDispatcher* extension_function_dispatcher() const {
return extension_function_dispatcher_.get();
// Set up the RenderView child process.
virtual bool CreateRenderView();
// Returns true if the RenderView is active and has not crashed.
virtual bool IsRenderViewLive() const;
virtual void SetRendererPrefs(const RendererPreferences& renderer_prefs);
// 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);
// Returns whether navigation messages are currently suspended for this
// RenderViewHost. Only true during a cross-site navigation, while waiting
// for the onbeforeunload handler.
bool are_navigations_suspended() { return navigations_suspended_; }
// 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. This function
// should only be called to toggle the state; callers should check
// are_navigations_suspended() first.
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();
// Asks the renderer to "render" printed pages and initiate printing on our
// behalf.
bool PrintPages();
// Start looking for a string within the content of the page, with the
// specified options.
void StartFinding(int request_id,
const string16& 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);
// Insert some css into a frame in the page.
void InsertCSSInWebFrame(const std::wstring& frame_xpath,
const std::string& css);
// Logs a message to the console of a frame in the page.
void AddMessageToConsole(const string16& frame_xpath,
const string16& message,
const WebKit::WebConsoleMessage::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);
// This function is called when the JavaScript message box window has been
// destroyed.
void JavaScriptMessageBoxWindowDestroyed();
// 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.
// Must be called before CreateRenderView().
void AllowDomAutomationBindings();
// Tell the render view to allow the javascript access to
// the external host via automation.
// Must be called before CreateRenderView().
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();
// Tell the render view to expose privileged bindings for use by extensions.
// Must be called before CreateRenderView().
void AllowExtensionBindings();
// 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);
// Tells the renderer view to focus the first (last if reverse is true) node.
void SetInitialFocus(bool reverse);
// Clears the node that is currently focused (if any).
void ClearFocusedNode();
// 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<GURL>& links,
const std::vector<FilePath>& local_paths,
const FilePath& 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 FilePath& 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<FilePath>& files);
// Notifies the RenderViewHost that its load state changed.
void LoadStateChanged(const GURL& url, net::LoadState load_state);
bool SuddenTerminationAllowed() const;
void set_sudden_termination_allowed(bool enabled) {
sudden_termination_allowed_ = enabled;
// Forward a message from external host to chrome renderer.
void ForwardMessageFromExternalHost(const std::string& message,
const std::string& origin,
const std::string& target);
// 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<std::wstring>& suggestions,
int64 node_id,
int request_id,
int default_suggestion_index);
// Notifies the Renderer that a move or resize of its containing window has
// started (this is used to hide the autocomplete popups if any).
void WindowMoveOrResizeStarted();
// RenderWidgetHost public overrides.
virtual void Shutdown();
virtual bool IsRenderView() { return true; }
virtual void OnMessageReceived(const IPC::Message& msg);
virtual void GotFocus();
virtual bool CanBlur() const;
virtual void ForwardMouseEvent(const WebKit::WebMouseEvent& mouse_event);
virtual gfx::Rect GetRootWindowResizerRect() const;
// Creates a new RenderView with the given route id.
void CreateNewWindow(int route_id, ModalDialogEvent modal_dialog_event);
// Creates a new RenderWidget with the given route id.
void CreateNewWidget(int route_id, bool activatable);
// Senf the response to an extension api call.
void SendExtensionResponse(int request_id, bool success,
const std::string& response,
const std::string& error);
// RenderWidgetHost protected overrides.
virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event);
virtual void OnUserGesture();
virtual void NotifyRendererUnresponsive();
virtual void NotifyRendererResponsive();
// IPC message handlers.
void OnMsgShowView(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture,
const GURL& creator_url);
void OnMsgShowWidget(int route_id, const gfx::Rect& initial_pos);
void OnMsgRunModal(IPC::Message* reply_msg);
void OnMsgRenderViewReady();
void OnMsgRenderViewGone();
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 GURL& url,
const ThumbnailScore& score,
const SkBitmap& bitmap);
void OnMsgClose();
void OnMsgRequestMove(const gfx::Rect& pos);
void OnMsgDidRedirectProvisionalLoad(int32 page_id,
const GURL& source_url,
const GURL& target_url);
void OnMsgDidStartLoading();
void OnMsgDidStopLoading();
void OnMsgDidLoadResourceFromMemoryCache(const GURL& url,
const std::string& frame_origin,
const std::string& main_frame_origin,
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 ContextMenuParams& params);
void OnMsgOpenURL(const GURL& url, const GURL& referrer,
WindowOpenDisposition disposition);
void OnMsgDidContentsPreferredWidthChange(int pref_width);
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& message,
const std::string& origin,
const std::string& target);
void OnMsgDocumentLoadedInFrame();
void OnMsgGoToEntryAtOffset(int offset);
void OnMsgSetTooltipText(const std::wstring& tooltip_text);
void OnMsgSelectionChanged(const std::string& text);
void OnMsgPasteFromSelectionClipboard();
void OnMsgRunFileChooser(bool multiple_files,
const string16& title,
const FilePath& default_file);
void OnMsgRunJavaScriptMessage(const std::wstring& message,
const std::wstring& default_prompt,
const GURL& frame_url,
const int flags,
IPC::Message* reply_msg);
void OnMsgRunBeforeUnloadConfirm(const GURL& frame_url,
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<PasswordForm>& 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 OnUpdateInspectorSettings(const std::wstring& raw_settings);
void OnForwardToDevToolsAgent(const IPC::Message& message);
void OnForwardToDevToolsClient(const IPC::Message& message);
void OnUserMetricsRecordAction(const std::wstring& action);
void OnMissingPluginStatus(int status);
void OnMessageReceived(IPC::Message* msg) { }
void OnReceivedSavableResourceLinksForCurrentPage(
const std::vector<GURL>& resources_list,
const std::vector<GURL>& referrers_list,
const std::vector<GURL>& 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 OnQueryFormFieldAutofill(const std::wstring& field_name,
const std::wstring& user_text,
int64 node_id,
int request_id);
void OnRemoveAutofillEntry(const std::wstring& field_name,
const std::wstring& value);
void OnExtensionRequest(const std::string& name, const std::string& args,
int request_id, bool has_callback);
void OnExtensionPostMessage(int port_id, const std::string& message);
void OnAccessibilityFocusChange(int acc_obj_id);
// 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.
// The URL parameter should match the one in the message. It's provided so
// that we don't have to decode the message to check it.
void DoNavigate(const GURL& url, ViewMsg_Navigate* nav_message);
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<SiteInstance> instance_;
// Our delegate, which wants to know about changes in the RenderView.
RenderViewHostDelegate* delegate_;
// 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_;
// A bitwise OR of bindings types that have been enabled for this RenderView.
// See BindingsPolicy for details.
int enabled_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_;
// 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<base::WaitableEvent> 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
// TabContents. There will only ever be one suspended navigation, because
// TabContents will destroy the pending RVH and create a new one if a second
// navigation occurs.
scoped_ptr<ViewMsg_Navigate> 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 is_waiting_for_unload_ack_;
bool are_javascript_messages_suppressed_;
// Handles processing IPC messages request extension functions be executed.
// This changes during navigation and may be NULL if the current content is
// not an extension.
scoped_ptr<ExtensionFunctionDispatcher> extension_function_dispatcher_;
// True if the render view can be shut down suddenly.
bool sudden_termination_allowed_;