// 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.

#ifndef CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_ENTRY_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_ENTRY_IMPL_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/back_forward_cache_metrics.h"
#include "content/browser/renderer_host/frame_navigation_entry.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/reload_type.h"
#include "content/public/browser/replaced_navigation_entry_data.h"
#include "content/public/browser/restore_type.h"
#include "content/public/browser/ssl_status.h"
#include "net/base/isolation_info.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/common/page_state/page_state.h"
#include "third_party/blink/public/mojom/navigation/navigation_params.mojom-forward.h"
#include "url/origin.h"

namespace blink {
struct FramePolicy;
namespace scheduler {
class TaskAttributionId;
}  // namespace scheduler
}  // namespace blink

namespace content {

class FrameTreeNode;
class NavigationEntryRestoreContext;
class NavigationEntryRestoreContextImpl;
class SubresourceWebBundleNavigationInfo;

class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
 public:
  // Determines whether CloneAndReplace will share the existing
  // FrameNavigationEntries in the new NavigationEntry or not.
  enum class ClonePolicy { kShareFrameEntries, kCloneFrameEntries };

  // Represents a tree of FrameNavigationEntries that make up this joint session
  // history item.
  struct TreeNode {
    TreeNode(TreeNode* parent, scoped_refptr<FrameNavigationEntry> frame_entry);
    ~TreeNode();

    // Returns whether this TreeNode corresponds to |frame_tree_node|.  If this
    // is called on the root TreeNode, we only check if |frame_tree_node| is the
    // main frame.  Otherwise, we check if the unique name matches.
    bool MatchesFrame(FrameTreeNode* frame_tree_node) const;

    // Recursively makes a copy of this TreeNode, either sharing
    // FrameNavigationEntries or making deep copies depending on |clone_policy|.
    // Replaces the TreeNode corresponding to |target_frame_tree_node|,
    // clearing all of its children unless |clone_children_of_target| is true.
    // This function omits any subframe history items that do not correspond to
    // frames actually in the current page, using |current_frame_tree_node| (if
    // present). |restore_context| is used to keep track of the
    // FrameNavigationEntries that have been created during a deep clone, and to
    // ensure that multiple copies of the same FrameNavigationEntry in different
    // NavigationEntries are de-duplicated.
    std::unique_ptr<TreeNode> CloneAndReplace(
        scoped_refptr<FrameNavigationEntry> frame_navigation_entry,
        bool clone_children_of_target,
        FrameTreeNode* target_frame_tree_node,
        FrameTreeNode* current_frame_tree_node,
        TreeNode* parent_node,
        NavigationEntryRestoreContextImpl* restore_context,
        ClonePolicy clone_policy) const;

    // The parent of this node.
    raw_ptr<TreeNode> parent;

    // Ref counted pointer that keeps the FrameNavigationEntry alive as long as
    // it is needed by this node's NavigationEntry.
    scoped_refptr<FrameNavigationEntry> frame_entry;

    // List of child TreeNodes, which will be deleted when this node is.
    std::vector<std::unique_ptr<TreeNode>> children;
  };

  static NavigationEntryImpl* FromNavigationEntry(NavigationEntry* entry);
  static const NavigationEntryImpl* FromNavigationEntry(
      const NavigationEntry* entry);
  static std::unique_ptr<NavigationEntryImpl> FromNavigationEntry(
      std::unique_ptr<NavigationEntry> entry);

  NavigationEntryImpl();
  NavigationEntryImpl(
      scoped_refptr<SiteInstanceImpl> instance,
      const GURL& url,
      const Referrer& referrer,
      const absl::optional<url::Origin>& initiator_origin,
      const absl::optional<GURL>& initiator_base_url,
      const std::u16string& title,
      ui::PageTransition transition_type,
      bool is_renderer_initiated,
      scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
      bool is_initial_entry);

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

  ~NavigationEntryImpl() override;

