Update To 11.40.268.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/field_trial.h"
19 #include "base/metrics/histogram.h"
20 #include "base/stl_util.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/sys_info.h"
24 #include "base/time/time.h"
25 #include "base/values.h"
26 #include "cc/base/switches.h"
27 #include "content/browser/child_process_security_policy_impl.h"
28 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
29 #include "content/browser/frame_host/frame_tree.h"
30 #include "content/browser/gpu/compositor_util.h"
31 #include "content/browser/gpu/gpu_data_manager_impl.h"
32 #include "content/browser/gpu/gpu_process_host.h"
33 #include "content/browser/gpu/gpu_surface_tracker.h"
34 #include "content/browser/host_zoom_map_impl.h"
35 #include "content/browser/loader/resource_dispatcher_host_impl.h"
36 #include "content/browser/renderer_host/dip_util.h"
37 #include "content/browser/renderer_host/media/audio_renderer_host.h"
38 #include "content/browser/renderer_host/render_process_host_impl.h"
39 #include "content/browser/renderer_host/render_view_host_delegate.h"
40 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
41 #include "content/browser/renderer_host/render_widget_host_view_base.h"
42 #include "content/common/browser_plugin/browser_plugin_messages.h"
43 #include "content/common/content_switches_internal.h"
44 #include "content/common/drag_messages.h"
45 #include "content/common/frame_messages.h"
46 #include "content/common/input_messages.h"
47 #include "content/common/inter_process_time_ticks_converter.h"
48 #include "content/common/speech_recognition_messages.h"
49 #include "content/common/swapped_out_messages.h"
50 #include "content/common/view_messages.h"
51 #include "content/public/browser/ax_event_notification_details.h"
52 #include "content/public/browser/browser_accessibility_state.h"
53 #include "content/public/browser/browser_context.h"
54 #include "content/public/browser/browser_message_filter.h"
55 #include "content/public/browser/content_browser_client.h"
56 #include "content/public/browser/native_web_keyboard_event.h"
57 #include "content/public/browser/notification_details.h"
58 #include "content/public/browser/notification_service.h"
59 #include "content/public/browser/notification_types.h"
60 #include "content/public/browser/render_frame_host.h"
61 #include "content/public/browser/render_widget_host_iterator.h"
62 #include "content/public/browser/storage_partition.h"
63 #include "content/public/browser/user_metrics.h"
64 #include "content/public/common/bindings_policy.h"
65 #include "content/public/common/content_constants.h"
66 #include "content/public/common/content_switches.h"
67 #include "content/public/common/context_menu_params.h"
68 #include "content/public/common/drop_data.h"
69 #include "content/public/common/file_chooser_file_info.h"
70 #include "content/public/common/file_chooser_params.h"
71 #include "content/public/common/result_codes.h"
72 #include "content/public/common/url_constants.h"
73 #include "content/public/common/url_utils.h"
74 #include "net/base/filename_util.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 "storage/browser/fileapi/isolated_context.h"
79 #include "third_party/skia/include/core/SkBitmap.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 "url/url_constants.h"
87
88 #if defined(OS_WIN)
89 #include "base/win/win_util.h"
90 #endif
91
92 #if defined(ENABLE_BROWSER_CDMS)
93 #include "content/browser/media/media_web_contents_observer.h"
94 #endif
95
96 #if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
97 #include "xwalk/tizen/browser/media/media_webcontents_observer.h"
98 #endif
99
100 using base::TimeDelta;
101 using blink::WebConsoleMessage;
102 using blink::WebDragOperation;
103 using blink::WebDragOperationNone;
104 using blink::WebDragOperationsMask;
105 using blink::WebInputEvent;
106 using blink::WebMediaPlayerAction;
107 using blink::WebPluginAction;
108
109 namespace content {
110 namespace {
111
112 #if defined(OS_WIN)
113
114 const int kVirtualKeyboardDisplayWaitTimeoutMs = 100;
115 const int kMaxVirtualKeyboardDisplayRetries = 5;
116
117 void DismissVirtualKeyboardTask() {
118   static int virtual_keyboard_display_retries = 0;
119   // If the virtual keyboard is not yet visible, then we execute the task again
120   // waiting for it to show up.
121   if (!base::win::DismissVirtualKeyboard()) {
122     if (virtual_keyboard_display_retries < kMaxVirtualKeyboardDisplayRetries) {
123       BrowserThread::PostDelayedTask(
124           BrowserThread::UI, FROM_HERE,
125           base::Bind(base::IgnoreResult(&DismissVirtualKeyboardTask)),
126           TimeDelta::FromMilliseconds(kVirtualKeyboardDisplayWaitTimeoutMs));
127       ++virtual_keyboard_display_retries;
128     } else {
129       virtual_keyboard_display_retries = 0;
130     }
131   }
132 }
133 #endif
134
135 }  // namespace
136
137 // static
138 const int64 RenderViewHostImpl::kUnloadTimeoutMS = 1000;
139
140 ///////////////////////////////////////////////////////////////////////////////
141 // RenderViewHost, public:
142
143 // static
144 RenderViewHost* RenderViewHost::FromID(int render_process_id,
145                                        int render_view_id) {
146   return RenderViewHostImpl::FromID(render_process_id, render_view_id);
147 }
148
149 // static
150 RenderViewHost* RenderViewHost::From(RenderWidgetHost* rwh) {
151   DCHECK(rwh->IsRenderView());
152   return static_cast<RenderViewHostImpl*>(RenderWidgetHostImpl::From(rwh));
153 }
154
155 ///////////////////////////////////////////////////////////////////////////////
156 // RenderViewHostImpl, public:
157
158 // static
159 RenderViewHostImpl* RenderViewHostImpl::FromID(int render_process_id,
160                                                int render_view_id) {
161   RenderWidgetHost* widget =
162       RenderWidgetHost::FromID(render_process_id, render_view_id);
163   if (!widget || !widget->IsRenderView())
164     return NULL;
165   return static_cast<RenderViewHostImpl*>(RenderWidgetHostImpl::From(widget));
166 }
167
168 RenderViewHostImpl::RenderViewHostImpl(
169     SiteInstance* instance,
170     RenderViewHostDelegate* delegate,
171     RenderWidgetHostDelegate* widget_delegate,
172     int routing_id,
173     int main_frame_routing_id,
174     bool swapped_out,
175     bool hidden,
176     bool has_initialized_audio_host)
177     : RenderWidgetHostImpl(widget_delegate,
178                            instance->GetProcess(),
179                            routing_id,
180                            hidden),
181       frames_ref_count_(0),
182       delegate_(delegate),
183       instance_(static_cast<SiteInstanceImpl*>(instance)),
184       waiting_for_drag_context_response_(false),
185       enabled_bindings_(0),
186       page_id_(-1),
187       is_active_(!swapped_out),
188       is_swapped_out_(swapped_out),
189       main_frame_routing_id_(main_frame_routing_id),
190       run_modal_reply_msg_(NULL),
191       run_modal_opener_id_(MSG_ROUTING_NONE),
192       is_waiting_for_close_ack_(false),
193       sudden_termination_allowed_(false),
194       render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING),
195       virtual_keyboard_requested_(false),
196       is_focused_element_editable_(false),
197       updating_web_preferences_(false),
198       weak_factory_(this) {
199   DCHECK(instance_.get());
200   CHECK(delegate_);  // http://crbug.com/82827
201
202   GetProcess()->EnableSendQueue();
203
204   if (ResourceDispatcherHostImpl::Get()) {
205     bool has_active_audio = false;
206     if (has_initialized_audio_host) {
207       scoped_refptr<AudioRendererHost> arh =
208           static_cast<RenderProcessHostImpl*>(GetProcess())
209               ->audio_renderer_host();
210       if (arh.get())
211         has_active_audio = arh->RenderViewHasActiveAudio(GetRoutingID());
212     }
213     BrowserThread::PostTask(
214         BrowserThread::IO,
215         FROM_HERE,
216         base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostCreated,
217                    base::Unretained(ResourceDispatcherHostImpl::Get()),
218                    GetProcess()->GetID(),
219                    GetRoutingID(),
220                    !is_hidden(),
221                    has_active_audio));
222   }
223 #if defined(ENABLE_BROWSER_CDMS)
224   media_web_contents_observer_.reset(new MediaWebContentsObserver(this));
225 #endif
226
227 #if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
228   media_webcontents_observer_.reset(new tizen::MediaWebContentsObserver(this));
229 #endif
230 }
231
232 RenderViewHostImpl::~RenderViewHostImpl() {
233   if (ResourceDispatcherHostImpl::Get()) {
234     BrowserThread::PostTask(
235         BrowserThread::IO, FROM_HERE,
236         base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostDeleted,
237                    base::Unretained(ResourceDispatcherHostImpl::Get()),
238                    GetProcess()->GetID(), GetRoutingID()));
239   }
240
241   delegate_->RenderViewDeleted(this);
242 }
243
244 RenderViewHostDelegate* RenderViewHostImpl::GetDelegate() const {
245   return delegate_;
246 }
247
248 SiteInstanceImpl* RenderViewHostImpl::GetSiteInstance() const {
249   return instance_.get();
250 }
251
252 bool RenderViewHostImpl::CreateRenderView(
253     const base::string16& frame_name,
254     int opener_route_id,
255     int proxy_route_id,
256     int32 max_page_id,
257     bool window_was_created_with_opener) {
258   TRACE_EVENT0("renderer_host,navigation",
259                "RenderViewHostImpl::CreateRenderView");
260   DCHECK(!IsRenderViewLive()) << "Creating view twice";
261
262   // The process may (if we're sharing a process with another host that already
263   // initialized it) or may not (we have our own process or the old process
264   // crashed) have been initialized. Calling Init multiple times will be
265   // ignored, so this is safe.
266   if (!GetProcess()->Init())
267     return false;
268   DCHECK(GetProcess()->HasConnection());
269   DCHECK(GetProcess()->GetBrowserContext());
270
271   renderer_initialized_ = true;
272
273   GpuSurfaceTracker::Get()->SetSurfaceHandle(
274       surface_id(), GetCompositingSurface());
275
276   // Ensure the RenderView starts with a next_page_id larger than any existing
277   // page ID it might be asked to render.
278   int32 next_page_id = 1;
279   if (max_page_id > -1)
280     next_page_id = max_page_id + 1;
281
282   ViewMsg_New_Params params;
283   params.renderer_preferences =
284       delegate_->GetRendererPrefs(GetProcess()->GetBrowserContext());
285   params.web_preferences = GetWebkitPreferences();
286   params.view_id = GetRoutingID();
287   params.main_frame_routing_id = main_frame_routing_id_;
288   params.surface_id = surface_id();
289   params.session_storage_namespace_id =
290       delegate_->GetSessionStorageNamespace(instance_.get())->id();
291   params.frame_name = frame_name;
292   // Ensure the RenderView sets its opener correctly.
293   params.opener_route_id = opener_route_id;
294   params.swapped_out = !is_active_;
295   params.proxy_routing_id = proxy_route_id;
296   params.hidden = is_hidden();
297   params.never_visible = delegate_->IsNeverVisible();
298   params.window_was_created_with_opener = window_was_created_with_opener;
299   params.next_page_id = next_page_id;
300   GetWebScreenInfo(&params.screen_info);
301
302   Send(new ViewMsg_New(params));
303
304   // If it's enabled, tell the renderer to set up the Javascript bindings for
305   // sending messages back to the browser.
306   if (GetProcess()->IsIsolatedGuest())
307     DCHECK_EQ(0, enabled_bindings_);
308   Send(new ViewMsg_AllowBindings(GetRoutingID(), enabled_bindings_));
309   // Let our delegate know that we created a RenderView.
310   delegate_->RenderViewCreated(this);
311
312   return true;
313 }
314
315 bool RenderViewHostImpl::IsRenderViewLive() const {
316   return GetProcess()->HasConnection() && renderer_initialized_;
317 }
318
319 void RenderViewHostImpl::SyncRendererPrefs() {
320   Send(new ViewMsg_SetRendererPrefs(GetRoutingID(),
321                                     delegate_->GetRendererPrefs(
322                                         GetProcess()->GetBrowserContext())));
323 }
324
325 WebPreferences RenderViewHostImpl::ComputeWebkitPrefs(const GURL& url) {
326   TRACE_EVENT0("browser", "RenderViewHostImpl::GetWebkitPrefs");
327   WebPreferences prefs;
328
329   const base::CommandLine& command_line =
330       *base::CommandLine::ForCurrentProcess();
331
332   prefs.javascript_enabled =
333       !command_line.HasSwitch(switches::kDisableJavaScript);
334   prefs.web_security_enabled =
335       !command_line.HasSwitch(switches::kDisableWebSecurity);
336   prefs.plugins_enabled =
337       !command_line.HasSwitch(switches::kDisablePlugins);
338   prefs.java_enabled =
339       !command_line.HasSwitch(switches::kDisableJava);
340
341   prefs.remote_fonts_enabled =
342       !command_line.HasSwitch(switches::kDisableRemoteFonts);
343   prefs.xslt_enabled =
344       !command_line.HasSwitch(switches::kDisableXSLT);
345   prefs.xss_auditor_enabled =
346       !command_line.HasSwitch(switches::kDisableXSSAuditor);
347   prefs.application_cache_enabled =
348       !command_line.HasSwitch(switches::kDisableApplicationCache);
349
350   prefs.local_storage_enabled =
351       !command_line.HasSwitch(switches::kDisableLocalStorage);
352   prefs.databases_enabled =
353       !command_line.HasSwitch(switches::kDisableDatabases);
354 #if defined(OS_ANDROID)
355   // WebAudio is enabled by default on x86 and ARM.
356   prefs.webaudio_enabled =
357       !command_line.HasSwitch(switches::kDisableWebAudio);
358 #endif
359
360   prefs.experimental_webgl_enabled =
361       GpuProcessHost::gpu_enabled() &&
362       !command_line.HasSwitch(switches::kDisable3DAPIs) &&
363       !command_line.HasSwitch(switches::kDisableExperimentalWebGL);
364
365   prefs.pepper_3d_enabled =
366       !command_line.HasSwitch(switches::kDisablePepper3d);
367
368   prefs.flash_3d_enabled =
369       GpuProcessHost::gpu_enabled() &&
370       !command_line.HasSwitch(switches::kDisableFlash3d);
371   prefs.flash_stage3d_enabled =
372       GpuProcessHost::gpu_enabled() &&
373       !command_line.HasSwitch(switches::kDisableFlashStage3d);
374   prefs.flash_stage3d_baseline_enabled =
375       GpuProcessHost::gpu_enabled() &&
376       !command_line.HasSwitch(switches::kDisableFlashStage3d);
377
378   prefs.allow_file_access_from_file_urls =
379       command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
380
381   prefs.layer_squashing_enabled = true;
382   if (command_line.HasSwitch(switches::kEnableLayerSquashing))
383       prefs.layer_squashing_enabled = true;
384   if (command_line.HasSwitch(switches::kDisableLayerSquashing))
385       prefs.layer_squashing_enabled = false;
386
387   prefs.accelerated_2d_canvas_enabled =
388       GpuProcessHost::gpu_enabled() &&
389       !command_line.HasSwitch(switches::kDisableAccelerated2dCanvas);
390   prefs.antialiased_2d_canvas_disabled =
391       command_line.HasSwitch(switches::kDisable2dCanvasAntialiasing);
392   prefs.antialiased_clips_2d_canvas_enabled =
393       command_line.HasSwitch(switches::kEnable2dCanvasClipAntialiasing);
394   prefs.accelerated_2d_canvas_msaa_sample_count =
395       atoi(command_line.GetSwitchValueASCII(
396       switches::kAcceleratedCanvas2dMSAASampleCount).c_str());
397   prefs.container_culling_enabled =
398       command_line.HasSwitch(switches::kEnableContainerCulling);
399   prefs.text_blobs_enabled =
400       command_line.HasSwitch(switches::kEnableTextBlobs);
401   prefs.region_based_columns_enabled =
402       command_line.HasSwitch(switches::kEnableRegionBasedColumns);
403
404   if (IsPinchVirtualViewportEnabled()) {
405     prefs.pinch_virtual_viewport_enabled = true;
406     prefs.pinch_overlay_scrollbar_thickness = 10;
407   }
408   prefs.use_solid_color_scrollbars = ui::IsOverlayScrollbarEnabled();
409
410 #if defined(OS_ANDROID)
411   // On Android, user gestures are normally required, unless that requirement
412   // is disabled with a command-line switch or the equivalent field trial is
413   // is set to "Enabled".
414   const std::string autoplay_group_name = base::FieldTrialList::FindFullName(
415       "MediaElementAutoplay");
416   prefs.user_gesture_required_for_media_playback = !command_line.HasSwitch(
417       switches::kDisableGestureRequirementForMediaPlayback) &&
418           (autoplay_group_name.empty() || autoplay_group_name != "Enabled");
419 #endif
420
421   prefs.touch_enabled = ui::AreTouchEventsEnabled();
422   prefs.device_supports_touch = prefs.touch_enabled &&
423       ui::IsTouchDevicePresent();
424 #if defined(OS_ANDROID)
425   prefs.device_supports_mouse = false;
426 #endif
427
428   prefs.pointer_events_max_touch_points = ui::MaxTouchPoints();
429
430   prefs.touch_adjustment_enabled =
431       !command_line.HasSwitch(switches::kDisableTouchAdjustment);
432
433   prefs.slimming_paint_enabled =
434       command_line.HasSwitch(switches::kEnableSlimmingPaint);
435
436 #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
437   bool default_enable_scroll_animator = true;
438 #else
439   bool default_enable_scroll_animator = false;
440 #endif
441   prefs.enable_scroll_animator = default_enable_scroll_animator;
442   if (command_line.HasSwitch(switches::kEnableSmoothScrolling))
443     prefs.enable_scroll_animator = true;
444   if (command_line.HasSwitch(switches::kDisableSmoothScrolling))
445     prefs.enable_scroll_animator = false;
446
447   // Certain GPU features might have been blacklisted.
448   GpuDataManagerImpl::GetInstance()->UpdateRendererWebPrefs(&prefs);
449
450   if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
451           GetProcess()->GetID())) {
452     prefs.loads_images_automatically = true;
453     prefs.javascript_enabled = true;
454   }
455
456   prefs.connection_type = net::NetworkChangeNotifier::GetConnectionType();
457   prefs.is_online =
458       prefs.connection_type != net::NetworkChangeNotifier::CONNECTION_NONE;
459
460   prefs.number_of_cpu_cores = base::SysInfo::NumberOfProcessors();
461
462   prefs.viewport_meta_enabled =
463       command_line.HasSwitch(switches::kEnableViewportMeta);
464
465   prefs.viewport_enabled =
466       command_line.HasSwitch(switches::kEnableViewport) ||
467       prefs.viewport_meta_enabled;
468
469   prefs.main_frame_resizes_are_orientation_changes =
470       command_line.HasSwitch(switches::kMainFrameResizesAreOrientationChanges);
471
472   prefs.deferred_image_decoding_enabled =
473       command_line.HasSwitch(switches::kEnableDeferredImageDecoding) ||
474       content::IsImplSidePaintingEnabled();
475
476   prefs.image_color_profiles_enabled =
477       command_line.HasSwitch(switches::kEnableImageColorProfiles);
478
479   prefs.spatial_navigation_enabled = command_line.HasSwitch(
480       switches::kEnableSpatialNavigation);
481
482   if (command_line.HasSwitch(switches::kV8CacheOptions)) {
483     const std::string v8_cache_options =
484         command_line.GetSwitchValueASCII(switches::kV8CacheOptions);
485     if (v8_cache_options == "parse") {
486       prefs.v8_cache_options = V8_CACHE_OPTIONS_PARSE;
487     } else if (v8_cache_options == "code") {
488       prefs.v8_cache_options = V8_CACHE_OPTIONS_CODE;
489     } else {
490       prefs.v8_cache_options = V8_CACHE_OPTIONS_OFF;
491     }
492   }
493
494   std::string streaming_experiment_group =
495       base::FieldTrialList::FindFullName("V8ScriptStreaming");
496   prefs.v8_script_streaming_enabled =
497       command_line.HasSwitch(switches::kEnableV8ScriptStreaming);
498   if (streaming_experiment_group == "Enabled") {
499     prefs.v8_script_streaming_enabled = true;
500     prefs.v8_script_streaming_mode = V8_SCRIPT_STREAMING_MODE_ALL;
501   } else if (streaming_experiment_group == "OnlyAsyncAndDefer") {
502     prefs.v8_script_streaming_enabled = true;
503     prefs.v8_script_streaming_mode =
504         V8_SCRIPT_STREAMING_MODE_ONLY_ASYNC_AND_DEFER;
505   } else if (streaming_experiment_group == "AllPlusBlockParserBlocking") {
506     prefs.v8_script_streaming_enabled = true;
507     prefs.v8_script_streaming_mode =
508         V8_SCRIPT_STREAMING_MODE_ALL_PLUS_BLOCK_PARSER_BLOCKING;
509   }
510
511   GetContentClient()->browser()->OverrideWebkitPrefs(this, url, &prefs);
512   return prefs;
513 }
514
515 void RenderViewHostImpl::SuppressDialogsUntilSwapOut() {
516   Send(new ViewMsg_SuppressDialogsUntilSwapOut(GetRoutingID()));
517 }
518
519 void RenderViewHostImpl::ClosePage() {
520   is_waiting_for_close_ack_ = true;
521   StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
522
523   if (IsRenderViewLive()) {
524     // Since we are sending an IPC message to the renderer, increase the event
525     // count to prevent the hang monitor timeout from being stopped by input
526     // event acknowledgements.
527     increment_in_flight_event_count();
528
529     // TODO(creis): Should this be moved to Shutdown?  It may not be called for
530     // RenderViewHosts that have been swapped out.
531     NotificationService::current()->Notify(
532         NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW,
533         Source<RenderViewHost>(this),
534         NotificationService::NoDetails());
535
536     Send(new ViewMsg_ClosePage(GetRoutingID()));
537   } else {
538     // This RenderViewHost doesn't have a live renderer, so just skip the unload
539     // event and close the page.
540     ClosePageIgnoringUnloadEvents();
541   }
542 }
543
544 void RenderViewHostImpl::ClosePageIgnoringUnloadEvents() {
545   StopHangMonitorTimeout();
546   is_waiting_for_close_ack_ = false;
547
548   sudden_termination_allowed_ = true;
549   delegate_->Close(this);
550 }
551
552 #if defined(OS_ANDROID)
553 void RenderViewHostImpl::ActivateNearestFindResult(int request_id,
554                                                    float x,
555                                                    float y) {
556   Send(new InputMsg_ActivateNearestFindResult(GetRoutingID(),
557                                               request_id, x, y));
558 }
559
560 void RenderViewHostImpl::RequestFindMatchRects(int current_version) {
561   Send(new ViewMsg_FindMatchRects(GetRoutingID(), current_version));
562 }
563 #endif
564
565 void RenderViewHostImpl::DragTargetDragEnter(
566     const DropData& drop_data,
567     const gfx::Point& client_pt,
568     const gfx::Point& screen_pt,
569     WebDragOperationsMask operations_allowed,
570     int key_modifiers) {
571   const int renderer_id = GetProcess()->GetID();
572   ChildProcessSecurityPolicyImpl* policy =
573       ChildProcessSecurityPolicyImpl::GetInstance();
574
575 #if defined(OS_CHROMEOS)
576   // The externalfile:// scheme is used in Chrome OS to open external files in a
577   // browser tab.
578   if (drop_data.url.SchemeIs(content::kExternalFileScheme))
579     policy->GrantRequestURL(renderer_id, drop_data.url);
580 #endif
581
582   // The URL could have been cobbled together from any highlighted text string,
583   // and can't be interpreted as a capability.
584   DropData filtered_data(drop_data);
585   GetProcess()->FilterURL(true, &filtered_data.url);
586   if (drop_data.did_originate_from_renderer) {
587     filtered_data.filenames.clear();
588   }
589
590   // The filenames vector, on the other hand, does represent a capability to
591   // access the given files.
592   storage::IsolatedContext::FileInfoSet files;
593   for (std::vector<ui::FileInfo>::iterator iter(
594            filtered_data.filenames.begin());
595        iter != filtered_data.filenames.end();
596        ++iter) {
597     // A dragged file may wind up as the value of an input element, or it
598     // may be used as the target of a navigation instead.  We don't know
599     // which will happen at this point, so generously grant both access
600     // and request permissions to the specific file to cover both cases.
601     // We do not give it the permission to request all file:// URLs.
602
603     // Make sure we have the same display_name as the one we register.
604     if (iter->display_name.empty()) {
605       std::string name;
606       files.AddPath(iter->path, &name);
607       iter->display_name = base::FilePath::FromUTF8Unsafe(name);
608     } else {
609       files.AddPathWithName(iter->path, iter->display_name.AsUTF8Unsafe());
610     }
611
612     policy->GrantRequestSpecificFileURL(renderer_id,
613                                         net::FilePathToFileURL(iter->path));
614
615     // If the renderer already has permission to read these paths, we don't need
616     // to re-grant them. This prevents problems with DnD for files in the CrOS
617     // file manager--the file manager already had read/write access to those
618     // directories, but dragging a file would cause the read/write access to be
619     // overwritten with read-only access, making them impossible to delete or
620     // rename until the renderer was killed.
621     if (!policy->CanReadFile(renderer_id, iter->path))
622       policy->GrantReadFile(renderer_id, iter->path);
623   }
624
625   storage::IsolatedContext* isolated_context =
626       storage::IsolatedContext::GetInstance();
627   DCHECK(isolated_context);
628   std::string filesystem_id = isolated_context->RegisterDraggedFileSystem(
629       files);
630   if (!filesystem_id.empty()) {
631     // Grant the permission iff the ID is valid.
632     policy->GrantReadFileSystem(renderer_id, filesystem_id);
633   }
634   filtered_data.filesystem_id = base::UTF8ToUTF16(filesystem_id);
635
636   storage::FileSystemContext* file_system_context =
637       BrowserContext::GetStoragePartition(GetProcess()->GetBrowserContext(),
638                                           GetSiteInstance())
639           ->GetFileSystemContext();
640   for (size_t i = 0; i < filtered_data.file_system_files.size(); ++i) {
641     storage::FileSystemURL file_system_url =
642         file_system_context->CrackURL(filtered_data.file_system_files[i].url);
643
644     std::string register_name;
645     std::string filesystem_id = isolated_context->RegisterFileSystemForPath(
646         file_system_url.type(), file_system_url.filesystem_id(),
647         file_system_url.path(), &register_name);
648     policy->GrantReadFileSystem(renderer_id, filesystem_id);
649
650     // Note: We are using the origin URL provided by the sender here. It may be
651     // different from the receiver's.
652     filtered_data.file_system_files[i].url =
653         GURL(storage::GetIsolatedFileSystemRootURIString(
654                  file_system_url.origin(), filesystem_id, std::string())
655                  .append(register_name));
656   }
657
658   Send(new DragMsg_TargetDragEnter(GetRoutingID(), filtered_data, client_pt,
659                                    screen_pt, operations_allowed,
660                                    key_modifiers));
661 }
662
663 void RenderViewHostImpl::DragTargetDragOver(
664     const gfx::Point& client_pt,
665     const gfx::Point& screen_pt,
666     WebDragOperationsMask operations_allowed,
667     int key_modifiers) {
668   Send(new DragMsg_TargetDragOver(GetRoutingID(), client_pt, screen_pt,
669                                   operations_allowed, key_modifiers));
670 }
671
672 void RenderViewHostImpl::DragTargetDragLeave() {
673   Send(new DragMsg_TargetDragLeave(GetRoutingID()));
674 }
675
676 void RenderViewHostImpl::DragTargetDrop(
677     const gfx::Point& client_pt,
678     const gfx::Point& screen_pt,
679     int key_modifiers) {
680   Send(new DragMsg_TargetDrop(GetRoutingID(), client_pt, screen_pt,
681                               key_modifiers));
682 }
683
684 void RenderViewHostImpl::DragSourceEndedAt(
685     int client_x, int client_y, int screen_x, int screen_y,
686     WebDragOperation operation) {
687   Send(new DragMsg_SourceEnded(GetRoutingID(),
688                                gfx::Point(client_x, client_y),
689                                gfx::Point(screen_x, screen_y),
690                                operation));
691 }
692
693 void RenderViewHostImpl::DragSourceSystemDragEnded() {
694   Send(new DragMsg_SourceSystemDragEnded(GetRoutingID()));
695 }
696
697 RenderFrameHost* RenderViewHostImpl::GetMainFrame() {
698   return RenderFrameHost::FromID(GetProcess()->GetID(), main_frame_routing_id_);
699 }
700
701 void RenderViewHostImpl::AllowBindings(int bindings_flags) {
702   // Never grant any bindings to browser plugin guests.
703   if (GetProcess()->IsIsolatedGuest()) {
704     NOTREACHED() << "Never grant bindings to a guest process.";
705     return;
706   }
707
708   // Ensure we aren't granting WebUI bindings to a process that has already
709   // been used for non-privileged views.
710   if (bindings_flags & BINDINGS_POLICY_WEB_UI &&
711       GetProcess()->HasConnection() &&
712       !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
713           GetProcess()->GetID())) {
714     // This process has no bindings yet. Make sure it does not have more
715     // than this single active view.
716     RenderProcessHostImpl* process =
717         static_cast<RenderProcessHostImpl*>(GetProcess());
718     // --single-process only has one renderer.
719     if (process->GetActiveViewCount() > 1 &&
720         !base::CommandLine::ForCurrentProcess()->HasSwitch(
721             switches::kSingleProcess))
722       return;
723   }
724
725   if (bindings_flags & BINDINGS_POLICY_WEB_UI) {
726     ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
727         GetProcess()->GetID());
728   }
729
730   enabled_bindings_ |= bindings_flags;
731   if (renderer_initialized_)
732     Send(new ViewMsg_AllowBindings(GetRoutingID(), enabled_bindings_));
733 }
734
735 int RenderViewHostImpl::GetEnabledBindings() const {
736   return enabled_bindings_;
737 }
738
739 void RenderViewHostImpl::SetWebUIProperty(const std::string& name,
740                                           const std::string& value) {
741   // This is a sanity check before telling the renderer to enable the property.
742   // It could lie and send the corresponding IPC messages anyway, but we will
743   // not act on them if enabled_bindings_ doesn't agree. If we get here without
744   // WebUI bindings, kill the renderer process.
745   if (enabled_bindings_ & BINDINGS_POLICY_WEB_UI) {
746     Send(new ViewMsg_SetWebUIProperty(GetRoutingID(), name, value));
747   } else {
748     RecordAction(
749         base::UserMetricsAction("BindingsMismatchTerminate_RVH_WebUI"));
750     base::KillProcess(
751         GetProcess()->GetHandle(), content::RESULT_CODE_KILLED, false);
752   }
753 }
754
755 void RenderViewHostImpl::GotFocus() {
756   RenderWidgetHostImpl::GotFocus();  // Notifies the renderer it got focus.
757
758   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
759   if (view)
760     view->GotFocus();
761 }
762
763 void RenderViewHostImpl::LostCapture() {
764   RenderWidgetHostImpl::LostCapture();
765   delegate_->LostCapture();
766 }
767
768 void RenderViewHostImpl::LostMouseLock() {
769   RenderWidgetHostImpl::LostMouseLock();
770   delegate_->LostMouseLock();
771 }
772
773 void RenderViewHostImpl::SetInitialFocus(bool reverse) {
774   Send(new ViewMsg_SetInitialFocus(GetRoutingID(), reverse));
775 }
776
777 void RenderViewHostImpl::FilesSelectedInChooser(
778     const std::vector<content::FileChooserFileInfo>& files,
779     FileChooserParams::Mode permissions) {
780   storage::FileSystemContext* const file_system_context =
781       BrowserContext::GetStoragePartition(GetProcess()->GetBrowserContext(),
782                                           GetSiteInstance())
783           ->GetFileSystemContext();
784   // Grant the security access requested to the given files.
785   for (size_t i = 0; i < files.size(); ++i) {
786     const content::FileChooserFileInfo& file = files[i];
787     if (permissions == FileChooserParams::Save) {
788       ChildProcessSecurityPolicyImpl::GetInstance()->GrantCreateReadWriteFile(
789           GetProcess()->GetID(), file.file_path);
790     } else {
791       ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
792           GetProcess()->GetID(), file.file_path);
793     }
794     if (file.file_system_url.is_valid()) {
795       ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFileSystem(
796           GetProcess()->GetID(),
797           file_system_context->CrackURL(file.file_system_url)
798           .mount_filesystem_id());
799     }
800   }
801   Send(new ViewMsg_RunFileChooserResponse(GetRoutingID(), files));
802 }
803
804 void RenderViewHostImpl::DirectoryEnumerationFinished(
805     int request_id,
806     const std::vector<base::FilePath>& files) {
807   // Grant the security access requested to the given files.
808   for (std::vector<base::FilePath>::const_iterator file = files.begin();
809        file != files.end(); ++file) {
810     ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
811         GetProcess()->GetID(), *file);
812   }
813   Send(new ViewMsg_EnumerateDirectoryResponse(GetRoutingID(),
814                                               request_id,
815                                               files));
816 }
817
818 void RenderViewHostImpl::SetIsLoading(bool is_loading) {
819   if (ResourceDispatcherHostImpl::Get()) {
820     BrowserThread::PostTask(
821         BrowserThread::IO,
822         FROM_HERE,
823         base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading,
824                    base::Unretained(ResourceDispatcherHostImpl::Get()),
825                    GetProcess()->GetID(),
826                    GetRoutingID(),
827                    is_loading));
828   }
829   RenderWidgetHostImpl::SetIsLoading(is_loading);
830 }
831
832 void RenderViewHostImpl::LoadStateChanged(
833     const GURL& url,
834     const net::LoadStateWithParam& load_state,
835     uint64 upload_position,
836     uint64 upload_size) {
837   delegate_->LoadStateChanged(url, load_state, upload_position, upload_size);
838 }
839
840 bool RenderViewHostImpl::SuddenTerminationAllowed() const {
841   return sudden_termination_allowed_ ||
842       GetProcess()->SuddenTerminationAllowed();
843 }
844
845 ///////////////////////////////////////////////////////////////////////////////
846 // RenderViewHostImpl, IPC message handlers:
847
848 bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
849   if (!BrowserMessageFilter::CheckCanDispatchOnUI(msg, this))
850     return true;
851
852   // Filter out most IPC messages if this renderer is swapped out.
853   // We still want to handle certain ACKs to keep our state consistent.
854   if (is_swapped_out_) {
855     if (!SwappedOutMessages::CanHandleWhileSwappedOut(msg)) {
856       // If this is a synchronous message and we decided not to handle it,
857       // we must send an error reply, or else the renderer will be stuck
858       // and won't respond to future requests.
859       if (msg.is_sync()) {
860         IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
861         reply->set_reply_error();
862         Send(reply);
863       }
864       // Don't continue looking for someone to handle it.
865       return true;
866     }
867   }
868
869   if (delegate_->OnMessageReceived(this, msg))
870     return true;
871
872   bool handled = true;
873   IPC_BEGIN_MESSAGE_MAP(RenderViewHostImpl, msg)
874     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowView, OnShowView)
875     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
876     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget,
877                         OnShowFullscreenWidget)
878     IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunModal, OnRunModal)
879     IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady)
880     IPC_MESSAGE_HANDLER(ViewHostMsg_RenderProcessGone, OnRenderProcessGone)
881     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateState, OnUpdateState)
882     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL)
883     IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
884     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
885     IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentAvailableInMainFrame,
886                         OnDocumentAvailableInMainFrame)
887     IPC_MESSAGE_HANDLER(ViewHostMsg_ToggleFullscreen, OnToggleFullscreen)
888     IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange,
889                         OnDidContentsPreferredSizeChange)
890     IPC_MESSAGE_HANDLER(ViewHostMsg_RouteCloseEvent,
891                         OnRouteCloseEvent)
892     IPC_MESSAGE_HANDLER(ViewHostMsg_RouteMessageEvent, OnRouteMessageEvent)
893     IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging)
894     IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor)
895     IPC_MESSAGE_HANDLER(DragHostMsg_TargetDrop_ACK, OnTargetDropACK)
896     IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
897     IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnFocusedNodeChanged)
898     IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK)
899     IPC_MESSAGE_HANDLER(ViewHostMsg_DidZoomURL, OnDidZoomURL)
900     IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser)
901     IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched)
902     // Have the super handle all other messages.
903     IPC_MESSAGE_UNHANDLED(
904         handled = RenderWidgetHostImpl::OnMessageReceived(msg))
905   IPC_END_MESSAGE_MAP()
906
907   return handled;
908 }
909
910 void RenderViewHostImpl::Init() {
911   RenderWidgetHostImpl::Init();
912 }
913
914 void RenderViewHostImpl::Shutdown() {
915   // If we are being run modally (see RunModal), then we need to cleanup.
916   if (run_modal_reply_msg_) {
917     Send(run_modal_reply_msg_);
918     run_modal_reply_msg_ = NULL;
919     RenderViewHostImpl* opener =
920         RenderViewHostImpl::FromID(GetProcess()->GetID(), run_modal_opener_id_);
921     if (opener) {
922       opener->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(
923           hung_renderer_delay_ms_));
924       // Balance out the decrement when we got created.
925       opener->increment_in_flight_event_count();
926     }
927     run_modal_opener_id_ = MSG_ROUTING_NONE;
928   }
929
930   // We can't release the SessionStorageNamespace until our peer
931   // in the renderer has wound down.
932   if (GetProcess()->HasConnection()) {
933     RenderProcessHostImpl::ReleaseOnCloseACK(
934         GetProcess(),
935         delegate_->GetSessionStorageNamespaceMap(),
936         GetRoutingID());
937   }
938
939   RenderWidgetHostImpl::Shutdown();
940 }
941
942 void RenderViewHostImpl::WasHidden() {
943   if (ResourceDispatcherHostImpl::Get()) {
944     BrowserThread::PostTask(
945         BrowserThread::IO, FROM_HERE,
946         base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostWasHidden,
947                    base::Unretained(ResourceDispatcherHostImpl::Get()),
948                    GetProcess()->GetID(), GetRoutingID()));
949   }
950
951   RenderWidgetHostImpl::WasHidden();
952 }
953
954 void RenderViewHostImpl::WasShown(const ui::LatencyInfo& latency_info) {
955   if (ResourceDispatcherHostImpl::Get()) {
956     BrowserThread::PostTask(
957         BrowserThread::IO, FROM_HERE,
958         base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostWasShown,
959                    base::Unretained(ResourceDispatcherHostImpl::Get()),
960                    GetProcess()->GetID(), GetRoutingID()));
961   }
962
963   RenderWidgetHostImpl::WasShown(latency_info);
964 }
965
966 bool RenderViewHostImpl::IsRenderView() const {
967   return true;
968 }
969
970 void RenderViewHostImpl::CreateNewWindow(
971     int route_id,
972     int main_frame_route_id,
973     const ViewHostMsg_CreateWindow_Params& params,
974     SessionStorageNamespace* session_storage_namespace) {
975   ViewHostMsg_CreateWindow_Params validated_params(params);
976   GetProcess()->FilterURL(false, &validated_params.target_url);
977   GetProcess()->FilterURL(false, &validated_params.opener_url);
978   GetProcess()->FilterURL(true, &validated_params.opener_security_origin);
979
980   delegate_->CreateNewWindow(
981       GetProcess()->GetID(), route_id, main_frame_route_id, validated_params,
982       session_storage_namespace);
983 }
984
985 void RenderViewHostImpl::CreateNewWidget(int route_id,
986                                      blink::WebPopupType popup_type) {
987   delegate_->CreateNewWidget(GetProcess()->GetID(), route_id, popup_type);
988 }
989
990 void RenderViewHostImpl::CreateNewFullscreenWidget(int route_id) {
991   delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), route_id);
992 }
993
994 void RenderViewHostImpl::OnShowView(int route_id,
995                                     WindowOpenDisposition disposition,
996                                     const gfx::Rect& initial_pos,
997                                     bool user_gesture) {
998   if (is_active_) {
999     delegate_->ShowCreatedWindow(
1000         route_id, disposition, initial_pos, user_gesture);
1001   }
1002   Send(new ViewMsg_Move_ACK(route_id));
1003 }
1004
1005 void RenderViewHostImpl::OnShowWidget(int route_id,
1006                                       const gfx::Rect& initial_pos) {
1007   if (is_active_)
1008     delegate_->ShowCreatedWidget(route_id, initial_pos);
1009   Send(new ViewMsg_Move_ACK(route_id));
1010 }
1011
1012 void RenderViewHostImpl::OnShowFullscreenWidget(int route_id) {
1013   if (is_active_)
1014     delegate_->ShowCreatedFullscreenWidget(route_id);
1015   Send(new ViewMsg_Move_ACK(route_id));
1016 }
1017
1018 void RenderViewHostImpl::OnRunModal(int opener_id, IPC::Message* reply_msg) {
1019   DCHECK(!run_modal_reply_msg_);
1020   run_modal_reply_msg_ = reply_msg;
1021   run_modal_opener_id_ = opener_id;
1022
1023   RecordAction(base::UserMetricsAction("ShowModalDialog"));
1024
1025   RenderViewHostImpl* opener =
1026       RenderViewHostImpl::FromID(GetProcess()->GetID(), run_modal_opener_id_);
1027   if (opener) {
1028     opener->StopHangMonitorTimeout();
1029     // The ack for the mouse down won't come until the dialog closes, so fake it
1030     // so that we don't get a timeout.
1031     opener->decrement_in_flight_event_count();
1032   }
1033
1034   // TODO(darin): Bug 1107929: Need to inform our delegate to show this view in
1035   // an app-modal fashion.
1036 }
1037
1038 void RenderViewHostImpl::OnRenderViewReady() {
1039   render_view_termination_status_ = base::TERMINATION_STATUS_STILL_RUNNING;
1040   SendScreenRects();
1041   WasResized();
1042   delegate_->RenderViewReady(this);
1043 }
1044
1045 void RenderViewHostImpl::OnRenderProcessGone(int status, int exit_code) {
1046   // Keep the termination status so we can get at it later when we
1047   // need to know why it died.
1048   render_view_termination_status_ =
1049       static_cast<base::TerminationStatus>(status);
1050
1051   // Reset frame tree state associated with this process.  This must happen
1052   // before RenderViewTerminated because observers expect the subframes of any
1053   // affected frames to be cleared first.
1054   delegate_->GetFrameTree()->RenderProcessGone(this);
1055
1056   // Our base class RenderWidgetHost needs to reset some stuff.
1057   RendererExited(render_view_termination_status_, exit_code);
1058
1059   delegate_->RenderViewTerminated(this,
1060                                   static_cast<base::TerminationStatus>(status),
1061                                   exit_code);
1062 }
1063
1064 void RenderViewHostImpl::OnUpdateState(int32 page_id, const PageState& state) {
1065   // If the following DCHECK fails, you have encountered a tricky edge-case that
1066   // has evaded reproduction for a very long time. Please report what you were
1067   // doing on http://crbug.com/407376, whether or not you can reproduce the
1068   // failure.
1069   DCHECK_EQ(page_id, page_id_);
1070
1071   // Without this check, the renderer can trick the browser into using
1072   // filenames it can't access in a future session restore.
1073   if (!CanAccessFilesOfPageState(state)) {
1074     GetProcess()->ReceivedBadMessage();
1075     return;
1076   }
1077
1078   delegate_->UpdateState(this, page_id, state);
1079 }
1080
1081 void RenderViewHostImpl::OnUpdateTargetURL(const GURL& url) {
1082   if (is_active_)
1083     delegate_->UpdateTargetURL(url);
1084
1085   // Send a notification back to the renderer that we are ready to
1086   // receive more target urls.
1087   Send(new ViewMsg_UpdateTargetURL_ACK(GetRoutingID()));
1088 }
1089
1090 void RenderViewHostImpl::OnClose() {
1091   // If the renderer is telling us to close, it has already run the unload
1092   // events, and we can take the fast path.
1093   ClosePageIgnoringUnloadEvents();
1094 }
1095
1096 void RenderViewHostImpl::OnRequestMove(const gfx::Rect& pos) {
1097   if (is_active_)
1098     delegate_->RequestMove(pos);
1099   Send(new ViewMsg_Move_ACK(GetRoutingID()));
1100 }
1101
1102 void RenderViewHostImpl::OnDocumentAvailableInMainFrame(
1103     bool uses_temporary_zoom_level) {
1104   delegate_->DocumentAvailableInMainFrame(this);
1105
1106   if (!uses_temporary_zoom_level)
1107     return;
1108
1109   HostZoomMapImpl* host_zoom_map =
1110       static_cast<HostZoomMapImpl*>(HostZoomMap::GetDefaultForBrowserContext(
1111           GetProcess()->GetBrowserContext()));
1112   host_zoom_map->SetTemporaryZoomLevel(GetProcess()->GetID(),
1113                                        GetRoutingID(),
1114                                        host_zoom_map->GetDefaultZoomLevel());
1115 }
1116
1117 void RenderViewHostImpl::OnToggleFullscreen(bool enter_fullscreen) {
1118   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1119   delegate_->ToggleFullscreenMode(enter_fullscreen);
1120   // We need to notify the contents that its fullscreen state has changed. This
1121   // is done as part of the resize message.
1122   WasResized();
1123 }
1124
1125 void RenderViewHostImpl::OnDidContentsPreferredSizeChange(
1126     const gfx::Size& new_size) {
1127   delegate_->UpdatePreferredSize(new_size);
1128 }
1129
1130 void RenderViewHostImpl::OnRenderAutoResized(const gfx::Size& new_size) {
1131   delegate_->ResizeDueToAutoResize(new_size);
1132 }
1133
1134 void RenderViewHostImpl::OnRouteCloseEvent() {
1135   // Have the delegate route this to the active RenderViewHost.
1136   delegate_->RouteCloseEvent(this);
1137 }
1138
1139 void RenderViewHostImpl::OnRouteMessageEvent(
1140     const ViewMsg_PostMessage_Params& params) {
1141   // Give to the delegate to route to the active RenderViewHost.
1142   delegate_->RouteMessageEvent(this, params);
1143 }
1144
1145 void RenderViewHostImpl::OnStartDragging(
1146     const DropData& drop_data,
1147     WebDragOperationsMask drag_operations_mask,
1148     const SkBitmap& bitmap,
1149     const gfx::Vector2d& bitmap_offset_in_dip,
1150     const DragEventSourceInfo& event_info) {
1151   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1152   if (!view)
1153     return;
1154
1155   DropData filtered_data(drop_data);
1156   RenderProcessHost* process = GetProcess();
1157   ChildProcessSecurityPolicyImpl* policy =
1158       ChildProcessSecurityPolicyImpl::GetInstance();
1159
1160   // Allow drag of Javascript URLs to enable bookmarklet drag to bookmark bar.
1161   if (!filtered_data.url.SchemeIs(url::kJavaScriptScheme))
1162     process->FilterURL(true, &filtered_data.url);
1163   process->FilterURL(false, &filtered_data.html_base_url);
1164   // Filter out any paths that the renderer didn't have access to. This prevents
1165   // the following attack on a malicious renderer:
1166   // 1. StartDragging IPC sent with renderer-specified filesystem paths that it
1167   //    doesn't have read permissions for.
1168   // 2. We initiate a native DnD operation.
1169   // 3. DnD operation immediately ends since mouse is not held down. DnD events
1170   //    still fire though, which causes read permissions to be granted to the
1171   //    renderer for any file paths in the drop.
1172   filtered_data.filenames.clear();
1173   for (std::vector<ui::FileInfo>::const_iterator it =
1174            drop_data.filenames.begin();
1175        it != drop_data.filenames.end();
1176        ++it) {
1177     if (policy->CanReadFile(GetProcess()->GetID(), it->path))
1178       filtered_data.filenames.push_back(*it);
1179   }
1180
1181   storage::FileSystemContext* file_system_context =
1182       BrowserContext::GetStoragePartition(GetProcess()->GetBrowserContext(),
1183                                           GetSiteInstance())
1184           ->GetFileSystemContext();
1185   filtered_data.file_system_files.clear();
1186   for (size_t i = 0; i < drop_data.file_system_files.size(); ++i) {
1187     storage::FileSystemURL file_system_url =
1188         file_system_context->CrackURL(drop_data.file_system_files[i].url);
1189     if (policy->CanReadFileSystemFile(GetProcess()->GetID(), file_system_url))
1190       filtered_data.file_system_files.push_back(drop_data.file_system_files[i]);
1191   }
1192
1193   float scale = GetScaleFactorForView(GetView());
1194   gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, scale));
1195   view->StartDragging(filtered_data, drag_operations_mask, image,
1196       bitmap_offset_in_dip, event_info);
1197 }
1198
1199 void RenderViewHostImpl::OnUpdateDragCursor(WebDragOperation current_op) {
1200   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1201   if (view)
1202     view->UpdateDragCursor(current_op);
1203 }
1204
1205 void RenderViewHostImpl::OnTargetDropACK() {
1206   NotificationService::current()->Notify(
1207       NOTIFICATION_RENDER_VIEW_HOST_DID_RECEIVE_DRAG_TARGET_DROP_ACK,
1208       Source<RenderViewHost>(this),
1209       NotificationService::NoDetails());
1210 }
1211
1212 void RenderViewHostImpl::OnTakeFocus(bool reverse) {
1213   RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1214   if (view)
1215     view->TakeFocus(reverse);
1216 }
1217
1218 void RenderViewHostImpl::OnFocusedNodeChanged(bool is_editable_node) {
1219   is_focused_element_editable_ = is_editable_node;
1220   if (view_)
1221     view_->FocusedNodeChanged(is_editable_node);
1222 #if defined(OS_WIN)
1223   if (!is_editable_node && virtual_keyboard_requested_) {
1224     virtual_keyboard_requested_ = false;
1225     BrowserThread::PostDelayedTask(
1226         BrowserThread::UI, FROM_HERE,
1227         base::Bind(base::IgnoreResult(&DismissVirtualKeyboardTask)),
1228         TimeDelta::FromMilliseconds(kVirtualKeyboardDisplayWaitTimeoutMs));
1229   }
1230 #endif
1231   NotificationService::current()->Notify(
1232       NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
1233       Source<RenderViewHost>(this),
1234       Details<const bool>(&is_editable_node));
1235 }
1236
1237 void RenderViewHostImpl::OnUserGesture() {
1238   delegate_->OnUserGesture();
1239 }
1240
1241 void RenderViewHostImpl::OnClosePageACK() {
1242   decrement_in_flight_event_count();
1243   ClosePageIgnoringUnloadEvents();
1244 }
1245
1246 void RenderViewHostImpl::NotifyRendererUnresponsive() {
1247   delegate_->RendererUnresponsive(this);
1248 }
1249
1250 void RenderViewHostImpl::NotifyRendererResponsive() {
1251   delegate_->RendererResponsive(this);
1252 }
1253
1254 void RenderViewHostImpl::RequestToLockMouse(bool user_gesture,
1255                                             bool last_unlocked_by_target) {
1256   delegate_->RequestToLockMouse(user_gesture, last_unlocked_by_target);
1257 }
1258
1259 bool RenderViewHostImpl::IsFullscreen() const {
1260   return delegate_->IsFullscreenForCurrentTab();
1261 }
1262
1263 void RenderViewHostImpl::OnFocus() {
1264   // Note: We allow focus and blur from swapped out RenderViewHosts, even when
1265   // the active RenderViewHost is in a different BrowsingInstance (e.g., WebUI).
1266   delegate_->Activate();
1267 }
1268
1269 void RenderViewHostImpl::OnBlur() {
1270   delegate_->Deactivate();
1271 }
1272
1273 gfx::Rect RenderViewHostImpl::GetRootWindowResizerRect() const {
1274   return delegate_->GetRootWindowResizerRect();
1275 }
1276
1277 void RenderViewHostImpl::ForwardMouseEvent(
1278     const blink::WebMouseEvent& mouse_event) {
1279
1280   // We make a copy of the mouse event because
1281   // RenderWidgetHost::ForwardMouseEvent will delete |mouse_event|.
1282   blink::WebMouseEvent event_copy(mouse_event);
1283   RenderWidgetHostImpl::ForwardMouseEvent(event_copy);
1284
1285   switch (event_copy.type) {
1286     case WebInputEvent::MouseMove:
1287       delegate_->HandleMouseMove();
1288       break;
1289     case WebInputEvent::MouseLeave:
1290       delegate_->HandleMouseLeave();
1291       break;
1292     case WebInputEvent::MouseDown:
1293       delegate_->HandleMouseDown();
1294       break;
1295     case WebInputEvent::MouseWheel:
1296       if (ignore_input_events())
1297         delegate_->OnIgnoredUIEvent();
1298       break;
1299     case WebInputEvent::MouseUp:
1300       delegate_->HandleMouseUp();
1301     default:
1302       // For now, we don't care about the rest.
1303       break;
1304   }
1305 }
1306
1307 void RenderViewHostImpl::OnPointerEventActivate() {
1308   delegate_->HandlePointerActivate();
1309 }
1310
1311 void RenderViewHostImpl::ForwardKeyboardEvent(
1312     const NativeWebKeyboardEvent& key_event) {
1313   if (ignore_input_events()) {
1314     if (key_event.type == WebInputEvent::RawKeyDown)
1315       delegate_->OnIgnoredUIEvent();
1316     return;
1317   }
1318   RenderWidgetHostImpl::ForwardKeyboardEvent(key_event);
1319 }
1320
1321 void RenderViewHostImpl::OnTextSurroundingSelectionResponse(
1322     const base::string16& content,
1323     size_t start_offset,
1324     size_t end_offset) {
1325   if (!view_)
1326     return;
1327   view_->OnTextSurroundingSelectionResponse(content, start_offset, end_offset);
1328 }
1329
1330 void RenderViewHostImpl::ExitFullscreen() {
1331   RejectMouseLockOrUnlockIfNecessary();
1332   // Notify delegate_ and renderer of fullscreen state change.
1333   OnToggleFullscreen(false);
1334 }
1335
1336 WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
1337   if (!web_preferences_.get()) {
1338     OnWebkitPreferencesChanged();
1339   }
1340   return *web_preferences_;
1341 }
1342
1343 void RenderViewHostImpl::UpdateWebkitPreferences(const WebPreferences& prefs) {
1344   web_preferences_.reset(new WebPreferences(prefs));
1345   Send(new ViewMsg_UpdateWebPreferences(GetRoutingID(), prefs));
1346 }
1347
1348 void RenderViewHostImpl::OnWebkitPreferencesChanged() {
1349   // This is defensive code to avoid infinite loops due to code run inside
1350   // UpdateWebkitPreferences() accidentally updating more preferences and thus
1351   // calling back into this code. See crbug.com/398751 for one past example.
1352   if (updating_web_preferences_)
1353     return;
1354   updating_web_preferences_ = true;
1355   UpdateWebkitPreferences(delegate_->ComputeWebkitPrefs());
1356   updating_web_preferences_ = false;
1357 }
1358
1359 void RenderViewHostImpl::GetAudioOutputControllers(
1360     const GetAudioOutputControllersCallback& callback) const {
1361   scoped_refptr<AudioRendererHost> audio_host =
1362       static_cast<RenderProcessHostImpl*>(GetProcess())->audio_renderer_host();
1363   audio_host->GetOutputControllers(GetRoutingID(), callback);
1364 }
1365
1366 void RenderViewHostImpl::ClearFocusedElement() {
1367   is_focused_element_editable_ = false;
1368   Send(new ViewMsg_ClearFocusedElement(GetRoutingID()));
1369 }
1370
1371 bool RenderViewHostImpl::IsFocusedElementEditable() {
1372   return is_focused_element_editable_;
1373 }
1374
1375 void RenderViewHostImpl::Zoom(PageZoom zoom) {
1376   Send(new ViewMsg_Zoom(GetRoutingID(), zoom));
1377 }
1378
1379 void RenderViewHostImpl::DisableScrollbarsForThreshold(const gfx::Size& size) {
1380   Send(new ViewMsg_DisableScrollbarsForSmallWindows(GetRoutingID(), size));
1381 }
1382
1383 void RenderViewHostImpl::EnablePreferredSizeMode() {
1384   Send(new ViewMsg_EnablePreferredSizeChangedMode(GetRoutingID()));
1385 }
1386
1387 void RenderViewHostImpl::EnableAutoResize(const gfx::Size& min_size,
1388                                           const gfx::Size& max_size) {
1389   SetShouldAutoResize(true);
1390   Send(new ViewMsg_EnableAutoResize(GetRoutingID(), min_size, max_size));
1391 }
1392
1393 void RenderViewHostImpl::DisableAutoResize(const gfx::Size& new_size) {
1394   SetShouldAutoResize(false);
1395   Send(new ViewMsg_DisableAutoResize(GetRoutingID(), new_size));
1396   if (!new_size.IsEmpty())
1397     GetView()->SetSize(new_size);
1398 }
1399
1400 void RenderViewHostImpl::CopyImageAt(int x, int y) {
1401   Send(new ViewMsg_CopyImageAt(GetRoutingID(), x, y));
1402 }
1403
1404 void RenderViewHostImpl::SaveImageAt(int x, int y) {
1405   Send(new ViewMsg_SaveImageAt(GetRoutingID(), x, y));
1406 }
1407
1408 void RenderViewHostImpl::ExecuteMediaPlayerActionAtLocation(
1409   const gfx::Point& location, const blink::WebMediaPlayerAction& action) {
1410   Send(new ViewMsg_MediaPlayerActionAt(GetRoutingID(), location, action));
1411 }
1412
1413 void RenderViewHostImpl::ExecutePluginActionAtLocation(
1414   const gfx::Point& location, const blink::WebPluginAction& action) {
1415   Send(new ViewMsg_PluginActionAt(GetRoutingID(), location, action));
1416 }
1417
1418 void RenderViewHostImpl::NotifyMoveOrResizeStarted() {
1419   Send(new ViewMsg_MoveOrResizeStarted(GetRoutingID()));
1420 }
1421
1422 void RenderViewHostImpl::OnDidZoomURL(double zoom_level,
1423                                       const GURL& url) {
1424   HostZoomMapImpl* host_zoom_map =
1425       static_cast<HostZoomMapImpl*>(HostZoomMap::GetDefaultForBrowserContext(
1426           GetProcess()->GetBrowserContext()));
1427
1428   host_zoom_map->SetZoomLevelForView(GetProcess()->GetID(),
1429                                      GetRoutingID(),
1430                                      zoom_level,
1431                                      net::GetHostOrSpecFromURL(url));
1432 }
1433
1434 void RenderViewHostImpl::OnRunFileChooser(const FileChooserParams& params) {
1435   delegate_->RunFileChooser(this, params);
1436 }
1437
1438 void RenderViewHostImpl::OnFocusedNodeTouched(bool editable) {
1439 #if defined(OS_WIN)
1440   if (editable) {
1441     virtual_keyboard_requested_ = base::win::DisplayVirtualKeyboard();
1442   } else {
1443     virtual_keyboard_requested_ = false;
1444     base::win::DismissVirtualKeyboard();
1445   }
1446 #endif
1447 }
1448
1449 bool RenderViewHostImpl::CanAccessFilesOfPageState(
1450     const PageState& state) const {
1451   ChildProcessSecurityPolicyImpl* policy =
1452       ChildProcessSecurityPolicyImpl::GetInstance();
1453
1454   const std::vector<base::FilePath>& file_paths = state.GetReferencedFiles();
1455   for (std::vector<base::FilePath>::const_iterator file = file_paths.begin();
1456        file != file_paths.end(); ++file) {
1457     if (!policy->CanReadFile(GetProcess()->GetID(), *file))
1458       return false;
1459   }
1460   return true;
1461 }
1462
1463 void RenderViewHostImpl::AttachToFrameTree() {
1464   FrameTree* frame_tree = delegate_->GetFrameTree();
1465
1466   frame_tree->ResetForMainFrameSwap();
1467 }
1468
1469 void RenderViewHostImpl::SelectWordAroundCaret() {
1470   Send(new ViewMsg_SelectWordAroundCaret(GetRoutingID()));
1471 }
1472
1473 }  // namespace content