blob: 4dd8a1099f7878464dc4d88cdf4444d9f148914a [file] [log] [blame]
// Copyright (c) 2010 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 <string>
#include <utility>
#include <vector>
#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/json/json_reader.h"
#include "base/metrics/stats_counters.h"
#include "base/string_util.h"
#include "base/time.h"
#include "base/values.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/cross_site_request_manager.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/in_process_webkit/session_storage_namespace.h"
#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/printing/print_preview_tab_controller.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/renderer_host/site_instance.h"
#include "chrome/common/bindings_policy.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/native_web_keyboard_event.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
#include "chrome/common/result_codes.h"
#include "chrome/common/thumbnail_score.h"
#include "chrome/common/translate_errors.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/web_apps.h"
#include "gfx/native_widget_types.h"
#include "net/base/net_util.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFindOptions.h"
#include "webkit/glue/context_menu.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
#include "webkit/glue/password_form_dom_manager.h"
#include "webkit/glue/webaccessibility.h"
#include "webkit/glue/webdropdata.h"
using base::TimeDelta;
using webkit_glue::FormData;
using webkit_glue::PasswordForm;
using webkit_glue::PasswordFormDomManager;
using webkit_glue::PasswordFormFillData;
using WebKit::WebConsoleMessage;
using WebKit::WebDragOperation;
using WebKit::WebDragOperationNone;
using WebKit::WebDragOperationsMask;
using WebKit::WebFindOptions;
using WebKit::WebInputEvent;
using WebKit::WebMediaPlayerAction;
using WebKit::WebTextDirection;
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.
VLOG(1) << "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<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,
SessionStorageNamespace* session_storage)
: RenderWidgetHost(instance->GetProcess(), routing_id),
instance_(instance),
delegate_(delegate),
waiting_for_drag_context_response_(false),
enabled_bindings_(0),
pending_request_id_(0),
navigations_suspended_(false),
suspended_nav_message_(NULL),
run_modal_reply_msg_(NULL),
is_waiting_for_beforeunload_ack_(false),
is_waiting_for_unload_ack_(false),
unload_ack_is_for_cross_site_transition_(false),
are_javascript_messages_suppressed_(false),
sudden_termination_allowed_(false),
session_storage_namespace_(session_storage),
is_extension_process_(false),
autofill_query_id_(0),
save_accessibility_tree_for_testing_(false) {
if (!session_storage_namespace_) {
session_storage_namespace_ =
new SessionStorageNamespace(process()->profile());
}
DCHECK(instance_);
DCHECK(delegate_);
}
RenderViewHost::~RenderViewHost() {
delegate()->RenderViewDeleted(this);
// Be sure to clean up any leftover state from cross-site requests.
Singleton<CrossSiteRequestManager>()->SetHasPendingCrossSiteRequest(
process()->id(), routing_id(), false);
}
bool RenderViewHost::CreateRenderView(const string16& frame_name) {
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(renderer_accessible(), is_extension_process_))
return false;
DCHECK(process()->HasConnection());
DCHECK(process()->profile());
if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) {
ChildProcessSecurityPolicy::GetInstance()->GrantDOMUIBindings(
process()->id());
}
if (BindingsPolicy::is_extension_enabled(enabled_bindings_)) {
ChildProcessSecurityPolicy::GetInstance()->GrantExtensionBindings(
process()->id());
// Extensions may have permission to access chrome:// URLs.
ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
process()->id(), chrome::kChromeUIScheme);
}
renderer_initialized_ = true;
// Force local storage to be enabled for extensions. This is so that we can
// enable extensions by default before databases, if necessary.
// TODO(aa): This should be removed when local storage and databases are
// enabled by default (bugs 4359 and 4360).
WebPreferences webkit_prefs = delegate_->GetWebkitPrefs();
if (delegate_->GetURL().SchemeIs(chrome::kExtensionScheme)) {
webkit_prefs.local_storage_enabled = true;
webkit_prefs.databases_enabled = true;
}
ViewMsg_New_Params params;
params.parent_window = GetNativeViewId();
params.renderer_preferences =
delegate_->GetRendererPrefs(process()->profile());
params.web_preferences = webkit_prefs;
params.view_id = routing_id();
params.session_storage_namespace_id = session_storage_namespace_->id();
params.frame_name = frame_name;
Send(new ViewMsg_New(params));
// 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_));
UpdateBrowserWindowId(delegate_->GetBrowserWindowID());
Send(new ViewMsg_NotifyRenderViewType(routing_id(),
delegate_->GetRenderViewType()));
// Let our delegate know that we created a RenderView.
delegate_->RenderViewCreated(this);
process()->ViewCreated();
return true;
}
bool RenderViewHost::IsRenderViewLive() const {
return process()->HasConnection() && renderer_initialized_;
}
void RenderViewHost::SyncRendererPrefs() {
Send(new ViewMsg_SetRendererPrefs(routing_id(),
delegate_->GetRendererPrefs(
process()->profile())));
}
void RenderViewHost::Navigate(const ViewMsg_Navigate_Params& params) {
ChildProcessSecurityPolicy::GetInstance()->GrantRequestURL(
process()->id(), params.url);
ViewMsg_Navigate* nav_message = new ViewMsg_Navigate(routing_id(), params);
// 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 {
// Unset this, otherwise if true and the hang monitor fires we'll
// incorrectly close the tab.
is_waiting_for_unload_ack_ = false;
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 (!params.url.SchemeIs(chrome::kJavaScriptScheme))
delegate_->DidStartLoading();
const GURL& url = params.url;
if (!delegate_->IsExternalTabContainer() &&
(url.SchemeIs("http") || url.SchemeIs("https")))
chrome_browser_net::PreconnectUrlAndSubresources(url);
}
}
void RenderViewHost::NavigateToURL(const GURL& url) {
ViewMsg_Navigate_Params params;
params.page_id = -1;
params.url = url;
params.transition = PageTransition::LINK;
params.navigation_type = ViewMsg_Navigate_Params::NORMAL;
Navigate(params);
}
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(bool for_cross_site_transition) {
if (!IsRenderViewLive()) {
// This RenderViewHost doesn't have a live renderer, so just skip running
// the onbeforeunload handler.
is_waiting_for_beforeunload_ack_ = true; // Checked by OnMsgShouldCloseACK.
unload_ack_is_for_cross_site_transition_ = for_cross_site_transition;
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), and we only send the message once.
if (is_waiting_for_beforeunload_ack_) {
// Some of our close messages could be for the tab, others for cross-site
// transitions. We always want to think it's for closing the tab if any
// of the messages were, since otherwise it might be impossible to close
// (if there was a cross-site "close" request pending when the user clicked
// the close button). We want to keep the "for cross site" flag only if
// both the old and the new ones are also for cross site.
unload_ack_is_for_cross_site_transition_ =
unload_ack_is_for_cross_site_transition_ && for_cross_site_transition;
} else {
// Start the hang monitor in case the renderer hangs in the beforeunload
// handler.
is_waiting_for_beforeunload_ack_ = true;
unload_ack_is_for_cross_site_transition_ = for_cross_site_transition;
StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
Send(new ViewMsg_ShouldClose(routing_id()));
}
}
void RenderViewHost::ClosePage(bool for_cross_site_transition,
int new_render_process_host_id,
int new_request_id) {
// In most cases, this will not be set to false afterward. Either the tab
// will be closed, or a pending RenderViewHost will replace this one.
is_waiting_for_unload_ack_ = true;
// Start the hang monitor in case the renderer hangs in the unload handler.
StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
ViewMsg_ClosePage_Params params;
params.closing_process_id = process()->id();
params.closing_route_id = routing_id();
params.for_cross_site_transition = for_cross_site_transition;
params.new_render_process_host_id = new_render_process_host_id;
params.new_request_id = new_request_id;
if (IsRenderViewLive()) {
NotificationService::current()->Notify(
NotificationType::RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW,
Source<RenderViewHost>(this),
NotificationService::NoDetails());
Send(new ViewMsg_ClosePage(routing_id(), params));
} 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(params);
}
}
void RenderViewHost::ClosePageIgnoringUnloadEvents() {
StopHangMonitorTimeout();
is_waiting_for_beforeunload_ack_ = false;
is_waiting_for_unload_ack_ = false;
sudden_termination_allowed_ = true;
delegate_->Close(this);
}
void RenderViewHost::SetHasPendingCrossSiteRequest(bool has_pending_request,
int request_id) {
Singleton<CrossSiteRequestManager>()->SetHasPendingCrossSiteRequest(
process()->id(), routing_id(), has_pending_request);
pending_request_id_ = request_id;
}
int RenderViewHost::GetPendingRequestId() {
return pending_request_id_;
}
void RenderViewHost::Stop() {
Send(new ViewMsg_Stop(routing_id()));
}
void RenderViewHost::ReloadFrame() {
Send(new ViewMsg_ReloadFrame(routing_id()));
}
bool RenderViewHost::PrintPages() {
return Send(new ViewMsg_PrintPages(routing_id()));
}
bool RenderViewHost::PrintPreview() {
return Send(new ViewMsg_PrintPreview(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(
FindBarController::SelectionAction selection_action) {
ViewMsg_StopFinding_Params params;
switch (selection_action) {
case FindBarController::kClearSelection:
params.action = ViewMsg_StopFinding_Params::kClearSelection;
break;
case FindBarController::kKeepSelection:
params.action = ViewMsg_StopFinding_Params::kKeepSelection;
break;
case FindBarController::kActivateSelection:
params.action = ViewMsg_StopFinding_Params::kActivateSelection;
break;
default:
NOTREACHED();
params.action = ViewMsg_StopFinding_Params::kKeepSelection;
}
Send(new ViewMsg_StopFinding(routing_id(), params));
}
void RenderViewHost::Zoom(PageZoom::Function function) {
Send(new ViewMsg_Zoom(routing_id(), function));
}
void RenderViewHost::SetZoomLevel(double zoom_level) {
Send(new ViewMsg_SetZoomLevel(routing_id(), zoom_level));
}
void RenderViewHost::SetPageEncoding(const std::string& encoding_name) {
Send(new ViewMsg_SetPageEncoding(routing_id(), encoding_name));
}
void RenderViewHost::ResetPageEncodingToDefault() {
Send(new ViewMsg_ResetPageEncodingToDefault(routing_id()));
}
void RenderViewHost::SetAlternateErrorPageURL(const GURL& url) {
Send(new ViewMsg_SetAltErrorPageURL(routing_id(), url));
}
void RenderViewHost::FillPasswordForm(
const webkit_glue::PasswordFormFillData& 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,
WebDragOperationsMask operations_allowed) {
// Grant the renderer the ability to load the drop_data.
ChildProcessSecurityPolicy* policy =
ChildProcessSecurityPolicy::GetInstance();
policy->GrantRequestURL(process()->id(), drop_data.url);
for (std::vector<string16>::const_iterator iter(drop_data.filenames.begin());
iter != drop_data.filenames.end(); ++iter) {
FilePath path = FilePath::FromWStringHack(UTF16ToWideHack(*iter));
policy->GrantRequestURL(process()->id(),
net::FilePathToFileURL(path));
policy->GrantReadFile(process()->id(), path);
}
Send(new ViewMsg_DragTargetDragEnter(routing_id(), drop_data, client_pt,
screen_pt, operations_allowed));
}
void RenderViewHost::DragTargetDragOver(
const gfx::Point& client_pt, const gfx::Point& screen_pt,
WebDragOperationsMask operations_allowed) {
Send(new ViewMsg_DragTargetDragOver(routing_id(), client_pt, screen_pt,
operations_allowed));
}
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(), WideToUTF16(frame_xpath),
WideToUTF16(jscript),
0, false));
}
int RenderViewHost::ExecuteJavascriptInWebFrameNotifyResult(
const string16& frame_xpath,
const string16& jscript) {
static int next_id = 1;
Send(new ViewMsg_ScriptEvalRequest(routing_id(), frame_xpath, jscript,
next_id, true));
return next_id++;
}
void RenderViewHost::InsertCSSInWebFrame(
const std::wstring& frame_xpath,
const std::string& css,
const std::string& id) {
Send(new ViewMsg_CSSInsertRequest(routing_id(), frame_xpath, css, id));
}
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::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::CopyToFindPboard() {
#if defined(OS_MACOSX)
// Windows/Linux don't have the concept of a find pasteboard.
Send(new ViewMsg_CopyToFindPboard(routing_id()));
#endif
}
void RenderViewHost::Paste() {
Send(new ViewMsg_Paste(routing_id()));
}
void RenderViewHost::ToggleSpellCheck() {
Send(new ViewMsg_ToggleSpellCheck(routing_id()));
}
void RenderViewHost::Delete() {
Send(new ViewMsg_Delete(routing_id()));
}
void RenderViewHost::SelectAll() {
Send(new ViewMsg_SelectAll(routing_id()));
}
void RenderViewHost::ToggleSpellPanel(bool is_currently_visible) {
Send(new ViewMsg_ToggleSpellPanel(routing_id(), is_currently_visible));
}
int RenderViewHost::DownloadFavIcon(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_DownloadFavIcon(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::CaptureSnapshot() {
Send(new ViewMsg_CaptureSnapshot(routing_id()));
}
void RenderViewHost::JavaScriptMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& prompt) {
process()->set_ignore_input_events(false);
bool is_waiting =
is_waiting_for_beforeunload_ack_ || is_waiting_for_unload_ack_;
if (is_waiting)
StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
ViewHostMsg_RunJavaScriptMessage::WriteReplyParams(reply_msg,
success, prompt);
Send(reply_msg);
// If we are waiting for an unload or beforeunload ack and the user has
// suppressed messages, kill the tab immediately; a page that's spamming
// alerts in onbeforeunload is presumably malicious, so there's no point in
// continuing to run its script and dragging out the process.
// This must be done after sending the reply since RenderView can't close
// correctly while waiting for a response.
if (is_waiting && are_javascript_messages_suppressed_)
delegate_->RendererUnresponsive(this, is_waiting);
}
void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg,
const std::string& json_retval) {
if (is_waiting_for_beforeunload_ack_ || is_waiting_for_unload_ack_)
StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
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::DragSourceEndedAt(
int client_x, int client_y, int screen_x, int screen_y,
WebDragOperation operation) {
Send(new ViewMsg_DragSourceEndedOrMoved(
routing_id(),
gfx::Point(client_x, client_y),
gfx::Point(screen_x, screen_y),
true, operation));
}
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, WebDragOperationNone));
}
void RenderViewHost::DragSourceSystemDragEnded() {
Send(new ViewMsg_DragSourceSystemDragEnded(routing_id()));
}
void RenderViewHost::AllowBindings(int bindings_flags) {
DCHECK(!renderer_initialized_);
enabled_bindings_ |= bindings_flags;
}
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));
}
void RenderViewHost::GotFocus() {
RenderWidgetHost::GotFocus(); // Notifies the renderer it got focus.
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->GotFocus();
}
void RenderViewHost::LostCapture() {
RenderWidgetHost::LostCapture();
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->LostCapture();
}
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::LoadBlockedPlugins() {
Send(new ViewMsg_LoadBlockedPlugins(routing_id()));
}
void RenderViewHost::FilesSelectedInChooser(
const std::vector<FilePath>& files) {
// Grant the security access requested to the given files.
for (std::vector<FilePath>::const_iterator file = files.begin();
file != files.end(); ++file) {
ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
process()->id(), *file);
}
Send(new ViewMsg_RunFileChooserResponse(routing_id(), files));
}
void RenderViewHost::LoadStateChanged(const GURL& url,
net::LoadState load_state,
uint64 upload_position,
uint64 upload_size) {
delegate_->LoadStateChanged(url, load_state, upload_position, upload_size);
}
bool RenderViewHost::SuddenTerminationAllowed() const {
return sudden_termination_allowed_ || process()->sudden_termination_allowed();
}
///////////////////////////////////////////////////////////////////////////////
// RenderViewHost, IPC message handlers:
void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
#if defined(OS_WIN)
// On Windows there's a potential deadlock with sync messsages going in
// a circle from browser -> plugin -> renderer -> browser.
// On Linux we can avoid this by avoiding sync messages from browser->plugin.
// On Mac we avoid this by not supporting windowed plugins.
if (msg.is_sync() && !msg.is_caller_pumping_messages()) {
// NOTE: IF YOU HIT THIS ASSERT, THE SOLUTION IS ALMOST NEVER TO RUN A
// NESTED MESSAGE LOOP IN THE RENDERER!!!
// That introduces reentrancy which causes hard to track bugs. You should
// find a way to either turn this into an asynchronous message, or one
// that can be answered on the IO thread.
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;
}
#endif
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(ViewHostMsg_ShowFullscreenWidget,
OnMsgShowFullscreenWidget)
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_Snapshot, OnMsgScreenshot)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateInspectorSetting,
OnUpdateInspectorSetting);
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_DocumentAvailableInMainFrame,
OnMsgDocumentAvailableInMainFrame)
IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentOnLoadCompletedInMainFrame,
OnMsgDocumentOnLoadCompletedInMainFrame)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
OnMsgDidLoadResourceFromMemoryCache)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisplayInsecureContent,
OnMsgDidDisplayInsecureContent)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidRunInsecureContent,
OnMsgDidRunInsecureContent)
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(ViewMsg_ExecuteCodeFinished,
OnExecuteCodeFinished)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFavIconURL, OnMsgUpdateFavIconURL)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidDownloadFavIcon, OnMsgDidDownloadFavIcon)
IPC_MESSAGE_HANDLER(ViewHostMsg_ContextMenu, OnMsgContextMenu)
IPC_MESSAGE_HANDLER(ViewHostMsg_OpenURL, OnMsgOpenURL)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange,
OnMsgDidContentsPreferredSizeChange)
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_DidFinishLoad,
OnMsgDidFinishLoad)
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_FormsSeen, OnMsgFormsSeen)
IPC_MESSAGE_HANDLER(ViewHostMsg_PasswordFormsFound, OnMsgPasswordFormsFound)
IPC_MESSAGE_HANDLER(ViewHostMsg_PasswordFormsVisible,
OnMsgPasswordFormsVisible)
IPC_MESSAGE_HANDLER(ViewHostMsg_FormSubmitted, OnMsgFormSubmitted)
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_DidGetPrintedPagesCount,
OnDidGetPrintedPagesCount)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidPrintPage, DidPrintPage)
IPC_MESSAGE_HANDLER(ViewHostMsg_AddMessageToConsole, OnAddMessageToConsole)
IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToDevToolsAgent,
OnForwardToDevToolsAgent);
IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToDevToolsClient,
OnForwardToDevToolsClient);
IPC_MESSAGE_HANDLER(ViewHostMsg_ActivateDevToolsWindow,
OnActivateDevToolsWindow);
IPC_MESSAGE_HANDLER(ViewHostMsg_CloseDevToolsWindow,
OnCloseDevToolsWindow);
IPC_MESSAGE_HANDLER(ViewHostMsg_RequestDockDevToolsWindow,
OnRequestDockDevToolsWindow);
IPC_MESSAGE_HANDLER(ViewHostMsg_RequestUndockDevToolsWindow,
OnRequestUndockDevToolsWindow);
IPC_MESSAGE_HANDLER(ViewHostMsg_DevToolsRuntimePropertyChanged,
OnDevToolsRuntimePropertyChanged);
IPC_MESSAGE_HANDLER(ViewHostMsg_MissingPluginStatus, OnMissingPluginStatus);
IPC_MESSAGE_HANDLER(ViewHostMsg_CrashedPlugin, OnCrashedPlugin);
IPC_MESSAGE_HANDLER(ViewHostMsg_DisabledOutdatedPlugin,
OnDisabledOutdatedPlugin);
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_DidShowAutoFillSuggestions,
OnDidShowAutoFillSuggestions)
IPC_MESSAGE_HANDLER(ViewHostMsg_RemoveAutocompleteEntry,
OnRemoveAutocompleteEntry)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowAutoFillDialog,
OnShowAutoFillDialog)
IPC_MESSAGE_HANDLER(ViewHostMsg_FillAutoFillFormData,
OnFillAutoFillFormData)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidFillAutoFillFormData,
OnDidFillAutoFillFormData)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowDesktopNotification,
OnShowDesktopNotification)
IPC_MESSAGE_HANDLER(ViewHostMsg_CancelDesktopNotification,
OnCancelDesktopNotification)
IPC_MESSAGE_HANDLER(ViewHostMsg_RequestNotificationPermission,
OnRequestNotificationPermission)
IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionRequest, OnExtensionRequest)
IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionChanged, OnMsgSelectionChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionPostMessage,
OnExtensionPostMessage)
IPC_MESSAGE_HANDLER(ViewHostMsg_AccessibilityNotifications,
OnAccessibilityNotifications)
IPC_MESSAGE_HANDLER(ViewHostMsg_OnCSSInserted, OnCSSInserted)
IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents)
IPC_MESSAGE_HANDLER(ViewHostMsg_PageTranslated, OnPageTranslated)
IPC_MESSAGE_HANDLER(ViewHostMsg_ContentBlocked, OnContentBlocked)
IPC_MESSAGE_HANDLER(ViewHostMsg_AppCacheAccessed, OnAppCacheAccessed)
IPC_MESSAGE_HANDLER(ViewHostMsg_WebDatabaseAccessed, OnWebDatabaseAccessed)
IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnMsgFocusedNodeChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateZoomLimits, OnUpdateZoomLimits)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetSuggestions, OnSetSuggestions)
IPC_MESSAGE_HANDLER(ViewHostMsg_InstantSupportDetermined,
OnInstantSupportDetermined)
IPC_MESSAGE_HANDLER(ViewHostMsg_DetectedPhishingSite,
OnDetectedPhishingSite)
IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptEvalResponse, OnScriptEvalResponse)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateContentRestrictions,
OnUpdateContentRestrictions)
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnMsgShowPopup)
#endif
#if defined(OS_MACOSX) || defined(OS_WIN)
IPC_MESSAGE_HANDLER(ViewHostMsg_PageReadyForPreview,
OnPageReadyForPreview)
#else
IPC_MESSAGE_HANDLER(ViewHostMsg_PagesReadyForPreview,
OnPagesReadyForPreview)
#endif
// 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_) {
Send(run_modal_reply_msg_);
run_modal_reply_msg_ = NULL;
}
DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
if (devtools_manager) // NULL in tests
devtools_manager->UnregisterDevToolsClientHostFor(this);
RenderWidgetHost::Shutdown();
}
void RenderViewHost::CreateNewWindow(
int route_id,
WindowContainerType window_container_type,
const string16& frame_name) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (!view)
return;
view->CreateNewWindow(route_id, window_container_type, frame_name);
}
void RenderViewHost::CreateNewWidget(int route_id,
WebKit::WebPopupType popup_type) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->CreateNewWidget(route_id, popup_type);
}
void RenderViewHost::CreateNewFullscreenWidget(
int route_id, WebKit::WebPopupType popup_type) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->CreateNewFullscreenWidget(route_id, popup_type);
}
void RenderViewHost::OnMsgShowView(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view) {
view->ShowCreatedWindow(route_id, disposition, initial_pos, user_gesture);
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::OnMsgShowFullscreenWidget(int route_id) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view) {
view->ShowCreatedFullscreenWidget(route_id);
Send(new ViewMsg_Move_ACK(route_id));
}
}
void RenderViewHost::OnMsgRunModal(IPC::Message* reply_msg) {
DCHECK(!run_modal_reply_msg_);
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);
}
// 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;
// If we're waiting for a beforeunload ack from this renderer and we receive
// a Navigate message from the main frame, then the renderer was navigating
// before it received the request. If it is during a cross-site navigation,
// then we should forget about the beforeunload, because the navigation will
// now be canceled. (If it is instead during an attempt to close the page,
// we should be sure to keep waiting for the ack, which the new page will
// send.)
//
// If we did not clear this state, an unresponsiveness timer might think we
// are waiting for an ack but are not in a cross-site navigation, and would
// close the tab. TODO(creis): That timer code should be refactored to only
// close the tab if we explicitly know the user tried to close the tab, and
// not just check for the absence of a cross-site navigation. Once that's
// fixed, this check can go away.
if (is_waiting_for_beforeunload_ack_ &&
unload_ack_is_for_cross_site_transition_ &&
PageTransition::IsMainFrame(validated_params.transition)) {
is_waiting_for_beforeunload_ack_ = false;
StopHangMonitorTimeout();
}
// If we're waiting for an unload ack from this renderer and we receive a
// Navigate message, then the renderer was navigating before it received the
// unload request. It will either respond to the unload request soon or our
// timer will expire. Either way, we should ignore this message, because we
// have already committed to closing this renderer.
if (is_waiting_for_unload_ack_)
return;
const int renderer_id = process()->id();
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<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);
}
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::string& 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::OnMsgScreenshot(const SkBitmap& bitmap) {
NotificationService::current()->Notify(
NotificationType::TAB_SNAPSHOT_TAKEN,
Source<RenderViewHost>(this),
Details<const SkBitmap>(&bitmap));
}
void RenderViewHost::OnUpdateInspectorSetting(
const std::string& key, const std::string& value) {
delegate_->UpdateInspectorSetting(key, value);
}
void RenderViewHost::OnMsgClose() {
// If the renderer is telling us to close, it has already run the unload
// events, and we can take the fast path.
ClosePageIgnoringUnloadEvents();
}
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) {
RenderViewHostDelegate::Resource* resource_delegate =
delegate_->GetResourceDelegate();
if (resource_delegate) {
resource_delegate->DidRedirectProvisionalLoad(page_id,
source_url, target_url);
}
}
void RenderViewHost::OnMsgDidStartLoading() {
delegate_->DidStartLoading();
}
void RenderViewHost::OnMsgDidStopLoading() {
delegate_->DidStopLoading();
}
void RenderViewHost::OnMsgDocumentAvailableInMainFrame() {
delegate_->DocumentAvailableInMainFrame(this);
}
void RenderViewHost::OnMsgDocumentOnLoadCompletedInMainFrame(int32 page_id) {
delegate_->DocumentOnLoadCompletedInMainFrame(this, page_id);
}
void RenderViewHost::OnMsgDidLoadResourceFromMemoryCache(
const GURL& url,
const std::string& frame_origin,
const std::string& main_frame_origin,
const std::string& security_info) {
static base::StatsCounter cache("WebKit.CacheHit");
cache.Increment();
RenderViewHostDelegate::Resource* resource_delegate =
delegate_->GetResourceDelegate();
if (resource_delegate) {
resource_delegate->DidLoadResourceFromMemoryCache(
url, frame_origin, main_frame_origin, security_info);
}
}
void RenderViewHost::OnMsgDidDisplayInsecureContent() {
RenderViewHostDelegate::Resource* resource_delegate =
delegate_->GetResourceDelegate();
if (resource_delegate)
resource_delegate->DidDisplayInsecureContent();
}
void RenderViewHost::OnMsgDidRunInsecureContent(
const std::string& security_origin) {
RenderViewHostDelegate::Resource* resource_delegate =
delegate_->GetResourceDelegate();
if (resource_delegate)
resource_delegate->DidRunInsecureContent(security_origin);
}
void RenderViewHost::OnMsgDidStartProvisionalLoadForFrame(long long frame_id,
bool is_main_frame,
const GURL& url) {
GURL validated_url(url);
FilterURL(ChildProcessSecurityPolicy::GetInstance(),
process()->id(), &validated_url);
RenderViewHostDelegate::Resource* resource_delegate =
delegate_->GetResourceDelegate();
if (resource_delegate) {
resource_delegate->DidStartProvisionalLoadForFrame(
this, frame_id, is_main_frame, validated_url);
}
}
void RenderViewHost::OnMsgDidFailProvisionalLoadWithError(
long long frame_id,
bool is_main_frame,
int error_code,
const GURL& url,
bool showing_repost_interstitial) {
VLOG(1) << "Failed Provisional Load: " << url.possibly_invalid_spec()
<< ", error_code: " << error_code
<< " is_main_frame: " << is_main_frame
<< " showing_repost_interstitial: " << showing_repost_interstitial
<< " frame_id: " << frame_id;
GURL validated_url(url);
FilterURL(ChildProcessSecurityPolicy::GetInstance(),
process()->id(), &validated_url);
RenderViewHostDelegate::Resource* resource_delegate =
delegate_->GetResourceDelegate();
if (resource_delegate) {
resource_delegate->DidFailProvisionalLoadWithError(
this, frame_id, is_main_frame, error_code, validated_url,
showing_repost_interstitial);
}
}
void RenderViewHost::OnMsgFindReply(int request_id,
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (integration_delegate) {
integration_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::OnExecuteCodeFinished(int request_id, bool success) {
std::pair<int, bool> result_details(request_id, success);
NotificationService::current()->Notify(
NotificationType::TAB_CODE_EXECUTED,
NotificationService::AllSources(),
Details<std::pair<int, bool> >(&result_details));
}
void RenderViewHost::OnMsgUpdateFavIconURL(int32 page_id,
const GURL& icon_url) {
RenderViewHostDelegate::FavIcon* favicon_delegate =
delegate_->GetFavIconDelegate();
if (favicon_delegate)
favicon_delegate->UpdateFavIconURL(this, page_id, icon_url);
}
void RenderViewHost::OnMsgDidDownloadFavIcon(int id,
const GURL& image_url,
bool errored,
const SkBitmap& image) {
RenderViewHostDelegate::FavIcon* favicon_delegate =
delegate_->GetFavIconDelegate();
if (favicon_delegate)
favicon_delegate->DidDownloadFavIcon(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);
int renderer_id = process()->id();
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.src_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()->id(), &validated_url);
delegate_->RequestOpenURL(validated_url, referrer, disposition);
}
void RenderViewHost::OnMsgDidContentsPreferredSizeChange(
const gfx::Size& new_size) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (!view)
return;
view->UpdatePreferredSize(new_size);
}
void RenderViewHost::OnMsgDomOperationResponse(
const std::string& json_string, int automation_id) {
delegate_->DomOperationResponse(json_string, automation_id);
// We also fire a notification for more loosely-coupled use cases.
DomOperationNotificationDetails details(json_string, automation_id);
NotificationService::current()->Notify(
NotificationType::DOM_OPERATION_RESPONSE, Source<RenderViewHost>(this),
Details<DomOperationNotificationDetails>(&details));
}
void RenderViewHost::OnMsgDOMUISend(
const GURL& source_url, const std::string& message,
const std::string& content) {
if (!ChildProcessSecurityPolicy::GetInstance()->
HasDOMUIBindings(process()->id())) {
NOTREACHED() << "Blocked unauthorized use of DOMUIBindings.";
return;
}
scoped_ptr<Value> value;
if (!content.empty()) {
value.reset(base::JSONReader::Read(content, false));
if (!value.get() || !value->IsType(Value::TYPE_LIST)) {
// The page sent us something that we didn't understand.
// This probably indicates a programming error.
NOTREACHED() << "Invalid JSON argument in OnMsgDOMUISend.";
return;
}
}
ViewHostMsg_DomMessage_Params params;
params.name = message;
if (value.get())
params.arguments.Swap(static_cast<ListValue*>(value.get()));
params.source_url = source_url;
// DOMUI doesn't use these values yet.
// TODO(aa): When DOMUI is ported to ExtensionFunctionDispatcher, send real
// values here.
params.request_id = -1;
params.has_callback = false;
params.user_gesture = false;
delegate_->ProcessDOMUIMessage(params);
}
void RenderViewHost::OnMsgForwardMessageToExternalHost(
const std::string& message, const std::string& origin,
const std::string& target) {
delegate_->ProcessExternalHostMessage(message, origin, target);
}
void RenderViewHost::OnMsgDocumentLoadedInFrame(long long frame_id) {
RenderViewHostDelegate::Resource* resource_delegate =
delegate_->GetResourceDelegate();
if (resource_delegate)
resource_delegate->DocumentLoadedInFrame(frame_id);
}
void RenderViewHost::OnMsgDidFinishLoad(long long frame_id) {
RenderViewHostDelegate::Resource* resource_delegate =
delegate_->GetResourceDelegate();
if (resource_delegate)
resource_delegate->DidFinishLoad(frame_id);
}
void RenderViewHost::DisassociateFromPopupCount() {
Send(new ViewMsg_DisassociateFromPopupCount(routing_id()));
}
void RenderViewHost::AllowScriptToClose(bool script_can_close) {
Send(new ViewMsg_AllowScriptToClose(routing_id(), script_can_close));
}
void RenderViewHost::OnMsgGoToEntryAtOffset(int offset) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (integration_delegate)
integration_delegate->GoToEntryAtOffset(offset);
}
void RenderViewHost::OnMsgSetTooltipText(
const std::wstring& tooltip_text,
WebTextDirection text_direction_hint) {
// First, add directionality marks around tooltip text if necessary.
// A naive solution would be to simply always wrap the text. However, on
// windows, Unicode directional embedding characters can't be displayed on
// systems that lack RTL fonts and are instead displayed as empty squares.
//
// To get around this we only wrap the string when we deem it necessary i.e.
// when the locale direction is different than the tooltip direction hint.
//
// Currently, we use element's directionality as the tooltip direction hint.
// An alternate solution would be to set the overall directionality based on
// trying to detect the directionality from the tooltip text rather than the
// element direction. One could argue that would be a preferable solution
// but we use the current approach to match Fx & IE's behavior.
std::wstring wrapped_tooltip_text = tooltip_text;
if (!tooltip_text.empty()) {
if (text_direction_hint == WebKit::WebTextDirectionLeftToRight) {
// Force the tooltip to have LTR directionality.
wrapped_tooltip_text = UTF16ToWide(
base::i18n::GetDisplayStringInLTRDirectionality(
WideToUTF16(wrapped_tooltip_text)));
} else if (text_direction_hint == WebKit::WebTextDirectionRightToLeft &&
!base::i18n::IsRTL()) {
// Force the tooltip to have RTL directionality.
base::i18n::WrapStringWithRTLFormatting(&wrapped_tooltip_text);
}
}
if (view())
view()->SetTooltipText(wrapped_tooltip_text);
}
void RenderViewHost::OnMsgSelectionChanged(const std::string& text) {
if (view())
view()->SelectionChanged(text);
}
void RenderViewHost::OnMsgRunFileChooser(
const ViewHostMsg_RunFileChooser_Params& params) {
RenderViewHostDelegate::FileSelect* file_select_delegate =
delegate()->GetFileSelectDelegate();
if (file_select_delegate)
file_select_delegate->RunFileChooser(this, params);
}
void RenderViewHost::OnMsgRunJavaScriptMessage(
const std::wstring& message,
const std::wstring& default_prompt,
const GURL& frame_url,
const int flags,
IPC::Message* reply_msg) {
// While a JS message dialog is showing, tabs in the same process shouldn't
// process input events.
process()->set_ignore_input_events(true);
StopHangMonitorTimeout();
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) {
// While a JS before unload dialog is showing, tabs in the same process
// shouldn't process input events.
process()->set_ignore_input_events(true);
StopHangMonitorTimeout();
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();
delegate_->ShowModalHTMLDialog(url, width, height, json_arguments, reply_msg);
}
void RenderViewHost::MediaPlayerActionAt(const gfx::Point& location,
const WebMediaPlayerAction& action) {
// TODO(ajwong): Which thread should run this? Does it matter?
Send(new ViewMsg_MediaPlayerActionAt(routing_id(), location, action));
}
void RenderViewHost::OnMsgFormsSeen(const std::vector<FormData>& forms) {
RenderViewHostDelegate::AutoFill* autofill_delegate =
delegate_->GetAutoFillDelegate();
if (autofill_delegate)
autofill_delegate->FormsSeen(forms);
}
void RenderViewHost::OnMsgPasswordFormsFound(
const std::vector<PasswordForm>& forms) {
delegate_->PasswordFormsFound(forms);
}
void RenderViewHost::OnMsgPasswordFormsVisible(
const std::vector<PasswordForm>& visible_forms) {
delegate_->PasswordFormsVisible(visible_forms);
}
void RenderViewHost::OnMsgFormSubmitted(const FormData& form) {
RenderViewHostDelegate::Autocomplete* autocomplete_delegate =
delegate_->GetAutocompleteDelegate();
if (autocomplete_delegate)
autocomplete_delegate->FormSubmitted(form);
RenderViewHostDelegate::AutoFill* autofill_delegate =
delegate_->GetAutoFillDelegate();
if (autofill_delegate)
autofill_delegate->FormSubmitted(form);
}
void RenderViewHost::OnMsgStartDragging(
const WebDropData& drop_data,
WebDragOperationsMask drag_operations_mask,
const SkBitmap& image,
const gfx::Point& image_offset) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->StartDragging(drop_data, drag_operations_mask, image, image_offset);
}
void RenderViewHost::OnUpdateDragCursor(WebDragOperation current_op) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->UpdateDragCursor(current_op);
}
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,
const ViewHostMsg_PageHasOSDD_Type& provider_type) {
delegate_->PageHasOSDD(this, page_id, doc_url, provider_type);
}
void RenderViewHost::OnDidGetPrintedPagesCount(int cookie, int number_pages) {
RenderViewHostDelegate::Printing* printing_delegate =
delegate_->GetPrintingDelegate();
if (printing_delegate)
printing_delegate->DidGetPrintedPagesCount(cookie, number_pages);
}
void RenderViewHost::DidPrintPage(
const ViewHostMsg_DidPrintPage_Params& params) {
RenderViewHostDelegate::Printing* printing_delegate =
delegate_->GetPrintingDelegate();
if (printing_delegate)
printing_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;
}
void RenderViewHost::OnForwardToDevToolsAgent(const IPC::Message& message) {
DevToolsManager::GetInstance()->ForwardToDevToolsAgent(this, message);
}
void RenderViewHost::OnForwardToDevToolsClient(const IPC::Message& message) {
DevToolsManager::GetInstance()->ForwardToDevToolsClient(this, message);
}
void RenderViewHost::OnActivateDevToolsWindow() {
DevToolsManager::GetInstance()->ActivateWindow(this);
}
void RenderViewHost::OnCloseDevToolsWindow() {
DevToolsManager::GetInstance()->CloseWindow(this);
}
void RenderViewHost::OnRequestDockDevToolsWindow() {
DevToolsManager::GetInstance()->RequestDockWindow(this);
}
void RenderViewHost::OnRequestUndockDevToolsWindow() {
DevToolsManager::GetInstance()->RequestUndockWindow(this);
}
void RenderViewHost::OnDevToolsRuntimePropertyChanged(
const std::string& name,
const std::string& value) {
DevToolsManager::GetInstance()->
RuntimePropertyChanged(this, name, value);
}
bool RenderViewHost::PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
return view && view->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
}
void RenderViewHost::UnhandledKeyboardEvent(
const NativeWebKeyboardEvent& event) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->HandleKeyboardEvent(event);
}
void RenderViewHost::OnUserGesture() {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (integration_delegate)
integration_delegate->OnUserGesture();
}
void RenderViewHost::OnMissingPluginStatus(int status) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (integration_delegate)
integration_delegate->OnMissingPluginStatus(status);
}
void RenderViewHost::OnCrashedPlugin(const FilePath& plugin_path) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (integration_delegate)
integration_delegate->OnCrashedPlugin(plugin_path);
}
void RenderViewHost::OnDisabledOutdatedPlugin(const string16& name,
const GURL& update_url) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (integration_delegate)
integration_delegate->OnDisabledOutdatedPlugin(name, update_url);
}
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) {
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 WebApplicationInfo& info) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (integration_delegate)
integration_delegate->OnDidGetApplicationInfo(page_id, info);
}
void RenderViewHost::GetSerializedHtmlDataForCurrentPageWithLocalLinks(
const std::vector<GURL>& links,
const std::vector<FilePath>& 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();
// If this renderer navigated while the beforeunload request was in flight, we
// may have cleared this state in OnMsgNavigate, in which case we can ignore
// this message.
if (!is_waiting_for_beforeunload_ack_)
return;
is_waiting_for_beforeunload_ack_ = false;
RenderViewHostDelegate::RendererManagement* management_delegate =
delegate_->GetRendererManagementDelegate();
if (management_delegate) {
management_delegate->ShouldClosePage(
unload_ack_is_for_cross_site_transition_, proceed);
}
}
void RenderViewHost::OnQueryFormFieldAutoFill(
int query_id, bool field_autofilled, const webkit_glue::FormField& field) {
ResetAutoFillState(query_id);
// We first query the autofill delegate for suggestions. We keep track of the
// results it gives us, which we will later combine with the autocomplete
// suggestions.
RenderViewHostDelegate::AutoFill* autofill_delegate =
delegate_->GetAutoFillDelegate();
if (autofill_delegate) {
autofill_delegate->GetAutoFillSuggestions(field_autofilled, field);
}
// Now query the Autocomplete delegate for suggestions. These will be combined
// with the saved autofill suggestions in |AutocompleteSuggestionsReturned()|.
RenderViewHostDelegate::Autocomplete* autocomplete_delegate =
delegate_->GetAutocompleteDelegate();
if (autocomplete_delegate) {
autocomplete_delegate->GetAutocompleteSuggestions(field.name(),
field.value());
} else {
AutocompleteSuggestionsReturned(std::vector<string16>());
}
}
void RenderViewHost::OnDidShowAutoFillSuggestions() {
NotificationService::current()->Notify(
NotificationType::AUTOFILL_DID_SHOW_SUGGESTIONS,
Source<RenderViewHost>(this),
NotificationService::NoDetails());
}
void RenderViewHost::OnRemoveAutocompleteEntry(const string16& field_name,
const string16& value) {
RenderViewHostDelegate::Autocomplete* autocomplete_delegate =
delegate_->GetAutocompleteDelegate();
if (autocomplete_delegate)
autocomplete_delegate->RemoveAutocompleteEntry(field_name, value);
}
void RenderViewHost::OnShowAutoFillDialog() {
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableTabbedOptions)) {
Browser* browser = BrowserList::GetLastActive();
if (!browser)
return;
browser->ShowOptionsTab(chrome::kAutoFillSubPage);
} else {
RenderViewHostDelegate::AutoFill* autofill_delegate =
delegate_->GetAutoFillDelegate();
if (!autofill_delegate)
return;
autofill_delegate->ShowAutoFillDialog();
}
}
void RenderViewHost::OnFillAutoFillFormData(int query_id,
const FormData& form,
int unique_id) {
RenderViewHostDelegate::AutoFill* autofill_delegate =
delegate_->GetAutoFillDelegate();
if (!autofill_delegate)
return;
autofill_delegate->FillAutoFillFormData(query_id, form, unique_id);
}
void RenderViewHost::OnDidFillAutoFillFormData() {
NotificationService::current()->Notify(
NotificationType::AUTOFILL_DID_FILL_FORM_DATA,
Source<RenderViewHost>(this),
NotificationService::NoDetails());
}
void RenderViewHost::ResetAutoFillState(int query_id) {
autofill_query_id_ = query_id;
autofill_values_.clear();
autofill_labels_.clear();
autofill_icons_.clear();
autofill_unique_ids_.clear();
}
void RenderViewHost::AutoFillSuggestionsReturned(
const std::vector<string16>& values,
const std::vector<string16>& labels,
const std::vector<string16>& icons,
const std::vector<int>& unique_ids) {
autofill_values_.assign(values.begin(), values.end());
autofill_labels_.assign(labels.begin(), labels.end());
autofill_icons_.assign(icons.begin(), icons.end());
autofill_unique_ids_.assign(unique_ids.begin(), unique_ids.end());
}
void RenderViewHost::AutocompleteSuggestionsReturned(
const std::vector<string16>& suggestions) {
// Combine AutoFill and Autocomplete values into values and labels.
for (size_t i = 0; i < suggestions.size(); ++i) {
bool unique = true;
for (size_t j = 0; j < autofill_values_.size(); ++j) {
// TODO(isherman): Why just when the label is empty?
// If the AutoFill label is empty, we need to make sure we don't add a
// duplicate value.
if (autofill_labels_[j].empty() &&
autofill_values_[j] == suggestions[i]) {
unique = false;
break;
}
}
if (unique) {
autofill_values_.push_back(suggestions[i]);
autofill_labels_.push_back(string16());
autofill_icons_.push_back(string16());
autofill_unique_ids_.push_back(0); // 0 means no profile.
}
}
Send(new ViewMsg_AutoFillSuggestionsReturned(routing_id(),
autofill_query_id_,
autofill_values_,
autofill_labels_,
autofill_icons_,
autofill_unique_ids_));
}
void RenderViewHost::AutoFillFormDataFilled(int query_id,
const FormData& form) {
Send(new ViewMsg_AutoFillFormDataFilled(routing_id(), query_id, form));
}
void RenderViewHost::WindowMoveOrResizeStarted() {
Send(new ViewMsg_MoveOrResizeStarted(routing_id()));
}
void RenderViewHost::NotifyRendererUnresponsive() {
delegate_->RendererUnresponsive(
this, is_waiting_for_beforeunload_ack_ || is_waiting_for_unload_ack_);
}
void RenderViewHost::NotifyRendererResponsive() {
delegate_->RendererResponsive(this);
}
void RenderViewHost::OnMsgFocusedNodeChanged(bool is_editable_node) {
delegate_->FocusedNodeChanged();
#if defined(TOUCH_UI)
if (is_editable_node) {
// Need to summon on-screen keyboard
// TODO(bryeung): implement this
// The currently focused element can be placed out of the view as the screen
// is now shared by the keyboard. Hence, we tell the renderer to scroll
// until the focused element comes in view.
Send(new ViewMsg_ScrollFocusedEditableNodeIntoView(routing_id()));
} else {
// TODO(bryeung): implement this. Should hide the on-screen keyboard.
}
#endif
}
void RenderViewHost::OnMsgFocus() {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->Activate();
}
void RenderViewHost::OnMsgBlur() {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->Deactivate();
}
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->HandleMouseMove();
break;
case WebInputEvent::MouseLeave:
view->HandleMouseLeave();
break;
case WebInputEvent::MouseDown:
view->HandleMouseDown();
break;
case WebInputEvent::MouseWheel:
if (ignore_input_events() && delegate_)
delegate_->OnIgnoredUIEvent();
break;
case WebInputEvent::MouseUp:
view->HandleMouseUp();
default:
// For now, we don't care about the rest.
break;
}
}
}
void RenderViewHost::OnMouseActivate() {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
view->HandleMouseActivate();
}
void RenderViewHost::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& key_event) {
if (ignore_input_events()) {
if (key_event.type == WebInputEvent::RawKeyDown && delegate_)
delegate_->OnIgnoredUIEvent();
return;
}
RenderWidgetHost::ForwardKeyboardEvent(key_event);
}
void RenderViewHost::ForwardEditCommand(const std::string& name,
const std::string& value) {
IPC::Message* message = new ViewMsg_ExecuteEditCommand(routing_id(),
name,
value);
Send(message);
}
void RenderViewHost::ForwardEditCommandsForNextKeyEvent(
const EditCommands& edit_commands) {
IPC::Message* message = new ViewMsg_SetEditCommandsForNextKeyEvent(
routing_id(), edit_commands);
Send(message);
}
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::OnShowDesktopNotification(
const ViewHostMsg_ShowNotification_Params& params) {
DesktopNotificationService* service =
process()->profile()->GetDesktopNotificationService();
service->ShowDesktopNotification(
params, process()->id(), routing_id(),
DesktopNotificationService::PageNotification);
}
void RenderViewHost::OnCancelDesktopNotification(int notification_id) {
DesktopNotificationService* service=
process()->profile()->GetDesktopNotificationService();
service->CancelDesktopNotification(
process()->id(), routing_id(), notification_id);
}
void RenderViewHost::OnRequestNotificationPermission(
const GURL& source_origin, int callback_context) {
Browser* browser = BrowserList::GetLastActive();
// We may not have a BrowserList if the chrome browser process is launched as
// a ChromeFrame process in which case we attempt to use the TabContents
// provided by the RenderViewHostDelegate.
TabContents* tab = browser ? browser->GetSelectedTabContents() :
(delegate_ ? delegate_->GetAsTabContents() : NULL);
if (tab) {
DesktopNotificationService* service =
process()->profile()->GetDesktopNotificationService();
service->RequestPermission(
source_origin, process()->id(), routing_id(), callback_context, tab);
}
}
void RenderViewHost::OnExtensionRequest(
const ViewHostMsg_DomMessage_Params& params) {
if (!ChildProcessSecurityPolicy::GetInstance()->
HasExtensionBindings(process()->id())) {
// This can happen if someone uses window.open() to open an extension URL
// from a non-extension context.
BlockExtensionRequest(params.request_id);
return;
}
delegate_->ProcessDOMUIMessage(params);
}
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::BlockExtensionRequest(int request_id) {
SendExtensionResponse(request_id, false, "",
"Access to extension API denied.");
}
void RenderViewHost::UpdateBrowserWindowId(int window_id) {
Send(new ViewMsg_UpdateBrowserWindowId(routing_id(), window_id));
}
void RenderViewHost::PerformCustomContextMenuAction(unsigned action) {
Send(new ViewMsg_CustomContextMenuAction(routing_id(), action));
}
void RenderViewHost::TranslatePage(int page_id,
const std::string& translate_script,
const std::string& source_lang,
const std::string& target_lang) {
Send(new ViewMsg_TranslatePage(routing_id(), page_id, translate_script,
source_lang, target_lang));
}
void RenderViewHost::RevertTranslation(int page_id) {
Send(new ViewMsg_RevertTranslation(routing_id(), page_id));
}
void RenderViewHost::SendContentSettings(const GURL& url,
const ContentSettings& settings) {
Send(new ViewMsg_SetContentSettingsForCurrentURL(url, settings));
}
void RenderViewHost::EnablePreferredSizeChangedMode(int flags) {
Send(new ViewMsg_EnablePreferredSizeChangedMode(routing_id(), flags));
}
#if defined(OS_MACOSX)
void RenderViewHost::DidSelectPopupMenuItem(int selected_index) {
Send(new ViewMsg_SelectPopupMenuItem(routing_id(), selected_index));
}
void RenderViewHost::DidCancelPopupMenu() {
Send(new ViewMsg_SelectPopupMenuItem(routing_id(), -1));
}
#endif
void RenderViewHost::SearchBoxChange(const string16& value,
bool verbatim,
int selection_start,
int selection_end) {
Send(new ViewMsg_SearchBoxChange(
routing_id(), value, verbatim, selection_start, selection_end));
}
void RenderViewHost::SearchBoxSubmit(const string16& value,
bool verbatim) {
Send(new ViewMsg_SearchBoxSubmit(routing_id(), value, verbatim));
}
void RenderViewHost::SearchBoxCancel() {
Send(new ViewMsg_SearchBoxCancel(routing_id()));
}
void RenderViewHost::SearchBoxResize(const gfx::Rect& search_box_bounds) {
Send(new ViewMsg_SearchBoxResize(routing_id(), search_box_bounds));
}
void RenderViewHost::DetermineIfPageSupportsInstant(const string16& value) {
Send(new ViewMsg_DetermineIfPageSupportsInstant(routing_id(), value));
}
void RenderViewHost::OnExtensionPostMessage(
int port_id, const std::string& message) {
if (process()->profile()->GetExtensionMessageService()) {
process()->profile()->GetExtensionMessageService()->
PostMessageFromRenderer(port_id, message);
}
}
void RenderViewHost::OnAccessibilityNotifications(
const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) {
if (view())
view()->OnAccessibilityNotifications(params);
if (params.size() > 0) {
for (unsigned i = 0; i < params.size(); i++) {
const ViewHostMsg_AccessibilityNotification_Params& param = params[i];
if (param.notification_type ==
ViewHostMsg_AccessibilityNotification_Params::
NOTIFICATION_TYPE_LOAD_COMPLETE) {
// TODO(ctguil): Remove when mac processes OnAccessibilityNotifications.
if (view())
view()->UpdateAccessibilityTree(param.acc_obj);
if (save_accessibility_tree_for_testing_)
accessibility_tree_ = param.acc_obj;
}
}
NotificationService::current()->Notify(
NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED,
Source<RenderViewHost>(this),
NotificationService::NoDetails());
}
AccessibilityNotificationsAck();
}
void RenderViewHost::OnCSSInserted() {
delegate_->DidInsertCSS();
}
void RenderViewHost::OnPageContents(const GURL& url,
int32 page_id,
const string16& contents,
const std::string& language,
bool page_translatable) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (!integration_delegate)
return;
integration_delegate->OnPageContents(url, process()->id(), page_id, contents,
language, page_translatable);
}
void RenderViewHost::OnPageTranslated(int32 page_id,
const std::string& original_lang,
const std::string& translated_lang,
TranslateErrors::Type error_type) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (!integration_delegate)
return;
integration_delegate->OnPageTranslated(page_id, original_lang,
translated_lang, error_type);
}
void RenderViewHost::OnContentBlocked(ContentSettingsType type,
const std::string& resource_identifier) {
RenderViewHostDelegate::ContentSettings* content_settings_delegate =
delegate_->GetContentSettingsDelegate();
if (content_settings_delegate)
content_settings_delegate->OnContentBlocked(type, resource_identifier);
}
void RenderViewHost::OnAppCacheAccessed(const GURL& manifest_url,
bool blocked_by_policy) {
RenderViewHostDelegate::ContentSettings* content_settings_delegate =
delegate_->GetContentSettingsDelegate();
if (content_settings_delegate)
content_settings_delegate->OnAppCacheAccessed(manifest_url,
blocked_by_policy);
}
void RenderViewHost::OnWebDatabaseAccessed(const GURL& url,
const string16& name,
const string16& display_name,
unsigned long estimated_size,
bool blocked_by_policy) {
RenderViewHostDelegate::ContentSettings* content_settings_delegate =
delegate_->GetContentSettingsDelegate();
if (content_settings_delegate)
content_settings_delegate->OnWebDatabaseAccessed(
url, name, display_name, estimated_size, blocked_by_policy);
}
void RenderViewHost::OnUpdateZoomLimits(int minimum_percent,
int maximum_percent,
bool remember) {
delegate_->UpdateZoomLimits(minimum_percent, maximum_percent, remember);
}
void RenderViewHost::OnSetSuggestions(
int32 page_id,
const std::vector<std::string>& suggestions) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (!integration_delegate)
return;
integration_delegate->OnSetSuggestions(page_id, suggestions);
}
void RenderViewHost::OnInstantSupportDetermined(int32 page_id, bool result) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (!integration_delegate)
return;
integration_delegate->OnInstantSupportDetermined(page_id, result);
}
void RenderViewHost::OnDetectedPhishingSite(const GURL& phishing_url,
double phishing_score,
const SkBitmap& thumbnail) {
// TODO(noelutz): send an HTTP request to the client-side detection frontends
// to confirm that the URL is really phishing.
}
void RenderViewHost::OnScriptEvalResponse(int id, bool result) {
scoped_ptr<Value> result_value(Value::CreateBooleanValue(result));
std::pair<int, Value*> details(id, result_value.get());
NotificationService::current()->Notify(
NotificationType::EXECUTE_JAVASCRIPT_RESULT,
Source<RenderViewHost>(this),
Details<std::pair<int, Value*> >(&details));
}
void RenderViewHost::OnUpdateContentRestrictions(int restrictions) {
delegate_->UpdateContentRestrictions(restrictions);
}
#if defined(OS_MACOSX)
void RenderViewHost::OnMsgShowPopup(
const ViewHostMsg_ShowPopup_Params& params) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view) {
view->ShowPopupMenu(params.bounds,
params.item_height,
params.item_font_size,
params.selected_item,
params.popup_items,
params.right_aligned);
}
}
#endif
TabContents* RenderViewHost::GetOrCreatePrintPreviewTab() {
TabContents* initiator_tab = delegate_ ? delegate_->GetAsTabContents() : NULL;
if (initiator_tab) {
// Get/Create preview tab for initiator tab.
printing::PrintPreviewTabController* tab_controller =
printing::PrintPreviewTabController::GetInstance();
if (tab_controller)
return tab_controller->GetOrCreatePreviewTab(
initiator_tab, delegate_->GetBrowserWindowID());
}
return NULL;
}
#if defined(OS_MACOSX) || defined(OS_WIN)
void RenderViewHost::OnPageReadyForPreview(
const ViewHostMsg_DidPrintPage_Params& params) {
// Get/Create print preview tab.
TabContents* print_preview_tab = GetOrCreatePrintPreviewTab();
DCHECK(print_preview_tab);
// TODO(kmadhusu): Function definition needs to be changed.
// 'params' contains the metafile handle for preview.
// Send the printingDone msg for now.
Send(new ViewMsg_PrintingDone(routing_id(), -1, true));
}
#else
void RenderViewHost::OnPagesReadyForPreview(int fd_in_browser) {
// Get/Create print preview tab.
TabContents* print_preview_tab = GetOrCreatePrintPreviewTab();
DCHECK(print_preview_tab);
// TODO(kmadhusu): Function definition needs to be changed.
// fd_in_browser should be the file descriptor of the metafile.
// Send the printingDone msg for now.
Send(new ViewMsg_PrintingDone(routing_id(), -1, true));
}
#endif