chromium/content/browser/renderer_host/navigation_controller_impl.cc

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

/*
 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
 *     (http://www.torchmobile.com/)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "content/browser/renderer_host/navigation_controller_impl.h"

#include <algorithm>
#include <utility>

#include "base/command_line.h"
#include "base/containers/adapters.h"
#include "base/debug/dump_without_crashing.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/escape.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/trace_event/optional_trace_event.h"
#include "base/trace_event/trace_event.h"
#include "base/types/optional_util.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "content/browser/bad_message.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/browser_context_impl.h"
#include "content/browser/browser_url_handler_impl.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/browser/preloading/prerender/prerender_host.h"
#include "content/browser/process_lock.h"
#include "content/browser/renderer_host/back_forward_cache_impl.h"
#include "content/browser/renderer_host/debug_urls.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_entry_impl.h"
#include "content/browser/renderer_host/navigation_entry_restore_context_impl.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/navigation_transitions/navigation_entry_screenshot_cache.h"
#include "content/browser/renderer_host/navigation_transitions/navigation_entry_screenshot_manager.h"
#include "content/browser/renderer_host/navigation_transitions/navigation_transition_config.h"
#include "content/browser/renderer_host/navigator.h"
#include "content/browser/renderer_host/page_delegate.h"
#include "content/browser/renderer_host/render_frame_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/system_entropy_utils.h"
#include "content/browser/site_info.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/navigation_params_utils.h"
#include "content/common/trace_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/disallow_activation_reason.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/replaced_navigation_entry_data.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "media/base/mime_util.h"
#include "net/base/net_errors.h"
#include "net/http/http_status_code.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom-shared.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/history/session_history_constants.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "third_party/blink/public/common/navigation/navigation_params.h"
#include "third_party/blink/public/common/page_state/page_state_serialization.h"
#include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
#include "third_party/blink/public/mojom/navigation/prefetched_signed_exchange_info.mojom.h"
#include "third_party/blink/public/mojom/runtime_feature_state/runtime_feature.mojom.h"
#include "url/url_constants.h"

namespace content {
namespace {

// Invoked when entries have been pruned, or removed. For example, if the
// current entries are [google, digg, yahoo], with the current entry google,
// and the user types in cnet, then digg and yahoo are pruned.
void NotifyPrunedEntries(NavigationControllerImpl* nav_controller,
                         int index,
                         int count) {}

// Configure all the NavigationEntries in entries for restore. This resets
// the transition type to reload and makes sure the content state isn't empty.
void ConfigureEntriesForRestore(
    std::vector<std::unique_ptr<NavigationEntryImpl>>* entries,
    RestoreType type) {}

// Determines whether or not we should be carrying over a user agent override
// between two NavigationEntries.
bool ShouldKeepOverride(NavigationEntry* last_entry) {}

// Determines whether to override user agent for a navigation.
bool ShouldOverrideUserAgent(
    NavigationController::UserAgentOverrideOption override_user_agent,
    NavigationEntry* last_committed_entry) {}

// Returns true if this navigation should be treated as a reload. For e.g.
// navigating to the last committed url via the address bar or clicking on a
// link which results in a navigation to the last committed URL (but wasn't
// converted to do a replacement navigation in the renderer), etc.
// |node| is the FrameTreeNode which is navigating. |url|, |virtual_url|,
// |base_url_for_data_url|, |transition_type| correspond to the new navigation
// (i.e. the pending NavigationEntry). |last_committed_entry| is the last
// navigation that committed.
bool ShouldTreatNavigationAsReload(FrameTreeNode* node,
                                   const GURL& url,
                                   const GURL& virtual_url,
                                   const GURL& base_url_for_data_url,
                                   ui::PageTransition transition_type,
                                   bool is_post,
                                   bool should_replace_current_entry,
                                   NavigationEntryImpl* last_committed_entry) {}

std::optional<url::Origin> GetCommittedOriginForFrameEntry(
    const mojom::DidCommitProvisionalLoadParams& params,
    NavigationRequest* request) {}

bool IsValidURLForNavigation(FrameTreeNode* node,
                             const GURL& virtual_url,
                             const GURL& dest_url) {}

// See replaced_navigation_entry_data.h for details: this information is meant
// to ensure |*output_entry| keeps track of its original URL (landing page in
// case of server redirects) as it gets replaced (e.g. history.replaceState()),
// without overwriting it later, for main frames.
void CopyReplacedNavigationEntryDataIfPreviouslyEmpty(
    NavigationEntryImpl* replaced_entry,
    NavigationEntryImpl* output_entry) {}

blink::mojom::NavigationType GetNavigationType(
    const GURL& old_url,
    const GURL& new_url,
    ReloadType reload_type,
    NavigationEntryImpl* entry,
    FrameNavigationEntry* frame_entry,
    bool has_pending_cross_document_commit,
    bool is_currently_error_page,
    bool is_same_document_history_load,
    bool is_embedder_initiated_fenced_frame_navigation,
    bool is_unfenced_top_navigation) {}

// Adjusts the original input URL if needed, to get the URL to actually load and
// the virtual URL, which may differ.
void RewriteUrlForNavigation(const GURL& original_url,
                             BrowserContext* browser_context,
                             GURL* url_to_load,
                             GURL* virtual_url,
                             bool* reverse_on_redirect) {}

#if DCHECK_IS_ON()
// Helper sanity check function used in debug mode.
void ValidateRequestMatchesEntry(NavigationRequest* request,
                                 NavigationEntryImpl* entry) {}
#endif  // DCHECK_IS_ON()

// Returns whether the session history NavigationRequests in |navigations|
// would stay within the subtree of |sandboxed_initiator_rfh|.
bool DoesSandboxNavigationStayWithinSubtree(
    RenderFrameHostImpl* sandboxed_initiator_rfh,
    const std::vector<std::unique_ptr<NavigationRequest>>& navigations) {}

// Used for "Navigation.SessionHistoryCount" histogram.
enum class HistoryNavTypeForHistogram {};

void CountRequests(
    const std::vector<std::unique_ptr<NavigationRequest>>& requests,
    int& mutable_main_frame_cnt,
    int& mutable_subframe_cnt) {}

// Record the number of different types of navigations as histograms. See
// `HistoryNavTypeForHistogram` for the types.
void CountBrowserInitiatedMainframeAndSubframeHistoryNavigaions(
    const std::vector<std::unique_ptr<NavigationRequest>>& cross_doc_requests,
    const std::vector<std::unique_ptr<NavigationRequest>>& same_doc_requests) {}

}  // namespace

// NavigationControllerImpl::PendingEntryRef------------------------------------

NavigationControllerImpl::PendingEntryRef::PendingEntryRef(
    base::WeakPtr<NavigationControllerImpl> controller)
    :{}

NavigationControllerImpl::PendingEntryRef::~PendingEntryRef() {}

// NavigationControllerImpl ----------------------------------------------------

const size_t kMaxEntryCountForTestingNotSet =;

// static
size_t NavigationControllerImpl::max_entry_count_for_testing_ =;

// Should Reload check for post data? The default is true, but is set to false
// when testing.
static bool g_check_for_repost =;

// static
std::unique_ptr<NavigationEntry> NavigationController::CreateNavigationEntry(
    const GURL& url,
    Referrer referrer,
    std::optional<url::Origin> initiator_origin,
    std::optional<GURL> initiator_base_url,
    ui::PageTransition transition,
    bool is_renderer_initiated,
    const std::string& extra_headers,
    BrowserContext* browser_context,
    scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) {}

// static
std::unique_ptr<NavigationEntryImpl>
NavigationControllerImpl::CreateNavigationEntry(
    const GURL& url,
    Referrer referrer,
    std::optional<url::Origin> initiator_origin,
    std::optional<GURL> initiator_base_url,
    std::optional<GURL> source_process_site_url,
    ui::PageTransition transition,
    bool is_renderer_initiated,
    const std::string& extra_headers,
    BrowserContext* browser_context,
    scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
    bool rewrite_virtual_urls) {}

// static
void NavigationController::DisablePromptOnRepost() {}

base::Time NavigationControllerImpl::TimeSmoother::GetSmoothedTime(
    base::Time t) {}

NavigationControllerImpl::ScopedShowRepostDialogForTesting::
    ScopedShowRepostDialogForTesting()
    :{}

NavigationControllerImpl::ScopedShowRepostDialogForTesting::
    ~ScopedShowRepostDialogForTesting() {}

NavigationControllerImpl::RemovedEntriesTracker::RemovedEntriesTracker(
    base::SafeRef<NavigationControllerImpl> controller)
    :{}

void NavigationControllerImpl::RemovedEntriesTracker::PopulateKeySet(
    Direction direction) {}

NavigationControllerImpl::RemovedEntriesTracker::~RemovedEntriesTracker() {}

NavigationControllerImpl::NavigationControllerImpl(
    BrowserContext* browser_context,
    FrameTree& frame_tree,
    NavigationControllerDelegate* delegate)
    :{}

NavigationControllerImpl::~NavigationControllerImpl() {}

BrowserContext* NavigationControllerImpl::GetBrowserContext() {}

void NavigationControllerImpl::Restore(
    int selected_navigation,
    RestoreType type,
    std::vector<std::unique_ptr<NavigationEntry>>* entries) {}

void NavigationControllerImpl::Reload(ReloadType reload_type,
                                      bool check_for_repost) {}

void NavigationControllerImpl::CancelPendingReload() {}

void NavigationControllerImpl::ContinuePendingReload() {}

bool NavigationControllerImpl::IsInitialNavigation() {}

bool NavigationControllerImpl::IsInitialBlankNavigation() {}

NavigationEntryImpl* NavigationControllerImpl::GetEntryWithUniqueID(
    int nav_entry_id) const {}

NavigationEntryImpl*
NavigationControllerImpl::GetEntryWithUniqueIDIncludingPending(
    int nav_entry_id) const {}

void NavigationControllerImpl::RegisterExistingOriginAsHavingDefaultIsolation(
    const url::Origin& origin) {}

void NavigationControllerImpl::SetPendingEntry(
    std::unique_ptr<NavigationEntryImpl> entry) {}

NavigationEntryImpl* NavigationControllerImpl::GetActiveEntry() {}

NavigationEntryImpl* NavigationControllerImpl::GetVisibleEntry() {}

int NavigationControllerImpl::GetCurrentEntryIndex() {}

NavigationEntryImpl* NavigationControllerImpl::GetLastCommittedEntry() {}

bool NavigationControllerImpl::CanViewSource() {}

int NavigationControllerImpl::GetLastCommittedEntryIndex() {}

int NavigationControllerImpl::GetEntryCount() {}

NavigationEntryImpl* NavigationControllerImpl::GetEntryAtIndex(int index) {}

NavigationEntryImpl* NavigationControllerImpl::GetEntryAtOffset(int offset) {}

int NavigationControllerImpl::GetIndexForOffset(int offset) {}

std::optional<int> NavigationControllerImpl::GetIndexForGoBack() {}

bool NavigationControllerImpl::CanGoBack() {}

std::optional<int> NavigationControllerImpl::GetIndexForGoForward() {}

bool NavigationControllerImpl::CanGoForward() {}

bool NavigationControllerImpl::CanGoToOffset(int offset) {}

#if BUILDFLAG(IS_ANDROID)
bool NavigationControllerImpl::CanGoToOffsetWithSkipping(int offset) {
  if (offset == 0)
    return true;
  int increment = offset > 0 ? 1 : -1;
  int non_skippable_entries = 0;
  for (int index = GetIndexForOffset(increment);
       index >= 0 && index < GetEntryCount(); index += increment) {
    if (!GetEntryAtIndex(index)->should_skip_on_back_forward_ui())
      non_skippable_entries++;

    if (non_skippable_entries == std::abs(offset))
      return true;
  }
  return false;
}
#endif

void NavigationControllerImpl::GoBack() {}

void NavigationControllerImpl::GoForward() {}

void NavigationControllerImpl::GoToIndex(int index) {}

std::vector<base::WeakPtr<NavigationRequest>>
NavigationControllerImpl::GoToIndex(
    int index,
    RenderFrameHostImpl* initiator_rfh,
    std::optional<blink::scheduler::TaskAttributionId>
        soft_navigation_heuristics_task_id,
    const std::string* navigation_api_key) {}

void NavigationControllerImpl::GoToOffset(int offset) {}

void NavigationControllerImpl::GoToOffsetFromRenderer(
    int offset,
    RenderFrameHostImpl* initiator_rfh,
    std::optional<blink::scheduler::TaskAttributionId>
        soft_navigation_heuristics_task_id) {}

std::vector<base::WeakPtr<NavigationRequest>>
NavigationControllerImpl::GoToIndexAndReturnAllRequests(int index) {}

#if BUILDFLAG(IS_ANDROID)
void NavigationControllerImpl::GoToOffsetWithSkipping(int offset) {
  // Note: This is actually reached in unit tests.
  if (!CanGoToOffsetWithSkipping(offset))
    return;

  if (offset == 0) {
    GoToIndex(GetIndexForOffset(offset));
    return;
  }
  int increment = offset > 0 ? 1 : -1;
  // Find the offset without counting skippable entries.
  int target_index = GetIndexForOffset(increment);
  int non_skippable_entries = 0;
  for (int index = target_index; index >= 0 && index < GetEntryCount();
       index += increment) {
    if (!GetEntryAtIndex(index)->should_skip_on_back_forward_ui())
      non_skippable_entries++;

    if (non_skippable_entries == std::abs(offset)) {
      target_index = index;
      break;
    }
  }

  GoToIndex(target_index);
}
#endif

bool NavigationControllerImpl::RemoveEntryAtIndex(int index) {}

void NavigationControllerImpl::PruneForwardEntries() {}

void NavigationControllerImpl::UpdateVirtualURLToURL(NavigationEntryImpl* entry,
                                                     const GURL& new_url) {}

base::WeakPtr<NavigationHandle> NavigationControllerImpl::LoadURL(
    const GURL& url,
    const Referrer& referrer,
    ui::PageTransition transition,
    const std::string& extra_headers) {}

base::WeakPtr<NavigationHandle> NavigationControllerImpl::LoadURLWithParams(
    const LoadURLParams& params) {}

void NavigationControllerImpl::LoadOriginalRequestURL() {}

bool NavigationControllerImpl::PendingEntryMatchesRequest(
    NavigationRequest* request) const {}

bool NavigationControllerImpl::RendererDidNavigate(
    RenderFrameHostImpl* rfh,
    const mojom::DidCommitProvisionalLoadParams& params,
    LoadCommittedDetails* details,
    bool is_same_document_navigation,
    bool was_on_initial_empty_document,
    bool previous_document_had_history_intervention_activation,
    NavigationRequest* navigation_request) {}

NavigationType NavigationControllerImpl::ClassifyNavigation(
    RenderFrameHostImpl* rfh,
    const mojom::DidCommitProvisionalLoadParams& params,
    NavigationRequest* navigation_request) {}

void NavigationControllerImpl::UpdateNavigationEntryDetails(
    NavigationEntryImpl* entry,
    RenderFrameHostImpl* rfh,
    const mojom::DidCommitProvisionalLoadParams& params,
    NavigationRequest* request,
    NavigationEntryImpl::UpdatePolicy update_policy,
    bool is_new_entry,
    LoadCommittedDetails* commit_details) {}

void NavigationControllerImpl::CreateInitialEntry() {}

void NavigationControllerImpl::RendererDidNavigateToNewEntry(
    RenderFrameHostImpl* rfh,
    const mojom::DidCommitProvisionalLoadParams& params,
    bool is_same_document,
    bool replace_entry,
    bool previous_document_had_history_intervention_activation,
    NavigationRequest* request,
    LoadCommittedDetails* commit_details) {}

void NavigationControllerImpl::RendererDidNavigateToExistingEntry(
    RenderFrameHostImpl* rfh,
    const mojom::DidCommitProvisionalLoadParams& params,
    bool is_same_document,
    bool was_restored,
    NavigationRequest* request,
    bool keep_pending_entry,
    LoadCommittedDetails* commit_details) {}

void NavigationControllerImpl::RendererDidNavigateNewSubframe(
    RenderFrameHostImpl* rfh,
    const mojom::DidCommitProvisionalLoadParams& params,
    bool is_same_document,
    bool replace_entry,
    bool previous_document_had_history_intervention_activation,
    NavigationRequest* request,
    LoadCommittedDetails* commit_details) {}

bool NavigationControllerImpl::RendererDidNavigateAutoSubframe(
    RenderFrameHostImpl* rfh,
    const mojom::DidCommitProvisionalLoadParams& params,
    bool is_same_document,
    bool was_on_initial_empty_document,
    NavigationRequest* request,
    LoadCommittedDetails* commit_details) {}

int NavigationControllerImpl::GetIndexOfEntry(
    const NavigationEntryImpl* entry) const {}

void NavigationControllerImpl::CopyStateFrom(NavigationController* temp,
                                             bool needs_reload) {}

bool NavigationControllerImpl::CanPruneAllButLastCommitted() {}

void NavigationControllerImpl::PruneAllButLastCommitted() {}

void NavigationControllerImpl::PruneAllButLastCommittedInternal() {}

void NavigationControllerImpl::DeleteNavigationEntries(
    const DeletionPredicate& deletionPredicate) {}

BackForwardCacheImpl& NavigationControllerImpl::GetBackForwardCache() {}

NavigationEntryScreenshotCache*
NavigationControllerImpl::GetNavigationEntryScreenshotCache() {}

void NavigationControllerImpl::DiscardPendingEntry(bool was_failure) {}

void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) {}

#if BUILDFLAG(IS_ANDROID)
// static
bool NavigationControllerImpl::ValidateDataURLAsString(
    const scoped_refptr<const base::RefCountedString>& data_url_as_string) {
  if (!data_url_as_string)
    return false;

  if (data_url_as_string->size() > kMaxLengthOfDataURLString)
    return false;

  // The number of characters that is enough for validating a data: URI.
  // From the GURL's POV, the only important part here is scheme, it doesn't
  // check the actual content. Thus we can take only the prefix of the url, to
  // avoid unneeded copying of a potentially long string.
  constexpr size_t kDataUriPrefixMaxLen = 64;
  const size_t len = std::min(data_url_as_string->size(), kDataUriPrefixMaxLen);
  GURL data_url(base::as_string_view(*data_url_as_string).substr(0u, len));
  if (!data_url.is_valid() || !data_url.SchemeIs(url::kDataScheme))
    return false;

  return true;
}
#endif

void NavigationControllerImpl::NotifyUserActivation() {}

bool NavigationControllerImpl::StartHistoryNavigationInNewSubframe(
    RenderFrameHostImpl* render_frame_host,
    mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client,
    blink::LocalFrameToken initiator_frame_token,
    int initiator_process_id) {}

bool NavigationControllerImpl::ReloadFrame(FrameTreeNode* frame_tree_node) {}

void NavigationControllerImpl::NavigateFromFrameProxy(
    RenderFrameHostImpl* render_frame_host,
    const GURL& url,
    const blink::LocalFrameToken* initiator_frame_token,
    int initiator_process_id,
    const std::optional<url::Origin>& initiator_origin,
    const std::optional<GURL>& initiator_base_url,
    bool is_renderer_initiated,
    SiteInstance* source_site_instance,
    const Referrer& referrer,
    ui::PageTransition page_transition,
    bool should_replace_current_entry,
    blink::NavigationDownloadPolicy download_policy,
    const std::string& method,
    scoped_refptr<network::ResourceRequestBody> post_body,
    const std::string& extra_headers,
    network::mojom::SourceLocationPtr source_location,
    scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
    bool is_form_submission,
    const std::optional<blink::Impression>& impression,
    blink::mojom::NavigationInitiatorActivationAndAdStatus
        initiator_activation_and_ad_status,
    base::TimeTicks navigation_start_time,
    bool is_embedder_initiated_fenced_frame_navigation,
    bool is_unfenced_top_navigation,
    bool force_new_browsing_instance,
    bool is_container_initiated,
    bool has_rel_opener,
    net::StorageAccessApiStatus storage_access_api_status,
    std::optional<std::u16string> embedder_shared_storage_context) {}

void NavigationControllerImpl::SetSessionStorageNamespace(
    const StoragePartitionConfig& partition_config,
    SessionStorageNamespace* session_storage_namespace) {}

bool NavigationControllerImpl::IsUnmodifiedBlankTab() {}

SessionStorageNamespace* NavigationControllerImpl::GetSessionStorageNamespace(
    const StoragePartitionConfig& partition_config) {}

SessionStorageNamespace*
NavigationControllerImpl::GetDefaultSessionStorageNamespace() {}

const SessionStorageNamespaceMap&
NavigationControllerImpl::GetSessionStorageNamespaceMap() {}

bool NavigationControllerImpl::NeedsReload() {}

void NavigationControllerImpl::SetNeedsReload() {}

void NavigationControllerImpl::SetNeedsReload(NeedsReloadType type) {}

void NavigationControllerImpl::RemoveEntryAtIndexInternal(int index) {}

NavigationEntryImpl* NavigationControllerImpl::GetPendingEntry() {}

int NavigationControllerImpl::GetPendingEntryIndex() {}

void NavigationControllerImpl::InsertOrReplaceEntry(
    std::unique_ptr<NavigationEntryImpl> entry,
    bool replace,
    bool was_post_commit_error,
    bool in_fenced_frame_tree,
    LoadCommittedDetails* commit_details) {}

void NavigationControllerImpl::PruneOldestSkippableEntryIfFull() {}

std::vector<base::WeakPtr<NavigationRequest>>
NavigationControllerImpl::NavigateToExistingPendingEntry(
    ReloadType reload_type,
    RenderFrameHostImpl* initiator_rfh,
    std::optional<blink::scheduler::TaskAttributionId>
        soft_navigation_heuristics_task_id,
    const std::string* navigation_api_key) {}

NavigationControllerImpl::HistoryNavigationAction
NavigationControllerImpl::DetermineActionForHistoryNavigation(
    FrameTreeNode* frame,
    ReloadType reload_type) {}

void NavigationControllerImpl::FindFramesToNavigate(
    FrameTreeNode* frame,
    ReloadType reload_type,
    const std::optional<blink::LocalFrameToken>& initiator_frame_token,
    int initiator_process_id,
    std::optional<blink::scheduler::TaskAttributionId>
        soft_navigation_heuristics_task_id,
    std::vector<std::unique_ptr<NavigationRequest>>* same_document_loads,
    std::vector<std::unique_ptr<NavigationRequest>>* different_document_loads) {}

base::WeakPtr<NavigationHandle> NavigationControllerImpl::NavigateWithoutEntry(
    const LoadURLParams& params) {}

void NavigationControllerImpl::HandleRendererDebugURL(
    FrameTreeNode* frame_tree_node,
    const GURL& url) {}

std::unique_ptr<NavigationEntryImpl>
NavigationControllerImpl::CreateNavigationEntryFromLoadParams(
    FrameTreeNode* node,
    const LoadURLParams& params,
    bool override_user_agent,
    bool should_replace_current_entry,
    bool has_user_gesture) {}

std::unique_ptr<NavigationRequest>
NavigationControllerImpl::CreateNavigationRequestFromLoadParams(
    FrameTreeNode* node,
    const LoadURLParams& params,
    bool override_user_agent,
    bool should_replace_current_entry,
    bool has_user_gesture,
    network::mojom::SourceLocationPtr source_location,
    ReloadType reload_type,
    NavigationEntryImpl* entry,
    FrameNavigationEntry* frame_entry,
    base::TimeTicks navigation_start_time,
    bool is_embedder_initiated_fenced_frame_navigation,
    bool is_unfenced_top_navigation,
    bool is_container_initiated,
    net::StorageAccessApiStatus storage_access_api_status,
    std::optional<std::u16string> embedder_shared_storage_context) {}

std::unique_ptr<NavigationRequest>
NavigationControllerImpl::CreateNavigationRequestFromEntry(
    FrameTreeNode* frame_tree_node,
    NavigationEntryImpl* entry,
    FrameNavigationEntry* frame_entry,
    ReloadType reload_type,
    bool is_same_document_history_load,
    bool is_history_navigation_in_new_child_frame,
    const std::optional<blink::LocalFrameToken>& initiator_frame_token,
    int initiator_process_id,
    std::optional<blink::scheduler::TaskAttributionId>
        soft_navigation_heuristics_task_id) {}

void NavigationControllerImpl::NotifyNavigationEntryCommitted(
    LoadCommittedDetails* details) {}

// static
size_t NavigationControllerImpl::max_entry_count() {}

void NavigationControllerImpl::SetActive(bool is_active) {}

void NavigationControllerImpl::LoadIfNecessary() {}

base::WeakPtr<NavigationHandle>
NavigationControllerImpl::LoadPostCommitErrorPage(
    RenderFrameHost* render_frame_host,
    const GURL& url,
    const std::string& error_page_html) {}

void NavigationControllerImpl::NotifyEntryChanged(NavigationEntry* entry) {}

void NavigationControllerImpl::FinishRestore(int selected_index,
                                             RestoreType type) {}

void NavigationControllerImpl::DiscardNonCommittedEntries() {}

void NavigationControllerImpl::DiscardNonCommittedEntriesWithCommitDetails(
    LoadCommittedDetails* commit_details) {}

int NavigationControllerImpl::GetEntryIndexWithUniqueID(
    int nav_entry_id) const {}

void NavigationControllerImpl::InsertEntriesFrom(
    NavigationControllerImpl* source,
    int max_index) {}

void NavigationControllerImpl::SetGetTimestampCallbackForTest(
    const base::RepeatingCallback<base::Time()>& get_timestamp_callback) {}

// History manipulation intervention:
void NavigationControllerImpl::SetShouldSkipOnBackForwardUIIfNeeded(
    bool replace_entry,
    bool previous_document_had_history_intervention_activation,
    bool is_renderer_initiated,
    ukm::SourceId previous_page_load_ukm_source_id) {}

void NavigationControllerImpl::SetSkippableForSameDocumentEntries(
    int reference_index,
    bool skippable) {}

std::unique_ptr<NavigationControllerImpl::PendingEntryRef>
NavigationControllerImpl::ReferencePendingEntry() {}

void NavigationControllerImpl::PendingEntryRefDeleted(PendingEntryRef* ref) {}

std::unique_ptr<PolicyContainerPolicies>
NavigationControllerImpl::ComputePolicyContainerPoliciesForFrameEntry(
    RenderFrameHostImpl* rfh,
    bool is_same_document,
    const GURL& url) {}

void NavigationControllerImpl::BroadcastHistoryOffsetAndLength() {}

void NavigationControllerImpl::DidAccessInitialMainDocument() {}

void NavigationControllerImpl::UpdateStateForFrame(
    RenderFrameHostImpl* rfhi,
    const blink::PageState& page_state) {}

namespace {

// The caller is responsible for ensuring the entry is same-origin to the
// origin to be committed.
blink::mojom::NavigationApiHistoryEntryPtr ToNavigationApiHistoryEntry(
    FrameNavigationEntry* frame_entry,
    int64_t pending_document_sequence_number) {}

}  // namespace

std::vector<blink::mojom::NavigationApiHistoryEntryPtr>
NavigationControllerImpl::PopulateSingleNavigationApiHistoryEntryVector(
    Direction direction,
    int entry_index,
    const url::Origin& pending_origin,
    FrameTreeNode* node,
    SiteInstance* site_instance,
    int64_t pending_item_sequence_number,
    int64_t pending_document_sequence_number,
    int& last_index_checked) {}

blink::mojom::NavigationApiHistoryEntryArraysPtr
NavigationControllerImpl::GetNavigationApiHistoryEntryVectors(
    FrameTreeNode* node,
    NavigationRequest* request) {}

NavigationControllerImpl::HistoryNavigationAction
NavigationControllerImpl::ShouldNavigateToEntryForNavigationApiKey(
    FrameNavigationEntry* current_entry,
    FrameNavigationEntry* target_entry,
    const std::string& navigation_api_key) {}

void NavigationControllerImpl::NavigateToNavigationApiKey(
    RenderFrameHostImpl* initiator_rfh,
    std::optional<blink::scheduler::TaskAttributionId>
        soft_navigation_heuristics_task_id,
    const std::string& key) {}

bool NavigationControllerImpl::ShouldProtectUrlInNavigationApi(
    network::mojom::ReferrerPolicy referrer_policy) {}

bool NavigationControllerImpl::ShouldMaintainTrivialSessionHistory(
    const FrameTreeNode* frame_tree_node) const {}

void NavigationControllerImpl::DidChangeReferrerPolicy(
    FrameTreeNode* node,
    network::mojom::ReferrerPolicy referrer_policy) {}

}  // namespace content