#include "content/browser/renderer_host/render_frame_host_manager.h"
#include <stddef.h>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/containers/adapters.h"
#include "base/containers/contains.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/base_tracing.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.h"
#include "base/types/expected.h"
#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/preloading/prefetch/prefetch_features.h"
#include "content/browser/process_lock.h"
#include "content/browser/renderer_host/agent_scheduling_group_host.h"
#include "content/browser/renderer_host/back_forward_cache_metrics.h"
#include "content/browser/renderer_host/debug_urls.h"
#include "content/browser/renderer_host/frame_navigation_entry.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_impl.h"
#include "content/browser/renderer_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/navigator.h"
#include "content/browser/renderer_host/render_frame_host_delegate.h"
#include "content/browser/renderer_host/render_frame_host_factory.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_frame_host_owner.h"
#include "content/browser/renderer_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_enums.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/renderer_host/spare_render_process_host_manager.h"
#include "content/browser/security/coop/cross_origin_opener_policy_reporter.h"
#include "content/browser/site_info.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/navigation_params_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_host.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/disallow_activation_reason.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "net/base/url_util.h"
#include "services/network/public/cpp/features.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom.h"
#if BUILDFLAG(IS_MAC)
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
#endif
namespace content {
LifecycleStateImpl;
ChromeTrackEvent;
namespace {
const char kBackForwardCachePageWithFormStorableHistogramName[] = …;
bool IsAbout(const GURL& url) { … }
bool ShouldSwapBrowsingInstancesForDynamicIsolation(
RenderFrameHostImpl* current_rfh,
const UrlInfo& destination_effective_url_info) { … }
bool DoesNavigationChangeStoragePartition(SiteInstanceImpl* current_instance,
const UrlInfo& dest_url_info) { … }
bool IsSiteInstanceCompatibleWithErrorIsolation(
SiteInstanceImpl* site_instance,
const FrameTreeNode& frame_tree_node,
NavigationRequest::ErrorPageProcess error_page_process) { … }
bool IsSiteInstanceCompatibleWithWebExposedIsolation(
SiteInstanceImpl* site_instance,
const std::optional<WebExposedIsolationInfo>& web_exposed_isolation_info) { … }
void AppendReason(std::string* reason, const char* value) { … }
perfetto::protos::pbzero::ShouldSwapBrowsingInstance
ShouldSwapBrowsingInstanceToProto(ShouldSwapBrowsingInstance result) { … }
void TraceShouldSwapBrowsingInstanceResult(int frame_tree_node_id,
ShouldSwapBrowsingInstance result) { … }
void ReuseDefaultProcessFromDifferentBrowsingInstanceIfPossible(
scoped_refptr<SiteInstanceImpl> new_instance,
RenderFrameHostImpl* rfh) { … }
enum class ProcessPerSiteWithMainFrameThresholdBlockReason { … };
void RecordProcessPerSiteWithMainFrameThresholdBlockReason(
ProcessPerSiteWithMainFrameThresholdBlockReason reason) { … }
void UpdateProcessReusePolicyForProcessPerSiteWithMainFrameThreshold(
SiteInstanceImpl* site_instance,
FrameTreeNode* frame_tree_node) { … }
void PrepareViewTransitionForBFCacheActivation(
RenderFrameHostImpl* rfh_to_show) { … }
bool NavigationRequestUsesWebUI(NavigationRequest* request,
BrowserContext* browser_context) { … }
bool CanIntentionallyDeferSpeculativeRFHForRequest(
NavigationRequest* request,
BrowserContext* browser_context,
FrameTreeNode* frame_tree_node) { … }
}
RenderFrameHostManager::IsSameSiteGetter::IsSameSiteGetter()
: … { … }
RenderFrameHostManager::IsSameSiteGetter::IsSameSiteGetter(bool is_same_site)
: … { … }
bool RenderFrameHostManager::IsSameSiteGetter::Get(
const RenderFrameHostImpl& render_frame_host,
const UrlInfo& url_info) { … }
RenderFrameHostManager::RenderFrameHostManager(FrameTreeNode* frame_tree_node,
Delegate* delegate)
: … { … }
RenderFrameHostManager::~RenderFrameHostManager() { … }
void RenderFrameHostManager::InitRoot(
SiteInstanceImpl* site_instance,
bool renderer_initiated_creation,
blink::FramePolicy initial_main_frame_policy,
const std::string& name,
const base::UnguessableToken& devtools_frame_token) { … }
void RenderFrameHostManager::InitChild(
SiteInstanceImpl* site_instance,
int32_t frame_routing_id,
mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
const blink::LocalFrameToken& frame_token,
const blink::DocumentToken& document_token,
const base::UnguessableToken& devtools_frame_token,
blink::FramePolicy frame_policy,
std::string frame_name,
std::string frame_unique_name) { … }
RenderWidgetHostViewBase* RenderFrameHostManager::GetRenderWidgetHostView()
const { … }
bool RenderFrameHostManager::IsMainFrameForInnerDelegate() { … }
FrameTreeNode* RenderFrameHostManager::GetOuterDelegateNode() const { … }
RenderFrameProxyHost* RenderFrameHostManager::GetProxyToParent() { … }
RenderFrameProxyHost* RenderFrameHostManager::GetProxyToOuterDelegate() { … }
RenderFrameProxyHost*
RenderFrameHostManager::GetProxyToParentOrOuterDelegate() { … }
void RenderFrameHostManager::RemoveOuterDelegateFrame() { … }
void RenderFrameHostManager::Stop() { … }
void RenderFrameHostManager::SetIsLoading(bool is_loading) { … }
void RenderFrameHostManager::BeforeUnloadCompleted(bool proceed) { … }
void RenderFrameHostManager::DidNavigateFrame(
RenderFrameHostImpl* render_frame_host,
bool was_caused_by_user_gesture,
bool is_same_document_navigation,
bool clear_proxies_on_commit,
const blink::FramePolicy& frame_policy,
bool allow_subframe_paint_holding,
bool is_initiated_by_animated_transition) { … }
void RenderFrameHostManager::CommitPendingIfNecessary(
RenderFrameHostImpl* render_frame_host,
bool was_caused_by_user_gesture,
bool is_same_document_navigation,
bool clear_proxies_on_commit,
bool allow_subframe_paint_holding,
bool is_initiated_by_animated_transition) { … }
void RenderFrameHostManager::DidChangeOpener(
const std::optional<blink::LocalFrameToken>& opener_frame_token,
SiteInstanceGroup* source_site_instance_group) { … }
std::unique_ptr<StoredPage> RenderFrameHostManager::TakePrerenderedPage() { … }
void RenderFrameHostManager::PrepareForCollectingPage(
RenderFrameHostImpl* main_render_frame_host,
StoredPage::RenderViewHostImplSafeRefSet* render_view_hosts,
BrowsingContextState::RenderFrameProxyHostMap* proxy_hosts) { … }
std::unique_ptr<StoredPage> RenderFrameHostManager::CollectPage(
std::unique_ptr<RenderFrameHostImpl> main_render_frame_host) { … }
void RenderFrameHostManager::UpdateOpener(
RenderFrameHostImpl* render_frame_host) { … }
void RenderFrameHostManager::UnloadOldFrame(
std::unique_ptr<RenderFrameHostImpl> old_render_frame_host) { … }
void RenderFrameHostManager::DiscardUnusedFrame(
std::unique_ptr<RenderFrameHostImpl> render_frame_host) { … }
bool RenderFrameHostManager::DeleteFromPendingList(
RenderFrameHostImpl* render_frame_host) { … }
void RenderFrameHostManager::ActivatePrerender(
std::unique_ptr<StoredPage> stored_page) { … }
void RenderFrameHostManager::RestorePage(
std::unique_ptr<StoredPage> stored_page) { … }
void RenderFrameHostManager::ClearRFHsPendingShutdown() { … }
void RenderFrameHostManager::ClearWebUIInstances() { … }
bool RenderFrameHostManager::HasPendingCommitForCrossDocumentNavigation()
const { … }
void RenderFrameHostManager::DidCreateNavigationRequest(
NavigationRequest* request) { … }
void RenderFrameHostManager::PerformEarlyRenderFrameHostSwapIfNeeded(
NavigationRequest* request,
bool is_called_after_did_start_navigation) { … }
base::expected<RenderFrameHostImpl*, GetFrameHostForNavigationFailed>
RenderFrameHostManager::GetFrameHostForNavigation(
NavigationRequest* request,
BrowsingContextGroupSwap* browsing_context_group_swap,
std::string* reason) { … }
void RenderFrameHostManager::CreateWebUIForNavigationIfNeeded(
NavigationRequest* request,
SiteInstanceImpl* dest_site_instance,
bool use_current_rfh) { … }
void RenderFrameHostManager::DiscardSpeculativeRFHIfUnused(
NavigationDiscardReason reason) { … }
void RenderFrameHostManager::DiscardSpeculativeRFH(
NavigationDiscardReason reason) { … }
std::unique_ptr<RenderFrameHostImpl>
RenderFrameHostManager::UnsetSpeculativeRenderFrameHost(
NavigationDiscardReason reason) { … }
void RenderFrameHostManager::DiscardSpeculativeRenderFrameHostForShutdown() { … }
void RenderFrameHostManager::OnDidChangeCollapsedState(bool collapsed) { … }
void RenderFrameHostManager::OnDidUpdateFrameOwnerProperties(
const blink::mojom::FrameOwnerProperties& properties) { … }
RenderFrameHostManager::SiteInstanceDescriptor::SiteInstanceDescriptor(
SiteInstanceImpl* site_instance)
: … { … }
RenderFrameHostManager::SiteInstanceDescriptor::SiteInstanceDescriptor(
UrlInfo dest_url_info,
SiteInstanceRelation relation_to_current)
: … { … }
void RenderFrameHostManager::CleanupSpeculativeRfhForRenderProcessGone() { … }
void RenderFrameHostManager::UpdateUserActivationState(
blink::mojom::UserActivationUpdateType update_type,
blink::mojom::UserActivationNotificationType notification_type) { … }
BrowsingContextGroupSwap
RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
const GURL& current_effective_url,
bool current_is_view_source_mode,
SiteInstanceImpl* source_instance,
SiteInstanceImpl* current_instance,
SiteInstanceImpl* destination_instance,
const UrlInfo& destination_url_info,
bool destination_is_view_source_mode,
ui::PageTransition transition,
NavigationRequest::ErrorPageProcess error_page_process,
bool is_reload,
bool is_same_document,
IsSameSiteGetter& is_same_site,
CoopSwapResult coop_swap_result,
bool was_server_redirect,
bool should_replace_current_entry,
bool has_rel_opener) { … }
BrowsingContextGroupSwap
RenderFrameHostManager::ShouldProactivelySwapBrowsingInstance(
const UrlInfo& destination_url_info,
bool is_reload,
IsSameSiteGetter& is_same_site,
bool should_replace_current_entry,
bool has_rel_opener) { … }
scoped_refptr<SiteInstanceImpl>
RenderFrameHostManager::GetSiteInstanceForNavigation(
const UrlInfo& dest_url_info,
SiteInstanceImpl* source_instance,
SiteInstanceImpl* dest_instance,
SiteInstanceImpl* candidate_instance,
ui::PageTransition transition,
NavigationRequest::ErrorPageProcess error_page_process,
bool is_reload,
bool is_same_document,
IsSameSiteGetter& is_same_site,
bool dest_is_view_source_mode,
bool was_server_redirect,
CoopSwapResult coop_swap_result,
bool should_replace_current_entry,
bool force_new_browsing_instance,
bool has_rel_opener,
BrowsingContextGroupSwap* should_swap_result,
std::string* reason) { … }
bool RenderFrameHostManager::InitializeMainRenderFrameForImmediateUse() { … }
void RenderFrameHostManager::PrepareForInnerDelegateAttach(
RenderFrameHost::PrepareForInnerWebContentsAttachCallback callback) { … }
RenderFrameHostManager::SiteInstanceDescriptor
RenderFrameHostManager::DetermineSiteInstanceForURL(
const UrlInfo& dest_url_info,
SiteInstanceImpl* source_instance,
SiteInstanceImpl* current_instance,
SiteInstanceImpl* dest_instance,
ui::PageTransition transition,
NavigationRequest::ErrorPageProcess error_page_process,
IsSameSiteGetter& is_same_site,
BrowsingContextGroupSwap browsing_context_group_swap,
bool was_server_redirect,
std::string* reason) { … }
bool RenderFrameHostManager::CanUseDestinationInstance(
const UrlInfo& dest_url_info,
SiteInstanceImpl* current_instance,
SiteInstanceImpl* dest_instance,
NavigationRequest::ErrorPageProcess error_page_process,
const BrowsingContextGroupSwap& browsing_context_group_swap,
bool was_server_redirect) { … }
bool RenderFrameHostManager::IsBrowsingInstanceSwapAllowedForPageTransition(
ui::PageTransition transition,
const GURL& dest_url) { … }
scoped_refptr<SiteInstanceImpl> RenderFrameHostManager::ConvertToSiteInstance(
const SiteInstanceDescriptor& descriptor,
SiteInstanceImpl* candidate_instance) { … }
bool RenderFrameHostManager::CanUseSourceSiteInstance(
const UrlInfo& dest_url_info,
SiteInstanceImpl* source_instance,
bool was_server_redirect,
NavigationRequest::ErrorPageProcess error_page_process,
std::string* reason) { … }
bool RenderFrameHostManager::IsCandidateSameSite(RenderFrameHostImpl* candidate,
const UrlInfo& dest_url_info) { … }
void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
SiteInstanceGroup* old_group,
SiteInstanceGroup* new_group,
bool recovering_without_early_commit,
const scoped_refptr<BrowsingContextState>& browsing_context_state) { … }
void RenderFrameHostManager::CreateProxiesForNewNamedFrame(
const scoped_refptr<BrowsingContextState>& browsing_context_state) { … }
std::unique_ptr<RenderFrameHostImpl>
RenderFrameHostManager::CreateRenderFrameHost(
CreateFrameCase create_frame_case,
SiteInstanceImpl* site_instance,
int32_t frame_routing_id,
mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
const blink::LocalFrameToken& frame_token,
const blink::DocumentToken& document_token,
base::UnguessableToken devtools_frame_token,
bool renderer_initiated_creation,
scoped_refptr<BrowsingContextState> browsing_context_state) { … }
bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
SiteInstanceImpl* old_instance,
SiteInstanceImpl* new_instance,
bool recovering_without_early_commit) { … }
std::unique_ptr<RenderFrameHostImpl>
RenderFrameHostManager::CreateSpeculativeRenderFrame(
SiteInstanceImpl* instance,
bool recovering_without_early_commit,
const scoped_refptr<BrowsingContextState>& browsing_context_state) { … }
void RenderFrameHostManager::CreateRenderFrameProxy(
SiteInstanceGroup* group,
const scoped_refptr<BrowsingContextState>& browsing_context_state,
BatchedProxyIPCSender* batched_proxy_ipc_sender) { … }
void RenderFrameHostManager::CreateRenderFrameProxyAndAncestorChainIfNeeded(
SiteInstanceGroup* group) { … }
void RenderFrameHostManager::CreateProxiesForChildFrame(FrameTreeNode* child) { … }
void RenderFrameHostManager::EnsureRenderViewInitialized(
RenderViewHostImpl* render_view_host,
SiteInstanceGroup* group) { … }
void RenderFrameHostManager::SwapOuterDelegateFrame(
RenderFrameHostImpl* render_frame_host,
RenderFrameProxyHost* proxy) { … }
void RenderFrameHostManager::SetRWHViewForInnerFrameTree(
RenderWidgetHostViewChildFrame* child_rwhv) { … }
bool RenderFrameHostManager::InitRenderView(
SiteInstanceGroup* site_instance_group,
RenderViewHostImpl* render_view_host,
RenderFrameProxyHost* proxy) { … }
scoped_refptr<SiteInstanceImpl>
RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
NavigationRequest* request,
BrowsingContextGroupSwap* browsing_context_group_swap,
std::string* reason) { … }
scoped_refptr<SiteInstanceImpl>
RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
NavigationRequest* request,
IsSameSiteGetter& is_same_site,
BrowsingContextGroupSwap* browsing_context_group_swap,
std::string* reason) { … }
bool RenderFrameHostManager::InitRenderFrame(
RenderFrameHostImpl* render_frame_host) { … }
std::optional<blink::FrameToken>
RenderFrameHostManager::GetReplacementFrameToken(
RenderFrameProxyHost* existing_proxy,
RenderFrameHostImpl* render_frame_host) const { … }
bool RenderFrameHostManager::ReinitializeMainRenderFrame(
RenderFrameHostImpl* render_frame_host) { … }
int RenderFrameHostManager::GetRoutingIdForSiteInstanceGroup(
SiteInstanceGroup* site_instance_group) { … }
std::optional<blink::FrameToken>
RenderFrameHostManager::GetFrameTokenForSiteInstanceGroup(
SiteInstanceGroup* site_instance_group) { … }
void RenderFrameHostManager::CommitPending(
std::unique_ptr<RenderFrameHostImpl> pending_rfh,
std::unique_ptr<StoredPage> pending_stored_page,
bool clear_proxies_on_commit,
bool allow_subframe_paint_holding,
bool is_initiated_by_animated_transition) { … }
std::unique_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
std::unique_ptr<RenderFrameHostImpl> render_frame_host) { … }
void RenderFrameHostManager::CollectOpenerFrameTrees(
SiteInstanceGroup* site_instance_group,
std::vector<FrameTree*>* opener_frame_trees,
std::unordered_set<FrameTreeNode*>* nodes_with_back_links,
std::unordered_set<FrameTreeNode*>* cross_browsing_context_group_openers) { … }
void RenderFrameHostManager::CreateOpenerProxies(
SiteInstanceGroup* group,
FrameTreeNode* skip_this_node,
const scoped_refptr<BrowsingContextState>& browsing_context_state) { … }
void RenderFrameHostManager::CreateOpenerProxiesForFrameTree(
SiteInstanceGroup* group,
FrameTreeNode* skip_this_node,
const scoped_refptr<BrowsingContextState>& browsing_context_state) { … }
std::optional<blink::FrameToken> RenderFrameHostManager::GetOpenerFrameToken(
SiteInstanceGroup* group) { … }
void RenderFrameHostManager::ExecutePageBroadcastMethod(
PageBroadcastMethodCallback callback,
SiteInstanceGroup* group_to_skip) { … }
void RenderFrameHostManager::ExecuteRemoteFramesBroadcastMethod(
RemoteFramesBroadcastMethodCallback callback,
SiteInstanceGroup* group_to_skip) { … }
void RenderFrameHostManager::EnsureRenderFrameHostVisibilityConsistent() { … }
void RenderFrameHostManager::EnsureRenderFrameHostPageFocusConsistent() { … }
void RenderFrameHostManager::CreateNewFrameForInnerDelegateAttachIfNecessary() { … }
void RenderFrameHostManager::NotifyPrepareForInnerDelegateAttachComplete(
bool success) { … }
NavigationControllerImpl& RenderFrameHostManager::GetNavigationController() { … }
base::WeakPtr<RenderFrameHostManager> RenderFrameHostManager::GetWeakPtr() { … }
}