// 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_WEB_CONTENTS_WEB_CONTENTS_IMPL_H_
#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_IMPL_H_

#include <stdint.h>

#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_buildflags.h"
#include "base/callback_list.h"
#include "base/containers/flat_map.h"
#include "base/functional/callback_helpers.h"
#include "base/functional/function_ref.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/safe_ref.h"
#include "base/observer_list.h"
#include "base/process/kill.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/download/public/common/download_url_parameters.h"
#include "content/browser/media/audio_stream_monitor.h"
#include "content/browser/media/forwarding_audio_stream_factory.h"
#include "content/browser/preloading/prerender/prerender_final_status.h"
#include "content/browser/preloading/prerender/prerender_handle_impl.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_controller_delegate.h"
#include "content/browser/renderer_host/navigation_controller_impl.h"
#include "content/browser/renderer_host/navigator_delegate.h"
#include "content/browser/renderer_host/page_delegate.h"
#include "content/browser/renderer_host/page_impl.h"
#include "content/browser/renderer_host/render_frame_host_delegate.h"
#include "content/browser/renderer_host/render_frame_host_manager.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/visible_time_request_trigger.h"
#include "content/browser/web_contents/file_chooser_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/fullscreen_types.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/media_stream_request.h"
#include "content/public/browser/mhtml_generation_result.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/load_states.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/device/public/mojom/geolocation_context.mojom.h"
#include "services/network/public/mojom/fetch_api.mojom-forward.h"
#include "third_party/blink/public/common/frame/transient_allow_fullscreen.h"
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/choosers/color_chooser.mojom.h"
#include "third_party/blink/public/mojom/choosers/popup_menu.mojom-forward.h"
#include "third_party/blink/public/mojom/frame/blocked_navigation_types.mojom-shared.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-forward.h"
#include "third_party/blink/public/mojom/frame/text_autosizer_page_info.mojom.h"
#include "third_party/blink/public/mojom/input/input_handler.mojom-shared.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-forward.h"
#include "third_party/blink/public/mojom/media/capture_handle_config.mojom.h"
#include "third_party/blink/public/mojom/page/display_cutout.mojom-shared.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom-shared.h"
#include "ui/accessibility/ax_mode.h"
#include "ui/accessibility/platform/inspect/ax_event_recorder.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h"
#include "ui/base/ime/mojom/virtual_keyboard_types.mojom.h"
#include "ui/base/ui_base_types.h"
#include "ui/color/color_provider_key.h"
#include "ui/color/color_provider_source_observer.h"
#include "ui/gfx/geometry/size.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/native_theme_observer.h"

#if BUILDFLAG(IS_ANDROID)
#include "content/public/browser/android/child_process_importance.h"
#endif

#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(USE_STARSCAN)
#include "content/browser/starscan_load_observer.h"
#endif

namespace base {
class FilePath;
}  // namespace base

namespace device {
namespace mojom {
class WakeLock;
}
}  // namespace device

namespace network::mojom {
class SharedDictionaryAccessDetails;
}  // namespace network::mojom

namespace service_manager {
class InterfaceProvider;
}  // namespace service_manager

namespace content {
class JavaScriptDialogDismissNotifier;
enum class PictureInPictureResult;
class BeforeUnloadBlockingDelegate;  // content_browser_test_utils_internal.h
class BrowserPluginEmbedder;
class BrowserPluginGuest;
class FindRequestManager;
class JavaScriptDialogManager;
class MediaSession;
class MediaWebContentsObserver;
class NFCHost;
class RenderFrameHost;
class RenderFrameHostImpl;
class RenderViewHost;
class RenderViewHostDelegateView;
class RenderWidgetHostImpl;
class RenderWidgetHostInputEventRouter;
class SafeAreaInsetsHost;
class SavePackage;
class ScopedAccessibilityMode;
class ScreenChangeMonitor;
class ScreenOrientationProvider;
class SiteInstanceGroup;
// For web_contents_impl_browsertest.cc
class TestWCDelegateForDialogsAndFullscreen;
class TestWebContents;
class TextInputManager;
class WakeLockContextHost;
class WebContentsDelegate;
class WebContentsImpl;
class WebContentsView;
struct AXEventNotificationDetails;
struct MHTMLGenerationParams;
class PreloadingAttempt;

namespace mojom {
class CreateNewWindowParams;
}  // namespace mojom

#if BUILDFLAG(IS_ANDROID)
class WebContentsAndroid;
#endif

#if BUILDFLAG(ENABLE_PPAPI)
class PepperPlaybackObserver;
#endif

// CreatedWindow holds the WebContentsImpl and target url between IPC calls to
// CreateNewWindow and ShowCreatedWindow.
struct CONTENT_EXPORT CreatedWindow {
  CreatedWindow();
  CreatedWindow(std::unique_ptr<WebContentsImpl> contents, GURL target_url);
  CreatedWindow(CreatedWindow&&);
  CreatedWindow(const CreatedWindow&) = delete;
  CreatedWindow& operator=(CreatedWindow&&);
  CreatedWindow& operator=(const CreatedWindow&) = delete;
  ~CreatedWindow();