  // NavigationEntry implementation:
  bool IsInitialEntry() override;
  int GetUniqueID() override;
  PageType GetPageType() override;
  void SetURL(const GURL& url) override;
  const GURL& GetURL() override;
  void SetBaseURLForDataURL(const GURL& url) override;
  const GURL& GetBaseURLForDataURL() override;
#if BUILDFLAG(IS_ANDROID)
  void SetDataURLAsString(
      scoped_refptr<base::RefCountedString> data_url) override;
  const scoped_refptr<const base::RefCountedString>& GetDataURLAsString()
      override;
#endif
  void SetReferrer(const Referrer& referrer) override;
  const Referrer& GetReferrer() override;
  void SetVirtualURL(const GURL& url) override;
  const GURL& GetVirtualURL() override;
  void SetTitle(const std::u16string& title) override;
  const std::u16string& GetTitle() override;
  void SetPageState(const blink::PageState& state,
                    NavigationEntryRestoreContext* context) override;
  blink::PageState GetPageState() override;
  const std::u16string& GetTitleForDisplay() override;
  bool IsViewSourceMode() override;
  void SetTransitionType(ui::PageTransition transition_type) override;
  ui::PageTransition GetTransitionType() override;
  const GURL& GetUserTypedURL() override;
  void SetHasPostData(bool has_post_data) override;
  bool GetHasPostData() override;
  void SetPostID(int64_t post_id) override;
  int64_t GetPostID() override;
  void SetPostData(
      const scoped_refptr<network::ResourceRequestBody>& data) override;
  scoped_refptr<network::ResourceRequestBody> GetPostData() override;
  FaviconStatus& GetFavicon() override;
  SSLStatus& GetSSL() override;
  void SetOriginalRequestURL(const GURL& original_url) override;
  const GURL& GetOriginalRequestURL() override;
  void SetIsOverridingUserAgent(bool override_ua) override;
  bool GetIsOverridingUserAgent() override;
  void SetTimestamp(base::Time timestamp) override;
  base::Time GetTimestamp() override;
  void SetCanLoadLocalResources(bool allow) override;
  bool GetCanLoadLocalResources() override;
  void SetHttpStatusCode(int http_status_code) override;
  int GetHttpStatusCode() override;
  void SetRedirectChain(const std::vector<GURL>& redirects) override;
  const std::vector<GURL>& GetRedirectChain() override;
  const absl::optional<ReplacedNavigationEntryData>& GetReplacedEntryData()
      override;
  bool IsRestored() override;
  std::string GetExtraHeaders() override;
  void AddExtraHeaders(const std::string& extra_headers) override;
  int64_t GetMainFrameDocumentSequenceNumber() override;

  // Creates a copy of this NavigationEntryImpl that can be modified
  // independently from the original, but that shares FrameNavigationEntries.
  // Does not copy any value that would be cleared in ResetForCommit.  Unlike
  // |CloneAndReplace|, this does not check whether the subframe history items
  // are for frames that are still in the current page.
  std::unique_ptr<NavigationEntryImpl> Clone() const;

  // Creates a true deep copy of this NavigationEntryImpl. The
  // FrameNavigationEntries are cloned rather than merely taking a refptr to the
  // original.
  // |restore_context| is used when cloning a vector of NavigationEntryImpls to
  // ensure that FrameNavigationEntries that are shared across multiple entries
  // retain that relationship in the cloned entries.
  std::unique_ptr<NavigationEntryImpl> CloneWithoutSharing(
      NavigationEntryRestoreContextImpl* restore_context) const;

  // Like |Clone|, but replaces the FrameNavigationEntry corresponding to
  // |target_frame_tree_node| with |frame_entry|, clearing all of its children
  // unless |clone_children_of_target| is true.  This function omits any
  // subframe history items that do not correspond to frames actually in the
  // current page, using |root_frame_tree_node| (if present).
  std::unique_ptr<NavigationEntryImpl> CloneAndReplace(
      scoped_refptr<FrameNavigationEntry> frame_entry,
      bool clone_children_of_target,
      FrameTreeNode* target_frame_tree_node,
      FrameTreeNode* root_frame_tree_node) const;

  // Helper functions to construct NavigationParameters for a navigation to this
  // NavigationEntry.
  blink::mojom::CommonNavigationParamsPtr ConstructCommonNavigationParams(
      const FrameNavigationEntry& frame_entry,
      const scoped_refptr<network::ResourceRequestBody>& post_body,
      const GURL& dest_url,
      blink::mojom::ReferrerPtr dest_referrer,
      blink::mojom::NavigationType navigation_type,
      base::TimeTicks navigation_start,
      base::TimeTicks input_start);
  blink::mojom::CommitNavigationParamsPtr ConstructCommitNavigationParams(
      const FrameNavigationEntry& frame_entry,
      const GURL& original_url,
      const std::string& original_method,
      const base::flat_map<std::string, bool>& subframe_unique_names,
      bool intended_as_new_entry,
      int pending_offset_to_send,
      int current_offset_to_send,
      int current_length_to_send,
      const blink::FramePolicy& frame_policy,
      bool ancestor_or_self_has_cspee,
      absl::optional<blink::scheduler::TaskAttributionId>
          soft_navigation_heuristics_task_id);

