chromium/content/browser/renderer_host/back_forward_cache_impl.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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;

// Allows overriding the sizes of back/forward cache.
// Sizes set via this feature's parameters take precedence over others.
// Enables BackForwardCache size for
//  - desktop: https://crbug.com/1291435.
//  - android: https://crbug.com/1395281.
BASE_FEATURE();
// Sets BackForwardCache cache_size=6.
const base::FeatureParam<int> kBackForwardCacheSizeCacheSize{};
// Disables EnforceCacheSizeLimitInternal() with foreground_cache_size=0, as
// the BFCachePolicy manager takes care of pruning for foreground tabs as well.
const base::FeatureParam<int> kBackForwardCacheSizeForegroundCacheSize{};

namespace {

WebSchedulerTrackedFeature;
WebSchedulerTrackedFeatures;

// The default number of entries the BackForwardCache can hold per tab.
static constexpr size_t kDefaultBackForwardCacheSize =;

// The default number value for the "foreground_cache_size" field trial
// parameter. This parameter controls the numbers of entries associated with
// foregrounded process the BackForwardCache can hold per tab, when using the
// foreground/background cache-limiting strategy. This strategy is enabled if
// the parameter values is non-zero.
static constexpr size_t kDefaultForegroundBackForwardCacheSize =;

// The default time to live in seconds for documents in BackForwardCache.
// See also crbug.com/1305878.
static constexpr int kDefaultTimeToLiveInBackForwardCacheInSeconds =;

#if BUILDFLAG(IS_ANDROID)
bool IsProcessBindingEnabled() {
  // Avoid activating BackForwardCache trial for checking the parameters
  // associated with it.
  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";
}

// Association of ChildProcessImportance to corresponding string names.
const base::FeatureParam<ChildProcessImportance>::Option
    child_process_importance_options[] = {
        {ChildProcessImportance::IMPORTANT, "IMPORTANT"},
        {ChildProcessImportance::MODERATE, "MODERATE"},
        {ChildProcessImportance::NORMAL, "NORMAL"}};

// Defines the binding strength for a processes holding cached pages. The value
// is read from an experiment parameter value. Ideally this would be lower than
// the one for processes holding the foreground page and similar to that of
// background tabs so that the OS will hopefully kill the foreground tab last.
// The default importance is set to MODERATE.
const base::FeatureParam<ChildProcessImportance> kChildProcessImportanceParam{
    &features::kBackForwardCache, "process_binding_strength",
    ChildProcessImportance::MODERATE, &child_process_importance_options};
#endif

WebSchedulerTrackedFeatures SupportedFeaturesImpl() {}

WebSchedulerTrackedFeatures SupportedFeatures() {}

bool IgnoresOutstandingNetworkRequestForTesting() {}

// Ignore all features that the page is using and all DisableForRenderFrameHost
// calls and force all pages to be cached. Should be used only for local testing
// and debugging -- things will break when this param is used.
bool ShouldIgnoreBlocklists() {}

// A list of WebSchedulerTrackedFeatures that always block back/forward
// cache. Some of these features are listed as blocking back/forward cache
// when actually the blocking is flag controlled and they are not registered
// as being used if we don't want them to block.
WebSchedulerTrackedFeatures GetDisallowedWebSchedulerTrackedFeatures() {}
WebSchedulerTrackedFeatures GetInjectionWebSchedulerTrackedFeatures() {}
WebSchedulerTrackedFeatures GetNetworkWebSchedulerTrackedFeatures() {}
// A list of WebSchedulerTrackedFeatures that should never block back/forward
// cache unless the main frame has "Cache-Control: no-store" header.
WebSchedulerTrackedFeatures GetDisallowedForCacheControlNoStoreFeatures() {}
// A list of WebSchedulerTrackedFeatures that should never block back/forward
// cache.
WebSchedulerTrackedFeatures GetAllowedWebSchedulerTrackedFeatures() {}

// WebSchedulerTrackedFeatures that do not affect back/forward cache, but
// affects other scheduling policies (e.g. aggressive throttling).
WebSchedulerTrackedFeatures
GetNonBackForwardCacheAffectingWebSchedulerTrackedFeatures() {}

// The BackForwardCache feature is controlled via an experiment. This function
// returns the allowed URL list where it is enabled.
std::string GetAllowedURLList() {}

// This function returns the blocked URL list.
std::string GetBlockedURLList() {}

// Returns the list of blocked CGI params
std::string GetBlockedCgiParams() {}

// Parses the “allowed_websites” and "blocked_websites" field trial parameters
// and creates a map to represent hosts and corresponding path prefixes.
base::flat_map<std::string, std::vector<std::string>> ParseCommaSeparatedURLs(
    std::string_view comma_separated_urls) {}

// Parses the "cgi_params" field trial parameter into a set by splitting on "|".
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) {}

// Returns true if any of the processes associated with the RenderViewHosts in
// this Entry are foregrounded.
bool HasForegroundedProcess(BackForwardCacheImpl::Entry& entry) {}

// Returns true if all of the RenderViewHosts in this Entry have received the
// acknowledgement from renderer.
bool AllRenderViewHostsReceivedAckFromRenderer(
    BackForwardCacheImpl::Entry& entry) {}

// Behavior on pages with cache-control:no-store specified by flags.
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[] =;

// This param controls the TTL for pages with "Cache-Control: no-store".
const base::FeatureParam<base::TimeDelta> cache_control_no_store_ttl{};

base::TimeDelta GetCacheControlNoStoreTTL() {}

bool IsSameOriginForTreeResult(RenderFrameHostImpl* rfh,
                               const url::Origin& main_document_origin) {}

// Mark the result with No due to a single feature without JavaScript details.
void MarkNoWithSingleFeature(BackForwardCacheCanStoreDocumentResult* result,
                             WebSchedulerTrackedFeature feature) {}

// Mark the result with No due to multiple features for `rfh`.
void MarkNoWithMultipleFeatures(BackForwardCacheCanStoreDocumentResult* result,
                                RenderFrameHostImpl* rfh,
                                WebSchedulerTrackedFeatures features) {}

}  // namespace

// static
BlockListedFeatures BackForwardCacheImpl::GetAllowedFeatures(
    RequestedFeatures requested_features,
    CacheControlNoStoreContext ccns_context) {}

// static
BlockListedFeatures BackForwardCacheImpl::GetDisallowedFeatures(
    RequestedFeatures requested_features,
    CacheControlNoStoreContext ccns_context) {}

// static
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) {}

// static
size_t BackForwardCacheImpl::GetCacheSize() {}

// static
size_t BackForwardCacheImpl::GetForegroundedEntriesCacheSize() {}

// static
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) {}
}  // namespace

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() {}

// static
bool BackForwardCache::IsBackForwardCacheFeatureEnabled() {}

// static
void BackForwardCache::DisableForRenderFrameHost(
    RenderFrameHost* render_frame_host,
    DisabledReason reason,
    std::optional<ukm::SourceId> source_id) {}

// static
void BackForwardCache::DisableForRenderFrameHost(
    GlobalRenderFrameHostId id,
    DisabledReason reason,
    std::optional<ukm::SourceId> source_id) {}

// static
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() {}

// Static
bool BackForwardCacheImpl::IsUnloadAllowed() {}

// static
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;

}  // namespace content