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