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