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