  std::unique_ptr<WebContentsImpl> contents;
  GURL target_url;
};

using PageVisibilityState = blink::mojom::PageVisibilityState;

using ClipboardPasteData = content::ClipboardPasteData;

class CONTENT_EXPORT WebContentsImpl : public WebContents,
                                       public FrameTree::Delegate,
                                       public RenderFrameHostDelegate,
                                       public RenderViewHostDelegate,
                                       public RenderWidgetHostDelegate,
                                       public RenderFrameHostManager::Delegate,
                                       public PageDelegate,
                                       public blink::mojom::ColorChooserFactory,
                                       public NavigationControllerDelegate,
                                       public NavigatorDelegate,
                                       public ui::NativeThemeObserver,
                                       public ui::ColorProviderSourceObserver {
 public:
  class FriendWrapper;

  WebContentsImpl(const WebContentsImpl&) = delete;
  WebContentsImpl& operator=(const WebContentsImpl&) = delete;

  ~WebContentsImpl() override;

  static std::unique_ptr<WebContentsImpl> CreateWithOpener(
      const WebContents::CreateParams& params,
      RenderFrameHostImpl* opener_rfh);

  static std::vector<WebContentsImpl*> GetAllWebContents();

  static WebContentsImpl* FromFrameTreeNode(
      const FrameTreeNode* frame_tree_node);
  static WebContents* FromRenderFrameHostID(
      GlobalRenderFrameHostId render_frame_host_id);
  static WebContents* FromRenderFrameHostID(int render_process_host_id,
                                            int render_frame_host_id);
  static WebContents* FromFrameTreeNodeId(int frame_tree_node_id);
  static WebContentsImpl* FromOuterFrameTreeNode(
      const FrameTreeNode* frame_tree_node);
  static WebContentsImpl* FromRenderWidgetHostImpl(RenderWidgetHostImpl* rwh);
  static WebContentsImpl* FromRenderFrameHostImpl(RenderFrameHostImpl* rfh);

  // Complex initialization here. Specifically needed to avoid having
  // members call back into our virtual functions in the constructor.
  // The primary main frame policy might be passed down as it is inherited from
  // the opener when WebContents is created with an opener.
  virtual void Init(const WebContents::CreateParams& params,
                    blink::FramePolicy primary_main_frame_policy);

  // Returns the SavePackage which manages the page saving job. May be NULL.
  SavePackage* save_package() const { return save_package_.get(); }

  // Sets a BrowserPluginGuest object for this WebContents. If this WebContents
  // has a BrowserPluginGuest then that implies that it is being hosted by
  // a BrowserPlugin object in an embedder renderer process.
  void SetBrowserPluginGuest(std::unique_ptr<BrowserPluginGuest> guest);

  // Returns embedder browser plugin object, or NULL if this WebContents is not
  // an embedder.
  BrowserPluginEmbedder* GetBrowserPluginEmbedder() const;

  // Returns guest browser plugin object, or nullptr if this WebContents is not
  // for guest.
  BrowserPluginGuest* GetBrowserPluginGuest() const;

  // Creates a BrowserPluginEmbedder object for this WebContents if one doesn't
  // already exist.
  void CreateBrowserPluginEmbedderIfNecessary();

  // Cancels modal dialogs in this WebContents, as well as in any browser
  // plugins it is hosting.
  void CancelActiveAndPendingDialogs();

  // Informs the render view host and the BrowserPluginEmbedder, if present, of
  // a Drag Source End.
  void DragSourceEndedAt(float client_x,
                         float client_y,
                         float screen_x,
                         float screen_y,
                         ui::mojom::DragOperation operation,
                         RenderWidgetHost* source_rwh);

  // Notification that the RenderViewHost's load state changed.
  void LoadStateChanged(network::mojom::LoadInfoPtr load_info);

  // Updates the visibility and notifies observers. Note that this is
  // distinct from UpdateWebContentsVisibility which may also update the
  // visibility of renderer-side objects.
  void SetVisibilityAndNotifyObservers(Visibility visibility);

  // Notify observers that the web contents has been focused.
  void NotifyWebContentsFocused(RenderWidgetHost* render_widget_host);

  // Notify observers that the web contents has lost focus.
  void NotifyWebContentsLostFocus(RenderWidgetHost* render_widget_host);

  WebContentsView* GetView() const;

  // Called on screen information changes; |is_multi_screen_changed| is true iff
  // the plurality of connected screens changed (e.g. 1 screen <-> 2 screens).
  void OnScreensChange(bool is_multi_screen_changed);

  void OnScreenOrientationChange();

  ScreenOrientationProvider* GetScreenOrientationProviderForTesting() const {
    return screen_orientation_provider_.get();
  }

  // Adds the given accessibility mode to the current accessibility mode
  // bitmap.
  void AddAccessibilityModeForTesting(ui::AXMode mode);

  // Sets the zoom level for frames associated with this WebContents.
  void UpdateZoom();

  // Sets the zoom level for frames associated with this WebContents if it
  // matches |host| and (if non-empty) |scheme|. Matching is done on the
  // last committed entry.
  void UpdateZoomIfNecessary(const std::string& scheme,
                             const std::string& host);

  // Returns the focused WebContents.
  // If there are multiple inner/outer WebContents (when embedding <webview>,
  // <guestview>, ...) returns the single one containing the currently focused
  // frame. Otherwise, returns this WebContents.
  WebContentsImpl* GetFocusedWebContents();

  // Returns the focused FrameTree. For MPArch we may return a different
  // focused frame tree even though the focused WebContents is the same.
  FrameTree* GetFocusedFrameTree();

  // TODO(lukasza): Maybe this method can be removed altogether (so that the
  // focus of the location bar is only set in the //chrome layer).
  void SetFocusToLocationBar();

  // Returns a vector containing this WebContents and all inner WebContents
  // within it (recursively).
  std::vector<WebContentsImpl*> GetWebContentsAndAllInner();

  // Returns the primary FrameTree for this WebContents (as opposed to the
  // ones held by MPArch features like Prerender or Fenced Frame).
  // See docs/frame_trees.md for more details.
  FrameTree& GetPrimaryFrameTree() { return primary_frame_tree_; }

  // Whether the initial empty page of this view has been accessed by another
  // page, making it unsafe to show the pending URL. Always false after the
  // first commit.
  // TODO(https://crbug.com/1170277): Rename to HasAccessedInitialMainDocument
  bool HasAccessedInitialDocument();

#if BUILDFLAG(IS_ANDROID)
  void SetPrimaryMainFrameImportance(ChildProcessImportance importance);
#endif

  // Returns the human-readable name for title in Media Controls.
  // If the returned value is an empty string, it means that there is no
  // human-readable name.
  std::string GetTitleForMediaControls();

  // Sets the accessibility mode if this WebContents will potentially be
  // user-visible, and broadcasts it to all of its frames if it differs from the
  // previous mode.
  void SetAccessibilityMode(ui::AXMode mode);

  // WebContents ------------------------------------------------------
  WebContentsDelegate* GetDelegate() final;
  void SetDelegate(WebContentsDelegate* delegate) override;
  NavigationControllerImpl& GetController() override;
  BrowserContext* GetBrowserContext() override;
  base::WeakPtr<WebContents> GetWeakPtr() override;
  const GURL& GetURL() override;
  const GURL& GetVisibleURL() override;
  const GURL& GetLastCommittedURL() override;
  const RenderFrameHostImpl* GetPrimaryMainFrame() const override;
  RenderFrameHostImpl* GetPrimaryMainFrame() override;
  PageImpl& GetPrimaryPage() override;
  RenderFrameHostImpl* GetFocusedFrame() override;
  bool IsPrerenderedFrame(int frame_tree_node_id) override;
  RenderFrameHostImpl* UnsafeFindFrameByFrameTreeNodeId(
      int frame_tree_node_id) override;
  void ForEachRenderFrameHostWithAction(
      base::FunctionRef<FrameIterationAction(RenderFrameHost*)> on_frame)
      override;
  void ForEachRenderFrameHost(
      base::FunctionRef<void(RenderFrameHost*)> on_frame) override;
  RenderViewHostImpl* GetRenderViewHost() override;
  RenderWidgetHostView* GetRenderWidgetHostView() override;
  RenderWidgetHostView* GetTopLevelRenderWidgetHostView() override;
  void ClosePage() override;
  std::optional<SkColor> GetThemeColor() override;
  std::optional<SkColor> GetBackgroundColor() override;
  void SetPageBaseBackgroundColor(std::optional<SkColor> color) override;
  void SetColorProviderSource(ui::ColorProviderSource* source) override;
  ui::ColorProviderKey::ColorMode GetColorMode() const override;
  WebUI* GetWebUI() override;
  void SetUserAgentOverride(const blink::UserAgentOverride& ua_override,
                            bool override_in_new_tabs) override;
  void SetRendererInitiatedUserAgentOverrideOption(
      NavigationController::UserAgentOverrideOption option) override;
  const blink::UserAgentOverride& GetUserAgentOverride() override;
  bool ShouldOverrideUserAgentForRendererInitiatedNavigation() override;
  void SetAlwaysSendSubresourceNotifications() override;
  bool GetSendSubresourceNotification() override;
  bool IsWebContentsOnlyAccessibilityModeForTesting() override;
  bool IsFullAccessibilityModeForTesting() override;
  const std::u16string& GetTitle() override;
  const std::u16string& GetAppTitle() override;
  void UpdateTitleForEntry(NavigationEntry* entry,
                           const std::u16string& title) override;
  SiteInstanceImpl* GetSiteInstance() override;
  bool IsLoading() override;
  double GetLoadProgress() override;
  bool ShouldShowLoadingUI() override;
  bool IsDocumentOnLoadCompletedInPrimaryMainFrame() override;
  bool IsWaitingForResponse() override;
  const net::LoadStateWithParam& GetLoadState() override;
  const std::u16string& GetLoadStateHost() override;
  void RequestAXTreeSnapshot(AXTreeSnapshotCallback callback,
                             ui::AXMode ax_mode,
                             size_t max_nodes,
                             base::TimeDelta timeout) override;
  uint64_t GetUploadSize() override;
  uint64_t GetUploadPosition() override;
  const std::string& GetEncoding() override;
  bool WasDiscarded() override;
  void SetWasDiscarded(bool was_discarded) override;
  [[nodiscard]] base::ScopedClosureRunner IncrementCapturerCount(
      const gfx::Size& capture_size,
      bool stay_hidden,
      bool stay_awake,
      bool is_activity = true) override;
  const blink::mojom::CaptureHandleConfig& GetCaptureHandleConfig() override;
  bool IsBeingCaptured() override;
  bool IsBeingVisiblyCaptured() override;
  bool IsAudioMuted() override;
  void SetAudioMuted(bool mute) override;
  bool IsCurrentlyAudible() override;
  bool IsConnectedToBluetoothDevice() override;
  bool IsScanningForBluetoothDevices() override;
  bool IsConnectedToSerialPort() override;
  bool IsConnectedToHidDevice() override;
  bool IsConnectedToUsbDevice() override;
  bool HasFileSystemAccessHandles() override;
  bool HasPictureInPictureVideo() override;
  bool HasPictureInPictureDocument() override;
  bool IsCrashed() override;
  base::TerminationStatus GetCrashedStatus() override;
  int GetCrashedErrorCode() override;
  bool IsBeingDestroyed() override;
  void NotifyNavigationStateChanged(InvalidateTypes changed_flags) override;
  void OnAudioStateChanged() override;
  base::TimeTicks GetLastActiveTime() override;
  void WasShown() override;
  void WasHidden() override;
  void WasOccluded() override;
  Visibility GetVisibility() override;
  bool NeedToFireBeforeUnloadOrUnloadEvents() override;
  void DispatchBeforeUnload(bool auto_cancel) override;
  void AttachInnerWebContents(
      std::unique_ptr<WebContents> inner_web_contents,
      RenderFrameHost* render_frame_host,
      mojo::PendingAssociatedRemote<blink::mojom::RemoteFrame> remote_frame,
      mojo::PendingAssociatedReceiver<blink::mojom::RemoteFrameHost>
          remote_frame_host_receiver,
      bool is_full_page) override;
  bool IsInnerWebContentsForGuest() override;
  RenderFrameHostImpl* GetOuterWebContentsFrame() override;
  WebContentsImpl* GetOuterWebContents() override;
  WebContentsImpl* GetOutermostWebContents() override;
  std::vector<WebContents*> GetInnerWebContents() override;
  WebContentsImpl* GetResponsibleWebContents() override;
  void DidChangeVisibleSecurityState() override;
  void SyncRendererPrefs() override;
  void Stop() override;
  void SetPageFrozen(bool frozen) override;
  std::unique_ptr<WebContents> Clone() override;
  void ReloadFocusedFrame() override;
  void Undo() override;
  void Redo() override;
  void Cut() override;
  void Copy() override;
  void CopyToFindPboard() override;
  void CenterSelection() override;
  void Paste() override;
  void PasteAndMatchStyle() override;
  void Delete() override;
  void SelectAll() override;
  void CollapseSelection() override;
  void ScrollToTopOfDocument() override;
  void ScrollToBottomOfDocument() override;
  void Replace(const std::u16string& word) override;
  void ReplaceMisspelling(const std::u16string& word) override;
  void NotifyContextMenuClosed(const GURL& link_followed) override;
  void ExecuteCustomContextMenuCommand(int action,
                                       const GURL& link_followed) override;
  gfx::NativeView GetNativeView() override;
  gfx::NativeView GetContentNativeView() override;
  gfx::NativeWindow GetTopLevelNativeWindow() override;
  gfx::Rect GetContainerBounds() override;
  gfx::Rect GetViewBounds() override;
  DropData* GetDropData() override;
  void Focus() override;
  void SetInitialFocus() override;
  void StoreFocus() override;
  void RestoreFocus() override;
  void FocusThroughTabTraversal(bool reverse) override;
  bool IsSavable() override;
  void OnSavePage() override;
  bool SavePage(const base::FilePath& main_file,
                const base::FilePath& dir_path,
                SavePageType save_type) override;
  void SaveFrame(const GURL& url,
                 const Referrer& referrer,
                 RenderFrameHost* rfh) override;
  void SaveFrameWithHeaders(const GURL& url,
                            const Referrer& referrer,
                            const std::string& headers,
                            const std::u16string& suggested_filename,
                            RenderFrameHost* rfh,
                            bool is_subresource) override;
  void GenerateMHTML(const MHTMLGenerationParams& params,
                     base::OnceCallback<void(int64_t)> callback) override;
  void GenerateMHTMLWithResult(
      const MHTMLGenerationParams& params,
      MHTMLGenerationResult::GenerateMHTMLCallback callback) override;
  const std::string& GetContentsMimeType() override;
  blink::RendererPreferences* GetMutableRendererPrefs() override;
  void Close() override;
  void SetClosedByUserGesture(bool value) override;
  bool GetClosedByUserGesture() override;
  int GetMinimumZoomPercent() override;
  int GetMaximumZoomPercent() override;
  void SetPageScale(float page_scale_factor) override;
  gfx::Size GetPreferredSize() override;
  bool GotResponseToPointerLockRequest(
      blink::mojom::PointerLockResult result) override;
  void GotPointerLockPermissionResponse(bool allowed) override;
  void DropPointerLockForTesting() override;
  bool GotResponseToKeyboardLockRequest(bool allowed) override;
  bool HasOpener() override;
  RenderFrameHostImpl* GetOpener() override;
  bool HasLiveOriginalOpenerChain() override;
  WebContents* GetFirstWebContentsInLiveOriginalOpenerChain() override;
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
  void DidChooseColorInColorChooser(SkColor color) override;
  void DidEndColorChooser() override;
#endif
  int DownloadImage(const GURL& url,
                    bool is_favicon,
                    const gfx::Size& preferred_size,
                    uint32_t max_bitmap_size,
                    bool bypass_cache,
                    ImageDownloadCallback callback) override;
  int DownloadImageInFrame(
      const GlobalRenderFrameHostId& initiator_frame_routing_id,
      const GURL& url,
      bool is_favicon,
      const gfx::Size& preferred_size,
      uint32_t max_bitmap_size,
      bool bypass_cache,
      WebContents::ImageDownloadCallback callback) override;
  void Find(int request_id,
            const std::u16string& search_text,
            blink::mojom::FindOptionsPtr options,
            bool skip_delay = false) override;
  void StopFinding(StopFindAction action) override;
  bool WasEverAudible() override;
  bool IsFullscreen() override;
  bool ShouldShowStaleContentOnEviction() override;
  void ExitFullscreen(bool will_cause_resize) override;
  [[nodiscard]] base::ScopedClosureRunner ForSecurityDropFullscreen(
      int64_t display_id = display::kInvalidDisplayId) override;
  void ResumeLoadingCreatedWebContents() override;
  void SetIsOverlayContent(bool is_overlay_content) override;
  bool IsFocusedElementEditable() override;
  void ClearFocusedElement() override;
  bool IsShowingContextMenu() override;
  void SetShowingContextMenu(bool showing) override;
  base::UnguessableToken GetAudioGroupId() override;
  bool CompletedFirstVisuallyNonEmptyPaint() override;
  void UpdateFaviconURL(
      RenderFrameHostImpl* source,
      const std::vector<blink::mojom::FaviconURLPtr>& candidates) override;
  const std::vector<blink::mojom::FaviconURLPtr>& GetFaviconURLs() override;
  void Resize(const gfx::Rect& new_bounds) override;
  gfx::Size GetSize() override;
  void UpdateWindowControlsOverlay(const gfx::Rect& bounding_rect) override;
#if BUILDFLAG(IS_ANDROID)
  base::android::ScopedJavaLocalRef<jobject> GetJavaWebContents() override;
  base::android::ScopedJavaLocalRef<jthrowable> GetJavaCreatorLocation()
      override;
  WebContentsAndroid* GetWebContentsAndroid();
  void ClearWebContentsAndroid();
  void ActivateNearestFindResult(float x, float y) override;
  void RequestFindMatchRects(int current_version) override;
  service_manager::InterfaceProvider* GetJavaInterfaces() override;
#endif
  bool HasRecentInteraction() override;
  [[nodiscard]] ScopedIgnoreInputEvents IgnoreInputEvents() override;
  bool HasActiveEffectivelyFullscreenVideo() override;
  void WriteIntoTrace(perfetto::TracedValue context) override;
  const base::Location& GetCreatorLocation() override;
  const std::optional<blink::mojom::PictureInPictureWindowOptions>&
  GetPictureInPictureOptions() const override;
  void UpdateBrowserControlsState(cc::BrowserControlsState constraints,
                                  cc::BrowserControlsState current,
                                  bool animate) override;
  void SetV8CompileHints(base::ReadOnlySharedMemoryRegion data) override;
  void SetTabSwitchStartTime(base::TimeTicks start_time,
                             bool destination_is_loaded) override;
  bool IsInPreviewMode() const override;
  void WillActivatePreviewPage() override;
  void ActivatePreviewPage() override;

  // Implementation of PageNavigator.
  WebContents* OpenURL(const OpenURLParams& params) override;

  const blink::web_pref::WebPreferences& GetOrCreateWebPreferences() override;
  void NotifyPreferencesChanged() override;
  void SetWebPreferences(const blink::web_pref::WebPreferences& prefs) override;
  void OnWebPreferencesChanged() override;

  void AboutToBeDiscarded(WebContents* new_contents) override;

  [[nodiscard]] base::ScopedClosureRunner CreateDisallowCustomCursorScope(
      int max_dimension_dips) override;

  void SetOverscrollNavigationEnabled(bool enabled) override;

  // RenderFrameHostDelegate ---------------------------------------------------
  bool OnMessageReceived(RenderFrameHostImpl* render_frame_host,
                         const IPC::Message& message) override;
  void OnDidBlockNavigation(
      const GURL& blocked_url,
      const GURL& initiator_url,
      blink::mojom::NavigationBlockedReason reason) override;
  void OnDidFinishLoad(RenderFrameHostImpl* render_frame_host,
                       const GURL& url) override;
  void OnManifestUrlChanged(PageImpl& page) override;
  void RenderFrameCreated(RenderFrameHostImpl* render_frame_host) override;
  void RenderFrameDeleted(RenderFrameHostImpl* render_frame_host) override;
  void ShowContextMenu(
      RenderFrameHost& render_frame_host,
      mojo::PendingAssociatedRemote<blink::mojom::ContextMenuClient>
          context_menu_client,
      const ContextMenuParams& params) override;
  void RunJavaScriptDialog(RenderFrameHostImpl* render_frame_host,
                           const std::u16string& message,
                           const std::u16string& default_prompt,
                           JavaScriptDialogType dialog_type,
                           bool disable_third_party_subframe_suppresion,
                           JavaScriptDialogCallback response_callback) override;
  void RunBeforeUnloadConfirm(
      RenderFrameHostImpl* render_frame_host,
      bool is_reload,
      JavaScriptDialogCallback response_callback) override;
  void DidChangeName(RenderFrameHostImpl* render_frame_host,
                     const std::string& name) override;
  void DidReceiveUserActivation(
      RenderFrameHostImpl* render_frame_host) override;
  void WebAuthnAssertionRequestSucceeded(
      RenderFrameHostImpl* render_frame_host) override;
  void BindDisplayCutoutHost(
      RenderFrameHostImpl* render_frame_host,
      mojo::PendingAssociatedReceiver<blink::mojom::DisplayCutoutHost> receiver)
      override;
  void DidChangeDisplayState(RenderFrameHostImpl* render_frame_host,
                             bool is_display_none) override;
  void FrameSizeChanged(RenderFrameHostImpl* render_frame_host,
                        const gfx::Size& frame_size) override;
  void DOMContentLoaded(RenderFrameHostImpl* render_frame_host) override;
  void DocumentOnLoadCompleted(RenderFrameHostImpl* render_frame_host) override;
  void UpdateTitle(RenderFrameHostImpl* render_frame_host,
                   const std::u16string& title,
                   base::i18n::TextDirection title_direction) override;
  // The app title is an alternative title. If non-empty, the browser may choose
  // to use the app title instead of the regular title for a web app displayed
  // in an app window. See
  // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/DocumentSubtitle/explainer.md
  void UpdateAppTitle(RenderFrameHostImpl* render_frame_host,
                      const std::u16string& app_title) override;
  void UpdateTargetURL(RenderFrameHostImpl* render_frame_host,
                       const GURL& url) override;
  bool IsNeverComposited() override;
  void SetCaptureHandleConfig(
      blink::mojom::CaptureHandleConfigPtr config) override;
  ui::AXMode GetAccessibilityMode() override;
  // Broadcasts the mode change to all frames.
  void ResetAccessibility() override;
  void AXTreeIDForMainFrameHasChanged() override;
  void AccessibilityEventReceived(
      const AXEventNotificationDetails& details) override;
  void AccessibilityLocationChangesReceived(
      const std::vector<AXLocationChangeNotificationDetails>& details) override;
  std::string DumpAccessibilityTree(
      bool internal,
      std::vector<ui::AXPropertyFilter> property_filters) override;
  void RecordAccessibilityEvents(
      bool start_recording,
      std::optional<ui::AXEventCallback> callback) override;
  void AccessibilityFatalError() override;
  device::mojom::GeolocationContext* GetGeolocationContext() override;
  device::mojom::WakeLockContext* GetWakeLockContext() override;
#if BUILDFLAG(IS_ANDROID)
  void GetNFC(RenderFrameHost*,
              mojo::PendingReceiver<device::mojom::NFC>) override;
#endif
  bool CanEnterFullscreenMode(
      RenderFrameHostImpl* requesting_frame,
      const blink::mojom::FullscreenOptions& options) override;
  void EnterFullscreenMode(
      RenderFrameHostImpl* requesting_frame,
      const blink::mojom::FullscreenOptions& options) override;
  void ExitFullscreenMode(bool will_cause_resize) override;
  void FullscreenStateChanged(
      RenderFrameHostImpl* rfh,
      bool is_fullscreen,
      blink::mojom::FullscreenOptionsPtr options) override;
  bool CanUseWindowingControls(RenderFrameHostImpl* requesting_frame) override;
  void Maximize() override;
  void Minimize() override;
  void Restore() override;
#if BUILDFLAG(IS_ANDROID)
  void UpdateUserGestureCarryoverInfo() override;
#endif
  bool ShouldRouteMessageEvent(RenderFrameHostImpl* target_rfh) const override;
  void EnsureOpenerProxiesExist(RenderFrameHostImpl* source_rfh) override;
  void DidCallFocus() override;
  void OnFocusedElementChangedInFrame(
      RenderFrameHostImpl* frame,
      const gfx::Rect& bounds_in_root_view,
      blink::mojom::FocusType focus_type) override;
  void OnAdvanceFocus(RenderFrameHostImpl* source_rfh) override;
  FrameTree* CreateNewWindow(
      RenderFrameHostImpl* opener,
      const mojom::CreateNewWindowParams& params,
      bool is_new_browsing_instance,
      bool has_user_gesture,
      SessionStorageNamespace* session_storage_namespace) override;
  void ShowCreatedWindow(RenderFrameHostImpl* opener,
                         int main_frame_widget_route_id,
                         WindowOpenDisposition disposition,
                         const blink::mojom::WindowFeatures& window_features,
                         bool user_gesture) override;
  void PrimaryMainDocumentElementAvailable() override;
  void PassiveInsecureContentFound(const GURL& resource_url) override;
  bool ShouldAllowRunningInsecureContent(bool allowed_per_prefs,
                                         const url::Origin& origin,
                                         const GURL& resource_url) override;
  void ViewSource(RenderFrameHostImpl* frame) override;
  void PrintCrossProcessSubframe(
      const gfx::Rect& rect,
      int document_cookie,
      RenderFrameHostImpl* render_frame_host) override;
  void CapturePaintPreviewOfCrossProcessSubframe(
      const gfx::Rect& rect,
      const base::UnguessableToken& guid,
      RenderFrameHostImpl* render_frame_host) override;
#if BUILDFLAG(IS_ANDROID)
  base::android::ScopedJavaLocalRef<jobject> GetJavaRenderFrameHostDelegate()
      override;
#endif
  void ResourceLoadComplete(
      RenderFrameHostImpl* render_frame_host,
      const GlobalRequestID& request_id,
      blink::mojom::ResourceLoadInfoPtr resource_load_information) override;
  void OnCookiesAccessed(RenderFrameHostImpl*,
                         const CookieAccessDetails& details) override;
  void OnTrustTokensAccessed(RenderFrameHostImpl*,
                             const TrustTokenAccessDetails& details) override;
  void OnSharedDictionaryAccessed(
      RenderFrameHostImpl*,
      const network::mojom::SharedDictionaryAccessDetails& details) override;

  // Called when WebAudio starts or stops playing audible audio in an
  // AudioContext.
  void AudioContextPlaybackStarted(RenderFrameHostImpl* host,
                                   int context_id) override;
  void AudioContextPlaybackStopped(RenderFrameHostImpl* host,
                                   int context_id) override;
  void OnFrameAudioStateChanged(RenderFrameHostImpl* host,
                                bool is_audible) override;
  void OnFrameVisibilityChanged(
      RenderFrameHostImpl* host,
      blink::mojom::FrameVisibility visibility) override;
  void OnFrameIsCapturingMediaStreamChanged(
      RenderFrameHostImpl* host,
      bool is_capturing_media_stream) override;
  std::vector<FrameTreeNode*> GetUnattachedOwnedNodes(
      RenderFrameHostImpl* owner) override;
  void RegisterProtocolHandler(RenderFrameHostImpl* source,
                               const std::string& protocol,
                               const GURL& url,
                               bool user_gesture) override;
  void UnregisterProtocolHandler(RenderFrameHostImpl* source,
                                 const std::string& protocol,
                                 const GURL& url,
                                 bool user_gesture) override;
  bool IsAllowedToGoToEntryAtOffset(int32_t offset) override;
  void IsClipboardPasteAllowedByPolicy(
      const ClipboardEndpoint& source,
      const ClipboardEndpoint& destination,
      const ClipboardMetadata& metadata,
      ClipboardPasteData clipboard_paste_data,
      IsClipboardPasteAllowedCallback callback) override;
  void IsClipboardPasteAllowedWrapperCallback(
      IsClipboardPasteAllowedCallback callback,
      std::optional<ClipboardPasteData> clipboard_paste_data);
  void OnPageScaleFactorChanged(PageImpl& source) override;
  void BindScreenOrientation(
      RenderFrameHost* rfh,
      mojo::PendingAssociatedReceiver<device::mojom::ScreenOrientation>
          receiver) override;
  bool IsTransientActivationRequiredForHtmlFullscreen() override;
  bool IsBackForwardCacheSupported() override;
  RenderWidgetHostImpl* CreateNewPopupWidget(
      base::SafeRef<SiteInstanceGroup> site_instance_group,
      int32_t route_id,
      mojo::PendingAssociatedReceiver<blink::mojom::PopupWidgetHost>
          blink_popup_widget_host,
      mojo::PendingAssociatedReceiver<blink::mojom::WidgetHost>
          blink_widget_host,
      mojo::PendingAssociatedRemote<blink::mojom::Widget> blink_widget)
      override;
  bool ShowPopupMenu(RenderFrameHostImpl* render_frame_host,
                     const gfx::Rect& bounds) override;
  void DidLoadResourceFromMemoryCache(
      RenderFrameHostImpl* source,
      const GURL& url,
      const std::string& http_request,
      const std::string& mime_type,
      network::mojom::RequestDestination request_destination,
      bool include_credentials) override;
  void DomOperationResponse(RenderFrameHost* render_frame_host,
                            const std::string& json_string) override;
  void SavableResourceLinksResponse(
      RenderFrameHostImpl* source,
      const std::vector<GURL>& resources_list,
      blink::mojom::ReferrerPtr referrer,
      const std::vector<blink::mojom::SavableSubframePtr>& subframes) override;
  void SavableResourceLinksError(RenderFrameHostImpl* source) override;
  void RenderFrameHostStateChanged(
      RenderFrameHost* render_frame_host,
      RenderFrameHost::LifecycleState old_state,
      RenderFrameHost::LifecycleState new_state) override;
  void SetWindowRect(const gfx::Rect& new_bounds) override;
  void UpdateWindowPreferredSize(const gfx::Size& pref_size) override;
  std::vector<RenderFrameHostImpl*>
  GetActiveTopLevelDocumentsInBrowsingContextGroup(
      RenderFrameHostImpl* render_frame_host) override;
  std::vector<RenderFrameHostImpl*>
  GetActiveTopLevelDocumentsInCoopRelatedGroup(
      RenderFrameHostImpl* render_frame_host) override;
  PrerenderHostRegistry* GetPrerenderHostRegistry() override;
#if BUILDFLAG(ENABLE_PPAPI)
  void OnPepperInstanceCreated(RenderFrameHostImpl* source,
                               int32_t pp_instance) override;
  void OnPepperInstanceDeleted(RenderFrameHostImpl* source,
                               int32_t pp_instance) override;
  void OnPepperStartsPlayback(RenderFrameHostImpl* source,
                              int32_t pp_instance) override;
  void OnPepperStopsPlayback(RenderFrameHostImpl* source,
                             int32_t pp_instance) override;
  void OnPepperPluginCrashed(RenderFrameHostImpl* source,
                             const base::FilePath& plugin_path,
                             base::ProcessId plugin_pid) override;
  void OnPepperPluginHung(RenderFrameHostImpl* source,
                          int plugin_child_id,
                          const base::FilePath& path,
                          bool is_hung) override;
#endif  // BUILDFLAG(ENABLE_PPAPI)
  void DidChangeLoadProgressForPrimaryMainFrame() override;
  void DidFailLoadWithError(RenderFrameHostImpl* render_frame_host,
                            const GURL& url,
                            int error_code) override;

  // RenderViewHostDelegate ----------------------------------------------------
  RenderViewHostDelegateView* GetDelegateView() override;
  void RenderViewReady(RenderViewHost* render_view_host) override;
  void RenderViewTerminated(RenderViewHost* render_view_host,
                            base::TerminationStatus status,
                            int error_code) override;
  void RenderViewDeleted(RenderViewHost* render_view_host) override;
  bool DidAddMessageToConsole(
      RenderFrameHostImpl* source_frame,
      blink::mojom::ConsoleMessageLevel log_level,
      const std::u16string& message,
      int32_t line_no,
      const std::u16string& source_id,
      const std::optional<std::u16string>& untrusted_stack_trace) override;
  const blink::RendererPreferences& GetRendererPrefs() const override;
  void DidReceiveInputEvent(RenderWidgetHostImpl* render_widget_host,
                            const blink::WebInputEvent& event) override;
  bool ShouldIgnoreInputEvents() override;
  void OnIgnoredUIEvent() override;
  void Activate() override;
  void ShowCreatedWidget(int process_id,
                         int widget_route_id,
                         const gfx::Rect& initial_rect,
                         const gfx::Rect& initial_anchor_rect) override;
  void CreateMediaPlayerHostForRenderFrameHost(
      RenderFrameHostImpl* frame_host,
      mojo::PendingAssociatedReceiver<media::mojom::MediaPlayerHost> receiver)
      override;
  void RequestMediaAccessPermission(const MediaStreamRequest& request,
                                    MediaResponseCallback callback) override;
  bool CheckMediaAccessPermission(RenderFrameHostImpl* render_frame_host,
                                  const url::Origin& security_origin,
                                  blink::mojom::MediaStreamType type) override;
  bool IsJavaScriptDialogShowing() const override;
  bool ShouldIgnoreUnresponsiveRenderer() override;
  bool IsGuest() override;
  void RecomputeWebPreferencesSlow() override;
  std::optional<SkColor> GetBaseBackgroundColor() override;
  std::unique_ptr<PrerenderHandle> StartPrerendering(
      const GURL& prerendering_url,
      PreloadingTriggerType trigger_type,
      const std::string& embedder_histogram_suffix,
      ui::PageTransition page_transition,
      PreloadingHoldbackStatus holdback_status_override,
      PreloadingAttempt* preloading_attempt,
      std::optional<base::RepeatingCallback<bool(const GURL&)>>
          url_match_predicate = std::nullopt,
      std::optional<base::RepeatingCallback<void(NavigationHandle&)>>
          prerender_navigation_handle_callback = std::nullopt) override;
  void BackNavigationLikely(PreloadingPredictor predictor,
                            WindowOpenDisposition disposition) override;
  void SetOwnerLocationForDebug(
      std::optional<base::Location> owner_location) override;
  blink::ColorProviderColorMaps GetColorProviderColorMaps() const override;

  network::mojom::AttributionSupport GetAttributionSupport() override;
  void UpdateAttributionSupportRenderer() override;
  static void UpdateAttributionSupportAllRenderers();
  BackForwardTransitionAnimationManager*
  GetBackForwardTransitionAnimationManager() override;

  void GetMediaCaptureRawDeviceIdsOpened(
      blink::mojom::MediaStreamType type,
      base::OnceCallback<void(std::vector<std::string>)> callback) override;

  // NavigatorDelegate ---------------------------------------------------------

  void DidStartNavigation(NavigationHandle* navigation_handle) override;
  void DidRedirectNavigation(NavigationHandle* navigation_handle) override;
  void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override;
  void DidFinishNavigation(NavigationHandle* navigation_handle) override;
  void DidNavigateMainFramePreCommit(FrameTreeNode* frame_tree_node,
                                     bool navigation_is_within_page) override;
  void DidNavigateMainFramePostCommit(
      RenderFrameHostImpl* render_frame_host,
      const LoadCommittedDetails& details) override;
  void DidNavigateAnyFramePostCommit(
      RenderFrameHostImpl* render_frame_host,
      const LoadCommittedDetails& details) override;
  void NotifyChangedNavigationState(InvalidateTypes changed_flags) override;
  bool ShouldAllowRendererInitiatedCrossProcessNavigation(
      bool is_outermost_main_frame_navigation) override;
  std::vector<std::unique_ptr<NavigationThrottle>> CreateThrottlesForNavigation(
      NavigationHandle* navigation_handle) override;
  std::vector<std::unique_ptr<CommitDeferringCondition>>
  CreateDeferringConditionsForNavigationCommit(
      NavigationHandle& navigation_handle,
      CommitDeferringCondition::NavigationType type) override;
  std::unique_ptr<NavigationUIData> GetNavigationUIData(
      NavigationHandle* navigation_handle) override;
  void OnServiceWorkerAccessed(NavigationHandle* navigation,
                               const GURL& scope,
                               AllowServiceWorkerResult allowed) override;
  void OnCookiesAccessed(NavigationHandle*,
                         const CookieAccessDetails& details) override;
  void OnTrustTokensAccessed(NavigationHandle*,
                             const TrustTokenAccessDetails& details) override;
  void OnSharedDictionaryAccessed(
      NavigationHandle*,
      const network::mojom::SharedDictionaryAccessDetails& details) override;

  void RegisterExistingOriginAsHavingDefaultIsolation(
      const url::Origin& origin,
      NavigationRequest* navigation_request_to_exclude) override;

  // RenderWidgetHostDelegate --------------------------------------------------

  void SetTopControlsShownRatio(RenderWidgetHostImpl* render_widget_host,
                                float ratio) override;
  void SetTopControlsGestureScrollInProgress(bool in_progress) override;
  void RenderWidgetCreated(RenderWidgetHostImpl* render_widget_host) override;
  void RenderWidgetDeleted(RenderWidgetHostImpl* render_widget_host) override;
  void RenderWidgetWasResized(RenderWidgetHostImpl* render_widget_host,
                              bool width_changed) override;
  void ResizeDueToAutoResize(RenderWidgetHostImpl* render_widget_host,
                             const gfx::Size& new_size) override;
  void OnVerticalScrollDirectionChanged(
      viz::VerticalScrollDirection scroll_direction) override;
  int GetVirtualKeyboardResizeHeight() override;

  double GetPendingPageZoomLevel() override;

  KeyboardEventProcessingResult PreHandleKeyboardEvent(
      const NativeWebKeyboardEvent& event) override;
  bool HandleMouseEvent(const blink::WebMouseEvent& event) override;
  bool HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override;
  bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override;
  bool PreHandleGestureEvent(const blink::WebGestureEvent& event) override;
  BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override;
  BrowserAccessibilityManager* GetOrCreateRootBrowserAccessibilityManager()
      override;
  // The following 4 functions are already listed under WebContents overrides:
  // void Cut() override;
  // void Copy() override;
  // void Paste() override;
  // void SelectAll() override;
  void ExecuteEditCommand(const std::string& command,
                          const std::optional<std::u16string>& value) override;
  void MoveRangeSelectionExtent(const gfx::Point& extent) override;
  void SelectRange(const gfx::Point& base, const gfx::Point& extent) override;
  void SelectAroundCaret(blink::mojom::SelectionGranularity granularity,
                         bool should_show_handle,
                         bool should_show_context_menu) override;
  void MoveCaret(const gfx::Point& extent) override;
  void AdjustSelectionByCharacterOffset(int start_adjust,
                                        int end_adjust,
                                        bool show_selection_menu) override;
  RenderWidgetHostInputEventRouter* GetInputEventRouter() override;
  RenderWidgetHostImpl* GetFocusedRenderWidgetHost(
      RenderWidgetHostImpl* receiving_widget) override;
  RenderWidgetHostImpl* GetRenderWidgetHostWithPageFocus() override;
  void FocusOwningWebContents(
      RenderWidgetHostImpl* render_widget_host) override;
  void RendererUnresponsive(
      RenderWidgetHostImpl* render_widget_host,
      base::RepeatingClosure hang_monitor_restarter) override;
  void RendererResponsive(RenderWidgetHostImpl* render_widget_host) override;
  void RequestToLockPointer(RenderWidgetHostImpl* render_widget_host,
                            bool user_gesture,
                            bool last_unlocked_by_target,
                            bool privileged) override;
  bool RequestKeyboardLock(RenderWidgetHostImpl* render_widget_host,
                           bool esc_key_locked) override;
  void CancelKeyboardLock(RenderWidgetHostImpl* render_widget_host) override;
  RenderWidgetHostImpl* GetKeyboardLockWidget() override;
  // The following function is already listed under WebContents overrides:
  // bool IsFullscreen() const override;
  blink::mojom::DisplayMode GetDisplayMode() const override;
  ui::WindowShowState GetWindowShowState() override;
  DevicePostureProviderImpl* GetDevicePostureProvider() override;
  bool GetResizable() override;
  void LostPointerLock(RenderWidgetHostImpl* render_widget_host) override;
  bool HasPointerLock(RenderWidgetHostImpl* render_widget_host) override;
  RenderWidgetHostImpl* GetPointerLockWidget() override;
  bool OnRenderFrameProxyVisibilityChanged(
      RenderFrameProxyHost* render_frame_proxy_host,
      blink::mojom::FrameVisibility visibility) override;
  void SendScreenRects() override;
  void SendActiveState(bool active) override;
  TextInputManager* GetTextInputManager() override;
  bool IsWidgetForPrimaryMainFrame(
      RenderWidgetHostImpl* render_widget_host) override;
  bool IsShowingContextMenuOnPage() const override;
  void DidChangeScreenOrientation() override;
  gfx::Rect GetWindowsControlsOverlayRect() const override;
  VisibleTimeRequestTrigger& GetVisibleTimeRequestTrigger() final;

  // RenderFrameHostManager::Delegate ------------------------------------------

  bool CreateRenderViewForRenderManager(
      RenderViewHost* render_view_host,
      const std::optional<blink::FrameToken>& opener_frame_token,
      RenderFrameProxyHost* proxy_host) override;
  void ReattachOuterDelegateIfNeeded() override;
  void CreateRenderWidgetHostViewForRenderManager(
      RenderViewHost* render_view_host) override;
  void BeforeUnloadFiredFromRenderManager(
      bool proceed,
      bool* proceed_to_fire_unload) override;
  void CancelModalDialogsForRenderManager() override;
  void NotifySwappedFromRenderManager(RenderFrameHostImpl* old_frame,
                                      RenderFrameHostImpl* new_frame) override;
  void NotifySwappedFromRenderManagerWithoutFallbackContent(
      RenderFrameHostImpl* new_frame) override;
  void NotifyMainFrameSwappedFromRenderManager(
      RenderFrameHostImpl* old_frame,
      RenderFrameHostImpl* new_frame) override;
  bool FocusLocationBarByDefault() override;
  void OnFrameTreeNodeDestroyed(FrameTreeNode* node) override;

  // PageDelegate -------------------------------------------------------------

  void OnFirstVisuallyNonEmptyPaint(PageImpl& page) override;

  // These both check that the color has in fact changed before notifying
  // observers.
  void OnThemeColorChanged(PageImpl& page) override;
  void OnBackgroundColorChanged(PageImpl& page) override;
  void DidInferColorScheme(PageImpl& page) override;
  void OnVirtualKeyboardModeChanged(PageImpl& page) override;
  void NotifyPageBecamePrimary(PageImpl& page) override;

  bool IsPageInPreviewMode() const override;
  void CancelPreviewByMojoBinderPolicy(
      const std::string& interface_name) override;
  void OnCanResizeFromWebAPIChanged() override;

  // blink::mojom::ColorChooserFactory ---------------------------------------
  void OnColorChooserFactoryReceiver(
      mojo::PendingReceiver<blink::mojom::ColorChooserFactory> receiver);
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
  void OpenColorChooser(
      mojo::PendingReceiver<blink::mojom::ColorChooser> chooser,
      mojo::PendingRemote<blink::mojom::ColorChooserClient> client,
      SkColor color,
      std::vector<blink::mojom::ColorSuggestionPtr> suggestions) override;
#endif

  // FrameTree::Delegate -------------------------------------------------------

  void LoadingStateChanged(LoadingState new_state) override;
  void DidStartLoading(FrameTreeNode* frame_tree_node) override;
  void DidStopLoading() override;
  bool IsHidden() override;
  int GetOuterDelegateFrameTreeNodeId() override;
  RenderFrameHostImpl* GetProspectiveOuterDocument() override;
  FrameTree* LoadingTree() override;
  void SetFocusedFrame(FrameTreeNode* node, SiteInstanceGroup* source) override;

  // NavigationControllerDelegate ----------------------------------------------

  void NotifyNavigationEntryCommitted(
      const LoadCommittedDetails& load_details) override;
  void NotifyNavigationEntryChanged(
      const EntryChangedDetails& change_details) override;
  void NotifyNavigationListPruned(const PrunedDetails& pruned_details) override;
  void NotifyNavigationEntriesDeleted() override;
  bool ShouldPreserveAbortedURLs() override;
  void NotifyNavigationStateChangedFromController(
      InvalidateTypes changed_flags) override;

  // Invoked before a form repost warning is shown.
  void NotifyBeforeFormRepostWarningShow() override;

  // Activate this WebContents and show a form repost warning.
  void ActivateAndShowRepostFormWarningDialog() override;

  void MediaMutedStatusChanged(const MediaPlayerId& id, bool muted);

  void UpdateOverridingUserAgent() override;

  // Forces overscroll to be disabled (used by touch emulation).
  void SetForceDisableOverscrollContent(bool force_disable);

  // Override the render view/widget size of the main frame, return whether the
  // size changed.
  bool SetDeviceEmulationSize(const gfx::Size& new_size);
  void ClearDeviceEmulationSize();

  AudioStreamMonitor* audio_stream_monitor() { return &audio_stream_monitor_; }

  ForwardingAudioStreamFactory* GetAudioStreamFactory();

  // Called by MediaWebContentsObserver when playback starts or stops.  See the
  // WebContentsObserver function stubs for more details.
  void MediaStartedPlaying(
      const WebContentsObserver::MediaPlayerInfo& media_info,
      const MediaPlayerId& id);
  void MediaStoppedPlaying(
      const WebContentsObserver::MediaPlayerInfo& media_info,
      const MediaPlayerId& id,
      WebContentsObserver::MediaStoppedReason reason);
  // This will be called before playback is started, check
  // GetCurrentlyPlayingVideoCount if you need this when playback starts.
  void MediaResized(const gfx::Size& size, const MediaPlayerId& id);
  void MediaEffectivelyFullscreenChanged(bool is_fullscreen);

  // Called by MediaWebContentsObserver when a buffer underflow occurs. See the
  // WebContentsObserver function stubs for more details.
  void MediaBufferUnderflow(const MediaPlayerId& id);

  // Called by MediaWebContentsObserver when player seek event occurs.
  void MediaPlayerSeek(const MediaPlayerId& id);

  // Called by MediaWebContentsObserver when a media player is destroyed.
  void MediaDestroyed(const MediaPlayerId& id);

  // Called by MediaSessionImpl when one is created and initialized for this.
  void MediaSessionCreated(MediaSession* media_session);

  int GetCurrentlyPlayingVideoCount() override;
  std::optional<gfx::Size> GetFullscreenVideoSize() override;

  MediaWebContentsObserver* media_web_contents_observer() {
    return media_web_contents_observer_.get();
  }

  // Update the web contents visibility.
  void UpdateWebContentsVisibility(Visibility visibility) override;

  // Returns the PageVisibilityState for the primary page of this web contents,
  // taking the capturing state into account.
  PageVisibilityState GetPageVisibilityState() const;

  // Called by FindRequestManager when find replies come in from a renderer
  // process.
  void NotifyFindReply(int request_id,
                       int number_of_matches,
                       const gfx::Rect& selection_rect,
                       int active_match_ordinal,
                       bool final_update);

  // Modify the counter of connected devices for this WebContents.
  void IncrementBluetoothConnectedDeviceCount();
  void DecrementBluetoothConnectedDeviceCount();

  // Notifies the delegate and observers when the connected to Bluetooth device
  // state changes.
  void OnIsConnectedToBluetoothDeviceChanged(
      bool is_connected_to_bluetooth_device);

  void IncrementBluetoothScanningSessionsCount();
  void DecrementBluetoothScanningSessionsCount();

  // Modify the counter of frames in this WebContents actively using serial
  // ports.
  void IncrementSerialActiveFrameCount();
  void DecrementSerialActiveFrameCount();

  // Modify the counter of frames in this WebContents actively using HID
  // devices.
  void IncrementHidActiveFrameCount();
  void DecrementHidActiveFrameCount();

  // Notifies the delegate and observers when the connected to USB device state
  // changes.
  void OnIsConnectedToUsbDeviceChanged(bool is_connected_to_usb_device);

  // Modify the counter of frames in this WebContents actively using USB
  // devices.
  void IncrementUsbActiveFrameCount();
  void DecrementUsbActiveFrameCount();

  // Modify the counter of File System Access handles for this WebContents.
  void IncrementFileSystemAccessHandleCount();
  void DecrementFileSystemAccessHandleCount();

  // Called when the WebContents gains or loses a persistent video.
  void SetHasPersistentVideo(bool has_persistent_video);

  // Whether the WebContents effectively fullscreen active player allows
  // Picture-in-Picture.
  // |IsFullscreen| must return |true| when this method is called.
  bool IsPictureInPictureAllowedForFullscreenVideo() const;

  // Set this WebContents's `primary_frame_tree_` as the focused frame tree.
  // `primary_frame_tree_`'s main frame RenderWidget (and all of its
  // subframe widgets) will be activated. GetFocusedRenderWidgetHost will search
  // this WebContentsImpl for a focused RenderWidgetHost. The previously focused
  // WebContentsImpl, if any, will have its RenderWidgetHosts deactivated.
  void SetAsFocusedWebContentsIfNecessary();

  // Sets the focused frame tree to be the `frame_tree_to_focus`.
  // `frame_tree_to_focus` must be either this WebContents's frame tree or
  // contained within it (but not owned by another WebContents).
  void SetFocusedFrameTree(FrameTree* frame_tree_to_focus);

  // Notifies the Picture-in-Picture controller that there is a new video player
  // entering video Picture-in-Picture. (This is not used for document
  // Picture-in-Picture,
  // cf. PictureInPictureWindowManager::EnterDocumentPictureInPicture().)
  // Returns the result of the enter request.
  PictureInPictureResult EnterPictureInPicture();

  // Updates the Picture-in-Picture controller with a signal that
  // Picture-in-Picture mode has ended.
  void ExitPictureInPicture();

  // Updates the tracking information for |this| to know if there is
  // a video currently in Picture-in-Picture mode.
  void SetHasPictureInPictureVideo(bool has_picture_in_picture_video);

  // Updates the tracking information for |this| to know if there is
  // a document currently in Picture-in-Picture mode.
  void SetHasPictureInPictureDocument(bool has_picture_in_picture_document);

  // Sets the spatial navigation state.
  void SetSpatialNavigationDisabled(bool disabled);

  // Sets the Stylus handwriting feature status. This status is updated to web
  // preferences.
  void SetStylusHandwritingEnabled(bool enabled);

  // Called when a file selection is to be done.
  void RunFileChooser(
      base::WeakPtr<FileChooserImpl> file_chooser,
      RenderFrameHost* render_frame_host,
      scoped_refptr<FileChooserImpl::FileSelectListenerImpl> listener,
      const blink::mojom::FileChooserParams& params);

  // Request to enumerate a directory.  This is equivalent to running the file
  // chooser in directory-enumeration mode and having the user select the given
  // directory.
  void EnumerateDirectory(
      base::WeakPtr<FileChooserImpl> file_chooser,
      RenderFrameHost* render_frame_host,
      scoped_refptr<FileChooserImpl::FileSelectListenerImpl> listener,
      const base::FilePath& directory_path);

#if BUILDFLAG(IS_ANDROID)
  // Called by FindRequestManager when all of the find match rects are in.
  void NotifyFindMatchRectsReply(int version,
                                 const std::vector<gfx::RectF>& rects,
                                 const gfx::RectF& active_rect);
#endif

#if BUILDFLAG(IS_ANDROID)
  // Called by WebContentsAndroid to send the Display Cutout safe area to
  // DisplayCutoutHostImpl.
  void SetDisplayCutoutSafeArea(gfx::Insets insets);
#endif

  // Notify observers that the viewport fit value changed. This is called by
  // |DisplayCutoutHostImpl|.
  void NotifyViewportFitChanged(blink::mojom::ViewportFit value);

  // Returns the current FindRequestManager associated with the WebContents;
  // this won't create one if none exists.
  FindRequestManager* GetFindRequestManagerForTesting();

  // Convenience method to notify observers that an inner WebContents was
  // created with |this| WebContents as its owner. This does *not* immediately
  // guarantee that |inner_web_contents| has been added to the WebContents tree.
  void InnerWebContentsCreated(WebContents* inner_web_contents);

  // Detaches this WebContents from its outer WebContents.
  std::unique_ptr<WebContents> DetachFromOuterWebContents();

  // Reattaches this inner WebContents to its outer WebContents.
  virtual void ReattachToOuterWebContentsFrame();

  // Notifies observers that this WebContents completed preview activation
  // steps.
  // `activation_time` is the time the activation happened, in wall time.
  void DidActivatePreviewedPage(base::TimeTicks activation_time);

  void OnServiceWorkerAccessed(RenderFrameHost* render_frame_host,
                               const GURL& scope,
                               AllowServiceWorkerResult allowed);

  bool JavaScriptDialogDefersNavigations() {
    return javascript_dialog_dismiss_notifier_.get();
  }

  void NotifyOnJavaScriptDialogDismiss(base::OnceClosure callback);

  bool has_persistent_video() { return has_persistent_video_; }

  // Returns the focused frame's input handler.
  blink::mojom::FrameWidgetInputHandler* GetFocusedFrameWidgetInputHandler();

  // A render view-originated drag has ended. Informs the render view host and
  // WebContentsDelegate.
  void SystemDragEnded(RenderWidgetHost* source_rwh);

  // These are the content internal equivalents of
  // |WebContents::ForEachRenderFrameHost| whose comment can be referred to
  // for details. Content internals can also access speculative
  // RenderFrameHostImpls if necessary by using the
  // |ForEachRenderFrameHostIncludingSpeculative| variations.
  void ForEachRenderFrameHostWithAction(
      base::FunctionRef<FrameIterationAction(RenderFrameHostImpl*)> on_frame);
  void ForEachRenderFrameHost(
      base::FunctionRef<void(RenderFrameHostImpl*)> on_frame);
  void ForEachRenderFrameHostIncludingSpeculativeWithAction(
      base::FunctionRef<FrameIterationAction(RenderFrameHostImpl*)> on_frame);
  void ForEachRenderFrameHostIncludingSpeculative(
      base::FunctionRef<void(RenderFrameHostImpl*)> on_frame);

  // Computes and returns the content specific preferences for this WebContents.
  // Recomputes only the "fast" preferences (those not requiring slow
  // platform/device polling); the remaining "slow" ones are recomputed only if
  // the preference cache is empty.
  const blink::web_pref::WebPreferences ComputeWebPreferences();

  // Certain WebXr modes integrate with Viz as a compositor directly, and thus
  // have their own FrameSinkId that typically renders fullscreen, obscuring
  // the WebContents. This allows those WebXr modes to notify us if that
  // is occurring. When it has finished, this method may be called again with an
  // Invalid FrameSinkId to indicate such. Note that other fullscreen modes,
  // e.g. Fullscreen videos, are largely controlled by the renderer process and
  // as such are still parented under the existing FrameSinkId.
  void OnXrHasRenderTarget(const viz::FrameSinkId& frame_sink_id);

  // Because something else may be rendering as the primary contents of this
  // WebContents rather than the RenderHostView, targets that wish to capture
  // the contents of this WebContents should query its capture target here.
  struct CaptureTarget {
    viz::FrameSinkId sink_id;
    gfx::NativeView view;
  };
  CaptureTarget GetCaptureTarget();

  void set_show_popup_menu_callback_for_testing(
      base::OnceCallback<void(const gfx::Rect&)> callback) {
    show_popup_menu_callback_ = std::move(callback);
  }

  // Sets the value in tests to ensure expected ordering and correctness.
  void set_minimum_delay_between_loading_updates_for_testing(
      base::TimeDelta duration) {
    minimum_delay_between_loading_updates_ms_ = duration;
  }

  // If the given frame is prerendered, cancels the associated prerender.
  // Returns true if a prerender was canceled.
  bool CancelPrerendering(FrameTreeNode* frame_tree_node,
                          PrerenderFinalStatus final_status);

  void set_suppress_ime_events_for_testing(bool suppress) {
    suppress_ime_events_for_testing_ = suppress;
  }

  RenderWidgetHost* mouse_lock_widget_for_testing() {
    return pointer_lock_widget_;
  }

  ui::mojom::VirtualKeyboardMode GetVirtualKeyboardMode() const;

  const std::optional<base::Location>& ownership_location() const {
    return ownership_location_;
  }

 private:
  using FrameTreeIterationCallback = base::RepeatingCallback<void(FrameTree&)>;
  using RenderViewHostIterationCallback =
      base::RepeatingCallback<void(RenderViewHostImpl*)>;

  friend class WebContentsObserver;
  friend class WebContents;  // To implement factory methods.

  friend class RenderFrameHostImplBeforeUnloadBrowserTest;
  friend class WebContentsImplBrowserTest;
  friend class TestWebContentsDestructionObserver;
  friend class BeforeUnloadBlockingDelegate;
  friend class TestWCDelegateForDialogsAndFullscreen;

  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, CaptureHoldsWakeLock);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, NoJSMessageOnInterstitials);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, UpdateTitle);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, FindOpenerRVHWhenPending);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest,
                           CrossSiteCantPreemptAfterUnload);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, PendingContentsDestroyed);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, PendingContentsShown);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, FrameTreeShape);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest,
                           NonActivityCaptureDoesNotCountAsActivity);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, GetLastActiveTime);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest,
                           LoadResourceFromMemoryCacheWithBadSecurityInfo);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest,
                           LoadResourceWithEmptySecurityInfo);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest,
                           ResetJavaScriptDialogOnUserNavigate);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, ParseDownloadHeaders);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, FaviconURLsSet);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, FaviconURLsResetWithNavigation);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, FaviconURLsUpdateDelay);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           NotifyFullscreenAcquired);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           NotifyFullscreenAcquired_Navigate);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           NotifyFullscreenAcquired_SameOrigin);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           PropagateFullscreenOptions);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           FullscreenAfterFrameUnload);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           MaxFrameCountForCrossProcessNavigation);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           MaxFrameCountRemovedIframes);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           MaxFrameCountInjectedIframes);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           ForEachFrameTreeInnerContents);
  FRIEND_TEST_ALL_PREFIXES(FencedFrameMPArchBrowserTest, FrameIteration);
  FRIEND_TEST_ALL_PREFIXES(FencedFrameParameterizedBrowserTest,
                           ShouldIgnoreJsDialog);
  FRIEND_TEST_ALL_PREFIXES(FormStructureBrowserTest, HTMLFiles);
  FRIEND_TEST_ALL_PREFIXES(NavigationControllerTest, HistoryNavigate);
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostManagerTest, PageDoesBackAndReload);
  FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, CrossSiteIframe);
  FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
                           TwoSubframesCreatePopupsSimultaneously);
  FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, TextAutosizerPageInfo);
  FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
                           TwoSubframesCreatePopupMenuWidgetsSimultaneously);
  FRIEND_TEST_ALL_PREFIXES(SitePerProcessAccessibilityBrowserTest,
                           CrossSiteIframeAccessibility);
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
                           IframeBeforeUnloadParentHang);
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
                           BeforeUnloadDialogRequiresGesture);
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
                           CancelBeforeUnloadResetsURL);
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
                           BeforeUnloadDialogSuppressedForDiscard);
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
                           BeforeUnloadConfirmOnNonActive);
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
                           PendingDialogMakesDiscardUnloadReturnFalse);
  FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, JavaScriptDialogNotifications);
  FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, JavaScriptDialogInterop);
  FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, BeforeUnloadDialog);
  FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, PageDisableWithOpenedDialog);
  FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest,
                           PageDisableWithNoDialogManager);
  FRIEND_TEST_ALL_PREFIXES(
      PrerenderWithRenderDocumentBrowserTest,
      ModalDialogShouldNotBeDismissedAfterPrerenderSubframeNavigation);
  FRIEND_TEST_ALL_PREFIXES(PrerenderBrowserTest, ForEachRenderFrameHost);
  FRIEND_TEST_ALL_PREFIXES(PluginContentOriginAllowlistTest,
                           ClearAllowlistOnNavigate);
  FRIEND_TEST_ALL_PREFIXES(PluginContentOriginAllowlistTest,
                           SubframeInheritsAllowlist);
  FRIEND_TEST_ALL_PREFIXES(PointerLockBrowserTest,
                           PointerLockInnerContentsCrashes);
  FRIEND_TEST_ALL_PREFIXES(PointerLockBrowserTest, PointerLockOopifCrashes);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           PopupWindowBrowserNavResumeLoad);
  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
                           SuppressedPopupWindowBrowserNavResumeLoad);
  FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostSitePerProcessTest,
                           BrowserClosesPopupIntersectsPermissionPrompt);

  // So |find_request_manager_| can be accessed for testing.
  friend class FindRequestManagerTest;

  // TODO(brettw) TestWebContents shouldn't exist!
  friend class TestWebContents;

  class RenderWidgetHostDestructionObserver;
  class WebContentsDestructionObserver;

  // Represents a WebContents node in a tree of WebContents structure.
  //
  // Two WebContents with separate FrameTrees can be connected by
  // outer/inner relationship using this class. Note that their FrameTrees
  // still remain disjoint.
  // The parent is referred to as "outer WebContents" and the descendents are
  // referred to as "inner WebContents".
  // For each inner WebContents, the outer WebContents will have a
  // corresponding FrameTreeNode.
  class WebContentsTreeNode final : public FrameTreeNode::Observer {
   public:
    explicit WebContentsTreeNode(WebContentsImpl* current_web_contents);
    ~WebContentsTreeNode() final;

    // Attaches |inner_web_contents| to the |render_frame_host| within this
    // WebContents.
    void AttachInnerWebContents(std::unique_ptr<WebContents> inner_web_contents,
                                RenderFrameHostImpl* render_frame_host);

    // Disconnects the current WebContents from its outer WebContents, and
    // returns ownership to the caller. This is used when activating a portal,
    // which causes the WebContents to transition from an inner WebContents to
    // an outer WebContents.
    // TODO(lfg): Activating a nested portal currently replaces the outermost
    // WebContents with the portal. We should allow replacing only the inner
    // WebContents with the nested portal.
    std::unique_ptr<WebContents> DisconnectFromOuterWebContents();

    WebContentsImpl* outer_web_contents() const { return outer_web_contents_; }
    int outer_contents_frame_tree_node_id() const {
      return outer_contents_frame_tree_node_id_;
    }
    FrameTreeNode* OuterContentsFrameTreeNode() const;

    FrameTree* focused_frame_tree() { return &*focused_frame_tree_; }
    void SetFocusedFrameTree(FrameTree* frame_tree);

    // Returns the inner WebContents within |frame|, if one exists, or nullptr
    // otherwise.
    WebContentsImpl* GetInnerWebContentsInFrame(const FrameTreeNode* frame);

    std::vector<WebContentsImpl*> GetInnerWebContents() const;

   private:
    std::unique_ptr<WebContents> DetachInnerWebContents(
        WebContentsImpl* inner_web_contents);

    // FrameTreeNode::Observer implementation.
    void OnFrameTreeNodeDestroyed(FrameTreeNode* node) final;

    // The WebContents that owns this WebContentsTreeNode.
    const raw_ptr<WebContentsImpl, DanglingUntriaged> current_web_contents_;

    // The outer WebContents of |current_web_contents_|, or nullptr if
    // |current_web_contents_| is the outermost WebContents.
    raw_ptr<WebContentsImpl, DanglingUntriaged> outer_web_contents_;

    // The ID of the FrameTreeNode in the |outer_web_contents_| that hosts
    // |current_web_contents_| as an inner WebContents.
    int outer_contents_frame_tree_node_id_;

    // List of inner WebContents that we host. The outer WebContents owns the
    // inner WebContents.
    std::vector<std::unique_ptr<WebContents>> inner_web_contents_;

    // Only the root node should have this set. This indicates the FrameTree
    // that has the focused frame. The FrameTree tree could be arbitrarily deep.
    // An inner WebContents if focused is responsible for setting this back to
    // another valid during its destruction. See WebContentsImpl destructor.
    // TODO(crbug.com/1257595): Support clearing this for inner frame trees.
    base::SafeRef<FrameTree> focused_frame_tree_;
  };

  // Container for WebContentsObservers, which knows when we are iterating over
  // observer set.
  class WebContentsObserverList {
   public:
    WebContentsObserverList();
    ~WebContentsObserverList();

    void AddObserver(WebContentsObserver* observer);
    void RemoveObserver(WebContentsObserver* observer);

    // T1 must be a pointer to a WebContentsObserver method.
    template <typename T1, typename... P1>
    void NotifyObservers(T1 func, P1&&... args) {
      TRACE_EVENT0("content", "WebContentsObserverList::NotifyObservers");
      base::AutoReset<bool> scope(&is_notifying_observers_, true);
      for (WebContentsObserver& observer : observers_) {
        TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
                     "Dispatching WebContentsObserver callback");
        ((observer).*(func))(std::forward<P1>(args)...);
      }
    }

    bool is_notifying_observers() { return is_notifying_observers_; }

    // Exposed to deal with IPC message handlers which need to stop iteration
    // early.
    const base::ObserverList<WebContentsObserver>& observer_list() {
      return observers_;
    }

   private:
    bool is_notifying_observers_ = false;
    base::ObserverList<WebContentsObserver> observers_;
  };

  // See WebContents::Create for a description of these parameters.
  explicit WebContentsImpl(BrowserContext* browser_context);

  // Covariant return type alternative for WebContents::Create(). Avoids
  // need for casting of objects inside the content layer.
  static std::unique_ptr<WebContentsImpl> Create(const CreateParams& params);

  // Add and remove observers for page navigation notifications. The order in
  // which notifications are sent to observers is undefined. Clients must be
  // sure to remove the observer before they go away.
  void AddObserver(WebContentsObserver* observer);
  void RemoveObserver(WebContentsObserver* observer);

  // Indicates whether this tab should be considered crashed. The setter will
  // also notify the delegate when the flag is changed.
  void SetPrimaryMainFrameProcessStatus(base::TerminationStatus status,
                                        int error_code);

  // Clears a pending contents that has been closed before being shown.
  void OnWebContentsDestroyed(WebContentsImpl* web_contents);

  // Clears a pending render widget host that has been closed before being
  // shown.
  void OnRenderWidgetHostDestroyed(RenderWidgetHost* render_widget_host);

  // Creates and adds to the map a destruction observer watching `web_contents`.
  // No-op if such an observer already exists.
  void AddWebContentsDestructionObserver(WebContentsImpl* web_contents);

  // Deletes and removes from the map a destruction observer
  // watching `web_contents`. No-op if there is no such observer.
  void RemoveWebContentsDestructionObserver(WebContentsImpl* web_contents);

  // Creates and adds to the map a destruction observer watching
  // `render_widget_host`. No-op if such an observer already exists.
  void AddRenderWidgetHostDestructionObserver(
      RenderWidgetHost* render_widget_host);

  // Deletes and removes from the map a destruction observer
  // watching `render_widget_host`. No-op if there is no such observer.
  void RemoveRenderWidgetHostDestructionObserver(
      RenderWidgetHost* render_widget_host);

  // Traverses all the WebContents in the WebContentsTree and creates a set of
  // all the unique RenderWidgetHostViews.
  std::set<RenderWidgetHostViewBase*>
  GetRenderWidgetHostViewsInWebContentsTree();

  // Called with the result of a DownloadImage() request.
  void OnDidDownloadImage(base::WeakPtr<RenderFrameHostImpl> rfh,
                          ImageDownloadCallback callback,
                          int id,
                          const GURL& image_url,
                          int32_t http_status_code,
                          const std::vector<SkBitmap>& images,
                          const std::vector<gfx::Size>& original_image_sizes);

  // Callback function when showing JavaScript dialogs. Takes in a routing ID
  // pair to identify the RenderFrameHost that opened the dialog, because it's
  // possible for the RenderFrameHost to be deleted by the time this is called.
  void OnDialogClosed(int render_process_id,
                      int render_frame_id,
                      JavaScriptDialogCallback response_callback,
                      base::ScopedClosureRunner fullscreen_block,
                      bool dialog_was_suppressed,
                      bool success,
                      const std::u16string& user_input);

  // IPC message handlers.
  void OnUpdateZoomLimits(RenderViewHostImpl* source,
                          int minimum_percent,
                          int maximum_percent);
  void OnShowValidationMessage(RenderViewHostImpl* source,
                               const gfx::Rect& anchor_in_root_view,
                               const std::u16string& main_text,
                               const std::u16string& sub_text);
  void OnHideValidationMessage(RenderViewHostImpl* source);
  void OnMoveValidationMessage(RenderViewHostImpl* source,
                               const gfx::Rect& anchor_in_root_view);

  // Determines if content is allowed to overscroll. This value comes from the
  // WebContentsDelegate, but can also be overridden by the WebContents.
  bool CanOverscrollContent() const;

  // Inner WebContents Helpers -------------------------------------------------
  //
  // These functions are helpers in managing a hierarchy of WebContents
  // involved in rendering inner WebContents.

  // The following functions update registrations for all RenderWidgetHostViews
  // rooted at this WebContents. They are used when attaching/detaching an inner
  // WebContents.
  //
  // Some properties of RenderWidgetHostViews, such as the FrameSinkId and
  // TextInputManager, depend on the outermost WebContents, and must be updated
  // during attach/detach.
  void RecursivelyRegisterRenderWidgetHostViews();
  void RecursivelyUnregisterRenderWidgetHostViews();

  // When multiple WebContents are present within a tab or window, a single one
  // is focused and will route keyboard events in most cases to a RenderWidget
  // contained within it. |GetFocusedWebContents()|'s main frame widget will
  // receive page focus and blur events when the containing window changes focus
  // state.

  // Returns true if |this| is the focused WebContents or an ancestor of the
  // focused WebContents.
  bool ContainsOrIsFocusedWebContents();

  // Called just after an inner web contents is attached.
  void InnerWebContentsAttached(WebContents* inner_web_contents);

  // Called just after an inner web contents is detached.
  void InnerWebContentsDetached(WebContents* inner_web_contents);

  // Navigation helpers --------------------------------------------------------
  //
  // These functions are helpers for Navigate() and DidNavigate().

  // Handles post-navigation tasks in DidNavigate AFTER the entry has been
  // committed to the navigation controller. Note that the navigation entry is
  // not provided since it may be invalid/changed after being committed. The
  // current navigation entry is in the NavigationController at this point.

  // Finds the new RenderWidgetHost and returns it. Note that this can only be
  // called once as this call also removes it from the internal map.
  RenderWidgetHostView* GetCreatedWidget(int process_id, int route_id);

  // Finds the new CreatedWindow by |main_frame_widget_route_id|, initializes
  // it for renderer-initiated creation, and returns it. Note that this can only
  // be called once as this call also removes it from the internal map.
  std::optional<CreatedWindow> GetCreatedWindow(int process_id,
                                                int main_frame_widget_route_id);

  // Execute a PageBroadcast Mojo method.
  void ExecutePageBroadcastMethod(PageBroadcastMethodCallback callback);

  // Execute a PageBroadcast Mojo method for all MPArch pages.
  void ExecutePageBroadcastMethodForAllPages(
      PageBroadcastMethodCallback callback);

  void SetOpenerForNewContents(FrameTreeNode* opener, bool opener_suppressed);

  // Tracking loading progress -------------------------------------------------

  // Resets the tracking state of the current load progress.
  void ResetLoadProgressState();

  // Notifies the delegate that the load progress was updated.
  void SendChangeLoadProgress();

  // Misc non-view stuff -------------------------------------------------------

  // Sets the history for a specified RenderViewHost to |history_length|
  // entries, with an offset of |history_offset|.
  void SetHistoryOffsetAndLengthForView(RenderViewHost* render_view_host,
                                        int history_offset,
                                        int history_length);

  // Helper functions for sending notifications.
  void NotifyViewSwapped(RenderViewHost* old_view, RenderViewHost* new_view);
  void NotifyFrameSwapped(RenderFrameHostImpl* old_frame,
                          RenderFrameHostImpl* new_frame);

  // TODO(creis): This should take in a FrameTreeNode to know which node's
  // render manager to return.  For now, we just return the root's.
  RenderFrameHostManager* GetRenderManager();

  // Removes browser plugin embedder if there is one.
  void RemoveBrowserPluginEmbedder();

  // Returns the size that the main frame should be sized to.
  gfx::Size GetSizeForMainFrame();

  // Helper method that's called whenever |preferred_size_| or
  // |preferred_size_for_capture_| changes, to propagate the new value to the
  // |delegate_|.
  void OnPreferredSizeChanged(const gfx::Size& old_size);

  void SetJavaScriptDialogManagerForTesting(
      JavaScriptDialogManager* dialog_manager);

  // Returns the FindRequestManager, which may be found in an outer WebContents.
  FindRequestManager* GetFindRequestManager();

  // Returns the FindRequestManager, or tries to create one if it doesn't
  //  already exist. The FindRequestManager may be found in an outer
  // WebContents. If this is an inner WebContents which is not yet attached to
  // an outer WebContents the method will return nullptr.
  FindRequestManager* GetOrCreateFindRequestManager();

  // Prints a console warning when visiting a localhost site with a bad
  // certificate via --allow-insecure-localhost.
  void ShowInsecureLocalhostWarningIfNeeded(PageImpl& page);

  // Format of |headers| is a new line separated list of key value pairs:
  // "<key1>: <value1>\r\n<key2>: <value2>".
  static download::DownloadUrlParameters::RequestHeadersType
  ParseDownloadHeaders(const std::string& headers);

  // Sets the visibility of immediate child views, i.e. views whose parent view
  // is that of the main frame.
  void SetVisibilityForChildViews(bool visible);

  // A helper for clearing the link status bubble after navigating away.
  // See also UpdateTargetURL.
  void ClearTargetURL();

  // Called each time |fullscreen_frames_| is updated. Find the new
  // |current_fullscreen_frame_id_| and notify observers whenever it changes.
  void FullscreenFrameSetUpdated();

  // Adjusts bounds for minimum window size and available screen area
  // constraints. This compliments similar renderer-side adjustments, using the
  // resolved display mode for new windows, which renderers may be unable to
  // determine.
  int64_t AdjustWindowRect(gfx::Rect* bounds, RenderFrameHostImpl* opener);

  // ui::NativeThemeObserver:
  void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
  void OnCaptionStyleUpdated() override;

  // ui::ColorProviderSourceObserver:
  void OnColorProviderChanged() override;

  // Returns the ColorProvider instance for this WebContents object. This will
  // always return a valid ColorProvider instance.
  const ui::ColorProvider& GetColorProvider() const override;

  // Sets the visibility to |new_visibility| and propagates this to the
  // renderer side, taking into account the current capture state. This
  // can be called with the current visibility to affect capturing
  // changes.
  // |is_activity| controls whether a change to |visible| affects
  // the value returned by GetLastActiveTime().
  void UpdateVisibilityAndNotifyPageAndView(Visibility new_visibility,
                                            bool is_activity = true);

  // Returns UKM source id for the currently displayed page.
  // Intentionally kept private, prefer using
  // render_frame_host->GetPageUkmSourceId() if you already have a
  // |render_frame_host| reference or
  // GetPrimaryMainFrame()->GetPageUkmSourceId() if you don't.
  ukm::SourceId GetCurrentPageUkmSourceId() override;

  // Bit mask to indicate what types of RenderViewHosts to be returned in
  // ForEachRenderViewHost.
  enum ForEachRenderViewHostTypes {
    kPrerenderViews = 1 << 0,
    kBackForwardCacheViews = 1 << 1,
    kActiveViews = 1 << 2,
    kAllViews = kActiveViews | kBackForwardCacheViews | kPrerenderViews,
  };

  // For each RenderViewHost (including bfcache, prerendering) call the
  // callback, this will be filtered by `view_mask`.
  void ForEachRenderViewHost(
      ForEachRenderViewHostTypes view_mask,
      RenderViewHostIterationCallback on_render_view_host);

  // Sets the hardware-related fields in |prefs| that are slow to compute.  The
  // fields are set from cache if available, otherwise recomputed.
  void SetSlowWebPreferences(const base::CommandLine& command_line,
                             blink::web_pref::WebPreferences* prefs);

  // This is the actual implementation of the various overloads of
  // |ForEachRenderFrameHost|.
  void ForEachRenderFrameHostImpl(
      base::FunctionRef<FrameIterationAction(RenderFrameHostImpl*)> on_frame,
      bool include_speculative);

  // Calls |on_frame_tree| for every FrameTree in this WebContents.
  // This does not descend into inner WebContents, but does include inner frame
  // trees based on MPArch.
  void ForEachFrameTree(FrameTreeIterationCallback on_frame_tree);

  // Returns the primary frame tree, followed by any other outermost frame trees
  // in this WebContents. Outermost frame trees include, for example,
  // prerendering frame trees, and do not include, for example, fenced frames.
  // Also note that bfcached pages do not have a distinct frame tree,
  // so the primary frame tree in the result would be the only FrameTree
  // representing any bfcached pages.
  std::vector<FrameTree*> GetOutermostFrameTrees();

  // Returns the primary main frame, followed by the main frames of any other
  // outermost frame trees in this WebContents and the main frames of any
  // bfcached pages. Note that unlike GetOutermostFrameTrees, bfcached pages
  // have a distinct RenderFrameHostImpl in this result.
  std::vector<RenderFrameHostImpl*> GetOutermostMainFrames();

  // Called when the base::ScopedClosureRunner returned by
  // IncrementCapturerCount() is destructed.
  void DecrementCapturerCount(bool stay_hidden,
                              bool stay_awake,
                              bool is_activity = true);

  // Calculates the PageVisibilityState for |visibility|, taking the capturing
  // state into account.
  PageVisibilityState CalculatePageVisibilityState(Visibility visibility) const;

  // Called when the process hosting the primary main RenderFrameHost is known
  // to be alive.
  void NotifyPrimaryMainFrameProcessIsAlive();

  // Updates |entry|'s title. |entry| must belong to the WebContents' primary
  // NavigationController. Returns true if |entry|'s title was changed, and
  // false otherwise.
  bool UpdateTitleForEntryImpl(NavigationEntryImpl* entry,
                               const std::u16string& title);
  // Dispatches WebContentsObserver::TitleWasSet and also notifies the delegate
  // of a title change if |entry| is the entry whose title is being used as the
  // display title.
  void NotifyTitleUpdateForEntry(NavigationEntryImpl* entry);
  // Returns the navigation entry whose title is used as the display title for
  // this WebContents (i.e. for WebContents::GetTitle()).
  NavigationEntry* GetNavigationEntryForTitle();

  // Wrapper for ui::GetAvailablePointerAndHoverTypes which temporarily allows
  // blocking calls required on Windows when running on touch enabled devices.
  static std::pair<int, int> GetAvailablePointerAndHoverTypes();

  // Apply shared logic for SetHasPictureInPictureVideo() and
  // SetHasPictureInPictureDocument().
  void SetHasPictureInPictureCommon(bool has_picture_in_picture);

  // A scope that disallows custom cursors has expired.
  void DisallowCustomCursorScopeExpired();

  // Describes the different types of groups we can be interested in when
  // looking for scriptable frames.
  enum class GroupType { kBrowsingContextGroup, kCoopRelatedGroup };

  // Returns a vector of all the top-level active frames in the same group type
  // specified by `group_type`.
  std::vector<RenderFrameHostImpl*> GetActiveTopLevelDocumentsInGroup(
      RenderFrameHostImpl* render_frame_host,
      GroupType group_type);

  // Data for core operation ---------------------------------------------------

  // Delegate for notifying our owner about stuff. Not owned by us.
  raw_ptr<WebContentsDelegate, DanglingUntriaged> delegate_;

  // The corresponding view.
  std::unique_ptr<WebContentsView> view_;

  // The view of the RVHD. Usually this is our WebContentsView implementation,
  // but if an embedder uses a different WebContentsView, they'll need to
  // provide this.
  raw_ptr<RenderViewHostDelegateView> render_view_host_delegate_view_;

  // Tracks CreatedWindow objects that have not been shown yet. They are
  // identified by the process ID and routing ID passed to CreateNewWindow.
  std::map<GlobalRoutingID, CreatedWindow> pending_contents_;

  // Watches for the destruction of items in `pending_contents_`.
  std::map<WebContentsImpl*, std::unique_ptr<WebContentsDestructionObserver>>
      web_contents_destruction_observers_;

  // This map holds widgets that were created on behalf of the renderer but
  // haven't been shown yet.
  std::map<GlobalRoutingID, RenderWidgetHost*> pending_widgets_;

  // Watches for the destruction of items in `pending_widgets_`.
  std::map<RenderWidgetHost*,
           std::unique_ptr<RenderWidgetHostDestructionObserver>>
      render_widget_host_destruction_observers_;

  // A list of observers notified when page state changes. Weak references.
  // This MUST be listed above `primary_frame_tree_` since at destruction time
  // the latter might cause RenderViewHost's destructor to call us and we might
  // use the observer list then.
  WebContentsObserverList observers_;

  // True if this tab was opened by another window. This is true even if the tab
  // is opened with "noopener", and won't be unset if the opener is closed.
  bool opened_by_another_window_;