  // Once a navigation entry is committed, we should no longer track several
  // pieces of non-persisted state, as documented on the members below.
  // |frame_entry| is the FrameNavigationEntry for the frame that committed
  // the navigation. It can be null.
  void ResetForCommit(FrameNavigationEntry* frame_entry);

  // Exposes the tree of FrameNavigationEntries that make up this joint session
  // history item.
  TreeNode* root_node() const { return frame_tree_.get(); }

  // Finds the TreeNode associated with |frame_tree_node|, if any.
  NavigationEntryImpl::TreeNode* GetTreeNode(
      FrameTreeNode* frame_tree_node) const;

  // Finds the TreeNode associated with |frame_tree_node_id| to add or update
  // its FrameNavigationEntry.  A new FrameNavigationEntry is added if none
  // exists, or else the existing one (which might be shared with other
  // NavigationEntries) is updated or replaced (based on |update_policy|) with
  // the given parameters.
  // Does nothing if there is no entry already and |url| is about:blank, since
  // that does not count as a real commit.
  enum class UpdatePolicy { kUpdate, kReplace };
  void AddOrUpdateFrameEntry(
      FrameTreeNode* frame_tree_node,
      UpdatePolicy update_policy,
      int64_t item_sequence_number,
      int64_t document_sequence_number,
      const std::string& navigation_api_key,
      SiteInstanceImpl* site_instance,
      scoped_refptr<SiteInstanceImpl> source_site_instance,
      const GURL& url,
      const absl::optional<url::Origin>& origin,
      const Referrer& referrer,
      const absl::optional<url::Origin>& initiator_origin,
      const absl::optional<GURL>& initiator_base_url,
      const std::vector<GURL>& redirect_chain,
      const blink::PageState& page_state,
      const std::string& method,
      int64_t post_id,
      scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
      std::unique_ptr<SubresourceWebBundleNavigationInfo>
          subresource_web_bundle_navigation_info,
      std::unique_ptr<PolicyContainerPolicies> policy_container_policies);

  // Returns the FrameNavigationEntry corresponding to |frame_tree_node|, if
  // there is one in this NavigationEntry.
  FrameNavigationEntry* GetFrameEntry(FrameTreeNode* frame_tree_node) const;

  // Calls |on_frame_entry| for each FrameNavigationEntry in this
  // NavigationEntry. More efficient than calling GetFrameEntry() N times while
  // iterating over the current tree of FrameTreeNodes.
  using FrameEntryIterationCallback =
      base::FunctionRef<void(FrameNavigationEntry*)>;
  void ForEachFrameEntry(FrameEntryIterationCallback on_frame_entry);

  // Returns a map of frame unique names to |is_about_blank| for immediate
  // children of the TreeNode associated with |frame_tree_node|.  The renderer
  // process will use this list of names to know whether to ask the browser
  // process for a history item when new subframes are created during a
  // back/forward navigation.  (|is_about_blank| can be used to skip the request
  // if the frame's default URL is about:blank and the history item would be a
  // no-op.  See https://crbug.com/657896.)
  // TODO(creis): Send a data structure that also contains all corresponding
  // same-process PageStates for the whole subtree, so that the renderer process
  // only needs to ask the browser process to handle the cross-process cases.
  // See https://crbug.com/639842.
  base::flat_map<std::string, bool> GetSubframeUniqueNames(
      FrameTreeNode* frame_tree_node) const;

  // Walks the tree of FrameNavigationEntries to find entries with |origin| so
  // their isolation status can be registered.
  void RegisterExistingOriginAsHavingDefaultIsolation(
      const url::Origin& origin);

  // Removes any subframe FrameNavigationEntries that match the unique name of
  // |frame_tree_node|, and all of their children. There should be at most one,
  // since collisions are avoided but leave old FrameNavigationEntries in the
  // tree after their frame has been detached.
  //
  // If |only_if_different_position| is specified, then the removal is only
  // done if the found FNE is in a different tree position than the
  // |frame_tree_node|.
  void RemoveEntryForFrame(FrameTreeNode* frame_tree_node,
                           bool only_if_different_position);

  // Update NotRestoredReasons for |navigation_request| which should be a
  // cross-document main frame navigation and is not served from back/forward
  // cache. This will create a metrics object if there is none, which can happen
  // when doing a session restore.
  void UpdateBackForwardCacheNotRestoredReasons(
      NavigationRequest* navigation_request);

