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