#if BUILDFLAG(IS_ANDROID)
  std::unique_ptr<WebContentsAndroid> web_contents_android_;
#endif

  // Helper classes ------------------------------------------------------------

  // Primary FrameTree of this WebContents instance. This WebContents might have
  // additional FrameTrees for features like prerendering and fenced frames,
  // which either might be standalone (prerendering) to nested within a
  // different FrameTree (fenced frame).
  FrameTree primary_frame_tree_;

  // Contains information about the WebContents tree structure.
  WebContentsTreeNode node_;

  // SavePackage, lazily created.
  scoped_refptr<SavePackage> save_package_;

  // Manages/coordinates multi-process find-in-page requests. Created lazily.
  std::unique_ptr<FindRequestManager> find_request_manager_;

  // Data for loading state ----------------------------------------------------

  // Indicates the process state of the primary main frame's renderer process.
  // If the process is not live due to a crash, this will be reflected by
  // IsCrashed(), though it's possible to not be live while not indicating a
  // crash occurred.
  base::TerminationStatus primary_main_frame_process_status_;
  int primary_main_frame_process_error_code_;

  // The current load state and the URL associated with it.
  net::LoadStateWithParam load_state_;
  std::u16string load_state_host_;
  base::TimeTicks load_info_timestamp_;

  base::TimeTicks loading_last_progress_update_;

  // Default value is set to 100ms between LoadProgressChanged events.
  base::TimeDelta minimum_delay_between_loading_updates_ms_ =
      base::Milliseconds(100);

  // Upload progress, for displaying in the status bar.
  // Set to zero when there is no significant upload happening.
  uint64_t upload_size_;
  uint64_t upload_position_;

  // Tracks that this WebContents needs to unblock requests to the renderer.
  // See ResumeLoadingCreatedWebContents.
  bool is_resume_pending_;

  // Data for current page -----------------------------------------------------

  // The last published theme color.
  std::optional<SkColor> last_sent_theme_color_;

  // The last published background color.
  std::optional<SkColor> last_sent_background_color_;

  // Data for misc internal state ----------------------------------------------

  // When either > 0, the WebContents is currently being captured (e.g.,
  // for screenshots or mirroring); and the underlying RenderWidgetHost
  // should not be told it is hidden. If |visible_capturer_count_| > 0,
  // the underlying Page is set to fully visible. Otherwise, it is set
  // to be hidden but still paint.
  int visible_capturer_count_ = 0;
  int hidden_capturer_count_ = 0;

  // When > 0, |capture_wake_lock_| will be held to prevent display sleep.
  int stay_awake_capturer_count_ = 0;

  // WakeLock held to ensure screen capture keeps the display on. E.g., for
  // presenting through tab capture APIs.
  mojo::Remote<device::mojom::WakeLock> capture_wake_lock_;

  // The visibility of the WebContents. Initialized from
  // |CreateParams::initially_hidden|. Updated from
  // UpdateWebContentsVisibility(), WasShown(), WasHidden(), WasOccluded().
  Visibility visibility_ = Visibility::VISIBLE;

  // Whether there has been a call to UpdateWebContentsVisibility(VISIBLE).
  bool did_first_set_visible_ = false;

  // Set to true while calling out to notify one-off observers (ie non-
  // WebContentsObservers). These observers should not destroy WebContentsImpl
  // while it is on the call stack, as that leads to use-after-frees.
  bool prevent_destruction_ = false;

  bool is_being_destroyed_ = false;

  // Indicates whether we should notify about disconnection of this
  // WebContentsImpl. This is used to ensure disconnection notifications only
  // happen if a connection notification has happened and that they happen only
  // once.
  bool notify_disconnection_;

  // Counts the number of outstanding requests to ignore input events. They will
  // not be sent when this is greater than zero.
  int ignore_input_events_count_ = 0;

  // Pointer to the JavaScript dialog manager, lazily assigned. Used because the
  // delegate of this WebContentsImpl is nulled before its destructor is called.
  raw_ptr<JavaScriptDialogManager, DanglingUntriaged> dialog_manager_;

  // Set to true when there is an active JavaScript dialog showing.
  bool is_showing_javascript_dialog_ = false;

  // Set to true when there is an active "before unload" dialog.  When true,
  // we've forced the throbber to start in Navigate, and we need to remember to
  // turn it off in OnJavaScriptMessageBoxClosed if the navigation is canceled.
  bool is_showing_before_unload_dialog_;

  // Settings that get passed to the renderer process.
  blink::RendererPreferences renderer_preferences_;

  // The time that this WebContents was last made active. The initial value is
  // the WebContents creation time.
  base::TimeTicks last_active_time_;

  // The most recent time that this WebContents was interacted with. Currently,
  // this counts:
  // * 'interactive' input events from the user, like mouse clicks and keyboard
  // input but not mouse wheel scrolling
  // * editing commands such as `Paste()`, which are invoked programmatically,
  // presumably in response to user action
  base::TimeTicks last_interaction_time_;

  // See description above setter.
  bool closed_by_user_gesture_;

  // The number of active fullscreen blockers.
  int fullscreen_blocker_count_ = 0;

  // Minimum/maximum zoom percent.
  const int minimum_zoom_percent_;
  const int maximum_zoom_percent_;

  // Used to correctly handle integer zooming through a smooth scroll device.
  float zoom_scroll_remainder_;

  // The intrinsic size of the page.
  gfx::Size preferred_size_;

  // The preferred size for content screen capture.  When |capturer_count_| > 0,
  // this overrides |preferred_size_|.
  gfx::Size preferred_size_for_capture_;

  // When device emulation is enabled, override the size of current and newly
  // created render views/widgets.
  gfx::Size device_emulation_size_;
  gfx::Size view_size_before_emulation_;

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
  // Holds information about a current color chooser dialog, if one is visible.
  class ColorChooserHolder;
  std::unique_ptr<ColorChooserHolder> color_chooser_holder_;
