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