  void set_unique_id(int unique_id) { unique_id_ = unique_id; }

  void set_started_from_context_menu(bool started_from_context_menu) {
    started_from_context_menu_ = started_from_context_menu;
  }

  bool has_started_from_context_menu() const {
    return started_from_context_menu_;
  }

  // The SiteInstance represents which pages must share processes. This is a
  // reference counted pointer to a shared SiteInstance.
  //
  // Note that the SiteInstance should usually not be changed after it is set,
  // but this may happen if the NavigationEntry was cloned and needs to use a
  // different SiteInstance.
  void set_site_instance(scoped_refptr<SiteInstanceImpl> site_instance);
  SiteInstanceImpl* site_instance() const {
    return frame_tree_->frame_entry->site_instance();
  }

  // The |source_site_instance| is used to identify the SiteInstance of the
  // frame that initiated the navigation. It is set on the
  // FrameNavigationEntry for the main frame.
  void set_source_site_instance(
      scoped_refptr<SiteInstanceImpl> source_site_instance) {
    root_node()->frame_entry->set_source_site_instance(
        source_site_instance.get());
  }

  void set_page_type(PageType page_type) { page_type_ = page_type; }

  bool has_virtual_url() const { return !virtual_url_.is_empty(); }

  bool update_virtual_url_with_url() const {
    return update_virtual_url_with_url_;
  }
  void set_update_virtual_url_with_url(bool update) {
    update_virtual_url_with_url_ = update;
  }

  // Extra headers (separated by \r\n) to send during the request.
  void set_extra_headers(const std::string& extra_headers) {
    extra_headers_ = extra_headers;
  }
  const std::string& extra_headers() const { return extra_headers_; }

  // Whether this (pending) navigation is renderer-initiated.  Resets to false
  // for all types of navigations after commit.
  void set_is_renderer_initiated(bool is_renderer_initiated) {
    is_renderer_initiated_ = is_renderer_initiated;
  }
  bool is_renderer_initiated() const { return is_renderer_initiated_; }

  void set_user_typed_url(const GURL& user_typed_url) {
    user_typed_url_ = user_typed_url;
  }

  // The RestoreType for this entry. This is set if the entry was restored. This
  // is set to RestoreType::NONE once the entry is loaded.
  void set_restore_type(RestoreType type) { restore_type_ = type; }
  RestoreType restore_type() const { return restore_type_; }

  // The ReloadType for this entry.  This is set when a reload is requested.
  // This is set to ReloadType::NONE if the entry isn't for a reload, or once
  // the entry is loaded.
  void set_reload_type(ReloadType type) { reload_type_ = type; }
  ReloadType reload_type() const { return reload_type_; }

  // Whether this (pending) navigation should clear the session history. Resets
  // to false after commit.
  bool should_clear_history_list() const { return should_clear_history_list_; }
  void set_should_clear_history_list(bool should_clear_history_list) {
    should_clear_history_list_ = should_clear_history_list;
  }

  // Indicates which FrameTreeNode to navigate.  Currently only used if the
  // --site-per-process flag is passed.
  int frame_tree_node_id() const { return frame_tree_node_id_; }
  void set_frame_tree_node_id(int frame_tree_node_id) {
    frame_tree_node_id_ = frame_tree_node_id;
  }

  // Returns the history URL for a data URL to use in Blink.
  GURL GetHistoryURLForDataURL();

  // These flags are set when the navigation controller gets notified of an SSL
  // error while a navigation is pending.
  void set_ssl_error(bool error) { ssl_error_ = error; }
  bool ssl_error() const { return ssl_error_; }

  bool has_user_gesture() const { return has_user_gesture_; }

  void set_has_user_gesture(bool has_user_gesture) {
    has_user_gesture_ = has_user_gesture;
  }

  void set_isolation_info(const net::IsolationInfo& isolation_info) {
    isolation_info_ = isolation_info;
  }

  const absl::optional<net::IsolationInfo>& isolation_info() const {
    return isolation_info_;
  }

  // Stores a record of the what was committed in this NavigationEntry's main
  // frame before it was replaced (e.g. by history.replaceState()).
  void set_replaced_entry_data(const ReplacedNavigationEntryData& data) {
    replaced_entry_data_ = data;
  }

  // See comment for should_skip_on_back_forward_ui_.
  bool should_skip_on_back_forward_ui() const {
    return should_skip_on_back_forward_ui_;
  }

