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 <unordered_map>
10 #include <utility>
11 #include <vector>
12
13 #include "base/bind.h"
14 #include "base/callback.h"
15 #include "base/command_line.h"
16 #include "base/debug/dump_without_crashing.h"
17 #include "base/feature_list.h"
18 #include "base/hash/hash.h"
19 #include "base/i18n/rtl.h"
20 #include "base/json/json_reader.h"
21 #include "base/metrics/field_trial.h"
22 #include "base/metrics/histogram_macros.h"
23 #include "base/metrics/user_metrics.h"
24 #include "base/stl_util.h"
25 #include "base/strings/string_number_conversions.h"
26 #include "base/strings/string_util.h"
27 #include "base/strings/utf_string_conversions.h"
28 #include "base/system/sys_info.h"
29 #include "base/task/post_task.h"
30 #include "base/time/time.h"
31 #include "base/trace_event/trace_event.h"
32 #include "base/values.h"
33 #include "build/build_config.h"
34 #include "cc/base/switches.h"
35 #include "content/browser/bad_message.h"
36 #include "content/browser/child_process_security_policy_impl.h"
37 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
38 #include "content/browser/frame_host/frame_tree.h"
39 #include "content/browser/gpu/compositor_util.h"
40 #include "content/browser/gpu/gpu_data_manager_impl.h"
41 #include "content/browser/gpu/gpu_process_host.h"
42 #include "content/browser/renderer_host/input/timeout_monitor.h"
43 #include "content/browser/renderer_host/render_process_host_impl.h"
44 #include "content/browser/renderer_host/render_view_host_delegate.h"
45 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
46 #include "content/browser/renderer_host/render_widget_host_delegate.h"
47 #include "content/browser/renderer_host/render_widget_host_view_base.h"
48 #include "content/browser/scoped_active_url.h"
49 #include "content/common/content_switches_internal.h"
50 #include "content/common/frame_messages.h"
51 #include "content/common/input_messages.h"
52 #include "content/common/inter_process_time_ticks_converter.h"
53 #include "content/common/page_messages.h"
54 #include "content/common/render_message_filter.mojom.h"
55 #include "content/common/renderer.mojom.h"
56 #include "content/common/view_messages.h"
57 #include "content/common/widget_messages.h"
58 #include "content/public/browser/ax_event_notification_details.h"
59 #include "content/public/browser/browser_accessibility_state.h"
60 #include "content/public/browser/browser_context.h"
61 #include "content/public/browser/browser_message_filter.h"
62 #include "content/public/browser/browser_task_traits.h"
63 #include "content/public/browser/browser_thread.h"
64 #include "content/public/browser/content_browser_client.h"
65 #include "content/public/browser/context_menu_params.h"
66 #include "content/public/browser/native_web_keyboard_event.h"
67 #include "content/public/browser/notification_details.h"
68 #include "content/public/browser/notification_service.h"
69 #include "content/public/browser/notification_types.h"
70 #include "content/public/browser/render_frame_host.h"
71 #include "content/public/browser/render_widget_host_iterator.h"
72 #include "content/public/browser/storage_partition.h"
73 #include "content/public/common/bindings_policy.h"
74 #include "content/public/common/content_client.h"
75 #include "content/public/common/content_constants.h"
76 #include "content/public/common/content_features.h"
77 #include "content/public/common/content_switches.h"
78 #include "content/public/common/result_codes.h"
79 #include "content/public/common/url_constants.h"
80 #include "content/public/common/url_utils.h"
81 #include "media/base/media_switches.h"
82 #include "net/base/url_util.h"
83 #include "net/url_request/url_request_context_getter.h"
84 #include "services/network/public/cpp/features.h"
85 #include "third_party/blink/public/common/features.h"
86 #include "third_party/skia/include/core/SkBitmap.h"
87 #include "ui/base/clipboard/clipboard.h"
88 #include "ui/base/device_form_factor.h"
89 #include "ui/base/pointer/pointer_device.h"
90 #include "ui/base/ui_base_features.h"
91 #include "ui/base/ui_base_switches.h"
92 #include "ui/display/display_switches.h"
93 #include "ui/events/blink/blink_features.h"
94 #include "ui/gfx/animation/animation.h"
95 #include "ui/gfx/color_space.h"
96 #include "ui/gfx/image/image_skia.h"
97 #include "ui/gfx/native_widget_types.h"
98 #include "ui/gl/gpu_switching_manager.h"
99 #include "ui/native_theme/native_theme_features.h"
100 #include "url/url_constants.h"
101
102 #if defined(OS_WIN)
103 #include "ui/display/win/screen_win.h"
104 #include "ui/gfx/geometry/dip_util.h"
105 #include "ui/gfx/system_fonts_win.h"
106 #endif
107
108 #if !defined(OS_ANDROID)
109 #include "content/browser/host_zoom_map_impl.h"
110 #endif
111
112 using base::TimeDelta;
113
114 using blink::WebConsoleMessage;
115 using blink::WebInputEvent;
116
117 namespace content {
118 namespace {
119
120 // <process id, routing id>
121 using RenderViewHostID = std::pair<int32_t, int32_t>;
122 using RoutingIDViewMap =
123 std::unordered_map<RenderViewHostID,
124 RenderViewHostImpl*,
125 base::IntPairHash<RenderViewHostID>>;
126 base::LazyInstance<RoutingIDViewMap>::Leaky g_routing_id_view_map =
127 LAZY_INSTANCE_INITIALIZER;
128
129 #if defined(OS_WIN)
130 // Fetches the name and font size of a particular Windows system font.
GetFontInfo(gfx::win::SystemFont system_font,base::string16 * name,int32_t * size)131 void GetFontInfo(gfx::win::SystemFont system_font,
132 base::string16* name,
133 int32_t* size) {
134 const gfx::Font& font = gfx::win::GetSystemFont(system_font);
135 *name = base::UTF8ToUTF16(font.GetFontName());
136 *size = font.GetFontSize();
137 }
138 #endif // OS_WIN
139
140 } // namespace
141
142 // static
143 const int64_t RenderViewHostImpl::kUnloadTimeoutMS = 500;
144
145 ///////////////////////////////////////////////////////////////////////////////
146 // RenderViewHost, public:
147
148 // static
FromID(int render_process_id,int render_view_id)149 RenderViewHost* RenderViewHost::FromID(int render_process_id,
150 int render_view_id) {
151 return RenderViewHostImpl::FromID(render_process_id, render_view_id);
152 }
153
154 // static
From(RenderWidgetHost * rwh)155 RenderViewHost* RenderViewHost::From(RenderWidgetHost* rwh) {
156 return RenderViewHostImpl::From(rwh);
157 }
158
159 ///////////////////////////////////////////////////////////////////////////////
160 // RenderViewHostImpl, public:
161
162 // static
FromID(int process_id,int routing_id)163 RenderViewHostImpl* RenderViewHostImpl::FromID(int process_id, int routing_id) {
164 DCHECK_CURRENTLY_ON(BrowserThread::UI);
165 RoutingIDViewMap* views = g_routing_id_view_map.Pointer();
166 auto it = views->find(RenderViewHostID(process_id, routing_id));
167 return it == views->end() ? nullptr : it->second;
168 }
169
170 // static
From(RenderWidgetHost * rwh)171 RenderViewHostImpl* RenderViewHostImpl::From(RenderWidgetHost* rwh) {
172 DCHECK(rwh);
173 RenderWidgetHostOwnerDelegate* owner_delegate =
174 RenderWidgetHostImpl::From(rwh)->owner_delegate();
175 if (!owner_delegate)
176 return nullptr;
177 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(owner_delegate);
178 DCHECK_EQ(rwh, rvh->GetWidget());
179 return rvh;
180 }
181
182 // static
GetPlatformSpecificPrefs(blink::mojom::RendererPreferences * prefs)183 void RenderViewHostImpl::GetPlatformSpecificPrefs(
184 blink::mojom::RendererPreferences* prefs) {
185 #if defined(OS_WIN)
186 // Note that what is called "height" in this struct is actually the font size;
187 // font "height" typically includes ascender, descender, and padding and is
188 // often a third or so larger than the given font size.
189 GetFontInfo(gfx::win::SystemFont::kCaption, &prefs->caption_font_family_name,
190 &prefs->caption_font_height);
191 GetFontInfo(gfx::win::SystemFont::kSmallCaption,
192 &prefs->small_caption_font_family_name,
193 &prefs->small_caption_font_height);
194 GetFontInfo(gfx::win::SystemFont::kMenu, &prefs->menu_font_family_name,
195 &prefs->menu_font_height);
196 GetFontInfo(gfx::win::SystemFont::kMessage, &prefs->message_font_family_name,
197 &prefs->message_font_height);
198 GetFontInfo(gfx::win::SystemFont::kStatus, &prefs->status_font_family_name,
199 &prefs->status_font_height);
200
201 prefs->vertical_scroll_bar_width_in_dips =
202 display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXVSCROLL);
203 prefs->horizontal_scroll_bar_height_in_dips =
204 display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYHSCROLL);
205 prefs->arrow_bitmap_height_vertical_scroll_bar_in_dips =
206 display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYVSCROLL);
207 prefs->arrow_bitmap_width_horizontal_scroll_bar_in_dips =
208 display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXHSCROLL);
209 #elif defined(OS_LINUX) || defined(OS_BSD)
210 prefs->system_font_family_name = gfx::Font().GetFontName();
211 #elif defined(OS_FUCHSIA)
212 // Make Blink's "focus ring" invisible. The focus ring is a hairline border
213 // that's rendered around clickable targets.
214 // TODO(crbug.com/1066605): Consider exposing this as a FIDL parameter.
215 prefs->focus_ring_color = SK_AlphaTRANSPARENT;
216 #endif
217 }
218
RenderViewHostImpl(SiteInstance * instance,std::unique_ptr<RenderWidgetHostImpl> widget,RenderViewHostDelegate * delegate,int32_t routing_id,int32_t main_frame_routing_id,bool swapped_out,bool has_initialized_audio_host)219 RenderViewHostImpl::RenderViewHostImpl(
220 SiteInstance* instance,
221 std::unique_ptr<RenderWidgetHostImpl> widget,
222 RenderViewHostDelegate* delegate,
223 int32_t routing_id,
224 int32_t main_frame_routing_id,
225 bool swapped_out,
226 bool has_initialized_audio_host)
227 : render_widget_host_(std::move(widget)),
228 delegate_(delegate),
229 instance_(static_cast<SiteInstanceImpl*>(instance)),
230 routing_id_(routing_id),
231 main_frame_routing_id_(main_frame_routing_id) {
232 DCHECK(instance_.get());
233 DCHECK(delegate_);
234 DCHECK_NE(GetRoutingID(), render_widget_host_->GetRoutingID());
235
236 std::pair<RoutingIDViewMap::iterator, bool> result =
237 g_routing_id_view_map.Get().emplace(
238 RenderViewHostID(GetProcess()->GetID(), routing_id_), this);
239 CHECK(result.second) << "Inserting a duplicate item!";
240 GetProcess()->AddRoute(routing_id_, this);
241
242 GetProcess()->AddObserver(this);
243 ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
244
245 // New views may be created during RenderProcessHost::ProcessDied(), within a
246 // brief window where the internal ChannelProxy is null. This ensures that the
247 // ChannelProxy is re-initialized in such cases so that subsequent messages
248 // make their way to the new renderer once its restarted.
249 GetProcess()->EnableSendQueue();
250
251 if (!is_active())
252 GetWidget()->UpdatePriority();
253
254 close_timeout_ = std::make_unique<TimeoutMonitor>(base::BindRepeating(
255 &RenderViewHostImpl::ClosePageTimeout, weak_factory_.GetWeakPtr()));
256
257 input_device_change_observer_ =
258 std::make_unique<InputDeviceChangeObserver>(this);
259
260 page_lifecycle_state_manager_ =
261 std::make_unique<PageLifecycleStateManager>(this);
262
263 GetWidget()->set_owner_delegate(this);
264 }
265
~RenderViewHostImpl()266 RenderViewHostImpl::~RenderViewHostImpl() {
267 // We can't release the SessionStorageNamespace until our peer
268 // in the renderer has wound down.
269 if (GetProcess()->IsInitializedAndNotDead()) {
270 RenderProcessHostImpl::ReleaseOnCloseACK(
271 GetProcess(), delegate_->GetSessionStorageNamespaceMap(),
272 GetWidget()->GetRoutingID());
273 }
274
275 // Destroy the RenderWidgetHost.
276 GetWidget()->ShutdownAndDestroyWidget(false);
277 if (IsRenderViewLive()) {
278 // Destroy the RenderView, which will also destroy the RenderWidget.
279 GetProcess()->GetRendererInterface()->DestroyView(GetRoutingID());
280 }
281
282 ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
283
284 // Detach the routing ID as the object is going away.
285 GetProcess()->RemoveRoute(GetRoutingID());
286 g_routing_id_view_map.Get().erase(
287 RenderViewHostID(GetProcess()->GetID(), GetRoutingID()));
288
289 delegate_->RenderViewDeleted(this);
290 GetProcess()->RemoveObserver(this);
291
292 // This can be called inside the FrameTree destructor. When the delegate is
293 // the InterstialPageImpl, the |frame_tree| is set to null before deleting it.
294 if (FrameTree* frame_tree = GetDelegate()->GetFrameTree()) {
295 // If |this| is in the BackForwardCache, then it was already removed from
296 // the FrameTree at the time it entered the BackForwardCache.
297 if (!is_in_back_forward_cache_)
298 frame_tree->UnregisterRenderViewHost(this);
299 }
300 }
301
GetDelegate()302 RenderViewHostDelegate* RenderViewHostImpl::GetDelegate() {
303 return delegate_;
304 }
305
GetSiteInstance()306 SiteInstanceImpl* RenderViewHostImpl::GetSiteInstance() {
307 return instance_.get();
308 }
309
CreateRenderView(int opener_frame_route_id,int proxy_route_id,const base::UnguessableToken & devtools_frame_token,const FrameReplicationState & replicated_frame_state,bool window_was_created_with_opener)310 bool RenderViewHostImpl::CreateRenderView(
311 int opener_frame_route_id,
312 int proxy_route_id,
313 const base::UnguessableToken& devtools_frame_token,
314 const FrameReplicationState& replicated_frame_state,
315 bool window_was_created_with_opener) {
316 TRACE_EVENT0("renderer_host,navigation",
317 "RenderViewHostImpl::CreateRenderView");
318 DCHECK(!IsRenderViewLive()) << "Creating view twice";
319
320 // The process may (if we're sharing a process with another host that already
321 // initialized it) or may not (we have our own process or the old process
322 // crashed) have been initialized. Calling Init multiple times will be
323 // ignored, so this is safe.
324 if (!GetProcess()->Init())
325 return false;
326 DCHECK(GetProcess()->IsInitializedAndNotDead());
327 DCHECK(GetProcess()->GetBrowserContext());
328
329 // Exactly one of main_frame_routing_id_ or proxy_route_id should be set.
330 CHECK((main_frame_routing_id_ != MSG_ROUTING_NONE &&
331 proxy_route_id == MSG_ROUTING_NONE) ||
332 (main_frame_routing_id_ == MSG_ROUTING_NONE &&
333 proxy_route_id != MSG_ROUTING_NONE));
334
335 RenderFrameHostImpl* main_rfh = nullptr;
336 if (main_frame_routing_id_ != MSG_ROUTING_NONE) {
337 main_rfh = RenderFrameHostImpl::FromID(GetProcess()->GetID(),
338 main_frame_routing_id_);
339 DCHECK(main_rfh);
340 }
341
342 GetWidget()->set_renderer_initialized(true);
343
344 mojom::CreateViewParamsPtr params = mojom::CreateViewParams::New();
345 params->renderer_preferences =
346 delegate_->GetRendererPrefs(GetProcess()->GetBrowserContext()).Clone();
347 RenderViewHostImpl::GetPlatformSpecificPrefs(
348 params->renderer_preferences.get());
349 params->web_preferences = GetWebkitPreferences();
350 params->view_id = GetRoutingID();
351 if (main_rfh) {
352 params->main_frame_routing_id = main_frame_routing_id_;
353 params->main_frame_widget_routing_id =
354 main_rfh->GetRenderWidgetHost()->GetRoutingID();
355 params->main_frame_interface_bundle =
356 mojom::DocumentScopedInterfaceBundle::New();
357 main_rfh->BindInterfaceProviderReceiver(
358 params->main_frame_interface_bundle->interface_provider
359 .InitWithNewPipeAndPassReceiver());
360 main_rfh->BindBrowserInterfaceBrokerReceiver(
361 params->main_frame_interface_bundle->browser_interface_broker
362 .InitWithNewPipeAndPassReceiver());
363
364 std::tie(params->widget_host, params->widget) =
365 main_rfh->GetRenderWidgetHost()->BindNewWidgetInterfaces();
366 std::tie(params->frame_widget_host, params->frame_widget) =
367 main_rfh->GetRenderWidgetHost()->BindNewFrameWidgetInterfaces();
368 }
369 params->session_storage_namespace_id =
370 delegate_->GetSessionStorageNamespace(instance_.get())->id();
371 // Ensure the RenderView sets its opener correctly.
372 params->opener_frame_route_id = opener_frame_route_id;
373 params->replicated_frame_state = replicated_frame_state;
374 params->proxy_routing_id = proxy_route_id;
375 params->hidden = GetWidget()->delegate()->IsHidden();
376 params->never_composited = delegate_->IsNeverComposited();
377 params->window_was_created_with_opener = window_was_created_with_opener;
378 if (main_rfh) {
379 params->has_committed_real_load =
380 main_rfh->frame_tree_node()->has_committed_real_load();
381 }
382 params->devtools_main_frame_token = devtools_frame_token;
383 // GuestViews in the same StoragePartition need to find each other's frames.
384 params->renderer_wide_named_frame_lookup = GetSiteInstance()->IsGuest();
385 params->inside_portal = delegate_->IsPortal();
386 // RenderViweHostImpls is reused after a crash, so reset any endpoint that
387 // might be a leftover from a crash.
388 page_broadcast_.reset();
389 params->blink_page_broadcast =
390 page_broadcast_.BindNewEndpointAndPassReceiver();
391 // TODO(danakj): Make the visual_properties optional in the message.
392 if (proxy_route_id == MSG_ROUTING_NONE) {
393 params->visual_properties = GetWidget()->GetInitialVisualProperties();
394 }
395
396 // The RenderView is owned by this process. This call must be accompanied by a
397 // DestroyView [see destructor] or else there will be a leak in the renderer
398 // process.
399 GetProcess()->GetRendererInterface()->CreateView(std::move(params));
400
401 // Let our delegate know that we created a RenderView.
402 DispatchRenderViewCreated();
403
404 // Since this method can create the main RenderFrame in the renderer process,
405 // set the proper state on its corresponding RenderFrameHost.
406 if (main_rfh)
407 main_rfh->SetRenderFrameCreated(true);
408 GetWidget()->delegate()->SendScreenRects();
409 PostRenderViewReady();
410
411 return true;
412 }
413
SetMainFrameRoutingId(int routing_id)414 void RenderViewHostImpl::SetMainFrameRoutingId(int routing_id) {
415 main_frame_routing_id_ = routing_id;
416 GetWidget()->UpdatePriority();
417 }
418
419 // TODO(https://crbug.com/1006814): Delete this.
GetMainFrameRoutingIdForCrbug1006814()420 int RenderViewHostImpl::GetMainFrameRoutingIdForCrbug1006814() {
421 return main_frame_routing_id_;
422 }
423
EnterBackForwardCache()424 void RenderViewHostImpl::EnterBackForwardCache() {
425 if (!will_enter_back_forward_cache_callback_for_testing_.is_null())
426 will_enter_back_forward_cache_callback_for_testing_.Run();
427
428 TRACE_EVENT0("navigation", "RenderViewHostImpl::EnterBackForwardCache");
429 FrameTree* frame_tree = GetDelegate()->GetFrameTree();
430 frame_tree->UnregisterRenderViewHost(this);
431 is_in_back_forward_cache_ = true;
432 // TODO(altimin, dcheng): This should be a ViewMsg.
433 Send(new PageMsg_PutPageIntoBackForwardCache(GetRoutingID()));
434 }
435
LeaveBackForwardCache(base::TimeTicks navigation_start)436 void RenderViewHostImpl::LeaveBackForwardCache(
437 base::TimeTicks navigation_start) {
438 TRACE_EVENT0("navigation", "RenderViewHostImpl::LeaveBackForwardCache");
439 FrameTree* frame_tree = GetDelegate()->GetFrameTree();
440 // At this point, the frames |this| RenderViewHostImpl belongs to are
441 // guaranteed to be committed, so it should be reused going forward.
442 frame_tree->RegisterRenderViewHost(this);
443 is_in_back_forward_cache_ = false;
444 Send(new PageMsg_RestorePageFromBackForwardCache(GetRoutingID(),
445 navigation_start));
446 }
447
SetIsFrozen(bool frozen)448 void RenderViewHostImpl::SetIsFrozen(bool frozen) {
449 page_lifecycle_state_manager_->SetIsFrozen(frozen);
450 }
451
IsRenderViewLive()452 bool RenderViewHostImpl::IsRenderViewLive() {
453 return GetProcess()->IsInitializedAndNotDead() &&
454 GetWidget()->renderer_initialized();
455 }
456
SetBackgroundOpaque(bool opaque)457 void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
458 GetWidget()->GetAssociatedFrameWidget()->SetBackgroundOpaque(opaque);
459 }
460
IsMainFrameActive()461 bool RenderViewHostImpl::IsMainFrameActive() {
462 return is_active();
463 }
464
IsNeverComposited()465 bool RenderViewHostImpl::IsNeverComposited() {
466 return GetDelegate()->IsNeverComposited();
467 }
468
GetWebkitPreferencesForWidget()469 WebPreferences RenderViewHostImpl::GetWebkitPreferencesForWidget() {
470 return GetWebkitPreferences();
471 }
472
GetFocusedFrame()473 FrameTreeNode* RenderViewHostImpl::GetFocusedFrame() {
474 return GetDelegate()->GetFrameTree()->GetFocusedFrame();
475 }
476
ShowContextMenu(RenderFrameHost * render_frame_host,const ContextMenuParams & params)477 void RenderViewHostImpl::ShowContextMenu(RenderFrameHost* render_frame_host,
478 const ContextMenuParams& params) {
479 GetDelegate()->GetDelegateView()->ShowContextMenu(render_frame_host, params);
480 }
481
ComputeWebPreferences()482 const WebPreferences RenderViewHostImpl::ComputeWebPreferences() {
483 TRACE_EVENT0("browser", "RenderViewHostImpl::GetWebkitPrefs");
484 WebPreferences prefs;
485
486 const base::CommandLine& command_line =
487 *base::CommandLine::ForCurrentProcess();
488
489 SetSlowWebPreferences(command_line, &prefs);
490
491 prefs.web_security_enabled =
492 !command_line.HasSwitch(switches::kDisableWebSecurity);
493
494 prefs.remote_fonts_enabled =
495 !command_line.HasSwitch(switches::kDisableRemoteFonts);
496 prefs.application_cache_enabled =
497 base::FeatureList::IsEnabled(blink::features::kAppCache);
498 prefs.local_storage_enabled =
499 !command_line.HasSwitch(switches::kDisableLocalStorage);
500 prefs.databases_enabled =
501 !command_line.HasSwitch(switches::kDisableDatabases);
502
503 prefs.webgl1_enabled = !command_line.HasSwitch(switches::kDisable3DAPIs) &&
504 !command_line.HasSwitch(switches::kDisableWebGL);
505 prefs.webgl2_enabled = !command_line.HasSwitch(switches::kDisable3DAPIs) &&
506 !command_line.HasSwitch(switches::kDisableWebGL) &&
507 !command_line.HasSwitch(switches::kDisableWebGL2);
508
509 prefs.pepper_3d_enabled =
510 !command_line.HasSwitch(switches::kDisablePepper3d);
511
512 prefs.flash_3d_enabled =
513 !command_line.HasSwitch(switches::kDisableFlash3d);
514 prefs.flash_stage3d_enabled =
515 !command_line.HasSwitch(switches::kDisableFlashStage3d);
516 prefs.flash_stage3d_baseline_enabled =
517 !command_line.HasSwitch(switches::kDisableFlashStage3d);
518
519 prefs.allow_file_access_from_file_urls =
520 command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
521
522 prefs.accelerated_2d_canvas_enabled =
523 !command_line.HasSwitch(switches::kDisableAccelerated2dCanvas);
524 prefs.antialiased_2d_canvas_disabled =
525 command_line.HasSwitch(switches::kDisable2dCanvasAntialiasing);
526 prefs.antialiased_clips_2d_canvas_enabled =
527 !command_line.HasSwitch(switches::kDisable2dCanvasClipAntialiasing);
528 prefs.accelerated_2d_canvas_msaa_sample_count =
529 atoi(command_line.GetSwitchValueASCII(
530 switches::kAcceleratedCanvas2dMSAASampleCount).c_str());
531
532 prefs.disable_ipc_flooding_protection =
533 command_line.HasSwitch(switches::kDisableIpcFloodingProtection) ||
534 command_line.HasSwitch(switches::kDisablePushStateThrottle);
535
536 prefs.accelerated_video_decode_enabled =
537 !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode);
538
539 std::string autoplay_policy = media::GetEffectiveAutoplayPolicy(command_line);
540 if (autoplay_policy == switches::autoplay::kNoUserGestureRequiredPolicy) {
541 prefs.autoplay_policy = AutoplayPolicy::kNoUserGestureRequired;
542 } else if (autoplay_policy ==
543 switches::autoplay::kUserGestureRequiredPolicy) {
544 prefs.autoplay_policy = AutoplayPolicy::kUserGestureRequired;
545 } else if (autoplay_policy ==
546 switches::autoplay::kDocumentUserActivationRequiredPolicy) {
547 prefs.autoplay_policy = AutoplayPolicy::kDocumentUserActivationRequired;
548 } else {
549 NOTREACHED();
550 }
551
552 prefs.dont_send_key_events_to_javascript =
553 base::FeatureList::IsEnabled(features::kDontSendKeyEventsToJavascript);
554
555 // TODO(dtapuska): Enable barrel button selection drag support on Android.
556 // crbug.com/758042
557 #if defined(OS_WIN)
558 prefs.barrel_button_for_drag_enabled =
559 base::FeatureList::IsEnabled(features::kDirectManipulationStylus);
560 #endif // defined(OS_WIN)
561
562 prefs.touch_adjustment_enabled =
563 !command_line.HasSwitch(switches::kDisableTouchAdjustment);
564
565 prefs.enable_scroll_animator =
566 command_line.HasSwitch(switches::kEnableSmoothScrolling) ||
567 (!command_line.HasSwitch(switches::kDisableSmoothScrolling) &&
568 gfx::Animation::ScrollAnimationsEnabledBySystem());
569
570 prefs.prefers_reduced_motion = gfx::Animation::PrefersReducedMotion();
571
572 if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
573 GetProcess()->GetID())) {
574 prefs.loads_images_automatically = true;
575 prefs.javascript_enabled = true;
576 }
577
578 prefs.viewport_enabled = command_line.HasSwitch(switches::kEnableViewport);
579
580 if (delegate_->IsOverridingUserAgent())
581 prefs.viewport_meta_enabled = false;
582
583 prefs.main_frame_resizes_are_orientation_changes =
584 command_line.HasSwitch(switches::kMainFrameResizesAreOrientationChanges);
585
586 prefs.spatial_navigation_enabled = command_line.HasSwitch(
587 switches::kEnableSpatialNavigation);
588
589 if (delegate_->IsSpatialNavigationDisabled())
590 prefs.spatial_navigation_enabled = false;
591
592 prefs.caret_browsing_enabled =
593 command_line.HasSwitch(switches::kEnableCaretBrowsing);
594
595 prefs.disable_reading_from_canvas = command_line.HasSwitch(
596 switches::kDisableReadingFromCanvas);
597
598 prefs.strict_mixed_content_checking = command_line.HasSwitch(
599 switches::kEnableStrictMixedContentChecking);
600
601 prefs.strict_powerful_feature_restrictions = command_line.HasSwitch(
602 switches::kEnableStrictPowerfulFeatureRestrictions);
603
604 const std::string blockable_mixed_content_group =
605 base::FieldTrialList::FindFullName("BlockableMixedContent");
606 prefs.strictly_block_blockable_mixed_content =
607 blockable_mixed_content_group == "StrictlyBlockBlockableMixedContent";
608
609 const std::string plugin_mixed_content_status =
610 base::FieldTrialList::FindFullName("PluginMixedContentStatus");
611 prefs.block_mixed_plugin_content =
612 plugin_mixed_content_status == "BlockableMixedContent";
613
614 prefs.v8_cache_options = GetV8CacheOptions();
615
616 prefs.user_gesture_required_for_presentation = !command_line.HasSwitch(
617 switches::kDisableGestureRequirementForPresentation);
618
619 if (delegate_->HideDownloadUI())
620 prefs.hide_download_ui = true;
621
622 // `media_controls_enabled` is `true` by default.
623 if (delegate_->HasPersistentVideo())
624 prefs.media_controls_enabled = false;
625
626 GetContentClient()->browser()->OverrideWebkitPrefs(this, &prefs);
627 return prefs;
628 }
629
SetSlowWebPreferences(const base::CommandLine & command_line,WebPreferences * prefs)630 void RenderViewHostImpl::SetSlowWebPreferences(
631 const base::CommandLine& command_line,
632 WebPreferences* prefs) {
633 if (web_preferences_.get()) {
634 #define SET_FROM_CACHE(prefs, field) prefs->field = web_preferences_->field
635
636 SET_FROM_CACHE(prefs, touch_event_feature_detection_enabled);
637 SET_FROM_CACHE(prefs, available_pointer_types);
638 SET_FROM_CACHE(prefs, available_hover_types);
639 SET_FROM_CACHE(prefs, primary_pointer_type);
640 SET_FROM_CACHE(prefs, primary_hover_type);
641 SET_FROM_CACHE(prefs, pointer_events_max_touch_points);
642 SET_FROM_CACHE(prefs, number_of_cpu_cores);
643
644 #if defined(OS_ANDROID)
645 SET_FROM_CACHE(prefs, video_fullscreen_orientation_lock_enabled);
646 SET_FROM_CACHE(prefs, video_rotate_to_fullscreen_enabled);
647 #endif
648
649 #undef SET_FROM_CACHE
650 } else {
651 // Every prefs->field modified below should have a SET_FROM_CACHE entry
652 // above.
653
654 // On Android, Touch event feature detection is enabled by default,
655 // Otherwise default is disabled.
656 std::string touch_enabled_default_switch =
657 switches::kTouchEventFeatureDetectionDisabled;
658 #if defined(OS_ANDROID)
659 touch_enabled_default_switch = switches::kTouchEventFeatureDetectionEnabled;
660 #endif // defined(OS_ANDROID)
661 const std::string touch_enabled_switch =
662 command_line.HasSwitch(switches::kTouchEventFeatureDetection)
663 ? command_line.GetSwitchValueASCII(
664 switches::kTouchEventFeatureDetection)
665 : touch_enabled_default_switch;
666
667 prefs->touch_event_feature_detection_enabled =
668 (touch_enabled_switch == switches::kTouchEventFeatureDetectionAuto)
669 ? (ui::GetTouchScreensAvailability() ==
670 ui::TouchScreensAvailability::ENABLED)
671 : (touch_enabled_switch.empty() ||
672 touch_enabled_switch ==
673 switches::kTouchEventFeatureDetectionEnabled);
674
675 std::tie(prefs->available_pointer_types, prefs->available_hover_types) =
676 ui::GetAvailablePointerAndHoverTypes();
677 prefs->primary_pointer_type =
678 ui::GetPrimaryPointerType(prefs->available_pointer_types);
679 prefs->primary_hover_type =
680 ui::GetPrimaryHoverType(prefs->available_hover_types);
681
682 prefs->pointer_events_max_touch_points = ui::MaxTouchPoints();
683
684 prefs->number_of_cpu_cores = base::SysInfo::NumberOfProcessors();
685
686 #if defined(OS_ANDROID)
687 const bool device_is_phone =
688 ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE;
689 prefs->video_fullscreen_orientation_lock_enabled = device_is_phone;
690 prefs->video_rotate_to_fullscreen_enabled = device_is_phone;
691 #endif
692 }
693 }
694
DispatchRenderViewCreated()695 void RenderViewHostImpl::DispatchRenderViewCreated() {
696 if (has_notified_about_creation_)
697 return;
698
699 // Only send RenderViewCreated if there is a current or pending main frame
700 // RenderFrameHost (current or pending). Don't send notifications if this is
701 // an inactive RVH that is either used by subframe RFHs or not used by any
702 // RFHs at all (e.g., when created for the opener chain).
703 //
704 // While it would be nice to uniformly dispatch RenderViewCreated for all
705 // cases, some existing code (e.g., ExtensionViewHost) assumes it won't
706 // hear RenderViewCreated for a RVH created for an OOPIF.
707 //
708 // TODO(alexmos, creis): Revisit this as part of migrating RenderViewCreated
709 // usage to RenderFrameCreated. See https://crbug.com/763548.
710 if (!GetMainFrame())
711 return;
712
713 delegate_->RenderViewCreated(this);
714 has_notified_about_creation_ = true;
715 }
716
ClosePage()717 void RenderViewHostImpl::ClosePage() {
718 is_waiting_for_page_close_completion_ = true;
719
720 if (IsRenderViewLive() && !SuddenTerminationAllowed()) {
721 close_timeout_->Start(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
722
723 // TODO(creis): Should this be moved to Shutdown? It may not be called for
724 // RenderViewHosts that have been swapped out.
725 #if !defined(OS_ANDROID)
726 static_cast<HostZoomMapImpl*>(HostZoomMap::Get(GetSiteInstance()))
727 ->WillCloseRenderView(GetProcess()->GetID(), GetRoutingID());
728 #endif
729
730 static_cast<RenderFrameHostImpl*>(GetMainFrame())
731 ->GetAssociatedLocalMainFrame()
732 ->ClosePage(base::BindOnce(&RenderViewHostImpl::OnPageClosed,
733 weak_factory_.GetWeakPtr()));
734 } else {
735 // This RenderViewHost doesn't have a live renderer, so just skip the close
736 // event and close the page.
737 ClosePageIgnoringUnloadEvents();
738 }
739 }
740
ClosePageIgnoringUnloadEvents()741 void RenderViewHostImpl::ClosePageIgnoringUnloadEvents() {
742 close_timeout_->Stop();
743 is_waiting_for_page_close_completion_ = false;
744
745 sudden_termination_allowed_ = true;
746 delegate_->Close(this);
747 }
748
ZoomToFindInPageRect(const gfx::Rect & rect_to_zoom)749 void RenderViewHostImpl::ZoomToFindInPageRect(const gfx::Rect& rect_to_zoom) {
750 static_cast<RenderFrameHostImpl*>(GetMainFrame())
751 ->GetAssociatedLocalMainFrame()
752 ->ZoomToFindInPageRect(rect_to_zoom);
753 }
754
RenderProcessExited(RenderProcessHost * host,const ChildProcessTerminationInfo & info)755 void RenderViewHostImpl::RenderProcessExited(
756 RenderProcessHost* host,
757 const ChildProcessTerminationInfo& info) {
758 if (!GetWidget()->renderer_initialized())
759 return;
760
761 GetWidget()->RendererExited();
762 delegate_->RenderViewTerminated(this, info.status, info.exit_code);
763 }
764
Send(IPC::Message * msg)765 bool RenderViewHostImpl::Send(IPC::Message* msg) {
766 return GetWidget()->Send(msg);
767 }
768
GetWidget()769 RenderWidgetHostImpl* RenderViewHostImpl::GetWidget() {
770 return render_widget_host_.get();
771 }
772
GetProcess()773 RenderProcessHost* RenderViewHostImpl::GetProcess() {
774 return GetWidget()->GetProcess();
775 }
776
GetRoutingID()777 int RenderViewHostImpl::GetRoutingID() {
778 return routing_id_;
779 }
780
GetMainFrame()781 RenderFrameHost* RenderViewHostImpl::GetMainFrame() {
782 // If the RenderViewHost is active, it should always have a main frame
783 // RenderFrameHost. If it is inactive, it could've been created for a
784 // pending main frame navigation, in which case it will transition to active
785 // once that navigation commits. In this case, return the pending main frame
786 // RenderFrameHost, as that's expected by certain code paths,
787 // such as RenderViewHostImpl::SetUIProperty(). If there's no pending main
788 // frame navigation, return nullptr.
789 //
790 // TODO(alexmos, creis): Migrate these code paths to use RenderFrameHost APIs
791 // and remove this fallback. See https://crbug.com/763548.
792 if (is_active()) {
793 return RenderFrameHostImpl::FromID(GetProcess()->GetID(),
794 main_frame_routing_id_);
795 }
796 return delegate_->GetPendingMainFrame();
797 }
798
RenderWidgetGotFocus()799 void RenderViewHostImpl::RenderWidgetGotFocus() {
800 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
801 if (view)
802 view->GotFocus(GetWidget());
803 }
804
RenderWidgetLostFocus()805 void RenderViewHostImpl::RenderWidgetLostFocus() {
806 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
807 if (view)
808 view->LostFocus(GetWidget());
809 }
810
SetInitialFocus(bool reverse)811 void RenderViewHostImpl::SetInitialFocus(bool reverse) {
812 static_cast<RenderFrameHostImpl*>(GetMainFrame())
813 ->GetAssociatedLocalMainFrame()
814 ->SetInitialFocus(reverse);
815 }
816
AnimateDoubleTapZoom(const gfx::Point & point,const gfx::Rect & rect)817 void RenderViewHostImpl::AnimateDoubleTapZoom(const gfx::Point& point,
818 const gfx::Rect& rect) {
819 static_cast<RenderFrameHostImpl*>(GetMainFrame())
820 ->GetAssociatedLocalMainFrame()
821 ->AnimateDoubleTapZoom(point, rect);
822 }
823
RenderWidgetDidFirstVisuallyNonEmptyPaint()824 void RenderViewHostImpl::RenderWidgetDidFirstVisuallyNonEmptyPaint() {
825 did_first_visually_non_empty_paint_ = true;
826 delegate_->DidFirstVisuallyNonEmptyPaint(this);
827 }
828
SuddenTerminationAllowed()829 bool RenderViewHostImpl::SuddenTerminationAllowed() {
830 // If there is a JavaScript dialog up, don't bother sending the renderer the
831 // close event because it is known unresponsive, waiting for the reply from
832 // the dialog.
833 return sudden_termination_allowed_ ||
834 delegate_->IsJavaScriptDialogShowing() ||
835 static_cast<RenderFrameHostImpl*>(GetMainFrame())
836 ->BeforeUnloadTimedOut();
837 }
838
839 ///////////////////////////////////////////////////////////////////////////////
840 // RenderViewHostImpl, IPC message handlers:
841
OnMessageReceived(const IPC::Message & msg)842 bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
843 // Crash reports trigerred by the IPC messages below should be associated
844 // with URL of the main frame.
845 ScopedActiveURL scoped_active_url(this);
846
847 if (delegate_->OnMessageReceived(this, msg))
848 return true;
849
850 bool handled = true;
851 IPC_BEGIN_MESSAGE_MAP(RenderViewHostImpl, msg)
852 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
853 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget,
854 OnShowFullscreenWidget)
855 IPC_MESSAGE_HANDLER(ViewHostMsg_RouteCloseEvent, OnRouteCloseEvent)
856 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL)
857 IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
858 IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnFocus)
859 IPC_MESSAGE_UNHANDLED(handled = false)
860 IPC_END_MESSAGE_MAP()
861
862 return handled;
863 }
864
RenderWidgetDidInit()865 void RenderViewHostImpl::RenderWidgetDidInit() {
866 PostRenderViewReady();
867 }
868
RenderWidgetDidClose()869 void RenderViewHostImpl::RenderWidgetDidClose() {
870 // If the renderer is telling us to close, it has already run the unload
871 // events, and we can take the fast path.
872 ClosePageIgnoringUnloadEvents();
873 }
874
OnShowWidget(int widget_route_id,const gfx::Rect & initial_rect)875 void RenderViewHostImpl::OnShowWidget(int widget_route_id,
876 const gfx::Rect& initial_rect) {
877 delegate_->ShowCreatedWidget(GetProcess()->GetID(), widget_route_id,
878 initial_rect);
879 Send(new WidgetMsg_SetBounds_ACK(widget_route_id));
880 }
881
OnShowFullscreenWidget(int widget_route_id)882 void RenderViewHostImpl::OnShowFullscreenWidget(int widget_route_id) {
883 delegate_->ShowCreatedFullscreenWidget(GetProcess()->GetID(),
884 widget_route_id);
885 Send(new WidgetMsg_SetBounds_ACK(widget_route_id));
886 }
887
OnRouteCloseEvent()888 void RenderViewHostImpl::OnRouteCloseEvent() {
889 // This is only used when the RenderViewHost is not active, to signal to
890 // the active RenderViewHost that JS has requested the page to close.
891 //
892 // The delegate will route the close request to the active RenderViewHost.
893 delegate_->RouteCloseEvent(this);
894 }
895
OnUpdateTargetURL(const GURL & url)896 void RenderViewHostImpl::OnUpdateTargetURL(const GURL& url) {
897 delegate_->UpdateTargetURL(this, url);
898
899 // Send a notification back to the renderer that we are ready to
900 // receive more target urls.
901 Send(new ViewMsg_UpdateTargetURL_ACK(GetRoutingID()));
902 }
903
OnDidContentsPreferredSizeChange(const gfx::Size & new_size)904 void RenderViewHostImpl::OnDidContentsPreferredSizeChange(
905 const gfx::Size& new_size) {
906 delegate_->UpdatePreferredSize(new_size);
907 }
908
OnTakeFocus(bool reverse)909 void RenderViewHostImpl::OnTakeFocus(bool reverse) {
910 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
911 if (view)
912 view->TakeFocus(reverse);
913 }
914
OnPageClosed()915 void RenderViewHostImpl::OnPageClosed() {
916 ClosePageIgnoringUnloadEvents();
917 }
918
OnFocus()919 void RenderViewHostImpl::OnFocus() {
920 // Note: We allow focus and blur from swapped out RenderViewHosts, even when
921 // the active RenderViewHost is in a different BrowsingInstance (e.g., WebUI).
922 delegate_->Activate();
923 }
924
925 const mojo::AssociatedRemote<blink::mojom::PageBroadcast>&
GetAssociatedPageBroadcast()926 RenderViewHostImpl::GetAssociatedPageBroadcast() {
927 return page_broadcast_;
928 }
929
RenderWidgetDidForwardMouseEvent(const blink::WebMouseEvent & mouse_event)930 void RenderViewHostImpl::RenderWidgetDidForwardMouseEvent(
931 const blink::WebMouseEvent& mouse_event) {
932 if (mouse_event.GetType() == WebInputEvent::kMouseWheel &&
933 GetWidget()->IsIgnoringInputEvents()) {
934 delegate_->OnIgnoredUIEvent();
935 }
936 }
937
MayRenderWidgetForwardKeyboardEvent(const NativeWebKeyboardEvent & key_event)938 bool RenderViewHostImpl::MayRenderWidgetForwardKeyboardEvent(
939 const NativeWebKeyboardEvent& key_event) {
940 if (GetWidget()->IsIgnoringInputEvents()) {
941 if (key_event.GetType() == WebInputEvent::kRawKeyDown)
942 delegate_->OnIgnoredUIEvent();
943 return false;
944 }
945 return true;
946 }
947
ShouldContributePriorityToProcess()948 bool RenderViewHostImpl::ShouldContributePriorityToProcess() {
949 return is_active();
950 }
951
RequestSetBounds(const gfx::Rect & bounds)952 void RenderViewHostImpl::RequestSetBounds(const gfx::Rect& bounds) {
953 if (is_active())
954 delegate_->RequestSetBounds(bounds);
955 }
956
GetWebkitPreferences()957 WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
958 if (!web_preferences_.get()) {
959 OnWebkitPreferencesChanged();
960 }
961 return *web_preferences_;
962 }
963
UpdateWebkitPreferences(const WebPreferences & prefs)964 void RenderViewHostImpl::UpdateWebkitPreferences(const WebPreferences& prefs) {
965 web_preferences_.reset(new WebPreferences(prefs));
966 Send(new ViewMsg_UpdateWebPreferences(GetRoutingID(), prefs));
967 }
968
OnWebkitPreferencesChanged()969 void RenderViewHostImpl::OnWebkitPreferencesChanged() {
970 // This is defensive code to avoid infinite loops due to code run inside
971 // UpdateWebkitPreferences() accidentally updating more preferences and thus
972 // calling back into this code. See crbug.com/398751 for one past example.
973 if (updating_web_preferences_)
974 return;
975 updating_web_preferences_ = true;
976 UpdateWebkitPreferences(ComputeWebPreferences());
977 #if defined(OS_ANDROID)
978 for (FrameTreeNode* node : GetDelegate()->GetFrameTree()->Nodes()) {
979 RenderFrameHostImpl* rfh = node->current_frame_host();
980 if (rfh->is_local_root()) {
981 if (auto* rwh = rfh->GetRenderWidgetHost())
982 rwh->SetForceEnableZoom(web_preferences_->force_enable_zoom);
983 }
984 }
985 #endif
986 updating_web_preferences_ = false;
987 }
988
OnHardwareConfigurationChanged()989 void RenderViewHostImpl::OnHardwareConfigurationChanged() {
990 // OnWebkitPreferencesChanged is a no-op when this is true.
991 if (updating_web_preferences_)
992 return;
993 web_preferences_.reset();
994 OnWebkitPreferencesChanged();
995 }
996
EnablePreferredSizeMode()997 void RenderViewHostImpl::EnablePreferredSizeMode() {
998 if (is_active()) {
999 static_cast<RenderFrameHostImpl*>(GetMainFrame())
1000 ->GetAssociatedLocalMainFrame()
1001 ->EnablePreferredSizeChangedMode();
1002 }
1003 }
1004
ExecutePluginActionAtLocation(const gfx::Point & location,blink::mojom::PluginActionType plugin_action)1005 void RenderViewHostImpl::ExecutePluginActionAtLocation(
1006 const gfx::Point& location,
1007 blink::mojom::PluginActionType plugin_action) {
1008 // TODO(wjmaclean): See if this needs to be done for OOPIFs as well.
1009 // https://crbug.com/776807
1010 gfx::PointF local_location_f =
1011 GetWidget()->GetView()->TransformRootPointToViewCoordSpace(
1012 gfx::PointF(location.x(), location.y()));
1013 gfx::Point local_location(local_location_f.x(), local_location_f.y());
1014
1015 static_cast<RenderFrameHostImpl*>(GetMainFrame())
1016 ->GetAssociatedLocalMainFrame()
1017 ->PluginActionAt(local_location, plugin_action);
1018 }
1019
NotifyMoveOrResizeStarted()1020 void RenderViewHostImpl::NotifyMoveOrResizeStarted() {
1021 Send(new ViewMsg_MoveOrResizeStarted(GetRoutingID()));
1022 }
1023
PostRenderViewReady()1024 void RenderViewHostImpl::PostRenderViewReady() {
1025 GetProcess()->PostTaskWhenProcessIsReady(base::BindOnce(
1026 &RenderViewHostImpl::RenderViewReady, weak_factory_.GetWeakPtr()));
1027 }
1028
OnGpuSwitched(gl::GpuPreference active_gpu_heuristic)1029 void RenderViewHostImpl::OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) {
1030 OnHardwareConfigurationChanged();
1031 }
1032
RenderViewReady()1033 void RenderViewHostImpl::RenderViewReady() {
1034 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1035 delegate_->RenderViewReady(this);
1036 }
1037
ClosePageTimeout()1038 void RenderViewHostImpl::ClosePageTimeout() {
1039 if (delegate_->ShouldIgnoreUnresponsiveRenderer())
1040 return;
1041
1042 ClosePageIgnoringUnloadEvents();
1043 }
1044
CollectSurfaceIdsForEviction()1045 std::vector<viz::SurfaceId> RenderViewHostImpl::CollectSurfaceIdsForEviction() {
1046 if (!is_active())
1047 return {};
1048 RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame());
1049 if (!rfh || !rfh->IsCurrent())
1050 return {};
1051 FrameTreeNode* root = rfh->frame_tree_node();
1052 FrameTree* tree = root->frame_tree();
1053 std::vector<viz::SurfaceId> ids;
1054 for (FrameTreeNode* node : tree->SubtreeNodes(root)) {
1055 if (!node->current_frame_host()->is_local_root())
1056 continue;
1057 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
1058 node->current_frame_host()->GetView());
1059 if (!view)
1060 continue;
1061 viz::SurfaceId id = view->GetCurrentSurfaceId();
1062 if (id.is_valid())
1063 ids.push_back(id);
1064 view->set_is_evicted();
1065 }
1066 return ids;
1067 }
1068
ResetPerPageState()1069 void RenderViewHostImpl::ResetPerPageState() {
1070 did_first_visually_non_empty_paint_ = false;
1071 main_frame_theme_color_.reset();
1072 is_document_on_load_completed_in_main_frame_ = false;
1073 }
1074
OnThemeColorChanged(RenderFrameHostImpl * rfh,const base::Optional<SkColor> & theme_color)1075 void RenderViewHostImpl::OnThemeColorChanged(
1076 RenderFrameHostImpl* rfh,
1077 const base::Optional<SkColor>& theme_color) {
1078 if (GetMainFrame() != rfh)
1079 return;
1080 main_frame_theme_color_ = theme_color;
1081 delegate_->OnThemeColorChanged(this);
1082 }
1083
DocumentOnLoadCompletedInMainFrame()1084 void RenderViewHostImpl::DocumentOnLoadCompletedInMainFrame() {
1085 is_document_on_load_completed_in_main_frame_ = true;
1086 }
1087
IsDocumentOnLoadCompletedInMainFrame()1088 bool RenderViewHostImpl::IsDocumentOnLoadCompletedInMainFrame() {
1089 return is_document_on_load_completed_in_main_frame_;
1090 }
1091
IsTestRenderViewHost() const1092 bool RenderViewHostImpl::IsTestRenderViewHost() const {
1093 return false;
1094 }
1095
SetWillEnterBackForwardCacheCallbackForTesting(const WillEnterBackForwardCacheCallbackForTesting & callback)1096 void RenderViewHostImpl::SetWillEnterBackForwardCacheCallbackForTesting(
1097 const WillEnterBackForwardCacheCallbackForTesting& callback) {
1098 will_enter_back_forward_cache_callback_for_testing_ = callback;
1099 }
1100
1101 } // namespace content
1102