• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DismissVirtualKeyboardTask()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
IsRVHStateActive(RenderViewHostImplState rvh_state)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
FromID(int render_process_id,int render_view_id)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
From(RenderWidgetHost * rwh)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
FromID(int render_process_id,int render_view_id)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 
RenderViewHostImpl(SiteInstance * instance,RenderViewHostDelegate * delegate,RenderWidgetHostDelegate * widget_delegate,int routing_id,int main_frame_routing_id,bool swapped_out,bool hidden)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 
~RenderViewHostImpl()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 
GetDelegate() const257 RenderViewHostDelegate* RenderViewHostImpl::GetDelegate() const {
258   return delegate_;
259 }
260 
GetSiteInstance() const261 SiteInstance* RenderViewHostImpl::GetSiteInstance() const {
262   return instance_.get();
263 }
264 
CreateRenderView(const base::string16 & frame_name,int opener_route_id,int proxy_route_id,int32 max_page_id,bool window_was_created_with_opener)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 
IsRenderViewLive() const328 bool RenderViewHostImpl::IsRenderViewLive() const {
329   return GetProcess()->HasConnection() && renderer_initialized_;
330 }
331 
SyncRendererPrefs()332 void RenderViewHostImpl::SyncRendererPrefs() {
333   Send(new ViewMsg_SetRendererPrefs(GetRoutingID(),
334                                     delegate_->GetRendererPrefs(
335                                         GetProcess()->GetBrowserContext())));
336 }
337 
GetWebkitPrefs(const GURL & url)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 
Navigate(const FrameMsg_Navigate_Params & params)491 void RenderViewHostImpl::Navigate(const FrameMsg_Navigate_Params& params) {
492   TRACE_EVENT0("renderer_host", "RenderViewHostImpl::Navigate");
493   delegate_->GetFrameTree()->GetMainFrame()->Navigate(params);
494 }
495 
NavigateToURL(const GURL & url)496 void RenderViewHostImpl::NavigateToURL(const GURL& url) {
497   delegate_->GetFrameTree()->GetMainFrame()->NavigateToURL(url);
498 }
499 
SetNavigationsSuspended(bool suspend,const base::TimeTicks & proceed_time)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 
CancelSuspendedNavigations()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 
SuppressDialogsUntilSwapOut()528 void RenderViewHostImpl::SuppressDialogsUntilSwapOut() {
529   Send(new ViewMsg_SuppressDialogsUntilSwapOut(GetRoutingID()));
530 }
531 
OnSwappedOut(bool timed_out)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 
WasSwappedOut(const base::Closure & pending_delete_on_swap_out)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 
SetPendingShutdown(const base::Closure & on_swap_out)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 
ClosePage()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 
ClosePageIgnoringUnloadEvents()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 
HasPendingCrossSiteRequest()648 bool RenderViewHostImpl::HasPendingCrossSiteRequest() {
649   return CrossSiteRequestManager::GetInstance()->HasPendingCrossSiteRequest(
650       GetProcess()->GetID(), GetRoutingID());
651 }
652 
SetHasPendingCrossSiteRequest(bool has_pending_request)653 void RenderViewHostImpl::SetHasPendingCrossSiteRequest(
654     bool has_pending_request) {
655   CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest(
656       GetProcess()->GetID(), GetRoutingID(), has_pending_request);
657 }
658 
SetWebUIHandle(mojo::ScopedMessagePipeHandle handle)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)
ActivateNearestFindResult(int request_id,float x,float y)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 
RequestFindMatchRects(int current_version)688 void RenderViewHostImpl::RequestFindMatchRects(int current_version) {
689   Send(new ViewMsg_FindMatchRects(GetRoutingID(), current_version));
690 }
691 #endif
692 
DragTargetDragEnter(const DropData & drop_data,const gfx::Point & client_pt,const gfx::Point & screen_pt,WebDragOperationsMask operations_allowed,int key_modifiers)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 
DragTargetDragOver(const gfx::Point & client_pt,const gfx::Point & screen_pt,WebDragOperationsMask operations_allowed,int key_modifiers)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 
DragTargetDragLeave()794 void RenderViewHostImpl::DragTargetDragLeave() {
795   Send(new DragMsg_TargetDragLeave(GetRoutingID()));
796 }
797 
DragTargetDrop(const gfx::Point & client_pt,const gfx::Point & screen_pt,int key_modifiers)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 
DragSourceEndedAt(int client_x,int client_y,int screen_x,int screen_y,WebDragOperation operation)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 
DragSourceSystemDragEnded()815 void RenderViewHostImpl::DragSourceSystemDragEnded() {
816   Send(new DragMsg_SourceSystemDragEnded(GetRoutingID()));
817 }
818 
GetMainFrame()819 RenderFrameHost* RenderViewHostImpl::GetMainFrame() {
820   return RenderFrameHost::FromID(GetProcess()->GetID(), main_frame_routing_id_);
821 }
822 
AllowBindings(int bindings_flags)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 
GetEnabledBindings() const856 int RenderViewHostImpl::GetEnabledBindings() const {
857   return enabled_bindings_;
858 }
859 
SetWebUIProperty(const std::string & name,const std::string & value)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 
GotFocus()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 
LostCapture()884 void RenderViewHostImpl::LostCapture() {
885   RenderWidgetHostImpl::LostCapture();
886   delegate_->LostCapture();
887 }
888 
LostMouseLock()889 void RenderViewHostImpl::LostMouseLock() {
890   RenderWidgetHostImpl::LostMouseLock();
891   delegate_->LostMouseLock();
892 }
893 
SetInitialFocus(bool reverse)894 void RenderViewHostImpl::SetInitialFocus(bool reverse) {
895   Send(new ViewMsg_SetInitialFocus(GetRoutingID(), reverse));
896 }
897 
FilesSelectedInChooser(const std::vector<ui::SelectedFileInfo> & files,FileChooserParams::Mode permissions)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 
DirectoryEnumerationFinished(int request_id,const std::vector<base::FilePath> & files)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 
LoadStateChanged(const GURL & url,const net::LoadStateWithParam & load_state,uint64 upload_position,uint64 upload_size)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 
SuddenTerminationAllowed() const937 bool RenderViewHostImpl::SuddenTerminationAllowed() const {
938   return sudden_termination_allowed_ ||
939       GetProcess()->SuddenTerminationAllowed();
940 }
941 
942 ///////////////////////////////////////////////////////////////////////////////
943 // RenderViewHostImpl, IPC message handlers:
944 
OnMessageReceived(const IPC::Message & msg)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 
Init()1018 void RenderViewHostImpl::Init() {
1019   RenderWidgetHostImpl::Init();
1020 }
1021 
Shutdown()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 
IsRenderView() const1050 bool RenderViewHostImpl::IsRenderView() const {
1051   return true;
1052 }
1053 
CreateNewWindow(int route_id,int main_frame_route_id,const ViewHostMsg_CreateWindow_Params & params,SessionStorageNamespace * session_storage_namespace)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 
CreateNewWidget(int route_id,blink::WebPopupType popup_type)1069 void RenderViewHostImpl::CreateNewWidget(int route_id,
1070                                      blink::WebPopupType popup_type) {
1071   delegate_->CreateNewWidget(GetProcess()->GetID(), route_id, popup_type);
1072 }
1073 
CreateNewFullscreenWidget(int route_id)1074 void RenderViewHostImpl::CreateNewFullscreenWidget(int route_id) {
1075   delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), route_id);
1076 }
1077 
OnShowView(int route_id,WindowOpenDisposition disposition,const gfx::Rect & initial_pos,bool user_gesture)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 
OnShowWidget(int route_id,const gfx::Rect & initial_pos)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 
OnShowFullscreenWidget(int route_id)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 
OnRunModal(int opener_id,IPC::Message * reply_msg)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 
OnRenderViewReady()1122 void RenderViewHostImpl::OnRenderViewReady() {
1123   render_view_termination_status_ = base::TERMINATION_STATUS_STILL_RUNNING;
1124   SendScreenRects();
1125   WasResized();
1126   delegate_->RenderViewReady(this);
1127 }
1128 
OnRenderProcessGone(int status,int exit_code)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 
OnUpdateState(int32 page_id,const PageState & state)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 
OnUpdateTargetURL(int32 page_id,const GURL & url)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 
OnUpdateInspectorSetting(const std::string & key,const std::string & value)1168 void RenderViewHostImpl::OnUpdateInspectorSetting(
1169     const std::string& key, const std::string& value) {
1170   GetContentClient()->browser()->UpdateInspectorSetting(
1171       this, key, value);
1172 }
1173 
OnClose()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 
OnRequestMove(const gfx::Rect & pos)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 
OnDocumentAvailableInMainFrame(bool uses_temporary_zoom_level)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 
OnToggleFullscreen(bool enter_fullscreen)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 
OnDidContentsPreferredSizeChange(const gfx::Size & new_size)1208 void RenderViewHostImpl::OnDidContentsPreferredSizeChange(
1209     const gfx::Size& new_size) {
1210   delegate_->UpdatePreferredSize(new_size);
1211 }
1212 
OnRenderAutoResized(const gfx::Size & new_size)1213 void RenderViewHostImpl::OnRenderAutoResized(const gfx::Size& new_size) {
1214   delegate_->ResizeDueToAutoResize(new_size);
1215 }
1216 
OnDidChangeScrollOffset()1217 void RenderViewHostImpl::OnDidChangeScrollOffset() {
1218   if (view_)
1219     view_->ScrollOffsetChanged();
1220 }
1221 
OnRouteCloseEvent()1222 void RenderViewHostImpl::OnRouteCloseEvent() {
1223   // Have the delegate route this to the active RenderViewHost.
1224   delegate_->RouteCloseEvent(this);
1225 }
1226 
OnRouteMessageEvent(const ViewMsg_PostMessage_Params & params)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 
OnStartDragging(const DropData & drop_data,WebDragOperationsMask drag_operations_mask,const SkBitmap & bitmap,const gfx::Vector2d & bitmap_offset_in_dip,const DragEventSourceInfo & event_info)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 
OnUpdateDragCursor(WebDragOperation current_op)1287 void RenderViewHostImpl::OnUpdateDragCursor(WebDragOperation current_op) {
1288   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1289   if (view)
1290     view->UpdateDragCursor(current_op);
1291 }
1292 
OnTargetDropACK()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 
OnTakeFocus(bool reverse)1300 void RenderViewHostImpl::OnTakeFocus(bool reverse) {
1301   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1302   if (view)
1303     view->TakeFocus(reverse);
1304 }
1305 
OnFocusedNodeChanged(bool is_editable_node)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 
OnUserGesture()1325 void RenderViewHostImpl::OnUserGesture() {
1326   delegate_->OnUserGesture();
1327 }
1328 
OnClosePageACK()1329 void RenderViewHostImpl::OnClosePageACK() {
1330   decrement_in_flight_event_count();
1331   ClosePageIgnoringUnloadEvents();
1332 }
1333 
NotifyRendererUnresponsive()1334 void RenderViewHostImpl::NotifyRendererUnresponsive() {
1335   delegate_->RendererUnresponsive(
1336       this, is_waiting_for_beforeunload_ack_, IsWaitingForUnloadACK());
1337 }
1338 
NotifyRendererResponsive()1339 void RenderViewHostImpl::NotifyRendererResponsive() {
1340   delegate_->RendererResponsive(this);
1341 }
1342 
RequestToLockMouse(bool user_gesture,bool last_unlocked_by_target)1343 void RenderViewHostImpl::RequestToLockMouse(bool user_gesture,
1344                                             bool last_unlocked_by_target) {
1345   delegate_->RequestToLockMouse(user_gesture, last_unlocked_by_target);
1346 }
1347 
IsFullscreen() const1348 bool RenderViewHostImpl::IsFullscreen() const {
1349   return delegate_->IsFullscreenForCurrentTab();
1350 }
1351 
OnFocus()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 
OnBlur()1358 void RenderViewHostImpl::OnBlur() {
1359   delegate_->Deactivate();
1360 }
1361 
GetRootWindowResizerRect() const1362 gfx::Rect RenderViewHostImpl::GetRootWindowResizerRect() const {
1363   return delegate_->GetRootWindowResizerRect();
1364 }
1365 
ForwardMouseEvent(const blink::WebMouseEvent & mouse_event)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 
OnPointerEventActivate()1396 void RenderViewHostImpl::OnPointerEventActivate() {
1397   delegate_->HandlePointerActivate();
1398 }
1399 
ForwardKeyboardEvent(const NativeWebKeyboardEvent & key_event)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)
DidSelectPopupMenuItems(const std::vector<int> & selected_indices)1411 void RenderViewHostImpl::DidSelectPopupMenuItems(
1412     const std::vector<int>& selected_indices) {
1413   Send(new ViewMsg_SelectPopupMenuItems(GetRoutingID(), false,
1414                                         selected_indices));
1415 }
1416 
DidCancelPopupMenu()1417 void RenderViewHostImpl::DidCancelPopupMenu() {
1418   Send(new ViewMsg_SelectPopupMenuItems(GetRoutingID(), true,
1419                                         std::vector<int>()));
1420 }
1421 #endif
1422 
1423 #if defined(OS_MACOSX)
DidSelectPopupMenuItem(int selected_index)1424 void RenderViewHostImpl::DidSelectPopupMenuItem(int selected_index) {
1425   Send(new ViewMsg_SelectPopupMenuItem(GetRoutingID(), selected_index));
1426 }
1427 
DidCancelPopupMenu()1428 void RenderViewHostImpl::DidCancelPopupMenu() {
1429   Send(new ViewMsg_SelectPopupMenuItem(GetRoutingID(), -1));
1430 }
1431 #endif
1432 
IsWaitingForUnloadACK() const1433 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 
OnTextSurroundingSelectionResponse(const base::string16 & content,size_t start_offset,size_t end_offset)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 
ExitFullscreen()1449 void RenderViewHostImpl::ExitFullscreen() {
1450   RejectMouseLockOrUnlockIfNecessary();
1451   // Notify delegate_ and renderer of fullscreen state change.
1452   OnToggleFullscreen(false);
1453 }
1454 
GetWebkitPreferences()1455 WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
1456   return delegate_->GetWebkitPrefs();
1457 }
1458 
DisownOpener()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 
SetAccessibilityCallbackForTesting(const base::Callback<void (ui::AXEvent,int)> & callback)1466 void RenderViewHostImpl::SetAccessibilityCallbackForTesting(
1467     const base::Callback<void(ui::AXEvent, int)>& callback) {
1468   accessibility_testing_callback_ = callback;
1469 }
1470 
UpdateWebkitPreferences(const WebPreferences & prefs)1471 void RenderViewHostImpl::UpdateWebkitPreferences(const WebPreferences& prefs) {
1472   Send(new ViewMsg_UpdateWebPreferences(GetRoutingID(), prefs));
1473 }
1474 
GetAudioOutputControllers(const GetAudioOutputControllersCallback & callback) const1475 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 
ClearFocusedElement()1482 void RenderViewHostImpl::ClearFocusedElement() {
1483   is_focused_element_editable_ = false;
1484   Send(new ViewMsg_ClearFocusedElement(GetRoutingID()));
1485 }
1486 
IsFocusedElementEditable()1487 bool RenderViewHostImpl::IsFocusedElementEditable() {
1488   return is_focused_element_editable_;
1489 }
1490 
Zoom(PageZoom zoom)1491 void RenderViewHostImpl::Zoom(PageZoom zoom) {
1492   Send(new ViewMsg_Zoom(GetRoutingID(), zoom));
1493 }
1494 
DisableScrollbarsForThreshold(const gfx::Size & size)1495 void RenderViewHostImpl::DisableScrollbarsForThreshold(const gfx::Size& size) {
1496   Send(new ViewMsg_DisableScrollbarsForSmallWindows(GetRoutingID(), size));
1497 }
1498 
EnablePreferredSizeMode()1499 void RenderViewHostImpl::EnablePreferredSizeMode() {
1500   Send(new ViewMsg_EnablePreferredSizeChangedMode(GetRoutingID()));
1501 }
1502 
EnableAutoResize(const gfx::Size & min_size,const gfx::Size & max_size)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 
DisableAutoResize(const gfx::Size & new_size)1509 void RenderViewHostImpl::DisableAutoResize(const gfx::Size& new_size) {
1510   SetShouldAutoResize(false);
1511   Send(new ViewMsg_DisableAutoResize(GetRoutingID(), new_size));
1512 }
1513 
CopyImageAt(int x,int y)1514 void RenderViewHostImpl::CopyImageAt(int x, int y) {
1515   Send(new ViewMsg_CopyImageAt(GetRoutingID(), x, y));
1516 }
1517 
SaveImageAt(int x,int y)1518 void RenderViewHostImpl::SaveImageAt(int x, int y) {
1519   Send(new ViewMsg_SaveImageAt(GetRoutingID(), x, y));
1520 }
1521 
ExecuteMediaPlayerActionAtLocation(const gfx::Point & location,const blink::WebMediaPlayerAction & action)1522 void RenderViewHostImpl::ExecuteMediaPlayerActionAtLocation(
1523   const gfx::Point& location, const blink::WebMediaPlayerAction& action) {
1524   Send(new ViewMsg_MediaPlayerActionAt(GetRoutingID(), location, action));
1525 }
1526 
ExecutePluginActionAtLocation(const gfx::Point & location,const blink::WebPluginAction & action)1527 void RenderViewHostImpl::ExecutePluginActionAtLocation(
1528   const gfx::Point& location, const blink::WebPluginAction& action) {
1529   Send(new ViewMsg_PluginActionAt(GetRoutingID(), location, action));
1530 }
1531 
NotifyMoveOrResizeStarted()1532 void RenderViewHostImpl::NotifyMoveOrResizeStarted() {
1533   Send(new ViewMsg_MoveOrResizeStarted(GetRoutingID()));
1534 }
1535 
OnAccessibilityEvents(const std::vector<AccessibilityHostMsg_EventParams> & params)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 
OnAccessibilityLocationChanges(const std::vector<AccessibilityHostMsg_LocationChangeParams> & params)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 
OnDidZoomURL(double zoom_level,const GURL & url)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 
OnRunFileChooser(const FileChooserParams & params)1607 void RenderViewHostImpl::OnRunFileChooser(const FileChooserParams& params) {
1608   delegate_->RunFileChooser(this, params);
1609 }
1610 
OnFocusedNodeTouched(bool editable)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)
OnShowPopup(const ViewHostMsg_ShowPopup_Params & params)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 
OnHidePopup()1637 void RenderViewHostImpl::OnHidePopup() {
1638   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1639   if (view)
1640     view->HidePopupMenu();
1641 }
1642 #endif
1643 
SetState(RenderViewHostImplState rvh_state)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 
CanAccessFilesOfPageState(const PageState & state) const1665 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 
AttachToFrameTree()1679 void RenderViewHostImpl::AttachToFrameTree() {
1680   FrameTree* frame_tree = delegate_->GetFrameTree();
1681 
1682   frame_tree->ResetForMainFrameSwap();
1683 }
1684 
SelectWordAroundCaret()1685 void RenderViewHostImpl::SelectWordAroundCaret() {
1686   Send(new ViewMsg_SelectWordAroundCaret(GetRoutingID()));
1687 }
1688 
1689 }  // namespace content
1690