  void set_should_skip_on_back_forward_ui(bool should_skip) {
    should_skip_on_back_forward_ui_ = should_skip;
  }

  BackForwardCacheMetrics* back_forward_cache_metrics() {
    return back_forward_cache_metrics_.get();
  }

  scoped_refptr<BackForwardCacheMetrics> TakeBackForwardCacheMetrics() {
    return std::move(back_forward_cache_metrics_);
  }

  void set_back_forward_cache_metrics(
      scoped_refptr<BackForwardCacheMetrics> metrics) {
    DCHECK(metrics);
    DCHECK(!back_forward_cache_metrics_);
    back_forward_cache_metrics_ = metrics;
  }

  // Whether this NavigationEntry is the initial NavigationEntry or not, and
  // whether it's for the initial empty document or the synchronously
  // committed about:blank document. The original initial NavigationEntry is
  // created when the FrameTree is created, so it might not be associated with
  // any navigation, but represents a placeholder NavigationEntry for the
  // "initial empty document", which commits in the renderer on frame creation
  // but doesn't notify the browser of the commit. However, more initial
  // NavigationEntries might be created after that in response to navigations,
  // and update or replace the original NavigationEntry. The initial
  // NavigationEntry will only get replaced with a non-initial NavigationEntry
  // by the first navigation that satisfies all of the following conditions:
  //   1. Happens on the main frame
  //   2. Classified as NEW_ENTRY (won't reuse the NavigationEntry)
  //   3. Is not the synchronous about:blank commit
  // So the "initial" status will be retained/copied to the new
  // NavigationEntry on subframe navigations, or when the NavigationEntry is
  // reused/classified as EXISTING_ENTRY (same-document navigations,
  // renderer-initiated reloads), or on the synchronous about:blank commit.
  // Some other important properties of initial NavigationEntries:
  // - The initial NavigationEntry always gets reused or replaced on the next
  // navigation (potentially by another initial NavigationEntry), so if there
  // is an initial NavigationEntry in the session history, it must be the only
  // NavigationEntry (as it is impossible to append to session history if the
  // initial NavigationEntry exists), which means it's not possible to do
  // a history navigation to an initial NavigationEntry.
  // - The initial NavigationEntry never gets restored on session restore,
  // because we never restore tabs with only the initial NavigationEntry.
  enum class InitialNavigationEntryState {
    // An initial NavigationEntry for the initial empty document or a
    // renderer-reloaded initial empty document.
    kInitialNotForSynchronousAboutBlank,
    // An initial NavigationEntry for the synchronously committed about:blank
    // document.
    kInitialForSynchronousAboutBlank,
    // Not an initial NavigationEntry.
    kNonInitial
  };

  bool IsInitialEntryNotForSynchronousAboutBlank() {
    return initial_navigation_entry_state_ ==
           InitialNavigationEntryState::kInitialNotForSynchronousAboutBlank;
  }

  bool IsInitialEntryForSynchronousAboutBlank() {
    return initial_navigation_entry_state_ ==
           InitialNavigationEntryState::kInitialForSynchronousAboutBlank;
  }

  void set_initial_navigation_entry_state(
      InitialNavigationEntryState initial_navigation_entry_state) {
    initial_navigation_entry_state_ = initial_navigation_entry_state;
  }

  InitialNavigationEntryState initial_navigation_entry_state() {
    return initial_navigation_entry_state_;
  }

 private:
  std::unique_ptr<NavigationEntryImpl> CloneAndReplaceInternal(
      scoped_refptr<FrameNavigationEntry> frame_entry,
      bool clone_children_of_target,
      FrameTreeNode* target_frame_tree_node,
      FrameTreeNode* root_frame_tree_node,
      NavigationEntryRestoreContextImpl* restore_context,
      ClonePolicy clone_policy) const;

  // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
  // Session/Tab restore save portions of this class so that it can be recreated
  // later. If you add a new field that needs to be persisted you'll have to
  // update SessionService/TabRestoreService and Android WebView
  // state_serializer.cc appropriately.
  // For all new fields, update |Clone| and possibly |ResetForCommit|.
  // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING

  // Tree of FrameNavigationEntries, one for each frame on the page.
  // FrameNavigationEntries may be shared with other NavigationEntries;
  // TreeNodes are not shared.
  std::unique_ptr<TreeNode> frame_tree_;

