// 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 "third_party/blink/public/mojom/navigation/system_entropy.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 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,
      blink::mojom::SystemEntropy system_entropy_at_navigation_start,
      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<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.
  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_