#endif

  // Manages the embedder state for browser plugins, if this WebContents is an
  // embedder; NULL otherwise.
  std::unique_ptr<BrowserPluginEmbedder> browser_plugin_embedder_;
  // Manages the guest state for browser plugin, if this WebContents is a guest;
  // NULL otherwise.
  std::unique_ptr<BrowserPluginGuest> browser_plugin_guest_;

  // All live RenderWidgetHostImpls that are created by this object and may
  // outlive it.
  std::set<raw_ptr<RenderWidgetHostImpl, SetExperimental>> created_widgets_;

  // Process id of the shown fullscreen widget, or kInvalidUniqueID if there is
  // no fullscreen widget.
  int fullscreen_widget_process_id_;

  // Routing id of the shown fullscreen widget or MSG_ROUTING_NONE otherwise.
  int fullscreen_widget_routing_id_;

  // At the time the fullscreen widget was being shut down, did it have focus?
  // This is used to restore focus to the WebContentsView after both: 1) the
  // fullscreen widget is destroyed, and 2) the WebContentsDelegate has
  // completed making layout changes to effect an exit from fullscreen mode.
  bool fullscreen_widget_had_focus_at_shutdown_;

  // When a new tab is created asynchronously, stores the OpenURLParams needed
  // to continue loading the page once the tab is ready.
  std::unique_ptr<OpenURLParams> delayed_open_url_params_;

  // When a new tab is created with window.open(), navigation can be deferred
  // to execute asynchronously. In such case, the parameters need to be saved
  // for the navigation to be started at a later point.
  std::unique_ptr<NavigationController::LoadURLParams> delayed_load_url_params_;

  // Whether overscroll should be unconditionally disabled.
  bool force_disable_overscroll_content_;

  // Whether the last JavaScript dialog shown was suppressed. Used for testing.
  bool last_dialog_suppressed_;

  mojo::Remote<device::mojom::GeolocationContext> geolocation_context_;

  mojo::AssociatedRemote<blink::mojom::ContextMenuClient> context_menu_client_;

  std::unique_ptr<WakeLockContextHost> wake_lock_context_host_;
  bool enable_wake_locks_ = true;

  // The last set/computed value of WebPreferences for this WebContents, either
  // set directly through SetWebPreferences, or set after recomputing values
  // from ComputeWebPreferences.
  std::unique_ptr<blink::web_pref::WebPreferences> web_preferences_;

  bool updating_web_preferences_ = false;