  // See the accessors above for descriptions.
  int unique_id_;
  PageType page_type_;
  GURL virtual_url_;
  bool update_virtual_url_with_url_;
  std::u16string title_;
  FaviconStatus favicon_;
  SSLStatus ssl_;
  ui::PageTransition transition_type_;
  GURL user_typed_url_;
  RestoreType restore_type_;
  GURL original_request_url_;
  bool is_overriding_user_agent_;
  base::Time timestamp_;
  int http_status_code_;

  // This member is not persisted with session restore because it is transient.
  // If the post request succeeds, this field is cleared since the same
  // information is stored in PageState. It is also only shallow copied with
  // compiler provided copy constructor.  Cleared in |ResetForCommit|.
  scoped_refptr<network::ResourceRequestBody> post_data_;

  // This member is not persisted with session restore.
  std::string extra_headers_;

  // Used for specifying base URL for pages loaded via data URLs. Only used and
  // persisted by Android WebView.
  GURL base_url_for_data_url_;

#if BUILDFLAG(IS_ANDROID)
  // Used for passing really big data URLs from browser to renderers. Only used
  // and persisted by Android WebView.
  scoped_refptr<const base::RefCountedString> data_url_as_string_;
#endif

  // Whether the entry, while loading, was created for a renderer-initiated
  // navigation.  This dictates whether the URL should be displayed before the
  // navigation commits.  It is cleared in |ResetForCommit| and not persisted.
  bool is_renderer_initiated_;

  // This is a cached version of the result of GetTitleForDisplay. It prevents
  // us from having to do URL formatting on the URL every time the title is
  // displayed. When the URL, virtual URL, or title is set, this should be
  // cleared to force a refresh.
  mutable std::u16string cached_display_title_;

  // This is set to true when this entry's navigation should clear the session
  // history both on the renderer and browser side. The browser side history
  // won't be cleared until the renderer has committed this navigation. This
  // entry is not persisted by the session restore system, as it is always
  // cleared in |ResetForCommit|.
  bool should_clear_history_list_;

  // Set when this entry should be able to access local file:// resources. This
  // value is not needed after the entry commits and is not persisted.
  bool can_load_local_resources_;

  // If not -1, this indicates which FrameTreeNode to navigate.  This field is
  // not persisted because it is experimental and only used when the
  // --site-per-process flag is passed.  It is cleared in |ResetForCommit|
  // because we only use it while the navigation is pending.
  // TODO(creis): Move this to FrameNavigationEntry.
  int frame_tree_node_id_;

  // Whether the URL load carries a user gesture.
  bool has_user_gesture_;

  // Used to store ReloadType for the entry.  This is ReloadType::NONE for
  // non-reload navigations.  Reset at commit and not persisted.
  ReloadType reload_type_;

  // Determine if the navigation was started within a context menu.
  bool started_from_context_menu_;

  // Set to true if the navigation controller gets notified about a SSL error
  // for a pending navigation. Defaults to false.
  bool ssl_error_;

  // The net::IsolationInfo for this NavigationEntry. If provided, this
  // determines the IsolationInfo to be used when navigating to this
  // NavigationEntry; otherwise, it is determined based on the navigating frame
  // and top frame origins. For example, this is used for view-source.
  absl::optional<net::IsolationInfo> isolation_info_;

  // Stores information about the entry prior to being replaced (e.g.
  // history.replaceState()). It is preserved after commit (session sync for
  // offline analysis) but should not be persisted. The concept is valid for
  // subframe navigations but we only need to track it for main frames, that's
  // why the field is listed here.
  absl::optional<ReplacedNavigationEntryData> replaced_entry_data_;

  // Set to true if this page does a navigation without ever receiving a user
  // gesture. If true, it will be skipped on subsequent back/forward button
  // clicks. This is to intervene against pages that manipulate the history such
  // that the user is not able to go back to the last site they interacted with.
  // Navigation here implies both client side redirects and history.pushState
  // calls.
  // It is always false the first time an entry's navigation is committed and
  // is also reset to false if an entry is reused for any subsequent
  // navigations.
  // TODO(shivanisha): Persist this field once the intervention is stable.
  bool should_skip_on_back_forward_ui_;

  // TODO(altimin, crbug.com/933147): Remove this logic after we are done
  // with implement back-forward cache.
  // It is preserved at commit but not persisted.
  scoped_refptr<BackForwardCacheMetrics> back_forward_cache_metrics_;

  // See comment for the enum for explanation.
  InitialNavigationEntryState initial_navigation_entry_state_ =
      InitialNavigationEntryState::kNonInitial;
};

}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_ENTRY_IMPL_H_
