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