#include "content/browser/renderer_host/back_forward_cache_impl.h"
#include <list>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "base/barrier_closure.h"
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/containers/enum_set.h"
#include "base/functional/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/rand_util.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/trace_event/typed_macros.h"
#include "base/types/expected.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/renderer_host/back_forward_cache_can_store_document_result.h"
#include "content/browser/renderer_host/back_forward_cache_metrics.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/render_frame_host_delegate.h"
#include "content/browser/renderer_host/render_frame_host_impl.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_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/visible_time_request_trigger.h"
#include "content/browser/webid/idp_network_request_manager.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/features.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/visibility.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
#include "third_party/blink/public/mojom/back_forward_cache_not_restored_reasons.mojom.h"
#include "third_party/blink/public/mojom/frame/sudden_termination_disabler_type.mojom-shared.h"
#if BUILDFLAG(IS_ANDROID)
#include "content/public/browser/android/child_process_importance.h"
#endif
namespace content {
class RenderProcessHostInternalObserver;
BASE_FEATURE(…);
const base::FeatureParam<int> kBackForwardCacheSizeCacheSize{ … };
const base::FeatureParam<int> kBackForwardCacheSizeForegroundCacheSize{ … };
namespace {
WebSchedulerTrackedFeature;
WebSchedulerTrackedFeatures;
static constexpr size_t kDefaultBackForwardCacheSize = …;
static constexpr size_t kDefaultForegroundBackForwardCacheSize = …;
static constexpr int kDefaultTimeToLiveInBackForwardCacheInSeconds = …;
#if BUILDFLAG(IS_ANDROID)
bool IsProcessBindingEnabled() {
if (!IsBackForwardCacheEnabled())
return false;
const std::string process_binding_param =
base::GetFieldTrialParamValueByFeature(features::kBackForwardCache,
"process_binding_strength");
return process_binding_param.empty() || process_binding_param == "DISABLE";
}
const base::FeatureParam<ChildProcessImportance>::Option
child_process_importance_options[] = {
{ChildProcessImportance::IMPORTANT, "IMPORTANT"},
{ChildProcessImportance::MODERATE, "MODERATE"},
{ChildProcessImportance::NORMAL, "NORMAL"}};
const base::FeatureParam<ChildProcessImportance> kChildProcessImportanceParam{
&features::kBackForwardCache, "process_binding_strength",
ChildProcessImportance::MODERATE, &child_process_importance_options};
#endif
WebSchedulerTrackedFeatures SupportedFeaturesImpl() { … }
WebSchedulerTrackedFeatures SupportedFeatures() { … }
bool IgnoresOutstandingNetworkRequestForTesting() { … }
bool ShouldIgnoreBlocklists() { … }
WebSchedulerTrackedFeatures GetDisallowedWebSchedulerTrackedFeatures() { … }
WebSchedulerTrackedFeatures GetInjectionWebSchedulerTrackedFeatures() { … }
WebSchedulerTrackedFeatures GetNetworkWebSchedulerTrackedFeatures() { … }
WebSchedulerTrackedFeatures GetDisallowedForCacheControlNoStoreFeatures() { … }
WebSchedulerTrackedFeatures GetAllowedWebSchedulerTrackedFeatures() { … }
WebSchedulerTrackedFeatures
GetNonBackForwardCacheAffectingWebSchedulerTrackedFeatures() { … }
std::string GetAllowedURLList() { … }
std::string GetBlockedURLList() { … }
std::string GetBlockedCgiParams() { … }
base::flat_map<std::string, std::vector<std::string>> ParseCommaSeparatedURLs(
std::string_view comma_separated_urls) { … }
base::flat_set<std::string> ParseBlockedCgiParams(
std::string_view cgi_params_string) { … }
BackForwardCacheTestDelegate* g_bfcache_disabled_test_observer = …;
void RestoreBrowserControlsState(RenderFrameHostImpl* cached_rfh) { … }
void RequestRecordTimeToVisible(RenderFrameHostImpl* rfh,
base::TimeTicks navigation_start) { … }
bool HasForegroundedProcess(BackForwardCacheImpl::Entry& entry) { … }
bool AllRenderViewHostsReceivedAckFromRenderer(
BackForwardCacheImpl::Entry& entry) { … }
enum class CacheControlNoStoreExperimentLevel { … };
const char kCacheControlNoStoreExperimentLevelName[] = …;
static constexpr base::FeatureParam<CacheControlNoStoreExperimentLevel>::Option
cache_control_levels[] = …;
const base::FeatureParam<CacheControlNoStoreExperimentLevel>
cache_control_level{ … };
CacheControlNoStoreExperimentLevel GetCacheControlNoStoreLevel() { … }
const char kCacheControlNoStoreTimeToLiveName[] = …;
const base::FeatureParam<base::TimeDelta> cache_control_no_store_ttl{ … };
base::TimeDelta GetCacheControlNoStoreTTL() { … }
bool IsSameOriginForTreeResult(RenderFrameHostImpl* rfh,
const url::Origin& main_document_origin) { … }
void MarkNoWithSingleFeature(BackForwardCacheCanStoreDocumentResult* result,
WebSchedulerTrackedFeature feature) { … }
void MarkNoWithMultipleFeatures(BackForwardCacheCanStoreDocumentResult* result,
RenderFrameHostImpl* rfh,
WebSchedulerTrackedFeatures features) { … }
}
BlockListedFeatures BackForwardCacheImpl::GetAllowedFeatures(
RequestedFeatures requested_features,
CacheControlNoStoreContext ccns_context) { … }
BlockListedFeatures BackForwardCacheImpl::GetDisallowedFeatures(
RequestedFeatures requested_features,
CacheControlNoStoreContext ccns_context) { … }
BackForwardCacheImpl::MessageHandlingPolicyWhenCached
BackForwardCacheImpl::GetChannelAssociatedMessageHandlingPolicy() { … }
BackForwardCacheImpl::Entry::Entry(std::unique_ptr<StoredPage> stored_page)
: … { … }
BackForwardCacheImpl::Entry::~Entry() = default;
void BackForwardCacheImpl::Entry::WriteIntoTrace(
perfetto::TracedValue context) { … }
void BackForwardCacheImpl::RenderProcessPriorityChanged(
RenderProcessHostImpl* host) { … }
BackForwardCacheTestDelegate::BackForwardCacheTestDelegate() { … }
BackForwardCacheTestDelegate::~BackForwardCacheTestDelegate() { … }
BackForwardCacheImpl::BackForwardCacheImpl(BrowserContext* browser_context)
: … { … }
BackForwardCacheImpl::~BackForwardCacheImpl() { … }
std::optional<int> GetFieldTrialParamByFeatureAsOptionalInt(
const base::Feature& feature,
const std::string& param_name) { … }
base::TimeDelta BackForwardCacheImpl::GetTimeToLiveInBackForwardCache(
CacheControlNoStoreContext ccns_context) { … }
size_t BackForwardCacheImpl::GetCacheSize() { … }
size_t BackForwardCacheImpl::GetForegroundedEntriesCacheSize() { … }
bool BackForwardCacheImpl::UsingForegroundBackgroundCacheSizeLimit() { … }
BackForwardCacheImpl::Entry* BackForwardCacheImpl::FindMatchingEntry(
PageImpl& page) { … }
void BackForwardCacheImpl::UpdateCanStoreToIncludeCacheControlNoStore(
BackForwardCacheCanStoreDocumentResult& result,
RenderFrameHostImpl* render_frame_host) { … }
namespace {
void LogAndTraceResult(
const RenderFrameHostImpl& rfh,
const BackForwardCacheCanStoreDocumentResult& flattened_result,
const perfetto::StaticString& caller) { … }
}
BackForwardCacheCanStoreDocumentResultWithTree
BackForwardCacheImpl::GetCurrentBackForwardCacheEligibility(
RenderFrameHostImpl* rfh) { … }
BackForwardCacheCanStoreDocumentResultWithTree
BackForwardCacheImpl::GetCompleteBackForwardCacheEligibilityForReporting(
RenderFrameHostImpl* rfh) { … }
BackForwardCacheCanStoreDocumentResultWithTree
BackForwardCacheImpl::GetFutureBackForwardCacheEligibilityPotential(
RenderFrameHostImpl* rfh) { … }
BackForwardCacheCanStoreDocumentResultWithTree
BackForwardCacheImpl::PopulateReasonsForPage(
RenderFrameHostImpl* rfh,
BackForwardCacheCanStoreDocumentResult& flattened_result,
RequestedFeatures requested_features) { … }
void BackForwardCacheImpl::PopulateReasonsForMainDocument(
BackForwardCacheCanStoreDocumentResult& result,
RenderFrameHostImpl* rfh) { … }
void BackForwardCacheImpl::NotRestoredReasonBuilder::
PopulateStickyReasonsForDocument(
BackForwardCacheCanStoreDocumentResult& result,
RenderFrameHostImpl* rfh) { … }
void BackForwardCacheImpl::NotRestoredReasonBuilder::
PopulateNonStickyReasonsForDocument(
BackForwardCacheCanStoreDocumentResult& result,
RenderFrameHostImpl* rfh,
RequestedFeatures requested_features) { … }
void BackForwardCacheImpl::NotRestoredReasonBuilder::PopulateReasonsForDocument(
BackForwardCacheCanStoreDocumentResult& result,
RenderFrameHostImpl* rfh,
RequestedFeatures requested_features) { … }
BackForwardCacheCanStoreDocumentResultWithTree
BackForwardCacheImpl::CreateEvictionBackForwardCacheCanStoreTreeResult(
RenderFrameHostImpl& rfh,
BackForwardCacheCanStoreDocumentResult& eviction_reason) { … }
BackForwardCacheImpl::NotRestoredReasonBuilder::NotRestoredReasonBuilder(
RenderFrameHostImpl* root_rfh,
RequestedFeatures requested_features)
: … { … }
BackForwardCacheImpl::NotRestoredReasonBuilder::NotRestoredReasonBuilder(
RenderFrameHostImpl* root_rfh,
RequestedFeatures requested_features,
std::optional<EvictionInfo> eviction_info)
: … { … }
BackForwardCacheImpl::NotRestoredReasonBuilder::~NotRestoredReasonBuilder() =
default;
std::unique_ptr<BackForwardCacheCanStoreTreeResult>
BackForwardCacheImpl::NotRestoredReasonBuilder::PopulateReasons(
RenderFrameHostImpl* rfh) { … }
void BackForwardCacheImpl::StoreEntry(
std::unique_ptr<BackForwardCacheImpl::Entry> entry) { … }
void BackForwardCacheImpl::EnforceCacheSizeLimit() { … }
void BackForwardCacheImpl::Prune(size_t limit) { … }
size_t BackForwardCacheImpl::EnforceCacheSizeLimitInternal(
size_t limit,
bool foregrounded_only) { … }
std::unique_ptr<BackForwardCacheImpl::Entry> BackForwardCacheImpl::RestoreEntry(
int navigation_entry_id,
blink::mojom::PageRestoreParamsPtr page_restore_params) { … }
void BackForwardCacheImpl::Flush() { … }
void BackForwardCacheImpl::Flush(NotRestoredReason reason) { … }
void BackForwardCacheImpl::Flush(
const StoragePartition::StorageKeyMatcherFunction& storage_key_filter) { … }
void BackForwardCacheImpl::FlushCacheControlNoStoreEntries(
const StoragePartition::StorageKeyMatcherFunction& storage_key_filter) { … }
void BackForwardCacheImpl::Shutdown() { … }
void BackForwardCacheImpl::EvictFramesInRelatedSiteInstances(
SiteInstance* site_instance) { … }
void BackForwardCacheImpl::PostTaskToDestroyEvictedFrames() { … }
bool BackForwardCache::IsBackForwardCacheFeatureEnabled() { … }
void BackForwardCache::DisableForRenderFrameHost(
RenderFrameHost* render_frame_host,
DisabledReason reason,
std::optional<ukm::SourceId> source_id) { … }
void BackForwardCache::DisableForRenderFrameHost(
GlobalRenderFrameHostId id,
DisabledReason reason,
std::optional<ukm::SourceId> source_id) { … }
void BackForwardCache::SetHadFormDataAssociated(Page& page) { … }
void BackForwardCacheImpl::DisableForTesting(DisableForTestingReason reason) { … }
const std::list<std::unique_ptr<BackForwardCacheImpl::Entry>>&
BackForwardCacheImpl::GetEntries() { … }
std::list<BackForwardCacheImpl::Entry*>
BackForwardCacheImpl::GetEntriesForRenderViewHostImpl(
const RenderViewHostImpl* rvhi) const { … }
base::expected<BackForwardCacheImpl::Entry*,
BackForwardCacheImpl::GetEntryFailureCase>
BackForwardCacheImpl::GetOrEvictEntry(int navigation_entry_id) { … }
void BackForwardCacheImpl::RenderViewHostNoLongerStored(
RenderViewHostImpl* rvh) { … }
void BackForwardCacheImpl::RenderViewHostNoLongerStoredInternal(
RenderViewHostImpl* rvh) { … }
void BackForwardCacheImpl::AddProcessesForEntry(Entry& entry) { … }
void BackForwardCacheImpl::RemoveProcessesForEntry(Entry& entry) { … }
void BackForwardCacheImpl::DestroyEvictedFrames() { … }
bool BackForwardCacheImpl::IsAllowed(const GURL& current_url) { … }
bool BackForwardCacheImpl::IsHostPathAllowed(const GURL& current_url) { … }
bool BackForwardCacheImpl::IsQueryAllowed(const GURL& current_url) { … }
void BackForwardCacheImpl::WillCommitNavigationToCachedEntry(
Entry& bfcache_entry,
base::OnceClosure done_callback) { … }
bool BackForwardCacheImpl::IsBrowsingInstanceInBackForwardCacheForDebugging(
BrowsingInstanceId browsing_instance_id) { … }
bool BackForwardCacheImpl::IsProxyInBackForwardCacheForDebugging(
RenderFrameProxyHost* proxy) { … }
bool BackForwardCacheImpl::IsMediaSessionServiceAllowed() { … }
bool BackForwardCacheImpl::IsScreenReaderAllowed() { … }
bool BackForwardCacheImpl::IsUnloadAllowed() { … }
void BackForwardCacheImpl::VlogUnexpectedRendererToBrowserMessage(
const char* interface_name,
uint32_t message_name,
RenderFrameHostImpl* rfh) { … }
BackForwardCache::DisabledReason::DisabledReason(
content::BackForwardCache::DisabledSource source,
content::BackForwardCache::DisabledReasonType id,
std::string description,
std::string context,
std::string report_string)
: … { … }
BackForwardCache::DisabledReason::DisabledReason(
const BackForwardCache::DisabledReason& reason) = default;
bool BackForwardCache::DisabledReason::operator<(
const DisabledReason& other) const { … }
bool BackForwardCache::DisabledReason::operator==(
const DisabledReason& other) const { … }
bool BackForwardCache::DisabledReason::operator!=(
const DisabledReason& other) const { … }
BackForwardCacheCanStoreTreeResult::BackForwardCacheCanStoreTreeResult(
RenderFrameHostImpl* rfh,
const url::Origin& main_document_origin,
const GURL& url,
BackForwardCacheCanStoreDocumentResult& result_for_this_document)
: … { … }
BackForwardCacheCanStoreTreeResult::BackForwardCacheCanStoreTreeResult(
bool is_same_origin,
const GURL& url)
: … { … }
BackForwardCacheCanStoreTreeResult::~BackForwardCacheCanStoreTreeResult() =
default;
void BackForwardCacheCanStoreTreeResult::AddReasonsToSubtreeRootFrom(
const BackForwardCacheCanStoreDocumentResult& result) { … }
void BackForwardCacheCanStoreTreeResult::AppendChild(
std::unique_ptr<BackForwardCacheCanStoreTreeResult> child) { … }
const BackForwardCacheCanStoreDocumentResult
BackForwardCacheCanStoreTreeResult::FlattenTree() { … }
void BackForwardCacheCanStoreTreeResult::FlattenTreeHelper(
BackForwardCacheCanStoreDocumentResult* document_result) { … }
std::unique_ptr<BackForwardCacheCanStoreTreeResult>
BackForwardCacheCanStoreTreeResult::CreateEmptyTreeForNavigation(
NavigationRequest* navigation) { … }
std::unique_ptr<BackForwardCacheCanStoreTreeResult>
BackForwardCacheCanStoreTreeResult::CreateEmptyTree(RenderFrameHostImpl* rfh) { … }
blink::mojom::BackForwardCacheNotRestoredReasonsPtr
BackForwardCacheCanStoreTreeResult::GetWebExposedNotRestoredReasons() { … }
blink::mojom::BackForwardCacheNotRestoredReasonsPtr
BackForwardCacheCanStoreTreeResult::GetWebExposedNotRestoredReasonsInternal(
int& exposed_cross_origin_iframe_index) { … }
bool BackForwardCacheCanStoreTreeResult::HasUnexposedCrossOriginBlockingIframe(
int& exposed_cross_origin_iframe_index) { … }
uint32_t
BackForwardCacheCanStoreTreeResult::GetCrossOriginReachableFrameCount() { … }
BackForwardCacheCanStoreDocumentResultWithTree::
BackForwardCacheCanStoreDocumentResultWithTree(
BackForwardCacheCanStoreDocumentResult& flattened_reasons,
std::unique_ptr<BackForwardCacheCanStoreTreeResult> tree_reasons)
: … { … }
BackForwardCacheCanStoreDocumentResultWithTree::
BackForwardCacheCanStoreDocumentResultWithTree(
BackForwardCacheCanStoreDocumentResultWithTree&& other)
: … { … }
BackForwardCacheCanStoreDocumentResultWithTree::
~BackForwardCacheCanStoreDocumentResultWithTree() = default;
}