#if BUILDFLAG(IS_ANDROID)
  std::unique_ptr<NFCHost> nfc_host_;
#endif

  mojo::ReceiverSet<blink::mojom::ColorChooserFactory>
      color_chooser_factory_receivers_;

  std::unique_ptr<ScreenOrientationProvider> screen_orientation_provider_;

  // The accessibility mode for all frames. This is queried when each frame
  // is created, and broadcast to all frames when it changes.
  ui::AXMode accessibility_mode_;

  std::unique_ptr<ui::AXEventRecorder> event_recorder_;

  // Enables ui::kAXModeBasic for the duration of a recording session.
  std::unique_ptr<ScopedAccessibilityMode> recording_mode_;

  // Monitors power levels for audio streams associated with this WebContents.
  AudioStreamMonitor audio_stream_monitor_;

  // Coordinates all the audio streams for this WebContents. Lazily initialized.
  std::optional<ForwardingAudioStreamFactory> audio_stream_factory_;

  size_t bluetooth_connected_device_count_ = 0;
  size_t bluetooth_scanning_sessions_count_ = 0;
  size_t serial_active_frame_count_ = 0;
  size_t hid_active_frame_count_ = 0;
  size_t usb_active_frame_count_ = 0;

  size_t file_system_access_handle_count_ = 0;

  bool has_picture_in_picture_video_ = false;
  bool has_picture_in_picture_document_ = false;

  // Manages media players, CDMs, and power save blockers for media.
  std::unique_ptr<MediaWebContentsObserver> media_web_contents_observer_;

