| // Copyright 2012 The Chromium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_ | 
 | #define CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_ | 
 |  | 
 | #include <stddef.h> | 
 | #include <stdint.h> | 
 |  | 
 | #include <map> | 
 | #include <memory> | 
 | #include <string> | 
 | #include <vector> | 
 |  | 
 | #include "base/functional/callback.h" | 
 | #include "base/gtest_prod_util.h" | 
 | #include "base/memory/raw_ptr.h" | 
 | #include "base/memory/ref_counted.h" | 
 | #include "base/memory/safe_ref.h" | 
 | #include "base/process/kill.h" | 
 | #include "base/time/time.h" | 
 | #include "build/build_config.h" | 
 | #include "content/browser/renderer_host/browsing_context_state.h" | 
 | #include "content/browser/renderer_host/frame_tree.h" | 
 | #include "content/browser/renderer_host/input/input_device_change_observer.h" | 
 | #include "content/browser/renderer_host/page_lifecycle_state_manager.h" | 
 | #include "content/browser/renderer_host/render_widget_host_impl.h" | 
 | #include "content/browser/renderer_host/render_widget_host_owner_delegate.h" | 
 | #include "content/browser/site_instance_group.h" | 
 | #include "content/browser/site_instance_impl.h" | 
 | #include "content/common/content_export.h" | 
 | #include "content/common/render_message_filter.mojom.h" | 
 | #include "content/public/browser/global_routing_id.h" | 
 | #include "content/public/browser/notification_observer.h" | 
 | #include "content/public/browser/render_process_host_observer.h" | 
 | #include "content/public/browser/render_view_host.h" | 
 | #include "mojo/public/cpp/bindings/pending_remote.h" | 
 | #include "net/base/load_states.h" | 
 | #include "third_party/abseil-cpp/absl/types/optional.h" | 
 | #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" | 
 | #include "third_party/blink/public/common/tokens/tokens.h" | 
 | #include "third_party/blink/public/mojom/page/page.mojom.h" | 
 | #include "third_party/blink/public/web/web_ax_enums.h" | 
 | #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h" | 
 | #include "third_party/skia/include/core/SkColor.h" | 
 | #include "ui/base/window_open_disposition.h" | 
 | #include "ui/gl/gpu_preference.h" | 
 | #include "ui/gl/gpu_switching_observer.h" | 
 |  | 
 | namespace blink { | 
 | namespace web_pref { | 
 | struct WebPreferences; | 
 | } | 
 | }  // namespace blink | 
 |  | 
 | namespace content { | 
 |  | 
 | class AgentSchedulingGroupHost; | 
 | class RenderProcessHost; | 
 |  | 
 | // A callback which will be called immediately before EnterBackForwardCache | 
 | // starts. | 
 | using WillEnterBackForwardCacheCallbackForTesting = | 
 |     base::RepeatingCallback<void()>; | 
 |  | 
 | // A callback which will be called immediately before sending the | 
 | // RendererPreferences information to the renderer. | 
 | using WillSendRendererPreferencesCallbackForTesting = | 
 |     base::RepeatingCallback<void(const blink::RendererPreferences&)>; | 
 |  | 
 | // This implements the RenderViewHost interface that is exposed to | 
 | // embedders of content, and adds things only visible to content. | 
 | // | 
 | // The exact API of this object needs to be more thoroughly designed. Right | 
 | // now it mimics what WebContentsImpl exposed, which is a fairly large API and | 
 | // may contain things that are not relevant to a common subset of views. See | 
 | // also the comment in render_view_host_delegate.h about the size and scope of | 
 | // the delegate API. | 
 | // | 
 | // Right now, the concept of page navigation (both top level and frame) exists | 
 | // in the WebContentsImpl still, so if you instantiate one of these elsewhere, | 
 | // you will not be able to traverse pages back and forward. We need to determine | 
 | // if we want to bring that and other functionality down into this object so it | 
 | // can be shared by others. | 
 | // | 
 | // DEPRECATED: RenderViewHostImpl is being removed as part of the SiteIsolation | 
 | // project. New code should not be added here, but to either RenderFrameHostImpl | 
 | // (if frame specific) or PageImpl (if page specific). | 
 | // | 
 | // For context, please see https://crbug.com/467770 and | 
 | // https://www.chromium.org/developers/design-documents/site-isolation. | 
 | class CONTENT_EXPORT RenderViewHostImpl | 
 |     : public RenderViewHost, | 
 |       public RenderWidgetHostOwnerDelegate, | 
 |       public RenderProcessHostObserver, | 
 |       public ui::GpuSwitchingObserver, | 
 |       public IPC::Listener, | 
 |       public base::RefCounted<RenderViewHostImpl> { | 
 |  public: | 
 |   // Convenience function, just like RenderViewHost::FromID. | 
 |   static RenderViewHostImpl* FromID(int process_id, int routing_id); | 
 |  | 
 |   // Convenience function, just like RenderViewHost::From. | 
 |   static RenderViewHostImpl* From(RenderWidgetHost* rwh); | 
 |  | 
 |   static void GetPlatformSpecificPrefs(blink::RendererPreferences* prefs); | 
 |  | 
 |   // Checks whether any RenderViewHostImpl instance associated with a given | 
 |   // process is not currently in the back-forward cache. | 
 |   // TODO(https://crbug.com/1125996): Remove once a well-behaved frozen | 
 |   // RenderFrame never send IPCs messages, even if there are active pages in the | 
 |   // process. | 
 |   static bool HasNonBackForwardCachedInstancesForProcess( | 
 |       RenderProcessHost* process); | 
 |  | 
 |   RenderViewHostImpl( | 
 |       FrameTree* frame_tree, | 
 |       SiteInstanceGroup* group, | 
 |       const StoragePartitionConfig& storage_partition_config, | 
 |       std::unique_ptr<RenderWidgetHostImpl> widget, | 
 |       RenderViewHostDelegate* delegate, | 
 |       int32_t routing_id, | 
 |       int32_t main_frame_routing_id, | 
 |       bool has_initialized_audio_host, | 
 |       scoped_refptr<BrowsingContextState> main_browsing_context_state, | 
 |       CreateRenderViewHostCase create_case); | 
 |  | 
 |   RenderViewHostImpl(const RenderViewHostImpl&) = delete; | 
 |   RenderViewHostImpl& operator=(const RenderViewHostImpl&) = delete; | 
 |  | 
 |   // RenderViewHost implementation. | 
 |   RenderWidgetHostImpl* GetWidget() const override; | 
 |   RenderProcessHost* GetProcess() const override; | 
 |   int GetRoutingID() const override; | 
 |   void EnablePreferredSizeMode() override; | 
 |   void WriteIntoTrace(perfetto::TracedProto<TraceProto> context) const override; | 
 |  | 
 |   void SendWebPreferencesToRenderer(); | 
 |   void SendRendererPreferencesToRenderer( | 
 |       const blink::RendererPreferences& preferences); | 
 |  | 
 |   // RenderProcessHostObserver implementation | 
 |   void RenderProcessExited(RenderProcessHost* host, | 
 |                            const ChildProcessTerminationInfo& info) override; | 
 |  | 
 |   // GpuSwitchingObserver implementation. | 
 |   void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) override; | 
 |  | 
 |   // Set up the `blink::WebView` child process. Virtual because it is overridden | 
 |   // by TestRenderViewHost. | 
 |   // `opener_route_id` parameter indicates which `blink::WebView` created this | 
 |   //   (MSG_ROUTING_NONE if none). | 
 |   // `window_was_opened_by_another_window` is true if this top-level frame was | 
 |   //   created by another window, as opposed to independently created (through | 
 |   //   the browser UI, etc). This is true even when the window is opened with | 
 |   //   "noopener", and even if the opener has been closed since. | 
 |   // `proxy_route_id` is only used when creating a `blink::WebView` in an | 
 |   //   inactive state. | 
 |   virtual bool CreateRenderView( | 
 |       const absl::optional<blink::FrameToken>& opener_frame_token, | 
 |       int proxy_route_id, | 
 |       bool window_was_opened_by_another_window); | 
 |  | 
 |   RenderViewHostDelegate* GetDelegate(); | 
 |  | 
 |   bool is_speculative() { return is_speculative_; } | 
 |   void set_is_speculative(bool is_speculative) { | 
 |     is_speculative_ = is_speculative; | 
 |   } | 
 |   void set_is_registered_with_frame_tree(bool is_registered) { | 
 |     registered_with_frame_tree_ = is_registered; | 
 |   } | 
 |  | 
 |   FrameTree::RenderViewHostMapId rvh_map_id() const { | 
 |     return render_view_host_map_id_; | 
 |   } | 
 |  | 
 |   base::WeakPtr<RenderViewHostImpl> GetWeakPtr(); | 
 |  | 
 |   // Tracks whether this RenderViewHost is in an active state (rather than | 
 |   // pending unload or unloaded), according to its main frame | 
 |   // RenderFrameHost. | 
 |   bool is_active() const { return main_frame_routing_id_ != MSG_ROUTING_NONE; } | 
 |  | 
 |   // Returns true if the `blink::WebView` is active and has not crashed. | 
 |   bool IsRenderViewLive() const; | 
 |  | 
 |   // Called when the `blink::WebView` in the renderer process has been created, | 
 |   // at which point IsRenderViewLive() becomes true, and the mojo connections to | 
 |   // the renderer process for this view now exist. | 
 |   void RenderViewCreated(RenderFrameHostImpl* local_main_frame); | 
 |  | 
 |   // Returns the main RenderFrameHostImpl associated with this RenderViewHost or | 
 |   // null if it doesn't exist. It's null if the main frame is represented in | 
 |   // this RenderViewHost by RenderFrameProxyHost (from Blink perspective, | 
 |   // blink::Page's main blink::Frame is remote). | 
 |   RenderFrameHostImpl* GetMainRenderFrameHost(); | 
 |  | 
 |   // RenderViewHost is associated with a given SiteInstanceGroup and as | 
 |   // BrowsingContextState in non-legacy BrowsingContextState mode is tied to a | 
 |   // given BrowsingInstance, so the main BrowsingContextState stays the same | 
 |   // during the entire lifetime of a RenderViewHost: cross-SiteInstanceGroup | 
 |   // same-BrowsingInstance navigations might change the representation of the | 
 |   // main frame in a given `blink::WebView` from RenderFrame to | 
 |   // `blink::RemoteFrame` and back, while cross-BrowsingInstances result in | 
 |   // creating a new unrelated RenderViewHost. This is not true in the legacy BCS | 
 |   // mode, so there the `main_browsing_context_state_` is null. | 
 |   const absl::optional<base::SafeRef<BrowsingContextState>>& | 
 |   main_browsing_context_state() const { | 
 |     return main_browsing_context_state_; | 
 |   } | 
 |  | 
 |   // Returns the `AgentSchedulingGroupHost` this view is associated with (via | 
 |   // the widget). | 
 |   AgentSchedulingGroupHost& GetAgentSchedulingGroup() const; | 
 |  | 
 |   // Tells the renderer process to request a page-scale animation based on the | 
 |   // specified point/rect. | 
 |   void AnimateDoubleTapZoom(const gfx::Point& point, const gfx::Rect& rect); | 
 |  | 
 |   // Requests a page-scale animation based on the specified rect. | 
 |   void ZoomToFindInPageRect(const gfx::Rect& rect_to_zoom); | 
 |  | 
 |   // Tells the renderer view to focus the first (last if reverse is true) node. | 
 |   void SetInitialFocus(bool reverse); | 
 |  | 
 |   // Send RenderViewReady to observers once the process is launched, but not | 
 |   // re-entrantly. | 
 |   void PostRenderViewReady(); | 
 |  | 
 |   // Passes current web preferences to the renderer after recomputing all of | 
 |   // them, including the slow-to-compute hardware preferences. | 
 |   // (WebContents::OnWebPreferencesChanged is a faster alternate that avoids | 
 |   // slow recomputations.) | 
 |   void OnHardwareConfigurationChanged(); | 
 |  | 
 |   // Sets the routing id for the main frame. When set to MSG_ROUTING_NONE, the | 
 |   // view is not considered active. | 
 |   void SetMainFrameRoutingId(int routing_id); | 
 |  | 
 |   // Called when the RenderFrameHostImpls/RenderFrameProxyHosts that own this | 
 |   // RenderViewHost enter the BackForwardCache. | 
 |   void EnterBackForwardCache(); | 
 |  | 
 |   // Indicates whether or not |this| has received an acknowledgement from | 
 |   // renderer that it has enered BackForwardCache. | 
 |   bool DidReceiveBackForwardCacheAck(); | 
 |  | 
 |   // Called when the RenderFrameHostImpls/RenderFrameProxyHosts that own this | 
 |   // RenderViewHost leave the BackForwardCache. This occurs immediately before a | 
 |   // restored document is committed. | 
 |   // |page_restore_params| includes information that is needed by the page after | 
 |   // getting restored, which includes the latest history information (offset, | 
 |   // length) and the timestamp corresponding to the start of the back-forward | 
 |   // cached navigation, which would be communicated to the page to allow it to | 
 |   // record the latency of this navigation. | 
 |   void LeaveBackForwardCache( | 
 |       blink::mojom::PageRestoreParamsPtr page_restore_params); | 
 |  | 
 |   bool is_in_back_forward_cache() const { return is_in_back_forward_cache_; } | 
 |  | 
 |   void ActivatePrerenderedPage(blink::mojom::PrerenderPageActivationParamsPtr | 
 |                                    prerender_page_activation_params, | 
 |                                base::OnceClosure callback); | 
 |  | 
 |   void SetFrameTreeVisibility(blink::mojom::PageVisibilityState visibility); | 
 |  | 
 |   void SetIsFrozen(bool frozen); | 
 |   void OnBackForwardCacheTimeout(); | 
 |   void MaybeEvictFromBackForwardCache(); | 
 |   void EnforceBackForwardCacheSizeLimit(); | 
 |  | 
 |   PageLifecycleStateManager* GetPageLifecycleStateManager() { | 
 |     return page_lifecycle_state_manager_.get(); | 
 |   } | 
 |  | 
 |   // Called during frame eviction to return all SurfaceIds in the frame tree. | 
 |   // Marks all views in the frame tree as evicted. | 
 |   std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction(); | 
 |  | 
 |   // Manual RTTI to ensure safe downcasts in tests. | 
 |   virtual bool IsTestRenderViewHost() const; | 
 |  | 
 |   void SetWillEnterBackForwardCacheCallbackForTesting( | 
 |       const WillEnterBackForwardCacheCallbackForTesting& callback); | 
 |  | 
 |   void SetWillSendRendererPreferencesCallbackForTesting( | 
 |       const WillSendRendererPreferencesCallbackForTesting& callback); | 
 |  | 
 |   void BindPageBroadcast( | 
 |       mojo::PendingAssociatedRemote<blink::mojom::PageBroadcast> | 
 |           page_broadcast); | 
 |  | 
 |   // The remote mojom::PageBroadcast interface that is used to send messages to | 
 |   // the renderer's blink::WebViewImpl when broadcasting messages to all | 
 |   // renderers hosting frames in the frame tree. | 
 |   const mojo::AssociatedRemote<blink::mojom::PageBroadcast>& | 
 |   GetAssociatedPageBroadcast(); | 
 |  | 
 |   // Prepares the renderer page to leave the back-forward cache by disabling | 
 |   // Javascript eviction. |done_cb| is called upon receipt of the | 
 |   // acknowledgement from the renderer that this has actually happened. | 
 |   // | 
 |   // After |done_cb| is called you can be certain that this renderer will not | 
 |   // trigger an eviction of this page. | 
 |   void PrepareToLeaveBackForwardCache(base::OnceClosure done_cb); | 
 |  | 
 |   // TODO(https://crbug.com/1179502): FrameTree and FrameTreeNode will not be | 
 |   // const as with prerenderer activation the page needs to move between | 
 |   // FrameTreeNodes and FrameTrees. As it's hard to make sure that all places | 
 |   // handle this transition correctly, MPArch will remove references from this | 
 |   // class to FrameTree/FrameTreeNode. | 
 |   FrameTree* frame_tree() const { return frame_tree_; } | 
 |   void SetFrameTree(FrameTree& frame_tree); | 
 |  | 
 |   // Mark this RenderViewHost as not available for reuse. This will remove | 
 |   // it from being registered with the associated FrameTree. | 
 |   void DisallowReuse(); | 
 |  | 
 |   base::SafeRef<RenderViewHostImpl> GetSafeRef(); | 
 |  | 
 |   SiteInstanceGroup* site_instance_group() const { | 
 |     return &*site_instance_group_; | 
 |   } | 
 |  | 
 |   // NOTE: Do not add functions that just send an IPC message that are called in | 
 |   // one or two places. Have the caller send the IPC message directly (unless | 
 |   // the caller places are in different platforms, in which case it's better | 
 |   // to keep them consistent). | 
 |  | 
 |  protected: | 
 |   friend class base::RefCounted<RenderViewHostImpl>; | 
 |   ~RenderViewHostImpl() override; | 
 |  | 
 |   // RenderWidgetHostOwnerDelegate overrides. | 
 |   void RenderWidgetGotFocus() override; | 
 |   void RenderWidgetLostFocus() override; | 
 |   void RenderWidgetDidForwardMouseEvent( | 
 |       const blink::WebMouseEvent& mouse_event) override; | 
 |   bool MayRenderWidgetForwardKeyboardEvent( | 
 |       const NativeWebKeyboardEvent& key_event) override; | 
 |   bool ShouldContributePriorityToProcess() override; | 
 |   void SetBackgroundOpaque(bool opaque) override; | 
 |   bool IsMainFrameActive() override; | 
 |   bool IsNeverComposited() override; | 
 |   blink::web_pref::WebPreferences GetWebkitPreferencesForWidget() override; | 
 |  | 
 |   // IPC message handlers. | 
 |   void OnShowView(int route_id, | 
 |                   WindowOpenDisposition disposition, | 
 |                   const gfx::Rect& initial_rect, | 
 |                   bool user_gesture); | 
 |   void OnShowWidget(int widget_route_id, const gfx::Rect& initial_rect); | 
 |   void OnPasteFromSelectionClipboard(); | 
 |   void OnTakeFocus(bool reverse); | 
 |   void OnFocus(); | 
 |  | 
 |  private: | 
 |   // TODO(nasko): Temporarily friend RenderFrameHostImpl, so we don't duplicate | 
 |   // utility functions and state needed in both classes, while we move frame | 
 |   // specific code away from this class. | 
 |   friend class RenderFrameHostImpl; | 
 |   friend class TestRenderViewHost; | 
 |   friend class PageLifecycleStateManagerBrowserTest; | 
 |   FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, BasicRenderFrameHost); | 
 |   FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, RoutingIdSane); | 
 |  | 
 |   // IPC::Listener implementation. | 
 |   bool OnMessageReceived(const IPC::Message& msg) override; | 
 |   std::string ToDebugString() override; | 
 |  | 
 |   void RenderViewReady(); | 
 |  | 
 |   // The RenderWidgetHost. | 
 |   const std::unique_ptr<RenderWidgetHostImpl> render_widget_host_; | 
 |  | 
 |   // Our delegate, which wants to know about changes in the `blink::WebView`. | 
 |   raw_ptr<RenderViewHostDelegate> delegate_; | 
 |  | 
 |   // ID to use when registering/unregistering this object with its FrameTree. | 
 |   // This ID is generated by passing a SiteInstanceGroup to | 
 |   // FrameTree::GetRenderViewHostMapId(). This RenderViewHost may only be reused | 
 |   // by frames with SiteInstanceGroups that generate an ID that matches this | 
 |   // field. | 
 |   FrameTree::RenderViewHostMapId render_view_host_map_id_; | 
 |  | 
 |   // The SiteInstanceGroup this RenderViewHostImpl belongs to. | 
 |   base::SafeRef<SiteInstanceGroup> site_instance_group_; | 
 |  | 
 |   // Provides information for selecting the session storage namespace for this | 
 |   // view. | 
 |   const StoragePartitionConfig storage_partition_config_; | 
 |  | 
 |   // Routing ID for this RenderViewHost. | 
 |   const int routing_id_; | 
 |  | 
 |   // Whether the renderer-side `blink::WebView` is created. Becomes false when | 
 |   // the renderer crashes. | 
 |   bool renderer_view_created_ = false; | 
 |  | 
 |   // Routing ID for the main frame's RenderFrameHost. | 
 |   int main_frame_routing_id_; | 
 |  | 
 |   // This monitors input changes so they can be reflected to the interaction MQ. | 
 |   std::unique_ptr<InputDeviceChangeObserver> input_device_change_observer_; | 
 |  | 
 |   // This controls the lifecycle change and notify the renderer. | 
 |   std::unique_ptr<PageLifecycleStateManager> page_lifecycle_state_manager_; | 
 |  | 
 |   bool updating_web_preferences_ = false; | 
 |  | 
 |   // BackForwardCache: | 
 |   bool is_in_back_forward_cache_ = false; | 
 |  | 
 |   WillEnterBackForwardCacheCallbackForTesting | 
 |       will_enter_back_forward_cache_callback_for_testing_; | 
 |  | 
 |   WillSendRendererPreferencesCallbackForTesting | 
 |       will_send_renderer_preferences_callback_for_testing_; | 
 |  | 
 |   mojo::AssociatedRemote<blink::mojom::PageBroadcast> page_broadcast_; | 
 |  | 
 |   raw_ptr<FrameTree> frame_tree_; | 
 |  | 
 |   // See main_browsing_context_state() for more details. | 
 |   absl::optional<base::SafeRef<BrowsingContextState>> | 
 |       main_browsing_context_state_; | 
 |  | 
 |   bool registered_with_frame_tree_ = false; | 
 |  | 
 |   // Whether the RenderViewHost is a speculative RenderViewHost or not. | 
 |   // Currently this is never set, as the feature is not implemented yet. | 
 |   // TODO(https://crbug.com/1336305): Actually set this value for speculative | 
 |   // RenderViewHosts. | 
 |   bool is_speculative_ = false; | 
 |  | 
 |   base::WeakPtrFactory<RenderViewHostImpl> weak_factory_{this}; | 
 | }; | 
 |  | 
 | }  // namespace content | 
 |  | 
 | #endif  // CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_ |