1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/render_view_host_impl.h"
6
7 #include <set>
8 #include <string>
9 #include <utility>
10 #include <vector>
11
12 #include "base/callback.h"
13 #include "base/command_line.h"
14 #include "base/debug/trace_event.h"
15 #include "base/i18n/rtl.h"
16 #include "base/json/json_reader.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/metrics/histogram.h"
19 #include "base/stl_util.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/sys_info.h"
23 #include "base/time/time.h"
24 #include "base/values.h"
25 #include "cc/base/switches.h"
26 #include "content/browser/accessibility/browser_accessibility_manager.h"
27 #include "content/browser/child_process_security_policy_impl.h"
28 #include "content/browser/cross_site_request_manager.h"
29 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
30 #include "content/browser/frame_host/frame_tree.h"
31 #include "content/browser/gpu/compositor_util.h"
32 #include "content/browser/gpu/gpu_data_manager_impl.h"
33 #include "content/browser/gpu/gpu_process_host.h"
34 #include "content/browser/gpu/gpu_surface_tracker.h"
35 #include "content/browser/host_zoom_map_impl.h"
36 #include "content/browser/loader/resource_dispatcher_host_impl.h"
37 #include "content/browser/renderer_host/dip_util.h"
38 #include "content/browser/renderer_host/input/timeout_monitor.h"
39 #include "content/browser/renderer_host/media/audio_renderer_host.h"
40 #include "content/browser/renderer_host/render_process_host_impl.h"
41 #include "content/browser/renderer_host/render_view_host_delegate.h"
42 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
43 #include "content/browser/renderer_host/render_widget_host_view_base.h"
44 #include "content/common/accessibility_messages.h"
45 #include "content/common/browser_plugin/browser_plugin_messages.h"
46 #include "content/common/content_switches_internal.h"
47 #include "content/common/drag_messages.h"
48 #include "content/common/frame_messages.h"
49 #include "content/common/input_messages.h"
50 #include "content/common/inter_process_time_ticks_converter.h"
51 #include "content/common/mojo/mojo_service_names.h"
52 #include "content/common/speech_recognition_messages.h"
53 #include "content/common/swapped_out_messages.h"
54 #include "content/common/view_messages.h"
55 #include "content/common/web_ui_setup.mojom.h"
56 #include "content/public/browser/ax_event_notification_details.h"
57 #include "content/public/browser/browser_accessibility_state.h"
58 #include "content/public/browser/browser_context.h"
59 #include "content/public/browser/browser_message_filter.h"
60 #include "content/public/browser/content_browser_client.h"
61 #include "content/public/browser/native_web_keyboard_event.h"
62 #include "content/public/browser/notification_details.h"
63 #include "content/public/browser/notification_service.h"
64 #include "content/public/browser/notification_types.h"
65 #include "content/public/browser/render_frame_host.h"
66 #include "content/public/browser/render_widget_host_iterator.h"
67 #include "content/public/browser/storage_partition.h"
68 #include "content/public/browser/user_metrics.h"
69 #include "content/public/common/bindings_policy.h"
70 #include "content/public/common/content_constants.h"
71 #include "content/public/common/content_switches.h"
72 #include "content/public/common/context_menu_params.h"
73 #include "content/public/common/drop_data.h"
74 #include "content/public/common/result_codes.h"
75 #include "content/public/common/url_utils.h"
76 #include "net/base/filename_util.h"
77 #include "net/base/net_util.h"
78 #include "net/base/network_change_notifier.h"
79 #include "net/url_request/url_request_context_getter.h"
80 #include "third_party/skia/include/core/SkBitmap.h"
81 #include "ui/accessibility/ax_tree.h"
82 #include "ui/base/touch/touch_device.h"
83 #include "ui/base/touch/touch_enabled.h"
84 #include "ui/base/ui_base_switches.h"
85 #include "ui/gfx/image/image_skia.h"
86 #include "ui/gfx/native_widget_types.h"
87 #include "ui/native_theme/native_theme_switches.h"
88 #include "ui/shell_dialogs/selected_file_info.h"
89 #include "url/url_constants.h"
90 #include "webkit/browser/fileapi/isolated_context.h"
91
92 #if defined(OS_MACOSX)
93 #include "content/browser/renderer_host/popup_menu_helper_mac.h"
94 #elif defined(OS_WIN)
95 #include "base/win/win_util.h"
96 #endif
97
98 #if defined(ENABLE_BROWSER_CDMS)
99 #include "content/browser/media/media_web_contents_observer.h"
100 #endif
101
102 using base::TimeDelta;
103 using blink::WebConsoleMessage;
104 using blink::WebDragOperation;
105 using blink::WebDragOperationNone;
106 using blink::WebDragOperationsMask;
107 using blink::WebInputEvent;
108 using blink::WebMediaPlayerAction;
109 using blink::WebPluginAction;
110
111 namespace content {
112 namespace {
113
114 #if defined(OS_WIN)
115
116 const int kVirtualKeyboardDisplayWaitTimeoutMs = 100;
117 const int kMaxVirtualKeyboardDisplayRetries = 5;
118
DismissVirtualKeyboardTask()119 void DismissVirtualKeyboardTask() {
120 static int virtual_keyboard_display_retries = 0;
121 // If the virtual keyboard is not yet visible, then we execute the task again
122 // waiting for it to show up.
123 if (!base::win::DismissVirtualKeyboard()) {
124 if (virtual_keyboard_display_retries < kMaxVirtualKeyboardDisplayRetries) {
125 BrowserThread::PostDelayedTask(
126 BrowserThread::UI, FROM_HERE,
127 base::Bind(base::IgnoreResult(&DismissVirtualKeyboardTask)),
128 TimeDelta::FromMilliseconds(kVirtualKeyboardDisplayWaitTimeoutMs));
129 ++virtual_keyboard_display_retries;
130 } else {
131 virtual_keyboard_display_retries = 0;
132 }
133 }
134 }
135 #endif
136
137 } // namespace
138
139 // static
140 const int RenderViewHostImpl::kUnloadTimeoutMS = 1000;
141
142 ///////////////////////////////////////////////////////////////////////////////
143 // RenderViewHost, public:
144
145 // static
IsRVHStateActive(RenderViewHostImplState rvh_state)146 bool RenderViewHostImpl::IsRVHStateActive(RenderViewHostImplState rvh_state) {
147 if (rvh_state == STATE_DEFAULT ||
148 rvh_state == STATE_WAITING_FOR_UNLOAD_ACK ||
149 rvh_state == STATE_WAITING_FOR_COMMIT ||
150 rvh_state == STATE_WAITING_FOR_CLOSE)
151 return true;
152 return false;
153 }
154
155 // static
FromID(int render_process_id,int render_view_id)156 RenderViewHost* RenderViewHost::FromID(int render_process_id,
157 int render_view_id) {
158 return RenderViewHostImpl::FromID(render_process_id, render_view_id);
159 }
160
161 // static
From(RenderWidgetHost * rwh)162 RenderViewHost* RenderViewHost::From(RenderWidgetHost* rwh) {
163 DCHECK(rwh->IsRenderView());
164 return static_cast<RenderViewHostImpl*>(RenderWidgetHostImpl::From(rwh));
165 }
166
167 ///////////////////////////////////////////////////////////////////////////////
168 // RenderViewHostImpl, public:
169
170 // static
FromID(int render_process_id,int render_view_id)171 RenderViewHostImpl* RenderViewHostImpl::FromID(int render_process_id,
172 int render_view_id) {
173 RenderWidgetHost* widget =
174 RenderWidgetHost::FromID(render_process_id, render_view_id);
175 if (!widget || !widget->IsRenderView())
176 return NULL;
177 return static_cast<RenderViewHostImpl*>(RenderWidgetHostImpl::From(widget));
178 }
179
RenderViewHostImpl(SiteInstance * instance,RenderViewHostDelegate * delegate,RenderWidgetHostDelegate * widget_delegate,int routing_id,int main_frame_routing_id,bool swapped_out,bool hidden)180 RenderViewHostImpl::RenderViewHostImpl(
181 SiteInstance* instance,
182 RenderViewHostDelegate* delegate,
183 RenderWidgetHostDelegate* widget_delegate,
184 int routing_id,
185 int main_frame_routing_id,
186 bool swapped_out,
187 bool hidden)
188 : RenderWidgetHostImpl(widget_delegate,
189 instance->GetProcess(),
190 routing_id,
191 hidden),
192 frames_ref_count_(0),
193 delegate_(delegate),
194 instance_(static_cast<SiteInstanceImpl*>(instance)),
195 waiting_for_drag_context_response_(false),
196 enabled_bindings_(0),
197 navigations_suspended_(false),
198 main_frame_routing_id_(main_frame_routing_id),
199 run_modal_reply_msg_(NULL),
200 run_modal_opener_id_(MSG_ROUTING_NONE),
201 is_waiting_for_beforeunload_ack_(false),
202 unload_ack_is_for_cross_site_transition_(false),
203 sudden_termination_allowed_(false),
204 render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING),
205 virtual_keyboard_requested_(false),
206 weak_factory_(this),
207 is_focused_element_editable_(false) {
208 DCHECK(instance_.get());
209 CHECK(delegate_); // http://crbug.com/82827
210
211 GetProcess()->EnableSendQueue();
212
213 if (swapped_out) {
214 rvh_state_ = STATE_SWAPPED_OUT;
215 } else {
216 rvh_state_ = STATE_DEFAULT;
217 instance_->increment_active_view_count();
218 }
219
220 if (ResourceDispatcherHostImpl::Get()) {
221 BrowserThread::PostTask(
222 BrowserThread::IO, FROM_HERE,
223 base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostCreated,
224 base::Unretained(ResourceDispatcherHostImpl::Get()),
225 GetProcess()->GetID(), GetRoutingID()));
226 }
227
228 #if defined(ENABLE_BROWSER_CDMS)
229 media_web_contents_observer_.reset(new MediaWebContentsObserver(this));
230 #endif
231
232 unload_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind(
233 &RenderViewHostImpl::OnSwappedOut, weak_factory_.GetWeakPtr(), true)));
234 }
235
~RenderViewHostImpl()236 RenderViewHostImpl::~RenderViewHostImpl() {
237 if (ResourceDispatcherHostImpl::Get()) {
238 BrowserThread::PostTask(
239 BrowserThread::IO, FROM_HERE,
240 base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostDeleted,
241 base::Unretained(ResourceDispatcherHostImpl::Get()),
242 GetProcess()->GetID(), GetRoutingID()));
243 }
244
245 delegate_->RenderViewDeleted(this);
246
247 // Be sure to clean up any leftover state from cross-site requests.
248 CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest(
249 GetProcess()->GetID(), GetRoutingID(), false);
250
251 // If this was swapped out, it already decremented the active view
252 // count of the SiteInstance it belongs to.
253 if (IsRVHStateActive(rvh_state_))
254 instance_->decrement_active_view_count();
255 }
256
GetDelegate() const257 RenderViewHostDelegate* RenderViewHostImpl::GetDelegate() const {
258 return delegate_;
259 }
260
GetSiteInstance() const261 SiteInstance* RenderViewHostImpl::GetSiteInstance() const {
262 return instance_.get();
263 }
264
CreateRenderView(const base::string16 & frame_name,int opener_route_id,int proxy_route_id,int32 max_page_id,bool window_was_created_with_opener)265 bool RenderViewHostImpl::CreateRenderView(
266 const base::string16& frame_name,
267 int opener_route_id,
268 int proxy_route_id,
269 int32 max_page_id,
270 bool window_was_created_with_opener) {
271 TRACE_EVENT0("renderer_host", "RenderViewHostImpl::CreateRenderView");
272 DCHECK(!IsRenderViewLive()) << "Creating view twice";
273
274 // The process may (if we're sharing a process with another host that already
275 // initialized it) or may not (we have our own process or the old process
276 // crashed) have been initialized. Calling Init multiple times will be
277 // ignored, so this is safe.
278 if (!GetProcess()->Init())
279 return false;
280 DCHECK(GetProcess()->HasConnection());
281 DCHECK(GetProcess()->GetBrowserContext());
282
283 renderer_initialized_ = true;
284
285 GpuSurfaceTracker::Get()->SetSurfaceHandle(
286 surface_id(), GetCompositingSurface());
287
288 // Ensure the RenderView starts with a next_page_id larger than any existing
289 // page ID it might be asked to render.
290 int32 next_page_id = 1;
291 if (max_page_id > -1)
292 next_page_id = max_page_id + 1;
293
294 ViewMsg_New_Params params;
295 params.renderer_preferences =
296 delegate_->GetRendererPrefs(GetProcess()->GetBrowserContext());
297 params.web_preferences = delegate_->GetWebkitPrefs();
298 params.view_id = GetRoutingID();
299 params.main_frame_routing_id = main_frame_routing_id_;
300 params.surface_id = surface_id();
301 params.session_storage_namespace_id =
302 delegate_->GetSessionStorageNamespace(instance_)->id();
303 params.frame_name = frame_name;
304 // Ensure the RenderView sets its opener correctly.
305 params.opener_route_id = opener_route_id;
306 params.swapped_out = !IsRVHStateActive(rvh_state_);
307 params.proxy_routing_id = proxy_route_id;
308 params.hidden = is_hidden();
309 params.never_visible = delegate_->IsNeverVisible();
310 params.window_was_created_with_opener = window_was_created_with_opener;
311 params.next_page_id = next_page_id;
312 GetWebScreenInfo(¶ms.screen_info);
313 params.accessibility_mode = accessibility_mode();
314
315 Send(new ViewMsg_New(params));
316
317 // If it's enabled, tell the renderer to set up the Javascript bindings for
318 // sending messages back to the browser.
319 if (GetProcess()->IsIsolatedGuest())
320 DCHECK_EQ(0, enabled_bindings_);
321 Send(new ViewMsg_AllowBindings(GetRoutingID(), enabled_bindings_));
322 // Let our delegate know that we created a RenderView.
323 delegate_->RenderViewCreated(this);
324
325 return true;
326 }
327
IsRenderViewLive() const328 bool RenderViewHostImpl::IsRenderViewLive() const {
329 return GetProcess()->HasConnection() && renderer_initialized_;
330 }
331
SyncRendererPrefs()332 void RenderViewHostImpl::SyncRendererPrefs() {
333 Send(new ViewMsg_SetRendererPrefs(GetRoutingID(),
334 delegate_->GetRendererPrefs(
335 GetProcess()->GetBrowserContext())));
336 }
337
GetWebkitPrefs(const GURL & url)338 WebPreferences RenderViewHostImpl::GetWebkitPrefs(const GURL& url) {
339 TRACE_EVENT0("browser", "RenderViewHostImpl::GetWebkitPrefs");
340 WebPreferences prefs;
341
342 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
343
344 prefs.javascript_enabled =
345 !command_line.HasSwitch(switches::kDisableJavaScript);
346 prefs.web_security_enabled =
347 !command_line.HasSwitch(switches::kDisableWebSecurity);
348 prefs.plugins_enabled =
349 !command_line.HasSwitch(switches::kDisablePlugins);
350 prefs.java_enabled =
351 !command_line.HasSwitch(switches::kDisableJava);
352
353 prefs.remote_fonts_enabled =
354 !command_line.HasSwitch(switches::kDisableRemoteFonts);
355 prefs.xslt_enabled =
356 !command_line.HasSwitch(switches::kDisableXSLT);
357 prefs.xss_auditor_enabled =
358 !command_line.HasSwitch(switches::kDisableXSSAuditor);
359 prefs.application_cache_enabled =
360 !command_line.HasSwitch(switches::kDisableApplicationCache);
361
362 prefs.local_storage_enabled =
363 !command_line.HasSwitch(switches::kDisableLocalStorage);
364 prefs.databases_enabled =
365 !command_line.HasSwitch(switches::kDisableDatabases);
366 #if defined(OS_ANDROID)
367 // WebAudio is enabled by default on x86 and ARM.
368 prefs.webaudio_enabled =
369 !command_line.HasSwitch(switches::kDisableWebAudio);
370 #endif
371
372 prefs.experimental_webgl_enabled =
373 GpuProcessHost::gpu_enabled() &&
374 !command_line.HasSwitch(switches::kDisable3DAPIs) &&
375 !command_line.HasSwitch(switches::kDisableExperimentalWebGL);
376
377 prefs.pepper_3d_enabled =
378 !command_line.HasSwitch(switches::kDisablePepper3d);
379
380 prefs.flash_3d_enabled =
381 GpuProcessHost::gpu_enabled() &&
382 !command_line.HasSwitch(switches::kDisableFlash3d);
383 prefs.flash_stage3d_enabled =
384 GpuProcessHost::gpu_enabled() &&
385 !command_line.HasSwitch(switches::kDisableFlashStage3d);
386 prefs.flash_stage3d_baseline_enabled =
387 GpuProcessHost::gpu_enabled() &&
388 !command_line.HasSwitch(switches::kDisableFlashStage3d);
389
390 prefs.site_specific_quirks_enabled =
391 !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks);
392 prefs.allow_file_access_from_file_urls =
393 command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
394
395 prefs.layer_squashing_enabled = true;
396 if (command_line.HasSwitch(switches::kEnableLayerSquashing))
397 prefs.layer_squashing_enabled = true;
398 if (command_line.HasSwitch(switches::kDisableLayerSquashing))
399 prefs.layer_squashing_enabled = false;
400
401 prefs.accelerated_2d_canvas_enabled =
402 GpuProcessHost::gpu_enabled() &&
403 !command_line.HasSwitch(switches::kDisableAccelerated2dCanvas);
404 prefs.antialiased_2d_canvas_disabled =
405 command_line.HasSwitch(switches::kDisable2dCanvasAntialiasing);
406 prefs.accelerated_2d_canvas_msaa_sample_count =
407 atoi(command_line.GetSwitchValueASCII(
408 switches::kAcceleratedCanvas2dMSAASampleCount).c_str());
409 prefs.deferred_filters_enabled =
410 !command_line.HasSwitch(switches::kDisableDeferredFilters);
411 prefs.container_culling_enabled =
412 command_line.HasSwitch(switches::kEnableContainerCulling);
413 prefs.region_based_columns_enabled =
414 command_line.HasSwitch(switches::kEnableRegionBasedColumns);
415
416 if (IsPinchVirtualViewportEnabled()) {
417 prefs.pinch_virtual_viewport_enabled = true;
418 prefs.pinch_overlay_scrollbar_thickness = 10;
419 }
420 prefs.use_solid_color_scrollbars = ui::IsOverlayScrollbarEnabled();
421
422 #if defined(OS_ANDROID)
423 prefs.user_gesture_required_for_media_playback = !command_line.HasSwitch(
424 switches::kDisableGestureRequirementForMediaPlayback);
425 #endif
426
427 prefs.touch_enabled = ui::AreTouchEventsEnabled();
428 prefs.device_supports_touch = prefs.touch_enabled &&
429 ui::IsTouchDevicePresent();
430 #if defined(OS_ANDROID)
431 prefs.device_supports_mouse = false;
432 #endif
433
434 prefs.pointer_events_max_touch_points = ui::MaxTouchPoints();
435
436 prefs.touch_adjustment_enabled =
437 !command_line.HasSwitch(switches::kDisableTouchAdjustment);
438 prefs.compositor_touch_hit_testing =
439 !command_line.HasSwitch(cc::switches::kDisableCompositorTouchHitTesting);
440
441 #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
442 bool default_enable_scroll_animator = true;
443 #else
444 bool default_enable_scroll_animator = false;
445 #endif
446 prefs.enable_scroll_animator = default_enable_scroll_animator;
447 if (command_line.HasSwitch(switches::kEnableSmoothScrolling))
448 prefs.enable_scroll_animator = true;
449 if (command_line.HasSwitch(switches::kDisableSmoothScrolling))
450 prefs.enable_scroll_animator = false;
451
452 // Certain GPU features might have been blacklisted.
453 GpuDataManagerImpl::GetInstance()->UpdateRendererWebPrefs(&prefs);
454
455 if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
456 GetProcess()->GetID())) {
457 prefs.loads_images_automatically = true;
458 prefs.javascript_enabled = true;
459 }
460
461 prefs.connection_type = net::NetworkChangeNotifier::GetConnectionType();
462 prefs.is_online =
463 prefs.connection_type != net::NetworkChangeNotifier::CONNECTION_NONE;
464
465 prefs.gesture_tap_highlight_enabled = !command_line.HasSwitch(
466 switches::kDisableGestureTapHighlight);
467
468 prefs.number_of_cpu_cores = base::SysInfo::NumberOfProcessors();
469
470 prefs.viewport_meta_enabled =
471 command_line.HasSwitch(switches::kEnableViewportMeta);
472
473 prefs.viewport_enabled =
474 command_line.HasSwitch(switches::kEnableViewport) ||
475 prefs.viewport_meta_enabled;
476
477 prefs.main_frame_resizes_are_orientation_changes =
478 command_line.HasSwitch(switches::kMainFrameResizesAreOrientationChanges);
479
480 prefs.deferred_image_decoding_enabled =
481 command_line.HasSwitch(switches::kEnableDeferredImageDecoding) ||
482 content::IsImplSidePaintingEnabled();
483
484 prefs.spatial_navigation_enabled = command_line.HasSwitch(
485 switches::kEnableSpatialNavigation);
486
487 GetContentClient()->browser()->OverrideWebkitPrefs(this, url, &prefs);
488 return prefs;
489 }
490
Navigate(const FrameMsg_Navigate_Params & params)491 void RenderViewHostImpl::Navigate(const FrameMsg_Navigate_Params& params) {
492 TRACE_EVENT0("renderer_host", "RenderViewHostImpl::Navigate");
493 delegate_->GetFrameTree()->GetMainFrame()->Navigate(params);
494 }
495
NavigateToURL(const GURL & url)496 void RenderViewHostImpl::NavigateToURL(const GURL& url) {
497 delegate_->GetFrameTree()->GetMainFrame()->NavigateToURL(url);
498 }
499
SetNavigationsSuspended(bool suspend,const base::TimeTicks & proceed_time)500 void RenderViewHostImpl::SetNavigationsSuspended(
501 bool suspend,
502 const base::TimeTicks& proceed_time) {
503 // This should only be called to toggle the state.
504 DCHECK(navigations_suspended_ != suspend);
505
506 navigations_suspended_ = suspend;
507 if (!suspend && suspended_nav_params_) {
508 // There's navigation message params waiting to be sent. Now that we're not
509 // suspended anymore, resume navigation by sending them. If we were swapped
510 // out, we should also stop filtering out the IPC messages now.
511 SetState(STATE_DEFAULT);
512
513 DCHECK(!proceed_time.is_null());
514 suspended_nav_params_->browser_navigation_start = proceed_time;
515 Send(new FrameMsg_Navigate(
516 main_frame_routing_id_, *suspended_nav_params_.get()));
517 suspended_nav_params_.reset();
518 }
519 }
520
CancelSuspendedNavigations()521 void RenderViewHostImpl::CancelSuspendedNavigations() {
522 // Clear any state if a pending navigation is canceled or pre-empted.
523 if (suspended_nav_params_)
524 suspended_nav_params_.reset();
525 navigations_suspended_ = false;
526 }
527
SuppressDialogsUntilSwapOut()528 void RenderViewHostImpl::SuppressDialogsUntilSwapOut() {
529 Send(new ViewMsg_SuppressDialogsUntilSwapOut(GetRoutingID()));
530 }
531
OnSwappedOut(bool timed_out)532 void RenderViewHostImpl::OnSwappedOut(bool timed_out) {
533 // Ignore spurious swap out ack.
534 if (!IsWaitingForUnloadACK())
535 return;
536 unload_event_monitor_timeout_->Stop();
537 if (timed_out) {
538 base::ProcessHandle process_handle = GetProcess()->GetHandle();
539 int views = 0;
540
541 // Count the number of active widget hosts for the process, which
542 // is equivalent to views using the process as of this writing.
543 scoped_ptr<RenderWidgetHostIterator> widgets(
544 RenderWidgetHost::GetRenderWidgetHosts());
545 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
546 if (widget->GetProcess()->GetID() == GetProcess()->GetID())
547 ++views;
548 }
549
550 if (!RenderProcessHost::run_renderer_in_process() &&
551 process_handle && views <= 1) {
552 // The process can safely be terminated, only if WebContents sets
553 // SuddenTerminationAllowed, which indicates that the timer has expired.
554 // This is not the case if we load data URLs or about:blank. The reason
555 // is that those have no network requests and this code is hit without
556 // setting the unresponsiveness timer. This allows a corner case where a
557 // navigation to a data URL will leave a process running, if the
558 // beforeunload handler completes fine, but the unload handler hangs.
559 // At this time, the complexity to solve this edge case is not worthwhile.
560 if (SuddenTerminationAllowed()) {
561 // We should kill the process, but for now, just log the data so we can
562 // diagnose the kill rate and investigate if separate timer is needed.
563 // http://crbug.com/104346.
564
565 // Log a histogram point to help us diagnose how many of those kills
566 // we have performed. 1 is the enum value for RendererType Normal for
567 // the histogram.
568 UMA_HISTOGRAM_PERCENTAGE(
569 "BrowserRenderProcessHost.ChildKillsUnresponsive", 1);
570 }
571 }
572 }
573
574 switch (rvh_state_) {
575 case STATE_WAITING_FOR_UNLOAD_ACK:
576 SetState(STATE_WAITING_FOR_COMMIT);
577 break;
578 case STATE_PENDING_SWAP_OUT:
579 SetState(STATE_SWAPPED_OUT);
580 break;
581 case STATE_PENDING_SHUTDOWN:
582 DCHECK(!pending_shutdown_on_swap_out_.is_null());
583 pending_shutdown_on_swap_out_.Run();
584 break;
585 default:
586 NOTREACHED();
587 }
588 }
589
WasSwappedOut(const base::Closure & pending_delete_on_swap_out)590 void RenderViewHostImpl::WasSwappedOut(
591 const base::Closure& pending_delete_on_swap_out) {
592 Send(new ViewMsg_WasSwappedOut(GetRoutingID()));
593 if (rvh_state_ == STATE_WAITING_FOR_UNLOAD_ACK) {
594 SetState(STATE_PENDING_SWAP_OUT);
595 if (!instance_->active_view_count())
596 SetPendingShutdown(pending_delete_on_swap_out);
597 } else if (rvh_state_ == STATE_WAITING_FOR_COMMIT) {
598 SetState(STATE_SWAPPED_OUT);
599 } else if (rvh_state_ == STATE_DEFAULT) {
600 // When the RenderView is not live, the RenderFrameHostManager will call
601 // CommitPending directly, without calling SwapOut on the old RVH. This will
602 // cause WasSwappedOut to be called directly on the live old RVH.
603 DCHECK(!IsRenderViewLive());
604 SetState(STATE_SWAPPED_OUT);
605 } else {
606 NOTREACHED();
607 }
608 }
609
SetPendingShutdown(const base::Closure & on_swap_out)610 void RenderViewHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) {
611 pending_shutdown_on_swap_out_ = on_swap_out;
612 SetState(STATE_PENDING_SHUTDOWN);
613 }
614
ClosePage()615 void RenderViewHostImpl::ClosePage() {
616 SetState(STATE_WAITING_FOR_CLOSE);
617 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
618
619 if (IsRenderViewLive()) {
620 // Since we are sending an IPC message to the renderer, increase the event
621 // count to prevent the hang monitor timeout from being stopped by input
622 // event acknowledgements.
623 increment_in_flight_event_count();
624
625 // TODO(creis): Should this be moved to Shutdown? It may not be called for
626 // RenderViewHosts that have been swapped out.
627 NotificationService::current()->Notify(
628 NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW,
629 Source<RenderViewHost>(this),
630 NotificationService::NoDetails());
631
632 Send(new ViewMsg_ClosePage(GetRoutingID()));
633 } else {
634 // This RenderViewHost doesn't have a live renderer, so just skip the unload
635 // event and close the page.
636 ClosePageIgnoringUnloadEvents();
637 }
638 }
639
ClosePageIgnoringUnloadEvents()640 void RenderViewHostImpl::ClosePageIgnoringUnloadEvents() {
641 StopHangMonitorTimeout();
642 is_waiting_for_beforeunload_ack_ = false;
643
644 sudden_termination_allowed_ = true;
645 delegate_->Close(this);
646 }
647
HasPendingCrossSiteRequest()648 bool RenderViewHostImpl::HasPendingCrossSiteRequest() {
649 return CrossSiteRequestManager::GetInstance()->HasPendingCrossSiteRequest(
650 GetProcess()->GetID(), GetRoutingID());
651 }
652
SetHasPendingCrossSiteRequest(bool has_pending_request)653 void RenderViewHostImpl::SetHasPendingCrossSiteRequest(
654 bool has_pending_request) {
655 CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest(
656 GetProcess()->GetID(), GetRoutingID(), has_pending_request);
657 }
658
SetWebUIHandle(mojo::ScopedMessagePipeHandle handle)659 void RenderViewHostImpl::SetWebUIHandle(mojo::ScopedMessagePipeHandle handle) {
660 // Never grant any bindings to browser plugin guests.
661 if (GetProcess()->IsIsolatedGuest()) {
662 NOTREACHED() << "Never grant bindings to a guest process.";
663 return;
664 }
665
666 if ((enabled_bindings_ & BINDINGS_POLICY_WEB_UI) == 0) {
667 NOTREACHED() << "You must grant bindings before setting the handle";
668 return;
669 }
670
671 DCHECK(renderer_initialized_);
672
673 WebUISetupPtr web_ui_setup;
674 static_cast<RenderProcessHostImpl*>(GetProcess())->ConnectTo(
675 kRendererService_WebUISetup, &web_ui_setup);
676
677 web_ui_setup->SetWebUIHandle(GetRoutingID(), handle.Pass());
678 }
679
680 #if defined(OS_ANDROID)
ActivateNearestFindResult(int request_id,float x,float y)681 void RenderViewHostImpl::ActivateNearestFindResult(int request_id,
682 float x,
683 float y) {
684 Send(new InputMsg_ActivateNearestFindResult(GetRoutingID(),
685 request_id, x, y));
686 }
687
RequestFindMatchRects(int current_version)688 void RenderViewHostImpl::RequestFindMatchRects(int current_version) {
689 Send(new ViewMsg_FindMatchRects(GetRoutingID(), current_version));
690 }
691 #endif
692
DragTargetDragEnter(const DropData & drop_data,const gfx::Point & client_pt,const gfx::Point & screen_pt,WebDragOperationsMask operations_allowed,int key_modifiers)693 void RenderViewHostImpl::DragTargetDragEnter(
694 const DropData& drop_data,
695 const gfx::Point& client_pt,
696 const gfx::Point& screen_pt,
697 WebDragOperationsMask operations_allowed,
698 int key_modifiers) {
699 const int renderer_id = GetProcess()->GetID();
700 ChildProcessSecurityPolicyImpl* policy =
701 ChildProcessSecurityPolicyImpl::GetInstance();
702
703 // The URL could have been cobbled together from any highlighted text string,
704 // and can't be interpreted as a capability.
705 DropData filtered_data(drop_data);
706 GetProcess()->FilterURL(true, &filtered_data.url);
707 if (drop_data.did_originate_from_renderer) {
708 filtered_data.filenames.clear();
709 }
710
711 // The filenames vector, on the other hand, does represent a capability to
712 // access the given files.
713 fileapi::IsolatedContext::FileInfoSet files;
714 for (std::vector<ui::FileInfo>::iterator iter(
715 filtered_data.filenames.begin());
716 iter != filtered_data.filenames.end();
717 ++iter) {
718 // A dragged file may wind up as the value of an input element, or it
719 // may be used as the target of a navigation instead. We don't know
720 // which will happen at this point, so generously grant both access
721 // and request permissions to the specific file to cover both cases.
722 // We do not give it the permission to request all file:// URLs.
723
724 // Make sure we have the same display_name as the one we register.
725 if (iter->display_name.empty()) {
726 std::string name;
727 files.AddPath(iter->path, &name);
728 iter->display_name = base::FilePath::FromUTF8Unsafe(name);
729 } else {
730 files.AddPathWithName(iter->path, iter->display_name.AsUTF8Unsafe());
731 }
732
733 policy->GrantRequestSpecificFileURL(renderer_id,
734 net::FilePathToFileURL(iter->path));
735
736 // If the renderer already has permission to read these paths, we don't need
737 // to re-grant them. This prevents problems with DnD for files in the CrOS
738 // file manager--the file manager already had read/write access to those
739 // directories, but dragging a file would cause the read/write access to be
740 // overwritten with read-only access, making them impossible to delete or
741 // rename until the renderer was killed.
742 if (!policy->CanReadFile(renderer_id, iter->path))
743 policy->GrantReadFile(renderer_id, iter->path);
744 }
745
746 fileapi::IsolatedContext* isolated_context =
747 fileapi::IsolatedContext::GetInstance();
748 DCHECK(isolated_context);
749 std::string filesystem_id = isolated_context->RegisterDraggedFileSystem(
750 files);
751 if (!filesystem_id.empty()) {
752 // Grant the permission iff the ID is valid.
753 policy->GrantReadFileSystem(renderer_id, filesystem_id);
754 }
755 filtered_data.filesystem_id = base::UTF8ToUTF16(filesystem_id);
756
757 fileapi::FileSystemContext* file_system_context =
758 BrowserContext::GetStoragePartition(
759 GetProcess()->GetBrowserContext(),
760 GetSiteInstance())->GetFileSystemContext();
761 for (size_t i = 0; i < filtered_data.file_system_files.size(); ++i) {
762 fileapi::FileSystemURL file_system_url =
763 file_system_context->CrackURL(filtered_data.file_system_files[i].url);
764
765 std::string register_name;
766 std::string filesystem_id = isolated_context->RegisterFileSystemForPath(
767 file_system_url.type(), file_system_url.filesystem_id(),
768 file_system_url.path(), ®ister_name);
769 policy->GrantReadFileSystem(renderer_id, filesystem_id);
770
771 // Note: We are using the origin URL provided by the sender here. It may be
772 // different from the receiver's.
773 filtered_data.file_system_files[i].url = GURL(
774 fileapi::GetIsolatedFileSystemRootURIString(
775 file_system_url.origin(),
776 filesystem_id,
777 std::string()).append(register_name));
778 }
779
780 Send(new DragMsg_TargetDragEnter(GetRoutingID(), filtered_data, client_pt,
781 screen_pt, operations_allowed,
782 key_modifiers));
783 }
784
DragTargetDragOver(const gfx::Point & client_pt,const gfx::Point & screen_pt,WebDragOperationsMask operations_allowed,int key_modifiers)785 void RenderViewHostImpl::DragTargetDragOver(
786 const gfx::Point& client_pt,
787 const gfx::Point& screen_pt,
788 WebDragOperationsMask operations_allowed,
789 int key_modifiers) {
790 Send(new DragMsg_TargetDragOver(GetRoutingID(), client_pt, screen_pt,
791 operations_allowed, key_modifiers));
792 }
793
DragTargetDragLeave()794 void RenderViewHostImpl::DragTargetDragLeave() {
795 Send(new DragMsg_TargetDragLeave(GetRoutingID()));
796 }
797
DragTargetDrop(const gfx::Point & client_pt,const gfx::Point & screen_pt,int key_modifiers)798 void RenderViewHostImpl::DragTargetDrop(
799 const gfx::Point& client_pt,
800 const gfx::Point& screen_pt,
801 int key_modifiers) {
802 Send(new DragMsg_TargetDrop(GetRoutingID(), client_pt, screen_pt,
803 key_modifiers));
804 }
805
DragSourceEndedAt(int client_x,int client_y,int screen_x,int screen_y,WebDragOperation operation)806 void RenderViewHostImpl::DragSourceEndedAt(
807 int client_x, int client_y, int screen_x, int screen_y,
808 WebDragOperation operation) {
809 Send(new DragMsg_SourceEnded(GetRoutingID(),
810 gfx::Point(client_x, client_y),
811 gfx::Point(screen_x, screen_y),
812 operation));
813 }
814
DragSourceSystemDragEnded()815 void RenderViewHostImpl::DragSourceSystemDragEnded() {
816 Send(new DragMsg_SourceSystemDragEnded(GetRoutingID()));
817 }
818
GetMainFrame()819 RenderFrameHost* RenderViewHostImpl::GetMainFrame() {
820 return RenderFrameHost::FromID(GetProcess()->GetID(), main_frame_routing_id_);
821 }
822
AllowBindings(int bindings_flags)823 void RenderViewHostImpl::AllowBindings(int bindings_flags) {
824 // Never grant any bindings to browser plugin guests.
825 if (GetProcess()->IsIsolatedGuest()) {
826 NOTREACHED() << "Never grant bindings to a guest process.";
827 return;
828 }
829
830 // Ensure we aren't granting WebUI bindings to a process that has already
831 // been used for non-privileged views.
832 if (bindings_flags & BINDINGS_POLICY_WEB_UI &&
833 GetProcess()->HasConnection() &&
834 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
835 GetProcess()->GetID())) {
836 // This process has no bindings yet. Make sure it does not have more
837 // than this single active view.
838 RenderProcessHostImpl* process =
839 static_cast<RenderProcessHostImpl*>(GetProcess());
840 // --single-process only has one renderer.
841 if (process->GetActiveViewCount() > 1 &&
842 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
843 return;
844 }
845
846 if (bindings_flags & BINDINGS_POLICY_WEB_UI) {
847 ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
848 GetProcess()->GetID());
849 }
850
851 enabled_bindings_ |= bindings_flags;
852 if (renderer_initialized_)
853 Send(new ViewMsg_AllowBindings(GetRoutingID(), enabled_bindings_));
854 }
855
GetEnabledBindings() const856 int RenderViewHostImpl::GetEnabledBindings() const {
857 return enabled_bindings_;
858 }
859
SetWebUIProperty(const std::string & name,const std::string & value)860 void RenderViewHostImpl::SetWebUIProperty(const std::string& name,
861 const std::string& value) {
862 // This is a sanity check before telling the renderer to enable the property.
863 // It could lie and send the corresponding IPC messages anyway, but we will
864 // not act on them if enabled_bindings_ doesn't agree. If we get here without
865 // WebUI bindings, kill the renderer process.
866 if (enabled_bindings_ & BINDINGS_POLICY_WEB_UI) {
867 Send(new ViewMsg_SetWebUIProperty(GetRoutingID(), name, value));
868 } else {
869 RecordAction(
870 base::UserMetricsAction("BindingsMismatchTerminate_RVH_WebUI"));
871 base::KillProcess(
872 GetProcess()->GetHandle(), content::RESULT_CODE_KILLED, false);
873 }
874 }
875
GotFocus()876 void RenderViewHostImpl::GotFocus() {
877 RenderWidgetHostImpl::GotFocus(); // Notifies the renderer it got focus.
878
879 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
880 if (view)
881 view->GotFocus();
882 }
883
LostCapture()884 void RenderViewHostImpl::LostCapture() {
885 RenderWidgetHostImpl::LostCapture();
886 delegate_->LostCapture();
887 }
888
LostMouseLock()889 void RenderViewHostImpl::LostMouseLock() {
890 RenderWidgetHostImpl::LostMouseLock();
891 delegate_->LostMouseLock();
892 }
893
SetInitialFocus(bool reverse)894 void RenderViewHostImpl::SetInitialFocus(bool reverse) {
895 Send(new ViewMsg_SetInitialFocus(GetRoutingID(), reverse));
896 }
897
FilesSelectedInChooser(const std::vector<ui::SelectedFileInfo> & files,FileChooserParams::Mode permissions)898 void RenderViewHostImpl::FilesSelectedInChooser(
899 const std::vector<ui::SelectedFileInfo>& files,
900 FileChooserParams::Mode permissions) {
901 // Grant the security access requested to the given files.
902 for (size_t i = 0; i < files.size(); ++i) {
903 const ui::SelectedFileInfo& file = files[i];
904 if (permissions == FileChooserParams::Save) {
905 ChildProcessSecurityPolicyImpl::GetInstance()->GrantCreateReadWriteFile(
906 GetProcess()->GetID(), file.local_path);
907 } else {
908 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
909 GetProcess()->GetID(), file.local_path);
910 }
911 }
912 Send(new ViewMsg_RunFileChooserResponse(GetRoutingID(), files));
913 }
914
DirectoryEnumerationFinished(int request_id,const std::vector<base::FilePath> & files)915 void RenderViewHostImpl::DirectoryEnumerationFinished(
916 int request_id,
917 const std::vector<base::FilePath>& files) {
918 // Grant the security access requested to the given files.
919 for (std::vector<base::FilePath>::const_iterator file = files.begin();
920 file != files.end(); ++file) {
921 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
922 GetProcess()->GetID(), *file);
923 }
924 Send(new ViewMsg_EnumerateDirectoryResponse(GetRoutingID(),
925 request_id,
926 files));
927 }
928
LoadStateChanged(const GURL & url,const net::LoadStateWithParam & load_state,uint64 upload_position,uint64 upload_size)929 void RenderViewHostImpl::LoadStateChanged(
930 const GURL& url,
931 const net::LoadStateWithParam& load_state,
932 uint64 upload_position,
933 uint64 upload_size) {
934 delegate_->LoadStateChanged(url, load_state, upload_position, upload_size);
935 }
936
SuddenTerminationAllowed() const937 bool RenderViewHostImpl::SuddenTerminationAllowed() const {
938 return sudden_termination_allowed_ ||
939 GetProcess()->SuddenTerminationAllowed();
940 }
941
942 ///////////////////////////////////////////////////////////////////////////////
943 // RenderViewHostImpl, IPC message handlers:
944
OnMessageReceived(const IPC::Message & msg)945 bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
946 if (!BrowserMessageFilter::CheckCanDispatchOnUI(msg, this))
947 return true;
948
949 // Filter out most IPC messages if this renderer is swapped out.
950 // We still want to handle certain ACKs to keep our state consistent.
951 if (IsSwappedOut()) {
952 if (!SwappedOutMessages::CanHandleWhileSwappedOut(msg)) {
953 // If this is a synchronous message and we decided not to handle it,
954 // we must send an error reply, or else the renderer will be stuck
955 // and won't respond to future requests.
956 if (msg.is_sync()) {
957 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
958 reply->set_reply_error();
959 Send(reply);
960 }
961 // Don't continue looking for someone to handle it.
962 return true;
963 }
964 }
965
966 if (delegate_->OnMessageReceived(this, msg))
967 return true;
968
969 bool handled = true;
970 IPC_BEGIN_MESSAGE_MAP(RenderViewHostImpl, msg)
971 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowView, OnShowView)
972 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
973 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget,
974 OnShowFullscreenWidget)
975 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunModal, OnRunModal)
976 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady)
977 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderProcessGone, OnRenderProcessGone)
978 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateState, OnUpdateState)
979 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL)
980 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateInspectorSetting,
981 OnUpdateInspectorSetting)
982 IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
983 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
984 IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentAvailableInMainFrame,
985 OnDocumentAvailableInMainFrame)
986 IPC_MESSAGE_HANDLER(ViewHostMsg_ToggleFullscreen, OnToggleFullscreen)
987 IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange,
988 OnDidContentsPreferredSizeChange)
989 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeScrollOffset,
990 OnDidChangeScrollOffset)
991 IPC_MESSAGE_HANDLER(ViewHostMsg_RouteCloseEvent,
992 OnRouteCloseEvent)
993 IPC_MESSAGE_HANDLER(ViewHostMsg_RouteMessageEvent, OnRouteMessageEvent)
994 IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging)
995 IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor)
996 IPC_MESSAGE_HANDLER(DragHostMsg_TargetDrop_ACK, OnTargetDropACK)
997 IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
998 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnFocusedNodeChanged)
999 IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK)
1000 IPC_MESSAGE_HANDLER(ViewHostMsg_DidZoomURL, OnDidZoomURL)
1001 #if defined(OS_MACOSX) || defined(OS_ANDROID)
1002 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnShowPopup)
1003 IPC_MESSAGE_HANDLER(ViewHostMsg_HidePopup, OnHidePopup)
1004 #endif
1005 IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser)
1006 IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Events, OnAccessibilityEvents)
1007 IPC_MESSAGE_HANDLER(AccessibilityHostMsg_LocationChanges,
1008 OnAccessibilityLocationChanges)
1009 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched)
1010 // Have the super handle all other messages.
1011 IPC_MESSAGE_UNHANDLED(
1012 handled = RenderWidgetHostImpl::OnMessageReceived(msg))
1013 IPC_END_MESSAGE_MAP()
1014
1015 return handled;
1016 }
1017
Init()1018 void RenderViewHostImpl::Init() {
1019 RenderWidgetHostImpl::Init();
1020 }
1021
Shutdown()1022 void RenderViewHostImpl::Shutdown() {
1023 // If we are being run modally (see RunModal), then we need to cleanup.
1024 if (run_modal_reply_msg_) {
1025 Send(run_modal_reply_msg_);
1026 run_modal_reply_msg_ = NULL;
1027 RenderViewHostImpl* opener =
1028 RenderViewHostImpl::FromID(GetProcess()->GetID(), run_modal_opener_id_);
1029 if (opener) {
1030 opener->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(
1031 hung_renderer_delay_ms_));
1032 // Balance out the decrement when we got created.
1033 opener->increment_in_flight_event_count();
1034 }
1035 run_modal_opener_id_ = MSG_ROUTING_NONE;
1036 }
1037
1038 // We can't release the SessionStorageNamespace until our peer
1039 // in the renderer has wound down.
1040 if (GetProcess()->HasConnection()) {
1041 RenderProcessHostImpl::ReleaseOnCloseACK(
1042 GetProcess(),
1043 delegate_->GetSessionStorageNamespaceMap(),
1044 GetRoutingID());
1045 }
1046
1047 RenderWidgetHostImpl::Shutdown();
1048 }
1049
IsRenderView() const1050 bool RenderViewHostImpl::IsRenderView() const {
1051 return true;
1052 }
1053
CreateNewWindow(int route_id,int main_frame_route_id,const ViewHostMsg_CreateWindow_Params & params,SessionStorageNamespace * session_storage_namespace)1054 void RenderViewHostImpl::CreateNewWindow(
1055 int route_id,
1056 int main_frame_route_id,
1057 const ViewHostMsg_CreateWindow_Params& params,
1058 SessionStorageNamespace* session_storage_namespace) {
1059 ViewHostMsg_CreateWindow_Params validated_params(params);
1060 GetProcess()->FilterURL(false, &validated_params.target_url);
1061 GetProcess()->FilterURL(false, &validated_params.opener_url);
1062 GetProcess()->FilterURL(true, &validated_params.opener_security_origin);
1063
1064 delegate_->CreateNewWindow(
1065 GetProcess()->GetID(), route_id, main_frame_route_id, validated_params,
1066 session_storage_namespace);
1067 }
1068
CreateNewWidget(int route_id,blink::WebPopupType popup_type)1069 void RenderViewHostImpl::CreateNewWidget(int route_id,
1070 blink::WebPopupType popup_type) {
1071 delegate_->CreateNewWidget(GetProcess()->GetID(), route_id, popup_type);
1072 }
1073
CreateNewFullscreenWidget(int route_id)1074 void RenderViewHostImpl::CreateNewFullscreenWidget(int route_id) {
1075 delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), route_id);
1076 }
1077
OnShowView(int route_id,WindowOpenDisposition disposition,const gfx::Rect & initial_pos,bool user_gesture)1078 void RenderViewHostImpl::OnShowView(int route_id,
1079 WindowOpenDisposition disposition,
1080 const gfx::Rect& initial_pos,
1081 bool user_gesture) {
1082 if (IsRVHStateActive(rvh_state_)) {
1083 delegate_->ShowCreatedWindow(
1084 route_id, disposition, initial_pos, user_gesture);
1085 }
1086 Send(new ViewMsg_Move_ACK(route_id));
1087 }
1088
OnShowWidget(int route_id,const gfx::Rect & initial_pos)1089 void RenderViewHostImpl::OnShowWidget(int route_id,
1090 const gfx::Rect& initial_pos) {
1091 if (IsRVHStateActive(rvh_state_))
1092 delegate_->ShowCreatedWidget(route_id, initial_pos);
1093 Send(new ViewMsg_Move_ACK(route_id));
1094 }
1095
OnShowFullscreenWidget(int route_id)1096 void RenderViewHostImpl::OnShowFullscreenWidget(int route_id) {
1097 if (IsRVHStateActive(rvh_state_))
1098 delegate_->ShowCreatedFullscreenWidget(route_id);
1099 Send(new ViewMsg_Move_ACK(route_id));
1100 }
1101
OnRunModal(int opener_id,IPC::Message * reply_msg)1102 void RenderViewHostImpl::OnRunModal(int opener_id, IPC::Message* reply_msg) {
1103 DCHECK(!run_modal_reply_msg_);
1104 run_modal_reply_msg_ = reply_msg;
1105 run_modal_opener_id_ = opener_id;
1106
1107 RecordAction(base::UserMetricsAction("ShowModalDialog"));
1108
1109 RenderViewHostImpl* opener =
1110 RenderViewHostImpl::FromID(GetProcess()->GetID(), run_modal_opener_id_);
1111 if (opener) {
1112 opener->StopHangMonitorTimeout();
1113 // The ack for the mouse down won't come until the dialog closes, so fake it
1114 // so that we don't get a timeout.
1115 opener->decrement_in_flight_event_count();
1116 }
1117
1118 // TODO(darin): Bug 1107929: Need to inform our delegate to show this view in
1119 // an app-modal fashion.
1120 }
1121
OnRenderViewReady()1122 void RenderViewHostImpl::OnRenderViewReady() {
1123 render_view_termination_status_ = base::TERMINATION_STATUS_STILL_RUNNING;
1124 SendScreenRects();
1125 WasResized();
1126 delegate_->RenderViewReady(this);
1127 }
1128
OnRenderProcessGone(int status,int exit_code)1129 void RenderViewHostImpl::OnRenderProcessGone(int status, int exit_code) {
1130 // Keep the termination status so we can get at it later when we
1131 // need to know why it died.
1132 render_view_termination_status_ =
1133 static_cast<base::TerminationStatus>(status);
1134
1135 // Reset frame tree state associated with this process. This must happen
1136 // before RenderViewTerminated because observers expect the subframes of any
1137 // affected frames to be cleared first.
1138 delegate_->GetFrameTree()->RenderProcessGone(this);
1139
1140 // Our base class RenderWidgetHost needs to reset some stuff.
1141 RendererExited(render_view_termination_status_, exit_code);
1142
1143 delegate_->RenderViewTerminated(this,
1144 static_cast<base::TerminationStatus>(status),
1145 exit_code);
1146 }
1147
OnUpdateState(int32 page_id,const PageState & state)1148 void RenderViewHostImpl::OnUpdateState(int32 page_id, const PageState& state) {
1149 // Without this check, the renderer can trick the browser into using
1150 // filenames it can't access in a future session restore.
1151 if (!CanAccessFilesOfPageState(state)) {
1152 GetProcess()->ReceivedBadMessage();
1153 return;
1154 }
1155
1156 delegate_->UpdateState(this, page_id, state);
1157 }
1158
OnUpdateTargetURL(int32 page_id,const GURL & url)1159 void RenderViewHostImpl::OnUpdateTargetURL(int32 page_id, const GURL& url) {
1160 if (IsRVHStateActive(rvh_state_))
1161 delegate_->UpdateTargetURL(page_id, url);
1162
1163 // Send a notification back to the renderer that we are ready to
1164 // receive more target urls.
1165 Send(new ViewMsg_UpdateTargetURL_ACK(GetRoutingID()));
1166 }
1167
OnUpdateInspectorSetting(const std::string & key,const std::string & value)1168 void RenderViewHostImpl::OnUpdateInspectorSetting(
1169 const std::string& key, const std::string& value) {
1170 GetContentClient()->browser()->UpdateInspectorSetting(
1171 this, key, value);
1172 }
1173
OnClose()1174 void RenderViewHostImpl::OnClose() {
1175 // If the renderer is telling us to close, it has already run the unload
1176 // events, and we can take the fast path.
1177 ClosePageIgnoringUnloadEvents();
1178 }
1179
OnRequestMove(const gfx::Rect & pos)1180 void RenderViewHostImpl::OnRequestMove(const gfx::Rect& pos) {
1181 if (IsRVHStateActive(rvh_state_))
1182 delegate_->RequestMove(pos);
1183 Send(new ViewMsg_Move_ACK(GetRoutingID()));
1184 }
1185
OnDocumentAvailableInMainFrame(bool uses_temporary_zoom_level)1186 void RenderViewHostImpl::OnDocumentAvailableInMainFrame(
1187 bool uses_temporary_zoom_level) {
1188 delegate_->DocumentAvailableInMainFrame(this);
1189
1190 if (!uses_temporary_zoom_level)
1191 return;
1192
1193 HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
1194 HostZoomMap::GetForBrowserContext(GetProcess()->GetBrowserContext()));
1195 host_zoom_map->SetTemporaryZoomLevel(GetProcess()->GetID(),
1196 GetRoutingID(),
1197 host_zoom_map->GetDefaultZoomLevel());
1198 }
1199
OnToggleFullscreen(bool enter_fullscreen)1200 void RenderViewHostImpl::OnToggleFullscreen(bool enter_fullscreen) {
1201 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1202 delegate_->ToggleFullscreenMode(enter_fullscreen);
1203 // We need to notify the contents that its fullscreen state has changed. This
1204 // is done as part of the resize message.
1205 WasResized();
1206 }
1207
OnDidContentsPreferredSizeChange(const gfx::Size & new_size)1208 void RenderViewHostImpl::OnDidContentsPreferredSizeChange(
1209 const gfx::Size& new_size) {
1210 delegate_->UpdatePreferredSize(new_size);
1211 }
1212
OnRenderAutoResized(const gfx::Size & new_size)1213 void RenderViewHostImpl::OnRenderAutoResized(const gfx::Size& new_size) {
1214 delegate_->ResizeDueToAutoResize(new_size);
1215 }
1216
OnDidChangeScrollOffset()1217 void RenderViewHostImpl::OnDidChangeScrollOffset() {
1218 if (view_)
1219 view_->ScrollOffsetChanged();
1220 }
1221
OnRouteCloseEvent()1222 void RenderViewHostImpl::OnRouteCloseEvent() {
1223 // Have the delegate route this to the active RenderViewHost.
1224 delegate_->RouteCloseEvent(this);
1225 }
1226
OnRouteMessageEvent(const ViewMsg_PostMessage_Params & params)1227 void RenderViewHostImpl::OnRouteMessageEvent(
1228 const ViewMsg_PostMessage_Params& params) {
1229 // Give to the delegate to route to the active RenderViewHost.
1230 delegate_->RouteMessageEvent(this, params);
1231 }
1232
OnStartDragging(const DropData & drop_data,WebDragOperationsMask drag_operations_mask,const SkBitmap & bitmap,const gfx::Vector2d & bitmap_offset_in_dip,const DragEventSourceInfo & event_info)1233 void RenderViewHostImpl::OnStartDragging(
1234 const DropData& drop_data,
1235 WebDragOperationsMask drag_operations_mask,
1236 const SkBitmap& bitmap,
1237 const gfx::Vector2d& bitmap_offset_in_dip,
1238 const DragEventSourceInfo& event_info) {
1239 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1240 if (!view)
1241 return;
1242
1243 DropData filtered_data(drop_data);
1244 RenderProcessHost* process = GetProcess();
1245 ChildProcessSecurityPolicyImpl* policy =
1246 ChildProcessSecurityPolicyImpl::GetInstance();
1247
1248 // Allow drag of Javascript URLs to enable bookmarklet drag to bookmark bar.
1249 if (!filtered_data.url.SchemeIs(url::kJavaScriptScheme))
1250 process->FilterURL(true, &filtered_data.url);
1251 process->FilterURL(false, &filtered_data.html_base_url);
1252 // Filter out any paths that the renderer didn't have access to. This prevents
1253 // the following attack on a malicious renderer:
1254 // 1. StartDragging IPC sent with renderer-specified filesystem paths that it
1255 // doesn't have read permissions for.
1256 // 2. We initiate a native DnD operation.
1257 // 3. DnD operation immediately ends since mouse is not held down. DnD events
1258 // still fire though, which causes read permissions to be granted to the
1259 // renderer for any file paths in the drop.
1260 filtered_data.filenames.clear();
1261 for (std::vector<ui::FileInfo>::const_iterator it =
1262 drop_data.filenames.begin();
1263 it != drop_data.filenames.end();
1264 ++it) {
1265 if (policy->CanReadFile(GetProcess()->GetID(), it->path))
1266 filtered_data.filenames.push_back(*it);
1267 }
1268
1269 fileapi::FileSystemContext* file_system_context =
1270 BrowserContext::GetStoragePartition(
1271 GetProcess()->GetBrowserContext(),
1272 GetSiteInstance())->GetFileSystemContext();
1273 filtered_data.file_system_files.clear();
1274 for (size_t i = 0; i < drop_data.file_system_files.size(); ++i) {
1275 fileapi::FileSystemURL file_system_url =
1276 file_system_context->CrackURL(drop_data.file_system_files[i].url);
1277 if (policy->CanReadFileSystemFile(GetProcess()->GetID(), file_system_url))
1278 filtered_data.file_system_files.push_back(drop_data.file_system_files[i]);
1279 }
1280
1281 float scale = GetScaleFactorForView(GetView());
1282 gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, scale));
1283 view->StartDragging(filtered_data, drag_operations_mask, image,
1284 bitmap_offset_in_dip, event_info);
1285 }
1286
OnUpdateDragCursor(WebDragOperation current_op)1287 void RenderViewHostImpl::OnUpdateDragCursor(WebDragOperation current_op) {
1288 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1289 if (view)
1290 view->UpdateDragCursor(current_op);
1291 }
1292
OnTargetDropACK()1293 void RenderViewHostImpl::OnTargetDropACK() {
1294 NotificationService::current()->Notify(
1295 NOTIFICATION_RENDER_VIEW_HOST_DID_RECEIVE_DRAG_TARGET_DROP_ACK,
1296 Source<RenderViewHost>(this),
1297 NotificationService::NoDetails());
1298 }
1299
OnTakeFocus(bool reverse)1300 void RenderViewHostImpl::OnTakeFocus(bool reverse) {
1301 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1302 if (view)
1303 view->TakeFocus(reverse);
1304 }
1305
OnFocusedNodeChanged(bool is_editable_node)1306 void RenderViewHostImpl::OnFocusedNodeChanged(bool is_editable_node) {
1307 is_focused_element_editable_ = is_editable_node;
1308 if (view_)
1309 view_->FocusedNodeChanged(is_editable_node);
1310 #if defined(OS_WIN)
1311 if (!is_editable_node && virtual_keyboard_requested_) {
1312 virtual_keyboard_requested_ = false;
1313 BrowserThread::PostDelayedTask(
1314 BrowserThread::UI, FROM_HERE,
1315 base::Bind(base::IgnoreResult(&DismissVirtualKeyboardTask)),
1316 TimeDelta::FromMilliseconds(kVirtualKeyboardDisplayWaitTimeoutMs));
1317 }
1318 #endif
1319 NotificationService::current()->Notify(
1320 NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
1321 Source<RenderViewHost>(this),
1322 Details<const bool>(&is_editable_node));
1323 }
1324
OnUserGesture()1325 void RenderViewHostImpl::OnUserGesture() {
1326 delegate_->OnUserGesture();
1327 }
1328
OnClosePageACK()1329 void RenderViewHostImpl::OnClosePageACK() {
1330 decrement_in_flight_event_count();
1331 ClosePageIgnoringUnloadEvents();
1332 }
1333
NotifyRendererUnresponsive()1334 void RenderViewHostImpl::NotifyRendererUnresponsive() {
1335 delegate_->RendererUnresponsive(
1336 this, is_waiting_for_beforeunload_ack_, IsWaitingForUnloadACK());
1337 }
1338
NotifyRendererResponsive()1339 void RenderViewHostImpl::NotifyRendererResponsive() {
1340 delegate_->RendererResponsive(this);
1341 }
1342
RequestToLockMouse(bool user_gesture,bool last_unlocked_by_target)1343 void RenderViewHostImpl::RequestToLockMouse(bool user_gesture,
1344 bool last_unlocked_by_target) {
1345 delegate_->RequestToLockMouse(user_gesture, last_unlocked_by_target);
1346 }
1347
IsFullscreen() const1348 bool RenderViewHostImpl::IsFullscreen() const {
1349 return delegate_->IsFullscreenForCurrentTab();
1350 }
1351
OnFocus()1352 void RenderViewHostImpl::OnFocus() {
1353 // Note: We allow focus and blur from swapped out RenderViewHosts, even when
1354 // the active RenderViewHost is in a different BrowsingInstance (e.g., WebUI).
1355 delegate_->Activate();
1356 }
1357
OnBlur()1358 void RenderViewHostImpl::OnBlur() {
1359 delegate_->Deactivate();
1360 }
1361
GetRootWindowResizerRect() const1362 gfx::Rect RenderViewHostImpl::GetRootWindowResizerRect() const {
1363 return delegate_->GetRootWindowResizerRect();
1364 }
1365
ForwardMouseEvent(const blink::WebMouseEvent & mouse_event)1366 void RenderViewHostImpl::ForwardMouseEvent(
1367 const blink::WebMouseEvent& mouse_event) {
1368
1369 // We make a copy of the mouse event because
1370 // RenderWidgetHost::ForwardMouseEvent will delete |mouse_event|.
1371 blink::WebMouseEvent event_copy(mouse_event);
1372 RenderWidgetHostImpl::ForwardMouseEvent(event_copy);
1373
1374 switch (event_copy.type) {
1375 case WebInputEvent::MouseMove:
1376 delegate_->HandleMouseMove();
1377 break;
1378 case WebInputEvent::MouseLeave:
1379 delegate_->HandleMouseLeave();
1380 break;
1381 case WebInputEvent::MouseDown:
1382 delegate_->HandleMouseDown();
1383 break;
1384 case WebInputEvent::MouseWheel:
1385 if (ignore_input_events())
1386 delegate_->OnIgnoredUIEvent();
1387 break;
1388 case WebInputEvent::MouseUp:
1389 delegate_->HandleMouseUp();
1390 default:
1391 // For now, we don't care about the rest.
1392 break;
1393 }
1394 }
1395
OnPointerEventActivate()1396 void RenderViewHostImpl::OnPointerEventActivate() {
1397 delegate_->HandlePointerActivate();
1398 }
1399
ForwardKeyboardEvent(const NativeWebKeyboardEvent & key_event)1400 void RenderViewHostImpl::ForwardKeyboardEvent(
1401 const NativeWebKeyboardEvent& key_event) {
1402 if (ignore_input_events()) {
1403 if (key_event.type == WebInputEvent::RawKeyDown)
1404 delegate_->OnIgnoredUIEvent();
1405 return;
1406 }
1407 RenderWidgetHostImpl::ForwardKeyboardEvent(key_event);
1408 }
1409
1410 #if defined(OS_ANDROID)
DidSelectPopupMenuItems(const std::vector<int> & selected_indices)1411 void RenderViewHostImpl::DidSelectPopupMenuItems(
1412 const std::vector<int>& selected_indices) {
1413 Send(new ViewMsg_SelectPopupMenuItems(GetRoutingID(), false,
1414 selected_indices));
1415 }
1416
DidCancelPopupMenu()1417 void RenderViewHostImpl::DidCancelPopupMenu() {
1418 Send(new ViewMsg_SelectPopupMenuItems(GetRoutingID(), true,
1419 std::vector<int>()));
1420 }
1421 #endif
1422
1423 #if defined(OS_MACOSX)
DidSelectPopupMenuItem(int selected_index)1424 void RenderViewHostImpl::DidSelectPopupMenuItem(int selected_index) {
1425 Send(new ViewMsg_SelectPopupMenuItem(GetRoutingID(), selected_index));
1426 }
1427
DidCancelPopupMenu()1428 void RenderViewHostImpl::DidCancelPopupMenu() {
1429 Send(new ViewMsg_SelectPopupMenuItem(GetRoutingID(), -1));
1430 }
1431 #endif
1432
IsWaitingForUnloadACK() const1433 bool RenderViewHostImpl::IsWaitingForUnloadACK() const {
1434 return rvh_state_ == STATE_WAITING_FOR_UNLOAD_ACK ||
1435 rvh_state_ == STATE_WAITING_FOR_CLOSE ||
1436 rvh_state_ == STATE_PENDING_SHUTDOWN ||
1437 rvh_state_ == STATE_PENDING_SWAP_OUT;
1438 }
1439
OnTextSurroundingSelectionResponse(const base::string16 & content,size_t start_offset,size_t end_offset)1440 void RenderViewHostImpl::OnTextSurroundingSelectionResponse(
1441 const base::string16& content,
1442 size_t start_offset,
1443 size_t end_offset) {
1444 if (!view_)
1445 return;
1446 view_->OnTextSurroundingSelectionResponse(content, start_offset, end_offset);
1447 }
1448
ExitFullscreen()1449 void RenderViewHostImpl::ExitFullscreen() {
1450 RejectMouseLockOrUnlockIfNecessary();
1451 // Notify delegate_ and renderer of fullscreen state change.
1452 OnToggleFullscreen(false);
1453 }
1454
GetWebkitPreferences()1455 WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
1456 return delegate_->GetWebkitPrefs();
1457 }
1458
DisownOpener()1459 void RenderViewHostImpl::DisownOpener() {
1460 // This should only be called when swapped out.
1461 DCHECK(IsSwappedOut());
1462
1463 Send(new ViewMsg_DisownOpener(GetRoutingID()));
1464 }
1465
SetAccessibilityCallbackForTesting(const base::Callback<void (ui::AXEvent,int)> & callback)1466 void RenderViewHostImpl::SetAccessibilityCallbackForTesting(
1467 const base::Callback<void(ui::AXEvent, int)>& callback) {
1468 accessibility_testing_callback_ = callback;
1469 }
1470
UpdateWebkitPreferences(const WebPreferences & prefs)1471 void RenderViewHostImpl::UpdateWebkitPreferences(const WebPreferences& prefs) {
1472 Send(new ViewMsg_UpdateWebPreferences(GetRoutingID(), prefs));
1473 }
1474
GetAudioOutputControllers(const GetAudioOutputControllersCallback & callback) const1475 void RenderViewHostImpl::GetAudioOutputControllers(
1476 const GetAudioOutputControllersCallback& callback) const {
1477 AudioRendererHost* audio_host =
1478 static_cast<RenderProcessHostImpl*>(GetProcess())->audio_renderer_host();
1479 audio_host->GetOutputControllers(GetRoutingID(), callback);
1480 }
1481
ClearFocusedElement()1482 void RenderViewHostImpl::ClearFocusedElement() {
1483 is_focused_element_editable_ = false;
1484 Send(new ViewMsg_ClearFocusedElement(GetRoutingID()));
1485 }
1486
IsFocusedElementEditable()1487 bool RenderViewHostImpl::IsFocusedElementEditable() {
1488 return is_focused_element_editable_;
1489 }
1490
Zoom(PageZoom zoom)1491 void RenderViewHostImpl::Zoom(PageZoom zoom) {
1492 Send(new ViewMsg_Zoom(GetRoutingID(), zoom));
1493 }
1494
DisableScrollbarsForThreshold(const gfx::Size & size)1495 void RenderViewHostImpl::DisableScrollbarsForThreshold(const gfx::Size& size) {
1496 Send(new ViewMsg_DisableScrollbarsForSmallWindows(GetRoutingID(), size));
1497 }
1498
EnablePreferredSizeMode()1499 void RenderViewHostImpl::EnablePreferredSizeMode() {
1500 Send(new ViewMsg_EnablePreferredSizeChangedMode(GetRoutingID()));
1501 }
1502
EnableAutoResize(const gfx::Size & min_size,const gfx::Size & max_size)1503 void RenderViewHostImpl::EnableAutoResize(const gfx::Size& min_size,
1504 const gfx::Size& max_size) {
1505 SetShouldAutoResize(true);
1506 Send(new ViewMsg_EnableAutoResize(GetRoutingID(), min_size, max_size));
1507 }
1508
DisableAutoResize(const gfx::Size & new_size)1509 void RenderViewHostImpl::DisableAutoResize(const gfx::Size& new_size) {
1510 SetShouldAutoResize(false);
1511 Send(new ViewMsg_DisableAutoResize(GetRoutingID(), new_size));
1512 }
1513
CopyImageAt(int x,int y)1514 void RenderViewHostImpl::CopyImageAt(int x, int y) {
1515 Send(new ViewMsg_CopyImageAt(GetRoutingID(), x, y));
1516 }
1517
SaveImageAt(int x,int y)1518 void RenderViewHostImpl::SaveImageAt(int x, int y) {
1519 Send(new ViewMsg_SaveImageAt(GetRoutingID(), x, y));
1520 }
1521
ExecuteMediaPlayerActionAtLocation(const gfx::Point & location,const blink::WebMediaPlayerAction & action)1522 void RenderViewHostImpl::ExecuteMediaPlayerActionAtLocation(
1523 const gfx::Point& location, const blink::WebMediaPlayerAction& action) {
1524 Send(new ViewMsg_MediaPlayerActionAt(GetRoutingID(), location, action));
1525 }
1526
ExecutePluginActionAtLocation(const gfx::Point & location,const blink::WebPluginAction & action)1527 void RenderViewHostImpl::ExecutePluginActionAtLocation(
1528 const gfx::Point& location, const blink::WebPluginAction& action) {
1529 Send(new ViewMsg_PluginActionAt(GetRoutingID(), location, action));
1530 }
1531
NotifyMoveOrResizeStarted()1532 void RenderViewHostImpl::NotifyMoveOrResizeStarted() {
1533 Send(new ViewMsg_MoveOrResizeStarted(GetRoutingID()));
1534 }
1535
OnAccessibilityEvents(const std::vector<AccessibilityHostMsg_EventParams> & params)1536 void RenderViewHostImpl::OnAccessibilityEvents(
1537 const std::vector<AccessibilityHostMsg_EventParams>& params) {
1538 if ((accessibility_mode() != AccessibilityModeOff) && view_ &&
1539 IsRVHStateActive(rvh_state_)) {
1540 if (accessibility_mode() & AccessibilityModeFlagPlatform) {
1541 view_->CreateBrowserAccessibilityManagerIfNeeded();
1542 BrowserAccessibilityManager* manager =
1543 view_->GetBrowserAccessibilityManager();
1544 if (manager)
1545 manager->OnAccessibilityEvents(params);
1546 }
1547
1548 std::vector<AXEventNotificationDetails> details;
1549 for (unsigned int i = 0; i < params.size(); ++i) {
1550 const AccessibilityHostMsg_EventParams& param = params[i];
1551 AXEventNotificationDetails detail(param.update.nodes,
1552 param.event_type,
1553 param.id,
1554 GetProcess()->GetID(),
1555 GetRoutingID());
1556 details.push_back(detail);
1557 }
1558
1559 delegate_->AccessibilityEventReceived(details);
1560 }
1561
1562 // Always send an ACK or the renderer can be in a bad state.
1563 Send(new AccessibilityMsg_Events_ACK(GetRoutingID()));
1564
1565 // The rest of this code is just for testing; bail out if we're not
1566 // in that mode.
1567 if (accessibility_testing_callback_.is_null())
1568 return;
1569
1570 for (unsigned i = 0; i < params.size(); i++) {
1571 const AccessibilityHostMsg_EventParams& param = params[i];
1572 if (static_cast<int>(param.event_type) < 0)
1573 continue;
1574 if (!ax_tree_)
1575 ax_tree_.reset(new ui::AXTree(param.update));
1576 else
1577 CHECK(ax_tree_->Unserialize(param.update)) << ax_tree_->error();
1578 accessibility_testing_callback_.Run(param.event_type, param.id);
1579 }
1580 }
1581
OnAccessibilityLocationChanges(const std::vector<AccessibilityHostMsg_LocationChangeParams> & params)1582 void RenderViewHostImpl::OnAccessibilityLocationChanges(
1583 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) {
1584 if (view_ && IsRVHStateActive(rvh_state_)) {
1585 if (accessibility_mode() & AccessibilityModeFlagPlatform) {
1586 view_->CreateBrowserAccessibilityManagerIfNeeded();
1587 BrowserAccessibilityManager* manager =
1588 view_->GetBrowserAccessibilityManager();
1589 if (manager)
1590 manager->OnLocationChanges(params);
1591 }
1592 // TODO(aboxhall): send location change events to web contents observers too
1593 }
1594 }
1595
OnDidZoomURL(double zoom_level,const GURL & url)1596 void RenderViewHostImpl::OnDidZoomURL(double zoom_level,
1597 const GURL& url) {
1598 HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
1599 HostZoomMap::GetForBrowserContext(GetProcess()->GetBrowserContext()));
1600
1601 host_zoom_map->SetZoomLevelForView(GetProcess()->GetID(),
1602 GetRoutingID(),
1603 zoom_level,
1604 net::GetHostOrSpecFromURL(url));
1605 }
1606
OnRunFileChooser(const FileChooserParams & params)1607 void RenderViewHostImpl::OnRunFileChooser(const FileChooserParams& params) {
1608 delegate_->RunFileChooser(this, params);
1609 }
1610
OnFocusedNodeTouched(bool editable)1611 void RenderViewHostImpl::OnFocusedNodeTouched(bool editable) {
1612 #if defined(OS_WIN)
1613 if (editable) {
1614 virtual_keyboard_requested_ = base::win::DisplayVirtualKeyboard();
1615 } else {
1616 virtual_keyboard_requested_ = false;
1617 base::win::DismissVirtualKeyboard();
1618 }
1619 #endif
1620 }
1621
1622 #if defined(OS_MACOSX) || defined(OS_ANDROID)
OnShowPopup(const ViewHostMsg_ShowPopup_Params & params)1623 void RenderViewHostImpl::OnShowPopup(
1624 const ViewHostMsg_ShowPopup_Params& params) {
1625 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1626 if (view) {
1627 view->ShowPopupMenu(params.bounds,
1628 params.item_height,
1629 params.item_font_size,
1630 params.selected_item,
1631 params.popup_items,
1632 params.right_aligned,
1633 params.allow_multiple_selection);
1634 }
1635 }
1636
OnHidePopup()1637 void RenderViewHostImpl::OnHidePopup() {
1638 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1639 if (view)
1640 view->HidePopupMenu();
1641 }
1642 #endif
1643
SetState(RenderViewHostImplState rvh_state)1644 void RenderViewHostImpl::SetState(RenderViewHostImplState rvh_state) {
1645 // We update the number of RenderViews in a SiteInstance when the
1646 // swapped out status of this RenderView gets flipped to/from live.
1647 if (!IsRVHStateActive(rvh_state_) && IsRVHStateActive(rvh_state))
1648 instance_->increment_active_view_count();
1649 else if (IsRVHStateActive(rvh_state_) && !IsRVHStateActive(rvh_state))
1650 instance_->decrement_active_view_count();
1651
1652 // Whenever we change the RVH state to and from live or swapped out state, we
1653 // should not be waiting for beforeunload or unload acks. We clear them here
1654 // to be safe, since they can cause navigations to be ignored in OnNavigate.
1655 if (rvh_state == STATE_DEFAULT ||
1656 rvh_state == STATE_SWAPPED_OUT ||
1657 rvh_state_ == STATE_DEFAULT ||
1658 rvh_state_ == STATE_SWAPPED_OUT) {
1659 is_waiting_for_beforeunload_ack_ = false;
1660 }
1661 rvh_state_ = rvh_state;
1662
1663 }
1664
CanAccessFilesOfPageState(const PageState & state) const1665 bool RenderViewHostImpl::CanAccessFilesOfPageState(
1666 const PageState& state) const {
1667 ChildProcessSecurityPolicyImpl* policy =
1668 ChildProcessSecurityPolicyImpl::GetInstance();
1669
1670 const std::vector<base::FilePath>& file_paths = state.GetReferencedFiles();
1671 for (std::vector<base::FilePath>::const_iterator file = file_paths.begin();
1672 file != file_paths.end(); ++file) {
1673 if (!policy->CanReadFile(GetProcess()->GetID(), *file))
1674 return false;
1675 }
1676 return true;
1677 }
1678
AttachToFrameTree()1679 void RenderViewHostImpl::AttachToFrameTree() {
1680 FrameTree* frame_tree = delegate_->GetFrameTree();
1681
1682 frame_tree->ResetForMainFrameSwap();
1683 }
1684
SelectWordAroundCaret()1685 void RenderViewHostImpl::SelectWordAroundCaret() {
1686 Send(new ViewMsg_SelectWordAroundCaret(GetRoutingID()));
1687 }
1688
1689 } // namespace content
1690