#if BUILDFLAG(ENABLE_PPAPI)
  // Observes pepper playback changes, and notifies MediaSession.
  std::unique_ptr<PepperPlaybackObserver> pepper_playback_observer_;
#endif  // BUILDFLAG(ENABLE_PPAPI)

  std::unique_ptr<RenderWidgetHostInputEventRouter> rwh_input_event_router_;

  // TextInputManager tracks the IME-related state for all the
  // RenderWidgetHostViews on this WebContents. Only exists on the outermost
  // WebContents and is automatically destroyed when a WebContents becomes an
  // inner WebContents by attaching to an outer WebContents. Then the
  // IME-related state for RenderWidgetHosts on the inner WebContents is tracked
  // by the TextInputManager in the outer WebContents.
  std::unique_ptr<TextInputManager> text_input_manager_;

  // Tests can set this to true in order to force this web contents to always
  // return nullptr for the above `text_input_manager_`, effectively blocking
  // IME events from propagating out of the renderer.
  bool suppress_ime_events_for_testing_ = false;

  // Stores the RenderWidgetHost that currently holds a mouse lock or nullptr if
  // there's no RenderWidgetHost holding a lock.
  raw_ptr<RenderWidgetHostImpl, DanglingUntriaged> pointer_lock_widget_ =
      nullptr;

  // Stores the RenderWidgetHost that currently holds a keyboard lock or nullptr
  // if no RenderWidgetHost has the keyboard locked.
  raw_ptr<RenderWidgetHostImpl, DanglingUntriaged> keyboard_lock_widget_ =
      nullptr;

  // Indicates whether the escape key is one of the requested keys to be locked.
  // This information is used to drive the browser UI so the correct exit
  // instructions are displayed to the user in fullscreen mode.
  bool esc_key_locked_ = false;

