Home | History | Annotate | Download | only in renderer_host
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/renderer_host/render_view_host_impl.h"
      6 
      7 #include <set>
      8 #include <string>
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "base/callback.h"
     13 #include "base/command_line.h"
     14 #include "base/debug/trace_event.h"
     15 #include "base/i18n/rtl.h"
     16 #include "base/json/json_reader.h"
     17 #include "base/message_loop/message_loop.h"
     18 #include "base/metrics/histogram.h"
     19 #include "base/stl_util.h"
     20 #include "base/strings/string_util.h"
     21 #include "base/strings/utf_string_conversions.h"
     22 #include "base/sys_info.h"
     23 #include "base/time/time.h"
     24 #include "base/values.h"
     25 #include "cc/base/switches.h"
     26 #include "content/browser/accessibility/browser_accessibility_manager.h"
     27 #include "content/browser/child_process_security_policy_impl.h"
     28 #include "content/browser/cross_site_request_manager.h"
     29 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
     30 #include "content/browser/frame_host/frame_tree.h"
     31 #include "content/browser/gpu/compositor_util.h"
     32 #include "content/browser/gpu/gpu_data_manager_impl.h"
     33 #include "content/browser/gpu/gpu_process_host.h"
     34 #include "content/browser/gpu/gpu_surface_tracker.h"
     35 #include "content/browser/host_zoom_map_impl.h"
     36 #include "content/browser/loader/resource_dispatcher_host_impl.h"
     37 #include "content/browser/renderer_host/dip_util.h"
     38 #include "content/browser/renderer_host/input/timeout_monitor.h"
     39 #include "content/browser/renderer_host/media/audio_renderer_host.h"
     40 #include "content/browser/renderer_host/render_process_host_impl.h"
     41 #include "content/browser/renderer_host/render_view_host_delegate.h"
     42 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
     43 #include "content/browser/renderer_host/render_widget_host_view_base.h"
     44 #include "content/common/accessibility_messages.h"
     45 #include "content/common/browser_plugin/browser_plugin_messages.h"
     46 #include "content/common/content_switches_internal.h"
     47 #include "content/common/drag_messages.h"
     48 #include "content/common/frame_messages.h"
     49 #include "content/common/input_messages.h"
     50 #include "content/common/inter_process_time_ticks_converter.h"
     51 #include "content/common/mojo/mojo_service_names.h"
     52 #include "content/common/speech_recognition_messages.h"
     53 #include "content/common/swapped_out_messages.h"
     54 #include "content/common/view_messages.h"
     55 #include "content/common/web_ui_setup.mojom.h"
     56 #include "content/public/browser/ax_event_notification_details.h"
     57 #include "content/public/browser/browser_accessibility_state.h"
     58 #include "content/public/browser/browser_context.h"
     59 #include "content/public/browser/browser_message_filter.h"
     60 #include "content/public/browser/content_browser_client.h"
     61 #include "content/public/browser/native_web_keyboard_event.h"
     62 #include "content/public/browser/notification_details.h"
     63 #include "content/public/browser/notification_service.h"
     64 #include "content/public/browser/notification_types.h"
     65 #include "content/public/browser/render_frame_host.h"
     66 #include "content/public/browser/render_widget_host_iterator.h"
     67 #include "content/public/browser/storage_partition.h"
     68 #include "content/public/browser/user_metrics.h"
     69 #include "content/public/common/bindings_policy.h"
     70 #include "content/public/common/content_constants.h"
     71 #include "content/public/common/content_switches.h"
     72 #include "content/public/common/context_menu_params.h"
     73 #include "content/public/common/drop_data.h"
     74 #include "content/public/common/result_codes.h"
     75 #include "content/public/common/url_utils.h"
     76 #include "net/base/filename_util.h"
     77 #include "net/base/net_util.h"
     78 #include "net/base/network_change_notifier.h"
     79 #include "net/url_request/url_request_context_getter.h"
     80 #include "third_party/skia/include/core/SkBitmap.h"
     81 #include "ui/accessibility/ax_tree.h"
     82 #include "ui/base/touch/touch_device.h"
     83 #include "ui/base/touch/touch_enabled.h"
     84 #include "ui/base/ui_base_switches.h"
     85 #include "ui/gfx/image/image_skia.h"
     86 #include "ui/gfx/native_widget_types.h"
     87 #include "ui/native_theme/native_theme_switches.h"
     88 #include "ui/shell_dialogs/selected_file_info.h"
     89 #include "url/url_constants.h"
     90 #include "webkit/browser/fileapi/isolated_context.h"
     91 
     92 #if defined(OS_MACOSX)
     93 #include "content/browser/renderer_host/popup_menu_helper_mac.h"
     94 #elif defined(OS_WIN)
     95 #include "base/win/win_util.h"
     96 #endif
     97 
     98 #if defined(ENABLE_BROWSER_CDMS)
     99 #include "content/browser/media/media_web_contents_observer.h"
    100 #endif
    101 
    102 using base::TimeDelta;
    103 using blink::WebConsoleMessage;
    104 using blink::WebDragOperation;
    105 using blink::WebDragOperationNone;
    106 using blink::WebDragOperationsMask;
    107 using blink::WebInputEvent;
    108 using blink::WebMediaPlayerAction;
    109 using blink::WebPluginAction;
    110 
    111 namespace content {
    112 namespace {
    113 
    114 #if defined(OS_WIN)
    115 
    116 const int kVirtualKeyboardDisplayWaitTimeoutMs = 100;
    117 const int kMaxVirtualKeyboardDisplayRetries = 5;
    118 
    119 void DismissVirtualKeyboardTask() {
    120   static int virtual_keyboard_display_retries = 0;
    121   // If the virtual keyboard is not yet visible, then we execute the task again
    122   // waiting for it to show up.
    123   if (!base::win::DismissVirtualKeyboard()) {
    124     if (virtual_keyboard_display_retries < kMaxVirtualKeyboardDisplayRetries) {
    125       BrowserThread::PostDelayedTask(
    126           BrowserThread::UI, FROM_HERE,
    127           base::Bind(base::IgnoreResult(&DismissVirtualKeyboardTask)),
    128           TimeDelta::FromMilliseconds(kVirtualKeyboardDisplayWaitTimeoutMs));
    129       ++virtual_keyboard_display_retries;
    130     } else {
    131       virtual_keyboard_display_retries = 0;
    132     }
    133   }
    134 }
    135 #endif
    136 
    137 }  // namespace
    138 
    139 // static
    140 const int RenderViewHostImpl::kUnloadTimeoutMS = 1000;
    141 
    142 ///////////////////////////////////////////////////////////////////////////////
    143 // RenderViewHost, public:
    144 
    145 // static
    146 bool RenderViewHostImpl::IsRVHStateActive(RenderViewHostImplState rvh_state) {
    147   if (rvh_state == STATE_DEFAULT ||
    148       rvh_state == STATE_WAITING_FOR_UNLOAD_ACK ||
    149       rvh_state == STATE_WAITING_FOR_COMMIT ||
    150       rvh_state == STATE_WAITING_FOR_CLOSE)
    151     return true;
    152   return false;
    153 }
    154 
    155 // static
    156 RenderViewHost* RenderViewHost::FromID(int render_process_id,
    157                                        int render_view_id) {
    158   return RenderViewHostImpl::FromID(render_process_id, render_view_id);
    159 }
    160 
    161 // static
    162 RenderViewHost* RenderViewHost::From(RenderWidgetHost* rwh) {
    163   DCHECK(rwh->IsRenderView());
    164   return static_cast<RenderViewHostImpl*>(RenderWidgetHostImpl::From(rwh));
    165 }
    166 
    167 ///////////////////////////////////////////////////////////////////////////////
    168 // RenderViewHostImpl, public:
    169 
    170 // static
    171 RenderViewHostImpl* RenderViewHostImpl::FromID(int render_process_id,
    172                                                int render_view_id) {
    173   RenderWidgetHost* widget =
    174       RenderWidgetHost::FromID(render_process_id, render_view_id);
    175   if (!widget || !widget->IsRenderView())
    176     return NULL;
    177   return static_cast<RenderViewHostImpl*>(RenderWidgetHostImpl::From(widget));
    178 }
    179 
    180 RenderViewHostImpl::RenderViewHostImpl(
    181     SiteInstance* instance,
    182     RenderViewHostDelegate* delegate,
    183     RenderWidgetHostDelegate* widget_delegate,
    184     int routing_id,
    185     int main_frame_routing_id,
    186     bool swapped_out,
    187     bool hidden)
    188     : RenderWidgetHostImpl(widget_delegate,
    189                            instance->GetProcess(),
    190                            routing_id,
    191                            hidden),
    192       frames_ref_count_(0),
    193       delegate_(delegate),
    194       instance_(static_cast<SiteInstanceImpl*>(instance)),
    195       waiting_for_drag_context_response_(false),
    196       enabled_bindings_(0),
    197       navigations_suspended_(false),
    198       main_frame_routing_id_(main_frame_routing_id),
    199       run_modal_reply_msg_(NULL),
    200       run_modal_opener_id_(MSG_ROUTING_NONE),
    201       is_waiting_for_beforeunload_ack_(false),
    202       unload_ack_is_for_cross_site_transition_(false),
    203       sudden_termination_allowed_(false),
    204       render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING),
    205       virtual_keyboard_requested_(false),
    206       weak_factory_(this),
    207       is_focused_element_editable_(false) {
    208   DCHECK(instance_.get());
    209   CHECK(delegate_);  // http://crbug.com/82827
    210 
    211   GetProcess()->EnableSendQueue();
    212 
    213   if (swapped_out) {
    214     rvh_state_ = STATE_SWAPPED_OUT;
    215   } else {
    216     rvh_state_ = STATE_DEFAULT;
    217     instance_->increment_active_view_count();
    218   }
    219 
    220   if (ResourceDispatcherHostImpl::Get()) {
    221     BrowserThread::PostTask(
    222         BrowserThread::IO, FROM_HERE,
    223         base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostCreated,
    224                    base::Unretained(ResourceDispatcherHostImpl::Get()),
    225                    GetProcess()->GetID(), GetRoutingID()));
    226   }
    227 
    228 #if defined(ENABLE_BROWSER_CDMS)
    229   media_web_contents_observer_.reset(new MediaWebContentsObserver(this));
    230 #endif
    231 
    232   unload_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind(
    233       &RenderViewHostImpl::OnSwappedOut, weak_factory_.GetWeakPtr(), true)));
    234 }
    235 
    236 RenderViewHostImpl::~RenderViewHostImpl() {
    237   if (ResourceDispatcherHostImpl::Get()) {
    238     BrowserThread::PostTask(
    239         BrowserThread::IO, FROM_HERE,
    240         base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostDeleted,
    241                    base::Unretained(ResourceDispatcherHostImpl::Get()),
    242                    GetProcess()->GetID(), GetRoutingID()));
    243   }
    244 
    245   delegate_->RenderViewDeleted(this);
    246 
    247   // Be sure to clean up any leftover state from cross-site requests.
    248   CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest(
    249       GetProcess()->GetID(), GetRoutingID(), false);
    250 
    251   // If this was swapped out, it already decremented the active view
    252   // count of the SiteInstance it belongs to.
    253   if (IsRVHStateActive(rvh_state_))
    254     instance_->decrement_active_view_count();
    255 }
    256 
    257 RenderViewHostDelegate* RenderViewHostImpl::GetDelegate() const {
    258   return delegate_;
    259 }
    260 
    261 SiteInstance* RenderViewHostImpl::GetSiteInstance() const {
    262   return instance_.get();
    263 }
    264 
    265 bool RenderViewHostImpl::CreateRenderView(
    266     const base::string16& frame_name,
    267     int opener_route_id,
    268     int proxy_route_id,
    269     int32 max_page_id,
    270     bool window_was_created_with_opener) {
    271   TRACE_EVENT0("renderer_host", "RenderViewHostImpl::CreateRenderView");
    272   DCHECK(!IsRenderViewLive()) << "Creating view twice";
    273 
    274   // The process may (if we're sharing a process with another host that already
    275   // initialized it) or may not (we have our own process or the old process
    276   // crashed) have been initialized. Calling Init multiple times will be
    277   // ignored, so this is safe.
    278   if (!GetProcess()->Init())
    279     return false;
    280   DCHECK(GetProcess()->HasConnection());
    281   DCHECK(GetProcess()->GetBrowserContext());
    282 
    283   renderer_initialized_ = true;
    284 
    285   GpuSurfaceTracker::Get()->SetSurfaceHandle(
    286       surface_id(), GetCompositingSurface());
    287 
    288   // Ensure the RenderView starts with a next_page_id larger than any existing
    289   // page ID it might be asked to render.
    290   int32 next_page_id = 1;
    291   if (max_page_id > -1)
    292     next_page_id = max_page_id + 1;
    293 
    294   ViewMsg_New_Params params;
    295   params.renderer_preferences =
    296       delegate_->GetRendererPrefs(GetProcess()->GetBrowserContext());
    297   params.web_preferences = delegate_->GetWebkitPrefs();
    298   params.view_id = GetRoutingID();
    299   params.main_frame_routing_id = main_frame_routing_id_;
    300   params.surface_id = surface_id();
    301   params.session_storage_namespace_id =
    302       delegate_->GetSessionStorageNamespace(instance_)->id();
    303   params.frame_name = frame_name;
    304   // Ensure the RenderView sets its opener correctly.
    305   params.opener_route_id = opener_route_id;
    306   params.swapped_out = !IsRVHStateActive(rvh_state_);
    307   params.proxy_routing_id = proxy_route_id;
    308   params.hidden = is_hidden();
    309   params.never_visible = delegate_->IsNeverVisible();
    310   params.window_was_created_with_opener = window_was_created_with_opener;
    311   params.next_page_id = next_page_id;
    312   GetWebScreenInfo(&params.screen_info);
    313   params.accessibility_mode = accessibility_mode();
    314 
    315   Send(new ViewMsg_New(params));
    316 
    317   // If it's enabled, tell the renderer to set up the Javascript bindings for
    318   // sending messages back to the browser.
    319   if (GetProcess()->IsIsolatedGuest())
    320     DCHECK_EQ(0, enabled_bindings_);
    321   Send(new ViewMsg_AllowBindings(GetRoutingID(), enabled_bindings_));
    322   // Let our delegate know that we created a RenderView.
    323   delegate_->RenderViewCreated(this);
    324 
    325   return true;
    326 }
    327 
    328 bool RenderViewHostImpl::IsRenderViewLive() const {
    329   return GetProcess()->HasConnection() && renderer_initialized_;
    330 }
    331 
    332 void RenderViewHostImpl::SyncRendererPrefs() {
    333   Send(new ViewMsg_SetRendererPrefs(GetRoutingID(),
    334                                     delegate_->GetRendererPrefs(
    335                                         GetProcess()->GetBrowserContext())));
    336 }
    337 
    338 WebPreferences RenderViewHostImpl::GetWebkitPrefs(const GURL& url) {
    339   TRACE_EVENT0("browser", "RenderViewHostImpl::GetWebkitPrefs");
    340   WebPreferences prefs;
    341 
    342   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    343 
    344   prefs.javascript_enabled =
    345       !command_line.HasSwitch(switches::kDisableJavaScript);
    346   prefs.web_security_enabled =
    347       !command_line.HasSwitch(switches::kDisableWebSecurity);
    348   prefs.plugins_enabled =
    349       !command_line.HasSwitch(switches::kDisablePlugins);
    350   prefs.java_enabled =
    351       !command_line.HasSwitch(switches::kDisableJava);
    352 
    353   prefs.remote_fonts_enabled =
    354       !command_line.HasSwitch(switches::kDisableRemoteFonts);
    355   prefs.xslt_enabled =
    356       !command_line.HasSwitch(switches::kDisableXSLT);
    357   prefs.xss_auditor_enabled =
    358       !command_line.HasSwitch(switches::kDisableXSSAuditor);
    359   prefs.application_cache_enabled =
    360       !command_line.HasSwitch(switches::kDisableApplicationCache);
    361 
    362   prefs.local_storage_enabled =
    363       !command_line.HasSwitch(switches::kDisableLocalStorage);
    364   prefs.databases_enabled =
    365       !command_line.HasSwitch(switches::kDisableDatabases);
    366 #if defined(OS_ANDROID)
    367   // WebAudio is enabled by default on x86 and ARM.
    368   prefs.webaudio_enabled =
    369       !command_line.HasSwitch(switches::kDisableWebAudio);
    370 #endif
    371 
    372   prefs.experimental_webgl_enabled =
    373       GpuProcessHost::gpu_enabled() &&
    374       !command_line.HasSwitch(switches::kDisable3DAPIs) &&
    375       !command_line.HasSwitch(switches::kDisableExperimentalWebGL);
    376 
    377   prefs.pepper_3d_enabled =
    378       !command_line.HasSwitch(switches::kDisablePepper3d);
    379 
    380   prefs.flash_3d_enabled =
    381       GpuProcessHost::gpu_enabled() &&
    382       !command_line.HasSwitch(switches::kDisableFlash3d);
    383   prefs.flash_stage3d_enabled =
    384       GpuProcessHost::gpu_enabled() &&
    385       !command_line.HasSwitch(switches::kDisableFlashStage3d);
    386   prefs.flash_stage3d_baseline_enabled =
    387       GpuProcessHost::gpu_enabled() &&
    388       !command_line.HasSwitch(switches::kDisableFlashStage3d);
    389 
    390   prefs.site_specific_quirks_enabled =
    391       !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks);
    392   prefs.allow_file_access_from_file_urls =
    393       command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
    394 
    395   prefs.layer_squashing_enabled = true;
    396   if (command_line.HasSwitch(switches::kEnableLayerSquashing))
    397       prefs.layer_squashing_enabled = true;
    398   if (command_line.HasSwitch(switches::kDisableLayerSquashing))
    399       prefs.layer_squashing_enabled = false;
    400 
    401   prefs.accelerated_2d_canvas_enabled =
    402       GpuProcessHost::gpu_enabled() &&
    403       !command_line.HasSwitch(switches::kDisableAccelerated2dCanvas);
    404   prefs.antialiased_2d_canvas_disabled =
    405       command_line.HasSwitch(switches::kDisable2dCanvasAntialiasing);
    406   prefs.accelerated_2d_canvas_msaa_sample_count =
    407       atoi(command_line.GetSwitchValueASCII(
    408       switches::kAcceleratedCanvas2dMSAASampleCount).c_str());
    409   prefs.deferred_filters_enabled =
    410       !command_line.HasSwitch(switches::kDisableDeferredFilters);
    411   prefs.container_culling_enabled =
    412       command_line.HasSwitch(switches::kEnableContainerCulling);
    413   prefs.region_based_columns_enabled =
    414       command_line.HasSwitch(switches::kEnableRegionBasedColumns);
    415 
    416   if (IsPinchVirtualViewportEnabled()) {
    417     prefs.pinch_virtual_viewport_enabled = true;
    418     prefs.pinch_overlay_scrollbar_thickness = 10;
    419   }
    420   prefs.use_solid_color_scrollbars = ui::IsOverlayScrollbarEnabled();
    421 
    422 #if defined(OS_ANDROID)
    423   prefs.user_gesture_required_for_media_playback = !command_line.HasSwitch(
    424       switches::kDisableGestureRequirementForMediaPlayback);
    425 #endif
    426 
    427   prefs.touch_enabled = ui::AreTouchEventsEnabled();
    428   prefs.device_supports_touch = prefs.touch_enabled &&
    429       ui::IsTouchDevicePresent();
    430 #if defined(OS_ANDROID)
    431   prefs.device_supports_mouse = false;
    432 #endif
    433 
    434   prefs.pointer_events_max_touch_points = ui::MaxTouchPoints();
    435 
    436   prefs.touch_adjustment_enabled =
    437       !command_line.HasSwitch(switches::kDisableTouchAdjustment);
    438   prefs.compositor_touch_hit_testing =
    439       !command_line.HasSwitch(cc::switches::kDisableCompositorTouchHitTesting);
    440 
    441 #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
    442   bool default_enable_scroll_animator = true;
    443 #else
    444   bool default_enable_scroll_animator = false;
    445 #endif
    446   prefs.enable_scroll_animator = default_enable_scroll_animator;
    447   if (command_line.HasSwitch(switches::kEnableSmoothScrolling))
    448     prefs.enable_scroll_animator = true;
    449   if (command_line.HasSwitch(switches::kDisableSmoothScrolling))
    450     prefs.enable_scroll_animator = false;
    451 
    452   // Certain GPU features might have been blacklisted.
    453   GpuDataManagerImpl::GetInstance()->UpdateRendererWebPrefs(&prefs);
    454 
    455   if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
    456           GetProcess()->GetID())) {
    457     prefs.loads_images_automatically = true;
    458     prefs.javascript_enabled = true;
    459   }
    460 
    461   prefs.connection_type = net::NetworkChangeNotifier::GetConnectionType();
    462   prefs.is_online =
    463       prefs.connection_type != net::NetworkChangeNotifier::CONNECTION_NONE;
    464 
    465   prefs.gesture_tap_highlight_enabled = !command_line.HasSwitch(
    466       switches::kDisableGestureTapHighlight);
    467 
    468   prefs.number_of_cpu_cores = base::SysInfo::NumberOfProcessors();
    469 
    470   prefs.viewport_meta_enabled =
    471       command_line.HasSwitch(switches::kEnableViewportMeta);
    472 
    473   prefs.viewport_enabled =
    474       command_line.HasSwitch(switches::kEnableViewport) ||
    475       prefs.viewport_meta_enabled;
    476 
    477   prefs.main_frame_resizes_are_orientation_changes =
    478       command_line.HasSwitch(switches::kMainFrameResizesAreOrientationChanges);
    479 
    480   prefs.deferred_image_decoding_enabled =
    481       command_line.HasSwitch(switches::kEnableDeferredImageDecoding) ||
    482       content::IsImplSidePaintingEnabled();
    483 
    484   prefs.spatial_navigation_enabled = command_line.HasSwitch(
    485       switches::kEnableSpatialNavigation);
    486 
    487   GetContentClient()->browser()->OverrideWebkitPrefs(this, url, &prefs);
    488   return prefs;
    489 }
    490 
    491 void RenderViewHostImpl::Navigate(const FrameMsg_Navigate_Params& params) {
    492   TRACE_EVENT0("renderer_host", "RenderViewHostImpl::Navigate");
    493   delegate_->GetFrameTree()->GetMainFrame()->Navigate(params);
    494 }
    495 
    496 void RenderViewHostImpl::NavigateToURL(const GURL& url) {
    497   delegate_->GetFrameTree()->GetMainFrame()->NavigateToURL(url);
    498 }
    499 
    500 void RenderViewHostImpl::SetNavigationsSuspended(
    501     bool suspend,
    502     const base::TimeTicks& proceed_time) {
    503   // This should only be called to toggle the state.
    504   DCHECK(navigations_suspended_ != suspend);
    505 
    506   navigations_suspended_ = suspend;
    507   if (!suspend && suspended_nav_params_) {
    508     // There's navigation message params waiting to be sent.  Now that we're not
    509     // suspended anymore, resume navigation by sending them.  If we were swapped
    510     // out, we should also stop filtering out the IPC messages now.
    511     SetState(STATE_DEFAULT);
    512 
    513     DCHECK(!proceed_time.is_null());
    514     suspended_nav_params_->browser_navigation_start = proceed_time;
    515     Send(new FrameMsg_Navigate(
    516         main_frame_routing_id_, *suspended_nav_params_.get()));
    517     suspended_nav_params_.reset();
    518   }
    519 }
    520 
    521 void RenderViewHostImpl::CancelSuspendedNavigations() {
    522   // Clear any state if a pending navigation is canceled or pre-empted.
    523   if (suspended_nav_params_)
    524     suspended_nav_params_.reset();
    525   navigations_suspended_ = false;
    526 }
    527 
    528 void RenderViewHostImpl::SuppressDialogsUntilSwapOut() {
    529   Send(new ViewMsg_SuppressDialogsUntilSwapOut(GetRoutingID()));
    530 }
    531 
    532 void RenderViewHostImpl::OnSwappedOut(bool timed_out) {
    533   // Ignore spurious swap out ack.
    534   if (!IsWaitingForUnloadACK())
    535     return;
    536   unload_event_monitor_timeout_->Stop();
    537   if (timed_out) {
    538     base::ProcessHandle process_handle = GetProcess()->GetHandle();
    539     int views = 0;
    540 
    541     // Count the number of active widget hosts for the process, which
    542     // is equivalent to views using the process as of this writing.
    543     scoped_ptr<RenderWidgetHostIterator> widgets(
    544       RenderWidgetHost::GetRenderWidgetHosts());
    545     while (RenderWidgetHost* widget = widgets->GetNextHost()) {
    546       if (widget->GetProcess()->GetID() == GetProcess()->GetID())
    547         ++views;
    548     }
    549 
    550     if (!RenderProcessHost::run_renderer_in_process() &&
    551         process_handle && views <= 1) {
    552       // The process can safely be terminated, only if WebContents sets
    553       // SuddenTerminationAllowed, which indicates that the timer has expired.
    554       // This is not the case if we load data URLs or about:blank. The reason
    555       // is that those have no network requests and this code is hit without
    556       // setting the unresponsiveness timer. This allows a corner case where a
    557       // navigation to a data URL will leave a process running, if the
    558       // beforeunload handler completes fine, but the unload handler hangs.
    559       // At this time, the complexity to solve this edge case is not worthwhile.
    560       if (SuddenTerminationAllowed()) {
    561         // We should kill the process, but for now, just log the data so we can
    562         // diagnose the kill rate and investigate if separate timer is needed.
    563         // http://crbug.com/104346.
    564 
    565         // Log a histogram point to help us diagnose how many of those kills
    566         // we have performed. 1 is the enum value for RendererType Normal for
    567         // the histogram.
    568         UMA_HISTOGRAM_PERCENTAGE(
    569             "BrowserRenderProcessHost.ChildKillsUnresponsive", 1);
    570       }
    571     }
    572   }
    573 
    574   switch (rvh_state_) {
    575     case STATE_WAITING_FOR_UNLOAD_ACK:
    576       SetState(STATE_WAITING_FOR_COMMIT);
    577       break;
    578     case STATE_PENDING_SWAP_OUT:
    579       SetState(STATE_SWAPPED_OUT);
    580       break;
    581     case STATE_PENDING_SHUTDOWN:
    582       DCHECK(!pending_shutdown_on_swap_out_.is_null());
    583       pending_shutdown_on_swap_out_.Run();
    584       break;
    585     default:
    586       NOTREACHED();
    587   }
    588 }
    589 
    590 void RenderViewHostImpl::WasSwappedOut(
    591     const base::Closure& pending_delete_on_swap_out) {
    592   Send(new ViewMsg_WasSwappedOut(GetRoutingID()));
    593   if (rvh_state_ == STATE_WAITING_FOR_UNLOAD_ACK) {
    594     SetState(STATE_PENDING_SWAP_OUT);
    595     if (!instance_->active_view_count())
    596       SetPendingShutdown(pending_delete_on_swap_out);
    597   } else if (rvh_state_ == STATE_WAITING_FOR_COMMIT) {
    598     SetState(STATE_SWAPPED_OUT);
    599   } else if (rvh_state_ == STATE_DEFAULT) {
    600     // When the RenderView is not live, the RenderFrameHostManager will call
    601     // CommitPending directly, without calling SwapOut on the old RVH. This will
    602     // cause WasSwappedOut to be called directly on the live old RVH.
    603     DCHECK(!IsRenderViewLive());
    604     SetState(STATE_SWAPPED_OUT);
    605   } else {
    606     NOTREACHED();
    607   }
    608 }
    609 
    610 void RenderViewHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) {
    611   pending_shutdown_on_swap_out_ = on_swap_out;
    612   SetState(STATE_PENDING_SHUTDOWN);
    613 }
    614 
    615 void RenderViewHostImpl::ClosePage() {
    616   SetState(STATE_WAITING_FOR_CLOSE);
    617   StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
    618 
    619   if (IsRenderViewLive()) {
    620     // Since we are sending an IPC message to the renderer, increase the event
    621     // count to prevent the hang monitor timeout from being stopped by input
    622     // event acknowledgements.
    623     increment_in_flight_event_count();
    624 
    625     // TODO(creis): Should this be moved to Shutdown?  It may not be called for
    626     // RenderViewHosts that have been swapped out.
    627     NotificationService::current()->Notify(
    628         NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW,
    629         Source<RenderViewHost>(this),
    630         NotificationService::NoDetails());
    631 
    632     Send(new ViewMsg_ClosePage(GetRoutingID()));
    633   } else {
    634     // This RenderViewHost doesn't have a live renderer, so just skip the unload
    635     // event and close the page.
    636     ClosePageIgnoringUnloadEvents();
    637   }
    638 }
    639 
    640 void RenderViewHostImpl::ClosePageIgnoringUnloadEvents() {
    641   StopHangMonitorTimeout();
    642   is_waiting_for_beforeunload_ack_ = false;
    643 
    644   sudden_termination_allowed_ = true;
    645   delegate_->Close(this);
    646 }
    647 
    648 bool RenderViewHostImpl::HasPendingCrossSiteRequest() {
    649   return CrossSiteRequestManager::GetInstance()->HasPendingCrossSiteRequest(
    650       GetProcess()->GetID(), GetRoutingID());
    651 }
    652 
    653 void RenderViewHostImpl::SetHasPendingCrossSiteRequest(
    654     bool has_pending_request) {
    655   CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest(
    656       GetProcess()->GetID(), GetRoutingID(), has_pending_request);
    657 }
    658 
    659 void RenderViewHostImpl::SetWebUIHandle(mojo::ScopedMessagePipeHandle handle) {
    660   // Never grant any bindings to browser plugin guests.
    661   if (GetProcess()->IsIsolatedGuest()) {
    662     NOTREACHED() << "Never grant bindings to a guest process.";
    663     return;
    664   }
    665 
    666   if ((enabled_bindings_ & BINDINGS_POLICY_WEB_UI) == 0) {
    667     NOTREACHED() << "You must grant bindings before setting the handle";
    668     return;
    669   }
    670 
    671   DCHECK(renderer_initialized_);
    672 
    673   WebUISetupPtr web_ui_setup;
    674   static_cast<RenderProcessHostImpl*>(GetProcess())->ConnectTo(
    675       kRendererService_WebUISetup, &web_ui_setup);
    676 
    677   web_ui_setup->SetWebUIHandle(GetRoutingID(), handle.Pass());
    678 }
    679 
    680 #if defined(OS_ANDROID)
    681 void RenderViewHostImpl::ActivateNearestFindResult(int request_id,
    682                                                    float x,
    683                                                    float y) {
    684   Send(new InputMsg_ActivateNearestFindResult(GetRoutingID(),
    685                                               request_id, x, y));
    686 }
    687 
    688 void RenderViewHostImpl::RequestFindMatchRects(int current_version) {
    689   Send(new ViewMsg_FindMatchRects(GetRoutingID(), current_version));
    690 }
    691 #endif
    692 
    693 void RenderViewHostImpl::DragTargetDragEnter(
    694     const DropData& drop_data,
    695     const gfx::Point& client_pt,
    696     const gfx::Point& screen_pt,
    697     WebDragOperationsMask operations_allowed,
    698     int key_modifiers) {
    699   const int renderer_id = GetProcess()->GetID();
    700   ChildProcessSecurityPolicyImpl* policy =
    701       ChildProcessSecurityPolicyImpl::GetInstance();
    702 
    703   // The URL could have been cobbled together from any highlighted text string,
    704   // and can't be interpreted as a capability.
    705   DropData filtered_data(drop_data);
    706   GetProcess()->FilterURL(true, &filtered_data.url);
    707   if (drop_data.did_originate_from_renderer) {
    708     filtered_data.filenames.clear();
    709   }
    710 
    711   // The filenames vector, on the other hand, does represent a capability to
    712   // access the given files.
    713   fileapi::IsolatedContext::FileInfoSet files;
    714   for (std::vector<ui::FileInfo>::iterator iter(
    715            filtered_data.filenames.begin());
    716        iter != filtered_data.filenames.end();
    717        ++iter) {
    718     // A dragged file may wind up as the value of an input element, or it
    719     // may be used as the target of a navigation instead.  We don't know
    720     // which will happen at this point, so generously grant both access
    721     // and request permissions to the specific file to cover both cases.
    722     // We do not give it the permission to request all file:// URLs.
    723 
    724     // Make sure we have the same display_name as the one we register.
    725     if (iter->display_name.empty()) {
    726       std::string name;
    727       files.AddPath(iter->path, &name);
    728       iter->display_name = base::FilePath::FromUTF8Unsafe(name);
    729     } else {
    730       files.AddPathWithName(iter->path, iter->display_name.AsUTF8Unsafe());
    731     }
    732 
    733     policy->GrantRequestSpecificFileURL(renderer_id,
    734                                         net::FilePathToFileURL(iter->path));
    735 
    736     // If the renderer already has permission to read these paths, we don't need
    737     // to re-grant them. This prevents problems with DnD for files in the CrOS
    738     // file manager--the file manager already had read/write access to those
    739     // directories, but dragging a file would cause the read/write access to be
    740     // overwritten with read-only access, making them impossible to delete or
    741     // rename until the renderer was killed.
    742     if (!policy->CanReadFile(renderer_id, iter->path))
    743       policy->GrantReadFile(renderer_id, iter->path);
    744   }
    745 
    746   fileapi::IsolatedContext* isolated_context =
    747       fileapi::IsolatedContext::GetInstance();
    748   DCHECK(isolated_context);
    749   std::string filesystem_id = isolated_context->RegisterDraggedFileSystem(
    750       files);
    751   if (!filesystem_id.empty()) {
    752     // Grant the permission iff the ID is valid.
    753     policy->GrantReadFileSystem(renderer_id, filesystem_id);
    754   }
    755   filtered_data.filesystem_id = base::UTF8ToUTF16(filesystem_id);
    756 
    757   fileapi::FileSystemContext* file_system_context =
    758       BrowserContext::GetStoragePartition(
    759           GetProcess()->GetBrowserContext(),
    760           GetSiteInstance())->GetFileSystemContext();
    761   for (size_t i = 0; i < filtered_data.file_system_files.size(); ++i) {
    762     fileapi::FileSystemURL file_system_url =
    763         file_system_context->CrackURL(filtered_data.file_system_files[i].url);
    764 
    765     std::string register_name;
    766     std::string filesystem_id = isolated_context->RegisterFileSystemForPath(
    767         file_system_url.type(), file_system_url.filesystem_id(),
    768         file_system_url.path(), &register_name);
    769     policy->GrantReadFileSystem(renderer_id, filesystem_id);
    770 
    771     // Note: We are using the origin URL provided by the sender here. It may be
    772     // different from the receiver's.
    773     filtered_data.file_system_files[i].url = GURL(
    774         fileapi::GetIsolatedFileSystemRootURIString(
    775             file_system_url.origin(),
    776             filesystem_id,
    777             std::string()).append(register_name));
    778   }
    779 
    780   Send(new DragMsg_TargetDragEnter(GetRoutingID(), filtered_data, client_pt,
    781                                    screen_pt, operations_allowed,
    782                                    key_modifiers));
    783 }
    784 
    785 void RenderViewHostImpl::DragTargetDragOver(
    786     const gfx::Point& client_pt,
    787     const gfx::Point& screen_pt,
    788     WebDragOperationsMask operations_allowed,
    789     int key_modifiers) {
    790   Send(new DragMsg_TargetDragOver(GetRoutingID(), client_pt, screen_pt,
    791                                   operations_allowed, key_modifiers));
    792 }
    793 
    794 void RenderViewHostImpl::DragTargetDragLeave() {
    795   Send(new DragMsg_TargetDragLeave(GetRoutingID()));
    796 }
    797 
    798 void RenderViewHostImpl::DragTargetDrop(
    799     const gfx::Point& client_pt,
    800     const gfx::Point& screen_pt,
    801     int key_modifiers) {
    802   Send(new DragMsg_TargetDrop(GetRoutingID(), client_pt, screen_pt,
    803                               key_modifiers));
    804 }
    805 
    806 void RenderViewHostImpl::DragSourceEndedAt(
    807     int client_x, int client_y, int screen_x, int screen_y,
    808     WebDragOperation operation) {
    809   Send(new DragMsg_SourceEnded(GetRoutingID(),
    810                                gfx::Point(client_x, client_y),
    811                                gfx::Point(screen_x, screen_y),
    812                                operation));
    813 }
    814 
    815 void RenderViewHostImpl::DragSourceSystemDragEnded() {
    816   Send(new DragMsg_SourceSystemDragEnded(GetRoutingID()));
    817 }
    818 
    819 RenderFrameHost* RenderViewHostImpl::GetMainFrame() {
    820   return RenderFrameHost::FromID(GetProcess()->GetID(), main_frame_routing_id_);
    821 }
    822 
    823 void RenderViewHostImpl::AllowBindings(int bindings_flags) {
    824   // Never grant any bindings to browser plugin guests.
    825   if (GetProcess()->IsIsolatedGuest()) {
    826     NOTREACHED() << "Never grant bindings to a guest process.";
    827     return;
    828   }
    829 
    830   // Ensure we aren't granting WebUI bindings to a process that has already
    831   // been used for non-privileged views.
    832   if (bindings_flags & BINDINGS_POLICY_WEB_UI &&
    833       GetProcess()->HasConnection() &&
    834       !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
    835           GetProcess()->GetID())) {
    836     // This process has no bindings yet. Make sure it does not have more
    837     // than this single active view.
    838     RenderProcessHostImpl* process =
    839         static_cast<RenderProcessHostImpl*>(GetProcess());
    840     // --single-process only has one renderer.
    841     if (process->GetActiveViewCount() > 1 &&
    842         !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
    843       return;
    844   }
    845 
    846   if (bindings_flags & BINDINGS_POLICY_WEB_UI) {
    847     ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
    848         GetProcess()->GetID());
    849   }
    850 
    851   enabled_bindings_ |= bindings_flags;
    852   if (renderer_initialized_)
    853     Send(new ViewMsg_AllowBindings(GetRoutingID(), enabled_bindings_));
    854 }
    855 
    856 int RenderViewHostImpl::GetEnabledBindings() const {
    857   return enabled_bindings_;
    858 }
    859 
    860 void RenderViewHostImpl::SetWebUIProperty(const std::string& name,
    861                                           const std::string& value) {
    862   // This is a sanity check before telling the renderer to enable the property.
    863   // It could lie and send the corresponding IPC messages anyway, but we will
    864   // not act on them if enabled_bindings_ doesn't agree. If we get here without
    865   // WebUI bindings, kill the renderer process.
    866   if (enabled_bindings_ & BINDINGS_POLICY_WEB_UI) {
    867     Send(new ViewMsg_SetWebUIProperty(GetRoutingID(), name, value));
    868   } else {
    869     RecordAction(
    870         base::UserMetricsAction("BindingsMismatchTerminate_RVH_WebUI"));
    871     base::KillProcess(
    872         GetProcess()->GetHandle(), content::RESULT_CODE_KILLED, false);
    873   }
    874 }
    875 
    876 void RenderViewHostImpl::GotFocus() {
    877   RenderWidgetHostImpl::GotFocus();  // Notifies the renderer it got focus.
    878 
    879   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
    880   if (view)
    881     view->GotFocus();
    882 }
    883 
    884 void RenderViewHostImpl::LostCapture() {
    885   RenderWidgetHostImpl::LostCapture();
    886   delegate_->LostCapture();
    887 }
    888 
    889 void RenderViewHostImpl::LostMouseLock() {
    890   RenderWidgetHostImpl::LostMouseLock();
    891   delegate_->LostMouseLock();
    892 }
    893 
    894 void RenderViewHostImpl::SetInitialFocus(bool reverse) {
    895   Send(new ViewMsg_SetInitialFocus(GetRoutingID(), reverse));
    896 }
    897 
    898 void RenderViewHostImpl::FilesSelectedInChooser(
    899     const std::vector<ui::SelectedFileInfo>& files,
    900     FileChooserParams::Mode permissions) {
    901   // Grant the security access requested to the given files.
    902   for (size_t i = 0; i < files.size(); ++i) {
    903     const ui::SelectedFileInfo& file = files[i];
    904     if (permissions == FileChooserParams::Save) {
    905       ChildProcessSecurityPolicyImpl::GetInstance()->GrantCreateReadWriteFile(
    906           GetProcess()->GetID(), file.local_path);
    907     } else {
    908       ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
    909           GetProcess()->GetID(), file.local_path);
    910     }
    911   }
    912   Send(new ViewMsg_RunFileChooserResponse(GetRoutingID(), files));
    913 }
    914 
    915 void RenderViewHostImpl::DirectoryEnumerationFinished(
    916     int request_id,
    917     const std::vector<base::FilePath>& files) {
    918   // Grant the security access requested to the given files.
    919   for (std::vector<base::FilePath>::const_iterator file = files.begin();
    920        file != files.end(); ++file) {
    921     ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
    922         GetProcess()->GetID(), *file);
    923   }
    924   Send(new ViewMsg_EnumerateDirectoryResponse(GetRoutingID(),
    925                                               request_id,
    926                                               files));
    927 }
    928 
    929 void RenderViewHostImpl::LoadStateChanged(
    930     const GURL& url,
    931     const net::LoadStateWithParam& load_state,
    932     uint64 upload_position,
    933     uint64 upload_size) {
    934   delegate_->LoadStateChanged(url, load_state, upload_position, upload_size);
    935 }
    936 
    937 bool RenderViewHostImpl::SuddenTerminationAllowed() const {
    938   return sudden_termination_allowed_ ||
    939       GetProcess()->SuddenTerminationAllowed();
    940 }
    941 
    942 ///////////////////////////////////////////////////////////////////////////////
    943 // RenderViewHostImpl, IPC message handlers:
    944 
    945 bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
    946   if (!BrowserMessageFilter::CheckCanDispatchOnUI(msg, this))
    947     return true;
    948 
    949   // Filter out most IPC messages if this renderer is swapped out.
    950   // We still want to handle certain ACKs to keep our state consistent.
    951   if (IsSwappedOut()) {
    952     if (!SwappedOutMessages::CanHandleWhileSwappedOut(msg)) {
    953       // If this is a synchronous message and we decided not to handle it,
    954       // we must send an error reply, or else the renderer will be stuck
    955       // and won't respond to future requests.
    956       if (msg.is_sync()) {
    957         IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
    958         reply->set_reply_error();
    959         Send(reply);
    960       }
    961       // Don't continue looking for someone to handle it.
    962       return true;
    963     }
    964   }
    965 
    966   if (delegate_->OnMessageReceived(this, msg))
    967     return true;
    968 
    969   bool handled = true;
    970   IPC_BEGIN_MESSAGE_MAP(RenderViewHostImpl, msg)
    971     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowView, OnShowView)
    972     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
    973     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget,
    974                         OnShowFullscreenWidget)
    975     IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunModal, OnRunModal)
    976     IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady)
    977     IPC_MESSAGE_HANDLER(ViewHostMsg_RenderProcessGone, OnRenderProcessGone)
    978     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateState, OnUpdateState)
    979     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL)
    980     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateInspectorSetting,
    981                         OnUpdateInspectorSetting)
    982     IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
    983     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
    984     IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentAvailableInMainFrame,
    985                         OnDocumentAvailableInMainFrame)
    986     IPC_MESSAGE_HANDLER(ViewHostMsg_ToggleFullscreen, OnToggleFullscreen)
    987     IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange,
    988                         OnDidContentsPreferredSizeChange)
    989     IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeScrollOffset,
    990                         OnDidChangeScrollOffset)
    991     IPC_MESSAGE_HANDLER(ViewHostMsg_RouteCloseEvent,
    992                         OnRouteCloseEvent)
    993     IPC_MESSAGE_HANDLER(ViewHostMsg_RouteMessageEvent, OnRouteMessageEvent)
    994     IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging)
    995     IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor)
    996     IPC_MESSAGE_HANDLER(DragHostMsg_TargetDrop_ACK, OnTargetDropACK)
    997     IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
    998     IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnFocusedNodeChanged)
    999     IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK)
   1000     IPC_MESSAGE_HANDLER(ViewHostMsg_DidZoomURL, OnDidZoomURL)
   1001 #if defined(OS_MACOSX) || defined(OS_ANDROID)
   1002     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnShowPopup)
   1003     IPC_MESSAGE_HANDLER(ViewHostMsg_HidePopup, OnHidePopup)
   1004 #endif
   1005     IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser)
   1006     IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Events, OnAccessibilityEvents)
   1007     IPC_MESSAGE_HANDLER(AccessibilityHostMsg_LocationChanges,
   1008                         OnAccessibilityLocationChanges)
   1009     IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched)
   1010     // Have the super handle all other messages.
   1011     IPC_MESSAGE_UNHANDLED(
   1012         handled = RenderWidgetHostImpl::OnMessageReceived(msg))
   1013   IPC_END_MESSAGE_MAP()
   1014 
   1015   return handled;
   1016 }
   1017 
   1018 void RenderViewHostImpl::Init() {
   1019   RenderWidgetHostImpl::Init();
   1020 }
   1021 
   1022 void RenderViewHostImpl::Shutdown() {
   1023   // If we are being run modally (see RunModal), then we need to cleanup.
   1024   if (run_modal_reply_msg_) {
   1025     Send(run_modal_reply_msg_);
   1026     run_modal_reply_msg_ = NULL;
   1027     RenderViewHostImpl* opener =
   1028         RenderViewHostImpl::FromID(GetProcess()->GetID(), run_modal_opener_id_);
   1029     if (opener) {
   1030       opener->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(
   1031           hung_renderer_delay_ms_));
   1032       // Balance out the decrement when we got created.
   1033       opener->increment_in_flight_event_count();
   1034     }
   1035     run_modal_opener_id_ = MSG_ROUTING_NONE;
   1036   }
   1037 
   1038   // We can't release the SessionStorageNamespace until our peer
   1039   // in the renderer has wound down.
   1040   if (GetProcess()->HasConnection()) {
   1041     RenderProcessHostImpl::ReleaseOnCloseACK(
   1042         GetProcess(),
   1043         delegate_->GetSessionStorageNamespaceMap(),
   1044         GetRoutingID());
   1045   }
   1046 
   1047   RenderWidgetHostImpl::Shutdown();
   1048 }
   1049 
   1050 bool RenderViewHostImpl::IsRenderView() const {
   1051   return true;
   1052 }
   1053 
   1054 void RenderViewHostImpl::CreateNewWindow(
   1055     int route_id,
   1056     int main_frame_route_id,
   1057     const ViewHostMsg_CreateWindow_Params& params,
   1058     SessionStorageNamespace* session_storage_namespace) {
   1059   ViewHostMsg_CreateWindow_Params validated_params(params);
   1060   GetProcess()->FilterURL(false, &validated_params.target_url);
   1061   GetProcess()->FilterURL(false, &validated_params.opener_url);
   1062   GetProcess()->FilterURL(true, &validated_params.opener_security_origin);
   1063 
   1064   delegate_->CreateNewWindow(
   1065       GetProcess()->GetID(), route_id, main_frame_route_id, validated_params,
   1066       session_storage_namespace);
   1067 }
   1068 
   1069 void RenderViewHostImpl::CreateNewWidget(int route_id,
   1070                                      blink::WebPopupType popup_type) {
   1071   delegate_->CreateNewWidget(GetProcess()->GetID(), route_id, popup_type);
   1072 }
   1073 
   1074 void RenderViewHostImpl::CreateNewFullscreenWidget(int route_id) {
   1075   delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), route_id);
   1076 }
   1077 
   1078 void RenderViewHostImpl::OnShowView(int route_id,
   1079                                     WindowOpenDisposition disposition,
   1080                                     const gfx::Rect& initial_pos,
   1081                                     bool user_gesture) {
   1082   if (IsRVHStateActive(rvh_state_)) {
   1083     delegate_->ShowCreatedWindow(
   1084         route_id, disposition, initial_pos, user_gesture);
   1085   }
   1086   Send(new ViewMsg_Move_ACK(route_id));
   1087 }
   1088 
   1089 void RenderViewHostImpl::OnShowWidget(int route_id,
   1090                                       const gfx::Rect& initial_pos) {
   1091   if (IsRVHStateActive(rvh_state_))
   1092     delegate_->ShowCreatedWidget(route_id, initial_pos);
   1093   Send(new ViewMsg_Move_ACK(route_id));
   1094 }
   1095 
   1096 void RenderViewHostImpl::OnShowFullscreenWidget(int route_id) {
   1097   if (IsRVHStateActive(rvh_state_))
   1098     delegate_->ShowCreatedFullscreenWidget(route_id);
   1099   Send(new ViewMsg_Move_ACK(route_id));
   1100 }
   1101 
   1102 void RenderViewHostImpl::OnRunModal(int opener_id, IPC::Message* reply_msg) {
   1103   DCHECK(!run_modal_reply_msg_);
   1104   run_modal_reply_msg_ = reply_msg;
   1105   run_modal_opener_id_ = opener_id;
   1106 
   1107   RecordAction(base::UserMetricsAction("ShowModalDialog"));
   1108 
   1109   RenderViewHostImpl* opener =
   1110       RenderViewHostImpl::FromID(GetProcess()->GetID(), run_modal_opener_id_);
   1111   if (opener) {
   1112     opener->StopHangMonitorTimeout();
   1113     // The ack for the mouse down won't come until the dialog closes, so fake it
   1114     // so that we don't get a timeout.
   1115     opener->decrement_in_flight_event_count();
   1116   }
   1117 
   1118   // TODO(darin): Bug 1107929: Need to inform our delegate to show this view in
   1119   // an app-modal fashion.
   1120 }
   1121 
   1122 void RenderViewHostImpl::OnRenderViewReady() {
   1123   render_view_termination_status_ = base::TERMINATION_STATUS_STILL_RUNNING;
   1124   SendScreenRects();
   1125   WasResized();
   1126   delegate_->RenderViewReady(this);
   1127 }
   1128 
   1129 void RenderViewHostImpl::OnRenderProcessGone(int status, int exit_code) {
   1130   // Keep the termination status so we can get at it later when we
   1131   // need to know why it died.
   1132   render_view_termination_status_ =
   1133       static_cast<base::TerminationStatus>(status);
   1134 
   1135   // Reset frame tree state associated with this process.  This must happen
   1136   // before RenderViewTerminated because observers expect the subframes of any
   1137   // affected frames to be cleared first.
   1138   delegate_->GetFrameTree()->RenderProcessGone(this);
   1139 
   1140   // Our base class RenderWidgetHost needs to reset some stuff.
   1141   RendererExited(render_view_termination_status_, exit_code);
   1142 
   1143   delegate_->RenderViewTerminated(this,
   1144                                   static_cast<base::TerminationStatus>(status),
   1145                                   exit_code);
   1146 }
   1147 
   1148 void RenderViewHostImpl::OnUpdateState(int32 page_id, const PageState& state) {
   1149   // Without this check, the renderer can trick the browser into using
   1150   // filenames it can't access in a future session restore.
   1151   if (!CanAccessFilesOfPageState(state)) {
   1152     GetProcess()->ReceivedBadMessage();
   1153     return;
   1154   }
   1155 
   1156   delegate_->UpdateState(this, page_id, state);
   1157 }
   1158 
   1159 void RenderViewHostImpl::OnUpdateTargetURL(int32 page_id, const GURL& url) {
   1160   if (IsRVHStateActive(rvh_state_))
   1161     delegate_->UpdateTargetURL(page_id, url);
   1162 
   1163   // Send a notification back to the renderer that we are ready to
   1164   // receive more target urls.
   1165   Send(new ViewMsg_UpdateTargetURL_ACK(GetRoutingID()));
   1166 }
   1167 
   1168 void RenderViewHostImpl::OnUpdateInspectorSetting(
   1169     const std::string& key, const std::string& value) {
   1170   GetContentClient()->browser()->UpdateInspectorSetting(
   1171       this, key, value);
   1172 }
   1173 
   1174 void RenderViewHostImpl::OnClose() {
   1175   // If the renderer is telling us to close, it has already run the unload
   1176   // events, and we can take the fast path.
   1177   ClosePageIgnoringUnloadEvents();
   1178 }
   1179 
   1180 void RenderViewHostImpl::OnRequestMove(const gfx::Rect& pos) {
   1181   if (IsRVHStateActive(rvh_state_))
   1182     delegate_->RequestMove(pos);
   1183   Send(new ViewMsg_Move_ACK(GetRoutingID()));
   1184 }
   1185 
   1186 void RenderViewHostImpl::OnDocumentAvailableInMainFrame(
   1187     bool uses_temporary_zoom_level) {
   1188   delegate_->DocumentAvailableInMainFrame(this);
   1189 
   1190   if (!uses_temporary_zoom_level)
   1191     return;
   1192 
   1193   HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
   1194       HostZoomMap::GetForBrowserContext(GetProcess()->GetBrowserContext()));
   1195   host_zoom_map->SetTemporaryZoomLevel(GetProcess()->GetID(),
   1196                                        GetRoutingID(),
   1197                                        host_zoom_map->GetDefaultZoomLevel());
   1198 }
   1199 
   1200 void RenderViewHostImpl::OnToggleFullscreen(bool enter_fullscreen) {
   1201   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   1202   delegate_->ToggleFullscreenMode(enter_fullscreen);
   1203   // We need to notify the contents that its fullscreen state has changed. This
   1204   // is done as part of the resize message.
   1205   WasResized();
   1206 }
   1207 
   1208 void RenderViewHostImpl::OnDidContentsPreferredSizeChange(
   1209     const gfx::Size& new_size) {
   1210   delegate_->UpdatePreferredSize(new_size);
   1211 }
   1212 
   1213 void RenderViewHostImpl::OnRenderAutoResized(const gfx::Size& new_size) {
   1214   delegate_->ResizeDueToAutoResize(new_size);
   1215 }
   1216 
   1217 void RenderViewHostImpl::OnDidChangeScrollOffset() {
   1218   if (view_)
   1219     view_->ScrollOffsetChanged();
   1220 }
   1221 
   1222 void RenderViewHostImpl::OnRouteCloseEvent() {
   1223   // Have the delegate route this to the active RenderViewHost.
   1224   delegate_->RouteCloseEvent(this);
   1225 }
   1226 
   1227 void RenderViewHostImpl::OnRouteMessageEvent(
   1228     const ViewMsg_PostMessage_Params& params) {
   1229   // Give to the delegate to route to the active RenderViewHost.
   1230   delegate_->RouteMessageEvent(this, params);
   1231 }
   1232 
   1233 void RenderViewHostImpl::OnStartDragging(
   1234     const DropData& drop_data,
   1235     WebDragOperationsMask drag_operations_mask,
   1236     const SkBitmap& bitmap,
   1237     const gfx::Vector2d& bitmap_offset_in_dip,
   1238     const DragEventSourceInfo& event_info) {
   1239   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
   1240   if (!view)
   1241     return;
   1242 
   1243   DropData filtered_data(drop_data);
   1244   RenderProcessHost* process = GetProcess();
   1245   ChildProcessSecurityPolicyImpl* policy =
   1246       ChildProcessSecurityPolicyImpl::GetInstance();
   1247 
   1248   // Allow drag of Javascript URLs to enable bookmarklet drag to bookmark bar.
   1249   if (!filtered_data.url.SchemeIs(url::kJavaScriptScheme))
   1250     process->FilterURL(true, &filtered_data.url);
   1251   process->FilterURL(false, &filtered_data.html_base_url);
   1252   // Filter out any paths that the renderer didn't have access to. This prevents
   1253   // the following attack on a malicious renderer:
   1254   // 1. StartDragging IPC sent with renderer-specified filesystem paths that it
   1255   //    doesn't have read permissions for.
   1256   // 2. We initiate a native DnD operation.
   1257   // 3. DnD operation immediately ends since mouse is not held down. DnD events
   1258   //    still fire though, which causes read permissions to be granted to the
   1259   //    renderer for any file paths in the drop.
   1260   filtered_data.filenames.clear();
   1261   for (std::vector<ui::FileInfo>::const_iterator it =
   1262            drop_data.filenames.begin();
   1263        it != drop_data.filenames.end();
   1264        ++it) {
   1265     if (policy->CanReadFile(GetProcess()->GetID(), it->path))
   1266       filtered_data.filenames.push_back(*it);
   1267   }
   1268 
   1269   fileapi::FileSystemContext* file_system_context =
   1270       BrowserContext::GetStoragePartition(
   1271           GetProcess()->GetBrowserContext(),
   1272           GetSiteInstance())->GetFileSystemContext();
   1273   filtered_data.file_system_files.clear();
   1274   for (size_t i = 0; i < drop_data.file_system_files.size(); ++i) {
   1275     fileapi::FileSystemURL file_system_url =
   1276         file_system_context->CrackURL(drop_data.file_system_files[i].url);
   1277     if (policy->CanReadFileSystemFile(GetProcess()->GetID(), file_system_url))
   1278       filtered_data.file_system_files.push_back(drop_data.file_system_files[i]);
   1279   }
   1280 
   1281   float scale = GetScaleFactorForView(GetView());
   1282   gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, scale));
   1283   view->StartDragging(filtered_data, drag_operations_mask, image,
   1284       bitmap_offset_in_dip, event_info);
   1285 }
   1286 
   1287 void RenderViewHostImpl::OnUpdateDragCursor(WebDragOperation current_op) {
   1288   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
   1289   if (view)
   1290     view->UpdateDragCursor(current_op);
   1291 }
   1292 
   1293 void RenderViewHostImpl::OnTargetDropACK() {
   1294   NotificationService::current()->Notify(
   1295       NOTIFICATION_RENDER_VIEW_HOST_DID_RECEIVE_DRAG_TARGET_DROP_ACK,
   1296       Source<RenderViewHost>(this),
   1297       NotificationService::NoDetails());
   1298 }
   1299 
   1300 void RenderViewHostImpl::OnTakeFocus(bool reverse) {
   1301   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
   1302   if (view)
   1303     view->TakeFocus(reverse);
   1304 }
   1305 
   1306 void RenderViewHostImpl::OnFocusedNodeChanged(bool is_editable_node) {
   1307   is_focused_element_editable_ = is_editable_node;
   1308   if (view_)
   1309     view_->FocusedNodeChanged(is_editable_node);
   1310 #if defined(OS_WIN)
   1311   if (!is_editable_node && virtual_keyboard_requested_) {
   1312     virtual_keyboard_requested_ = false;
   1313     BrowserThread::PostDelayedTask(
   1314         BrowserThread::UI, FROM_HERE,
   1315         base::Bind(base::IgnoreResult(&DismissVirtualKeyboardTask)),
   1316         TimeDelta::FromMilliseconds(kVirtualKeyboardDisplayWaitTimeoutMs));
   1317   }
   1318 #endif
   1319   NotificationService::current()->Notify(
   1320       NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
   1321       Source<RenderViewHost>(this),
   1322       Details<const bool>(&is_editable_node));
   1323 }
   1324 
   1325 void RenderViewHostImpl::OnUserGesture() {
   1326   delegate_->OnUserGesture();
   1327 }
   1328 
   1329 void RenderViewHostImpl::OnClosePageACK() {
   1330   decrement_in_flight_event_count();
   1331   ClosePageIgnoringUnloadEvents();
   1332 }
   1333 
   1334 void RenderViewHostImpl::NotifyRendererUnresponsive() {
   1335   delegate_->RendererUnresponsive(
   1336       this, is_waiting_for_beforeunload_ack_, IsWaitingForUnloadACK());
   1337 }
   1338 
   1339 void RenderViewHostImpl::NotifyRendererResponsive() {
   1340   delegate_->RendererResponsive(this);
   1341 }
   1342 
   1343 void RenderViewHostImpl::RequestToLockMouse(bool user_gesture,
   1344                                             bool last_unlocked_by_target) {
   1345   delegate_->RequestToLockMouse(user_gesture, last_unlocked_by_target);
   1346 }
   1347 
   1348 bool RenderViewHostImpl::IsFullscreen() const {
   1349   return delegate_->IsFullscreenForCurrentTab();
   1350 }
   1351 
   1352 void RenderViewHostImpl::OnFocus() {
   1353   // Note: We allow focus and blur from swapped out RenderViewHosts, even when
   1354   // the active RenderViewHost is in a different BrowsingInstance (e.g., WebUI).
   1355   delegate_->Activate();
   1356 }
   1357 
   1358 void RenderViewHostImpl::OnBlur() {
   1359   delegate_->Deactivate();
   1360 }
   1361 
   1362 gfx::Rect RenderViewHostImpl::GetRootWindowResizerRect() const {
   1363   return delegate_->GetRootWindowResizerRect();
   1364 }
   1365 
   1366 void RenderViewHostImpl::ForwardMouseEvent(
   1367     const blink::WebMouseEvent& mouse_event) {
   1368 
   1369   // We make a copy of the mouse event because
   1370   // RenderWidgetHost::ForwardMouseEvent will delete |mouse_event|.
   1371   blink::WebMouseEvent event_copy(mouse_event);
   1372   RenderWidgetHostImpl::ForwardMouseEvent(event_copy);
   1373 
   1374   switch (event_copy.type) {
   1375     case WebInputEvent::MouseMove:
   1376       delegate_->HandleMouseMove();
   1377       break;
   1378     case WebInputEvent::MouseLeave:
   1379       delegate_->HandleMouseLeave();
   1380       break;
   1381     case WebInputEvent::MouseDown:
   1382       delegate_->HandleMouseDown();
   1383       break;
   1384     case WebInputEvent::MouseWheel:
   1385       if (ignore_input_events())
   1386         delegate_->OnIgnoredUIEvent();
   1387       break;
   1388     case WebInputEvent::MouseUp:
   1389       delegate_->HandleMouseUp();
   1390     default:
   1391       // For now, we don't care about the rest.
   1392       break;
   1393   }
   1394 }
   1395 
   1396 void RenderViewHostImpl::OnPointerEventActivate() {
   1397   delegate_->HandlePointerActivate();
   1398 }
   1399 
   1400 void RenderViewHostImpl::ForwardKeyboardEvent(
   1401     const NativeWebKeyboardEvent& key_event) {
   1402   if (ignore_input_events()) {
   1403     if (key_event.type == WebInputEvent::RawKeyDown)
   1404       delegate_->OnIgnoredUIEvent();
   1405     return;
   1406   }
   1407   RenderWidgetHostImpl::ForwardKeyboardEvent(key_event);
   1408 }
   1409 
   1410 #if defined(OS_ANDROID)
   1411 void RenderViewHostImpl::DidSelectPopupMenuItems(
   1412     const std::vector<int>& selected_indices) {
   1413   Send(new ViewMsg_SelectPopupMenuItems(GetRoutingID(), false,
   1414                                         selected_indices));
   1415 }
   1416 
   1417 void RenderViewHostImpl::DidCancelPopupMenu() {
   1418   Send(new ViewMsg_SelectPopupMenuItems(GetRoutingID(), true,
   1419                                         std::vector<int>()));
   1420 }
   1421 #endif
   1422 
   1423 #if defined(OS_MACOSX)
   1424 void RenderViewHostImpl::DidSelectPopupMenuItem(int selected_index) {
   1425   Send(new ViewMsg_SelectPopupMenuItem(GetRoutingID(), selected_index));
   1426 }
   1427 
   1428 void RenderViewHostImpl::DidCancelPopupMenu() {
   1429   Send(new ViewMsg_SelectPopupMenuItem(GetRoutingID(), -1));
   1430 }
   1431 #endif
   1432 
   1433 bool RenderViewHostImpl::IsWaitingForUnloadACK() const {
   1434   return rvh_state_ == STATE_WAITING_FOR_UNLOAD_ACK ||
   1435          rvh_state_ == STATE_WAITING_FOR_CLOSE ||
   1436          rvh_state_ == STATE_PENDING_SHUTDOWN ||
   1437          rvh_state_ == STATE_PENDING_SWAP_OUT;
   1438 }
   1439 
   1440 void RenderViewHostImpl::OnTextSurroundingSelectionResponse(
   1441     const base::string16& content,
   1442     size_t start_offset,
   1443     size_t end_offset) {
   1444   if (!view_)
   1445     return;
   1446   view_->OnTextSurroundingSelectionResponse(content, start_offset, end_offset);
   1447 }
   1448 
   1449 void RenderViewHostImpl::ExitFullscreen() {
   1450   RejectMouseLockOrUnlockIfNecessary();
   1451   // Notify delegate_ and renderer of fullscreen state change.
   1452   OnToggleFullscreen(false);
   1453 }
   1454 
   1455 WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
   1456   return delegate_->GetWebkitPrefs();
   1457 }
   1458 
   1459 void RenderViewHostImpl::DisownOpener() {
   1460   // This should only be called when swapped out.
   1461   DCHECK(IsSwappedOut());
   1462 
   1463   Send(new ViewMsg_DisownOpener(GetRoutingID()));
   1464 }
   1465 
   1466 void RenderViewHostImpl::SetAccessibilityCallbackForTesting(
   1467     const base::Callback<void(ui::AXEvent, int)>& callback) {
   1468   accessibility_testing_callback_ = callback;
   1469 }
   1470 
   1471 void RenderViewHostImpl::UpdateWebkitPreferences(const WebPreferences& prefs) {
   1472   Send(new ViewMsg_UpdateWebPreferences(GetRoutingID(), prefs));
   1473 }
   1474 
   1475 void RenderViewHostImpl::GetAudioOutputControllers(
   1476     const GetAudioOutputControllersCallback& callback) const {
   1477   AudioRendererHost* audio_host =
   1478       static_cast<RenderProcessHostImpl*>(GetProcess())->audio_renderer_host();
   1479   audio_host->GetOutputControllers(GetRoutingID(), callback);
   1480 }
   1481 
   1482 void RenderViewHostImpl::ClearFocusedElement() {
   1483   is_focused_element_editable_ = false;
   1484   Send(new ViewMsg_ClearFocusedElement(GetRoutingID()));
   1485 }
   1486 
   1487 bool RenderViewHostImpl::IsFocusedElementEditable() {
   1488   return is_focused_element_editable_;
   1489 }
   1490 
   1491 void RenderViewHostImpl::Zoom(PageZoom zoom) {
   1492   Send(new ViewMsg_Zoom(GetRoutingID(), zoom));
   1493 }
   1494 
   1495 void RenderViewHostImpl::DisableScrollbarsForThreshold(const gfx::Size& size) {
   1496   Send(new ViewMsg_DisableScrollbarsForSmallWindows(GetRoutingID(), size));
   1497 }
   1498 
   1499 void RenderViewHostImpl::EnablePreferredSizeMode() {
   1500   Send(new ViewMsg_EnablePreferredSizeChangedMode(GetRoutingID()));
   1501 }
   1502 
   1503 void RenderViewHostImpl::EnableAutoResize(const gfx::Size& min_size,
   1504                                           const gfx::Size& max_size) {
   1505   SetShouldAutoResize(true);
   1506   Send(new ViewMsg_EnableAutoResize(GetRoutingID(), min_size, max_size));
   1507 }
   1508 
   1509 void RenderViewHostImpl::DisableAutoResize(const gfx::Size& new_size) {
   1510   SetShouldAutoResize(false);
   1511   Send(new ViewMsg_DisableAutoResize(GetRoutingID(), new_size));
   1512 }
   1513 
   1514 void RenderViewHostImpl::CopyImageAt(int x, int y) {
   1515   Send(new ViewMsg_CopyImageAt(GetRoutingID(), x, y));
   1516 }
   1517 
   1518 void RenderViewHostImpl::SaveImageAt(int x, int y) {
   1519   Send(new ViewMsg_SaveImageAt(GetRoutingID(), x, y));
   1520 }
   1521 
   1522 void RenderViewHostImpl::ExecuteMediaPlayerActionAtLocation(
   1523   const gfx::Point& location, const blink::WebMediaPlayerAction& action) {
   1524   Send(new ViewMsg_MediaPlayerActionAt(GetRoutingID(), location, action));
   1525 }
   1526 
   1527 void RenderViewHostImpl::ExecutePluginActionAtLocation(
   1528   const gfx::Point& location, const blink::WebPluginAction& action) {
   1529   Send(new ViewMsg_PluginActionAt(GetRoutingID(), location, action));
   1530 }
   1531 
   1532 void RenderViewHostImpl::NotifyMoveOrResizeStarted() {
   1533   Send(new ViewMsg_MoveOrResizeStarted(GetRoutingID()));
   1534 }
   1535 
   1536 void RenderViewHostImpl::OnAccessibilityEvents(
   1537     const std::vector<AccessibilityHostMsg_EventParams>& params) {
   1538   if ((accessibility_mode() != AccessibilityModeOff) && view_ &&
   1539       IsRVHStateActive(rvh_state_)) {
   1540     if (accessibility_mode() & AccessibilityModeFlagPlatform) {
   1541       view_->CreateBrowserAccessibilityManagerIfNeeded();
   1542       BrowserAccessibilityManager* manager =
   1543           view_->GetBrowserAccessibilityManager();
   1544       if (manager)
   1545         manager->OnAccessibilityEvents(params);
   1546     }
   1547 
   1548     std::vector<AXEventNotificationDetails> details;
   1549     for (unsigned int i = 0; i < params.size(); ++i) {
   1550       const AccessibilityHostMsg_EventParams& param = params[i];
   1551       AXEventNotificationDetails detail(param.update.nodes,
   1552                                         param.event_type,
   1553                                         param.id,
   1554                                         GetProcess()->GetID(),
   1555                                         GetRoutingID());
   1556       details.push_back(detail);
   1557     }
   1558 
   1559     delegate_->AccessibilityEventReceived(details);
   1560   }
   1561 
   1562   // Always send an ACK or the renderer can be in a bad state.
   1563   Send(new AccessibilityMsg_Events_ACK(GetRoutingID()));
   1564 
   1565   // The rest of this code is just for testing; bail out if we're not
   1566   // in that mode.
   1567   if (accessibility_testing_callback_.is_null())
   1568     return;
   1569 
   1570   for (unsigned i = 0; i < params.size(); i++) {
   1571     const AccessibilityHostMsg_EventParams& param = params[i];
   1572     if (static_cast<int>(param.event_type) < 0)
   1573       continue;
   1574     if (!ax_tree_)
   1575       ax_tree_.reset(new ui::AXTree(param.update));
   1576     else
   1577       CHECK(ax_tree_->Unserialize(param.update)) << ax_tree_->error();
   1578     accessibility_testing_callback_.Run(param.event_type, param.id);
   1579   }
   1580 }
   1581 
   1582 void RenderViewHostImpl::OnAccessibilityLocationChanges(
   1583     const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) {
   1584   if (view_ && IsRVHStateActive(rvh_state_)) {
   1585     if (accessibility_mode() & AccessibilityModeFlagPlatform) {
   1586       view_->CreateBrowserAccessibilityManagerIfNeeded();
   1587       BrowserAccessibilityManager* manager =
   1588           view_->GetBrowserAccessibilityManager();
   1589       if (manager)
   1590         manager->OnLocationChanges(params);
   1591     }
   1592     // TODO(aboxhall): send location change events to web contents observers too
   1593   }
   1594 }
   1595 
   1596 void RenderViewHostImpl::OnDidZoomURL(double zoom_level,
   1597                                       const GURL& url) {
   1598   HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
   1599       HostZoomMap::GetForBrowserContext(GetProcess()->GetBrowserContext()));
   1600 
   1601   host_zoom_map->SetZoomLevelForView(GetProcess()->GetID(),
   1602                                      GetRoutingID(),
   1603                                      zoom_level,
   1604                                      net::GetHostOrSpecFromURL(url));
   1605 }
   1606 
   1607 void RenderViewHostImpl::OnRunFileChooser(const FileChooserParams& params) {
   1608   delegate_->RunFileChooser(this, params);
   1609 }
   1610 
   1611 void RenderViewHostImpl::OnFocusedNodeTouched(bool editable) {
   1612 #if defined(OS_WIN)
   1613   if (editable) {
   1614     virtual_keyboard_requested_ = base::win::DisplayVirtualKeyboard();
   1615   } else {
   1616     virtual_keyboard_requested_ = false;
   1617     base::win::DismissVirtualKeyboard();
   1618   }
   1619 #endif
   1620 }
   1621 
   1622 #if defined(OS_MACOSX) || defined(OS_ANDROID)
   1623 void RenderViewHostImpl::OnShowPopup(
   1624     const ViewHostMsg_ShowPopup_Params& params) {
   1625   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
   1626   if (view) {
   1627     view->ShowPopupMenu(params.bounds,
   1628                         params.item_height,
   1629                         params.item_font_size,
   1630                         params.selected_item,
   1631                         params.popup_items,
   1632                         params.right_aligned,
   1633                         params.allow_multiple_selection);
   1634   }
   1635 }
   1636 
   1637 void RenderViewHostImpl::OnHidePopup() {
   1638   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
   1639   if (view)
   1640     view->HidePopupMenu();
   1641 }
   1642 #endif
   1643 
   1644 void RenderViewHostImpl::SetState(RenderViewHostImplState rvh_state) {
   1645   // We update the number of RenderViews in a SiteInstance when the
   1646   // swapped out status of this RenderView gets flipped to/from live.
   1647   if (!IsRVHStateActive(rvh_state_) && IsRVHStateActive(rvh_state))
   1648     instance_->increment_active_view_count();
   1649   else if (IsRVHStateActive(rvh_state_) && !IsRVHStateActive(rvh_state))
   1650     instance_->decrement_active_view_count();
   1651 
   1652   // Whenever we change the RVH state to and from live or swapped out state, we
   1653   // should not be waiting for beforeunload or unload acks.  We clear them here
   1654   // to be safe, since they can cause navigations to be ignored in OnNavigate.
   1655   if (rvh_state == STATE_DEFAULT ||
   1656       rvh_state == STATE_SWAPPED_OUT ||
   1657       rvh_state_ == STATE_DEFAULT ||
   1658       rvh_state_ == STATE_SWAPPED_OUT) {
   1659     is_waiting_for_beforeunload_ack_ = false;
   1660   }
   1661   rvh_state_ = rvh_state;
   1662 
   1663 }
   1664 
   1665 bool RenderViewHostImpl::CanAccessFilesOfPageState(
   1666     const PageState& state) const {
   1667   ChildProcessSecurityPolicyImpl* policy =
   1668       ChildProcessSecurityPolicyImpl::GetInstance();
   1669 
   1670   const std::vector<base::FilePath>& file_paths = state.GetReferencedFiles();
   1671   for (std::vector<base::FilePath>::const_iterator file = file_paths.begin();
   1672        file != file_paths.end(); ++file) {
   1673     if (!policy->CanReadFile(GetProcess()->GetID(), *file))
   1674       return false;
   1675   }
   1676   return true;
   1677 }
   1678 
   1679 void RenderViewHostImpl::AttachToFrameTree() {
   1680   FrameTree* frame_tree = delegate_->GetFrameTree();
   1681 
   1682   frame_tree->ResetForMainFrameSwap();
   1683 }
   1684 
   1685 void RenderViewHostImpl::SelectWordAroundCaret() {
   1686   Send(new ViewMsg_SelectWordAroundCaret(GetRoutingID()));
   1687 }
   1688 
   1689 }  // namespace content
   1690