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