#if BUILDFLAG(IS_ANDROID)
  std::unique_ptr<service_manager::InterfaceProvider> java_interfaces_;
#endif

  // Whether this WebContents is for content overlay.
  bool is_overlay_content_;

  bool showing_context_menu_;

  int currently_playing_video_count_ = 0;
  base::flat_map<MediaPlayerId, gfx::Size> cached_video_sizes_;

  bool has_persistent_video_ = false;

  bool is_spatial_navigation_disabled_ = false;

  bool stylus_handwriting_enabled_ = false;

  bool is_currently_audible_ = false;
  bool was_ever_audible_ = false;

  // Helper variable for resolving races in UpdateTargetURL / ClearTargetURL.
  raw_ptr<RenderFrameHost, DanglingUntriaged> frame_that_set_last_target_url_ =
      nullptr;

  // Whether we should override user agent in new tabs.
  bool should_override_user_agent_in_new_tabs_ = false;

  // Used to determine the value of is-user-agent-overriden for renderer
  // initiated navigations.
  NavigationController::UserAgentOverrideOption
      renderer_initiated_user_agent_override_option_ =
          NavigationController::UA_OVERRIDE_INHERIT;

  // Gets notified about changes in viewport fit events.
  std::unique_ptr<SafeAreaInsetsHost> safe_area_insets_host_;

  // Stores a set of frames that are fullscreen.
  // See https://fullscreen.spec.whatwg.org.
  std::set<raw_ptr<RenderFrameHostImpl, SetExperimental>> fullscreen_frames_;

  // Store an ID for the frame that is currently fullscreen, or an invalid ID if
  // there is none.
  GlobalRenderFrameHostId current_fullscreen_frame_id_ =
      GlobalRenderFrameHostId();

  // Whether location bar should be focused by default. This is computed in
  // DidStartNavigation/DidFinishNavigation and only set for an initial
  // navigation triggered by the browser going to about:blank.
  bool should_focus_location_bar_by_default_ = false;

  // Stores the rect of the Windows Control Overlay, which contains system UX
  // affordances (e.g. close), for installed desktop Progress Web Apps (PWAs),
  // if the app specifies the 'window-controls-overlay' DisplayMode in its
  // manifest. This is in frame space coordinates.
  gfx::Rect window_controls_overlay_rect_;

  // Observe native theme for changes to dark mode, preferred color scheme, and
  // preferred contrast. Used to notify the renderer of preferred color scheme
  // and preferred contrast changes.
  base::ScopedObservation<ui::NativeTheme, ui::NativeThemeObserver>
      native_theme_observation_{this};

  bool using_dark_colors_ = false;
  ui::NativeTheme::PreferredColorScheme preferred_color_scheme_ =
      ui::NativeTheme::PreferredColorScheme::kLight;
  ui::NativeTheme::PreferredContrast preferred_contrast_ =
      ui::NativeTheme::PreferredContrast::kNoPreference;
  bool prefers_reduced_transparency_ = false;
  bool inverted_colors_ = false;

  // Tracks clients who want to be notified when a JavaScript dialog is
  // dismissed.
  std::unique_ptr<JavaScriptDialogDismissNotifier>
      javascript_dialog_dismiss_notifier_;

  // The max number of loaded frames that have been seen in this WebContents.
  // This number is reset with each main frame navigation.
  size_t max_loaded_frame_count_ = 0;

  // This boolean value is used to keep track of whether we finished the first
  // successful navigation in this WebContents's primary main frame.
  bool first_primary_navigation_completed_ = false;

  // Monitors system screen info changes to notify the renderer.
  std::unique_ptr<ScreenChangeMonitor> screen_change_monitor_;

  // Records the last time we saw a screen orientation change.
  base::TimeTicks last_screen_orientation_change_time_;

  // Manages a transient affordance for this page's frames to enter fullscreen.
  blink::TransientAllowFullscreen transient_allow_fullscreen_;

  // Indicates how many sources are currently suppressing the unresponsive
  // renderer dialog.
  int suppress_unresponsive_renderer_count_ = 0;

  std::unique_ptr<PrerenderHostRegistry> prerender_host_registry_;

  // Used to ignore multiple back navigation hints in rapid succession. For
  // example, we may get multiple hints due to imprecise mouse movement while
  // the user is trying to move the mouse to the back button.
  base::TimeTicks last_back_navigation_hint_time_ = base::TimeTicks::Min();

  viz::FrameSinkId xr_render_target_;

  base::OnceCallback<void(const gfx::Rect&)> show_popup_menu_callback_;

  // Allows the app in the current WebContents to opt-in to exposing
  // information to apps that capture it.
  blink::mojom::CaptureHandleConfig capture_handle_config_;

  // Background color of the page set by the embedder to be passed to all
  // renderers attached to this WebContents, for use in the main frame.
  // It is used when the page has not loaded enough to know a background
  // color or if the page does not set a background color.
  std::optional<SkColor> page_base_background_color_;

#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(USE_STARSCAN)
  // TODO(1231679): Remove/reevaluate after the PCScan experiment is finished.
  std::unique_ptr<StarScanLoadObserver> star_scan_load_observer_;
#endif

  // Stores WebContents::CreateParams::creator_location.
  base::Location creator_location_;

#if BUILDFLAG(IS_ANDROID)
  // Stores WebContents::CreateParams::java_creator_location.
  base::android::ScopedJavaGlobalRef<jthrowable> java_creator_location_;
#endif  // BUILDFLAG(IS_ANDROID)

  // The options used for WebContents associated with a PictureInPicture window.
  // This value is the parameter given in
  // WebContents::CreateParams::picture_in_picture_options.
  std::optional<blink::mojom::PictureInPictureWindowOptions>
      picture_in_picture_options_;

  VisibleTimeRequestTrigger visible_time_request_trigger_;

  // Counts the number of open scopes that disallow custom cursors in this web
  // contents. Custom cursors are allowed if this is 0.
  int disallow_custom_cursor_scope_count_ = 0;

  base::WeakPtr<FileChooserImpl> active_file_chooser_;

  std::optional<base::Location> ownership_location_;

  // Indicates if the instance is hosted in a preview window.
  // This will be set in Init() and will be reset in WillActivatePreviewPage().
  bool is_in_preview_mode_ = false;

  // Indicates accessibility had an unrecoverable error.
  bool accessibility_fatal_error_ = false;

  base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_{this};
  base::WeakPtrFactory<WebContentsImpl> weak_factory_{this};
};

// Dangerous methods which should never be made part of the public API, so we
// grant their use only to an explicit friend list (c++ attorney/client idiom).
class CONTENT_EXPORT WebContentsImpl::FriendWrapper {
 public:
  using CreatedCallback = base::RepeatingCallback<void(WebContents*)>;

  FriendWrapper(const FriendWrapper&) = delete;
  FriendWrapper& operator=(const FriendWrapper&) = delete;

 private:
  friend base::CallbackListSubscription RegisterWebContentsCreationCallback(
      base::RepeatingCallback<void(WebContents*)>);

  FriendWrapper();  // Not instantiable.

  // Adds a callback called on creation of each new WebContents.
  static base::CallbackListSubscription AddCreatedCallbackForTesting(
      const CreatedCallback& callback);
};

}  // namespace content

#endif  // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_IMPL_H_
