blob: 2ccc2751957888e2c46b1b2b8d52f6530894fd3d [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2013 The Chromium Authors
danakjc492bf82020-09-09 20:02:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_ENTRY_IMPL_H_
6#define CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_ENTRY_IMPL_H_
7
8#include <stdint.h>
9
10#include <memory>
Arthur Sonzognic686e8f2024-01-11 08:36:3711#include <optional>
danakjc492bf82020-09-09 20:02:4412#include <string>
13#include <vector>
14
15#include "base/containers/flat_map.h"
Keishi Hattori0e45c022021-11-27 09:25:5216#include "base/memory/raw_ptr.h"
danakjc492bf82020-09-09 20:02:4417#include "base/memory/ref_counted.h"
danakjc492bf82020-09-09 20:02:4418#include "base/time/time.h"
19#include "build/build_config.h"
20#include "content/browser/renderer_host/back_forward_cache_metrics.h"
21#include "content/browser/renderer_host/frame_navigation_entry.h"
William Liu525ec5a12024-06-13 12:47:5422#include "content/browser/renderer_host/navigation_transitions/navigation_transition_data.h"
danakjc492bf82020-09-09 20:02:4423#include "content/browser/site_instance_impl.h"
Lei Zhang7ab313752021-11-17 01:26:0024#include "content/common/content_export.h"
danakjc492bf82020-09-09 20:02:4425#include "content/public/browser/favicon_status.h"
Avi Drissmanbd153642024-09-03 18:58:0526#include "content/public/browser/frame_tree_node_id.h"
danakjc492bf82020-09-09 20:02:4427#include "content/public/browser/global_request_id.h"
28#include "content/public/browser/navigation_entry.h"
29#include "content/public/browser/reload_type.h"
30#include "content/public/browser/replaced_navigation_entry_data.h"
31#include "content/public/browser/restore_type.h"
32#include "content/public/browser/ssl_status.h"
danakjc492bf82020-09-09 20:02:4433#include "net/base/isolation_info.h"
Miyoung Shin5d77f72072020-10-09 15:14:2034#include "third_party/blink/public/common/page_state/page_state.h"
Minggang Wangb9f3fa92021-07-01 15:30:3135#include "third_party/blink/public/mojom/navigation/navigation_params.mojom-forward.h"
Mike Jacksone2aa7af2023-05-17 06:45:0736#include "third_party/blink/public/mojom/navigation/system_entropy.mojom-forward.h"
danakjc492bf82020-09-09 20:02:4437#include "url/origin.h"
38
Minggang Wangb9f3fa92021-07-01 15:30:3139namespace blink {
40struct FramePolicy;
Yoav Weiss8c573952022-11-17 17:35:1341namespace scheduler {
42class TaskAttributionId;
43} // namespace scheduler
Minggang Wangb9f3fa92021-07-01 15:30:3144} // namespace blink
45
danakjc492bf82020-09-09 20:02:4446namespace content {
47
Carlos Caballero40b0efd2021-01-26 11:55:0048class FrameTreeNode;
Nate Chapin214a86a2021-06-21 20:35:5749class NavigationEntryRestoreContext;
50class NavigationEntryRestoreContextImpl;
danakjc492bf82020-09-09 20:02:4451
52class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
53 public:
Nate Chapin9f169072021-06-09 19:32:3754 // Determines whether CloneAndReplace will share the existing
55 // FrameNavigationEntries in the new NavigationEntry or not.
56 enum class ClonePolicy { kShareFrameEntries, kCloneFrameEntries };
57
danakjc492bf82020-09-09 20:02:4458 // Represents a tree of FrameNavigationEntries that make up this joint session
59 // history item.
60 struct TreeNode {
61 TreeNode(TreeNode* parent, scoped_refptr<FrameNavigationEntry> frame_entry);
62 ~TreeNode();
63
64 // Returns whether this TreeNode corresponds to |frame_tree_node|. If this
65 // is called on the root TreeNode, we only check if |frame_tree_node| is the
66 // main frame. Otherwise, we check if the unique name matches.
67 bool MatchesFrame(FrameTreeNode* frame_tree_node) const;
68
Nate Chapin9f169072021-06-09 19:32:3769 // Recursively makes a copy of this TreeNode, either sharing
70 // FrameNavigationEntries or making deep copies depending on |clone_policy|.
71 // Replaces the TreeNode corresponding to |target_frame_tree_node|,
72 // clearing all of its children unless |clone_children_of_target| is true.
73 // This function omits any subframe history items that do not correspond to
74 // frames actually in the current page, using |current_frame_tree_node| (if
Nate Chapin214a86a2021-06-21 20:35:5775 // present). |restore_context| is used to keep track of the
76 // FrameNavigationEntries that have been created during a deep clone, and to
77 // ensure that multiple copies of the same FrameNavigationEntry in different
78 // NavigationEntries are de-duplicated.
danakjc492bf82020-09-09 20:02:4479 std::unique_ptr<TreeNode> CloneAndReplace(
80 scoped_refptr<FrameNavigationEntry> frame_navigation_entry,
81 bool clone_children_of_target,
82 FrameTreeNode* target_frame_tree_node,
83 FrameTreeNode* current_frame_tree_node,
Nate Chapin9f169072021-06-09 19:32:3784 TreeNode* parent_node,
Nate Chapin214a86a2021-06-21 20:35:5785 NavigationEntryRestoreContextImpl* restore_context,
Nate Chapin9f169072021-06-09 19:32:3786 ClonePolicy clone_policy) const;
danakjc492bf82020-09-09 20:02:4487
88 // The parent of this node.
Keishi Hattori0e45c022021-11-27 09:25:5289 raw_ptr<TreeNode> parent;
danakjc492bf82020-09-09 20:02:4490
91 // Ref counted pointer that keeps the FrameNavigationEntry alive as long as
92 // it is needed by this node's NavigationEntry.
93 scoped_refptr<FrameNavigationEntry> frame_entry;
94
95 // List of child TreeNodes, which will be deleted when this node is.
96 std::vector<std::unique_ptr<TreeNode>> children;
97 };
98
99 static NavigationEntryImpl* FromNavigationEntry(NavigationEntry* entry);
100 static const NavigationEntryImpl* FromNavigationEntry(
101 const NavigationEntry* entry);
102 static std::unique_ptr<NavigationEntryImpl> FromNavigationEntry(
103 std::unique_ptr<NavigationEntry> entry);
104
105 NavigationEntryImpl();
106 NavigationEntryImpl(
107 scoped_refptr<SiteInstanceImpl> instance,
108 const GURL& url,
109 const Referrer& referrer,
Arthur Sonzognic686e8f2024-01-11 08:36:37110 const std::optional<url::Origin>& initiator_origin,
111 const std::optional<GURL>& initiator_base_url,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58112 const std::u16string& title,
danakjc492bf82020-09-09 20:02:44113 ui::PageTransition transition_type,
114 bool is_renderer_initiated,
Rakina Zata Amniafd3c6582021-11-30 06:19:17115 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
116 bool is_initial_entry);
Peter Boström828b9022021-09-21 02:28:43117
118 NavigationEntryImpl(const NavigationEntryImpl&) = delete;
119 NavigationEntryImpl& operator=(const NavigationEntryImpl&) = delete;
120
danakjc492bf82020-09-09 20:02:44121 ~NavigationEntryImpl() override;
122
123 // NavigationEntry implementation:
Rakina Zata Amniafd3c6582021-11-30 06:19:17124 bool IsInitialEntry() override;
danakjc492bf82020-09-09 20:02:44125 int GetUniqueID() override;
126 PageType GetPageType() override;
127 void SetURL(const GURL& url) override;
Elad Alon32044f532025-03-04 22:16:03128 const GURL& GetURL() const override;
danakjc492bf82020-09-09 20:02:44129 void SetBaseURLForDataURL(const GURL& url) override;
130 const GURL& GetBaseURLForDataURL() override;
Xiaohan Wang7f8052e02022-01-14 18:44:28131#if BUILDFLAG(IS_ANDROID)
danakjc492bf82020-09-09 20:02:44132 void SetDataURLAsString(
133 scoped_refptr<base::RefCountedString> data_url) override;
134 const scoped_refptr<const base::RefCountedString>& GetDataURLAsString()
135 override;
136#endif
137 void SetReferrer(const Referrer& referrer) override;
138 const Referrer& GetReferrer() override;
139 void SetVirtualURL(const GURL& url) override;
Elad Alon32044f532025-03-04 22:16:03140 const GURL& GetVirtualURL() const override;
Sky Malice5e2945ca2024-07-09 17:38:25141 void SetTitle(std::u16string title) override;
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58142 const std::u16string& GetTitle() override;
Stanley Honf83c4b8b2025-01-08 00:52:30143 void SetApplicationTitle(const std::u16string& application_title) override;
144 const std::optional<std::u16string>& GetApplicationTitle() override;
Nate Chapin214a86a2021-06-21 20:35:57145 void SetPageState(const blink::PageState& state,
146 NavigationEntryRestoreContext* context) override;
Miyoung Shin5d77f72072020-10-09 15:14:20147 blink::PageState GetPageState() override;
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58148 const std::u16string& GetTitleForDisplay() override;
danakjc492bf82020-09-09 20:02:44149 bool IsViewSourceMode() override;
150 void SetTransitionType(ui::PageTransition transition_type) override;
151 ui::PageTransition GetTransitionType() override;
152 const GURL& GetUserTypedURL() override;
153 void SetHasPostData(bool has_post_data) override;
154 bool GetHasPostData() override;
155 void SetPostID(int64_t post_id) override;
156 int64_t GetPostID() override;
157 void SetPostData(
158 const scoped_refptr<network::ResourceRequestBody>& data) override;
159 scoped_refptr<network::ResourceRequestBody> GetPostData() override;
160 FaviconStatus& GetFavicon() override;
161 SSLStatus& GetSSL() override;
162 void SetOriginalRequestURL(const GURL& original_url) override;
163 const GURL& GetOriginalRequestURL() override;
164 void SetIsOverridingUserAgent(bool override_ua) override;
165 bool GetIsOverridingUserAgent() override;
166 void SetTimestamp(base::Time timestamp) override;
167 base::Time GetTimestamp() override;
168 void SetCanLoadLocalResources(bool allow) override;
169 bool GetCanLoadLocalResources() override;
170 void SetHttpStatusCode(int http_status_code) override;
171 int GetHttpStatusCode() override;
172 void SetRedirectChain(const std::vector<GURL>& redirects) override;
173 const std::vector<GURL>& GetRedirectChain() override;
Arthur Sonzognic686e8f2024-01-11 08:36:37174 const std::optional<ReplacedNavigationEntryData>& GetReplacedEntryData()
danakjc492bf82020-09-09 20:02:44175 override;
176 bool IsRestored() override;
177 std::string GetExtraHeaders() override;
178 void AddExtraHeaders(const std::string& extra_headers) override;
179 int64_t GetMainFrameDocumentSequenceNumber() override;
180
181 // Creates a copy of this NavigationEntryImpl that can be modified
Nate Chapin9f169072021-06-09 19:32:37182 // independently from the original, but that shares FrameNavigationEntries.
183 // Does not copy any value that would be cleared in ResetForCommit. Unlike
184 // |CloneAndReplace|, this does not check whether the subframe history items
185 // are for frames that are still in the current page.
danakjc492bf82020-09-09 20:02:44186 std::unique_ptr<NavigationEntryImpl> Clone() const;
187
Nate Chapin9f169072021-06-09 19:32:37188 // Creates a true deep copy of this NavigationEntryImpl. The
189 // FrameNavigationEntries are cloned rather than merely taking a refptr to the
190 // original.
Nate Chapin214a86a2021-06-21 20:35:57191 // |restore_context| is used when cloning a vector of NavigationEntryImpls to
192 // ensure that FrameNavigationEntries that are shared across multiple entries
193 // retain that relationship in the cloned entries.
194 std::unique_ptr<NavigationEntryImpl> CloneWithoutSharing(
195 NavigationEntryRestoreContextImpl* restore_context) const;
Nate Chapin9f169072021-06-09 19:32:37196
danakjc492bf82020-09-09 20:02:44197 // Like |Clone|, but replaces the FrameNavigationEntry corresponding to
198 // |target_frame_tree_node| with |frame_entry|, clearing all of its children
199 // unless |clone_children_of_target| is true. This function omits any
200 // subframe history items that do not correspond to frames actually in the
201 // current page, using |root_frame_tree_node| (if present).
danakjc492bf82020-09-09 20:02:44202 std::unique_ptr<NavigationEntryImpl> CloneAndReplace(
203 scoped_refptr<FrameNavigationEntry> frame_entry,
204 bool clone_children_of_target,
205 FrameTreeNode* target_frame_tree_node,
206 FrameTreeNode* root_frame_tree_node) const;
207
208 // Helper functions to construct NavigationParameters for a navigation to this
209 // NavigationEntry.
Minggang Wangb9f3fa92021-07-01 15:30:31210 blink::mojom::CommonNavigationParamsPtr ConstructCommonNavigationParams(
danakjc492bf82020-09-09 20:02:44211 const FrameNavigationEntry& frame_entry,
212 const scoped_refptr<network::ResourceRequestBody>& post_body,
213 const GURL& dest_url,
214 blink::mojom::ReferrerPtr dest_referrer,
Minggang Wangb9f3fa92021-07-01 15:30:31215 blink::mojom::NavigationType navigation_type,
Charlie Reise1d9b8182025-04-02 04:32:12216 base::TimeTicks actual_navigation_start,
danakjc492bf82020-09-09 20:02:44217 base::TimeTicks navigation_start,
218 base::TimeTicks input_start);
Minggang Wangb9f3fa92021-07-01 15:30:31219 blink::mojom::CommitNavigationParamsPtr ConstructCommitNavigationParams(
danakjc492bf82020-09-09 20:02:44220 const FrameNavigationEntry& frame_entry,
221 const GURL& original_url,
danakjc492bf82020-09-09 20:02:44222 const std::string& original_method,
223 const base::flat_map<std::string, bool>& subframe_unique_names,
224 bool intended_as_new_entry,
225 int pending_offset_to_send,
226 int current_offset_to_send,
227 int current_length_to_send,
Liam Bradyd2a41e152022-07-19 13:58:48228 const blink::FramePolicy& frame_policy,
Yoav Weiss8c573952022-11-17 17:35:13229 bool ancestor_or_self_has_cspee,
Mike Jacksone2aa7af2023-05-17 06:45:07230 blink::mojom::SystemEntropy system_entropy_at_navigation_start,
Arthur Sonzognic686e8f2024-01-11 08:36:37231 std::optional<blink::scheduler::TaskAttributionId>
Yoav Weiss8c573952022-11-17 17:35:13232 soft_navigation_heuristics_task_id);
danakjc492bf82020-09-09 20:02:44233
234 // Once a navigation entry is committed, we should no longer track several
235 // pieces of non-persisted state, as documented on the members below.
236 // |frame_entry| is the FrameNavigationEntry for the frame that committed
237 // the navigation. It can be null.
238 void ResetForCommit(FrameNavigationEntry* frame_entry);
239
240 // Exposes the tree of FrameNavigationEntries that make up this joint session
241 // history item.
danakjc492bf82020-09-09 20:02:44242 TreeNode* root_node() const { return frame_tree_.get(); }
243
244 // Finds the TreeNode associated with |frame_tree_node|, if any.
245 NavigationEntryImpl::TreeNode* GetTreeNode(
246 FrameTreeNode* frame_tree_node) const;
247
248 // Finds the TreeNode associated with |frame_tree_node_id| to add or update
249 // its FrameNavigationEntry. A new FrameNavigationEntry is added if none
250 // exists, or else the existing one (which might be shared with other
Nate Chapin9f169072021-06-09 19:32:37251 // NavigationEntries) is updated or replaced (based on |update_policy|) with
252 // the given parameters.
danakjc492bf82020-09-09 20:02:44253 // Does nothing if there is no entry already and |url| is about:blank, since
254 // that does not count as a real commit.
Nate Chapin9f169072021-06-09 19:32:37255 enum class UpdatePolicy { kUpdate, kReplace };
danakjc492bf82020-09-09 20:02:44256 void AddOrUpdateFrameEntry(
257 FrameTreeNode* frame_tree_node,
Nate Chapin9f169072021-06-09 19:32:37258 UpdatePolicy update_policy,
danakjc492bf82020-09-09 20:02:44259 int64_t item_sequence_number,
260 int64_t document_sequence_number,
Domenic Denicolacc094fb2022-03-16 23:40:57261 const std::string& navigation_api_key,
danakjc492bf82020-09-09 20:02:44262 SiteInstanceImpl* site_instance,
263 scoped_refptr<SiteInstanceImpl> source_site_instance,
264 const GURL& url,
Arthur Sonzognic686e8f2024-01-11 08:36:37265 const std::optional<url::Origin>& origin,
danakjc492bf82020-09-09 20:02:44266 const Referrer& referrer,
Arthur Sonzognic686e8f2024-01-11 08:36:37267 const std::optional<url::Origin>& initiator_origin,
268 const std::optional<GURL>& initiator_base_url,
danakjc492bf82020-09-09 20:02:44269 const std::vector<GURL>& redirect_chain,
Miyoung Shin5d77f72072020-10-09 15:14:20270 const blink::PageState& page_state,
danakjc492bf82020-09-09 20:02:44271 const std::string& method,
272 int64_t post_id,
273 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
Titouan Rigoudy6ec70402021-02-02 15:42:19274 std::unique_ptr<PolicyContainerPolicies> policy_container_policies);
danakjc492bf82020-09-09 20:02:44275
276 // Returns the FrameNavigationEntry corresponding to |frame_tree_node|, if
277 // there is one in this NavigationEntry.
278 FrameNavigationEntry* GetFrameEntry(FrameTreeNode* frame_tree_node) const;
279
Nate Chapin9eb16be72022-09-23 22:54:31280 // Calls |on_frame_entry| for each FrameNavigationEntry in this
281 // NavigationEntry. More efficient than calling GetFrameEntry() N times while
282 // iterating over the current tree of FrameTreeNodes.
283 using FrameEntryIterationCallback =
284 base::FunctionRef<void(FrameNavigationEntry*)>;
285 void ForEachFrameEntry(FrameEntryIterationCallback on_frame_entry);
286
danakjc492bf82020-09-09 20:02:44287 // Returns a map of frame unique names to |is_about_blank| for immediate
288 // children of the TreeNode associated with |frame_tree_node|. The renderer
289 // process will use this list of names to know whether to ask the browser
290 // process for a history item when new subframes are created during a
291 // back/forward navigation. (|is_about_blank| can be used to skip the request
292 // if the frame's default URL is about:blank and the history item would be a
293 // no-op. See https://crbug.com/657896.)
294 // TODO(creis): Send a data structure that also contains all corresponding
295 // same-process PageStates for the whole subtree, so that the renderer process
296 // only needs to ask the browser process to handle the cross-process cases.
297 // See https://crbug.com/639842.
298 base::flat_map<std::string, bool> GetSubframeUniqueNames(
299 FrameTreeNode* frame_tree_node) const;
300
301 // Walks the tree of FrameNavigationEntries to find entries with |origin| so
302 // their isolation status can be registered.
W. James MacLeanc07dc41b2022-07-25 18:52:16303 void RegisterExistingOriginAsHavingDefaultIsolation(
304 const url::Origin& origin);
danakjc492bf82020-09-09 20:02:44305
306 // Removes any subframe FrameNavigationEntries that match the unique name of
307 // |frame_tree_node|, and all of their children. There should be at most one,
308 // since collisions are avoided but leave old FrameNavigationEntries in the
309 // tree after their frame has been detached.
310 //
311 // If |only_if_different_position| is specified, then the removal is only
312 // done if the found FNE is in a different tree position than the
313 // |frame_tree_node|.
314 void RemoveEntryForFrame(FrameTreeNode* frame_tree_node,
315 bool only_if_different_position);
316
Yuzu Saijo29f96ca92022-12-08 04:54:12317 // Update NotRestoredReasons for |navigation_request| which should be a
318 // cross-document main frame navigation and is not served from back/forward
319 // cache. This will create a metrics object if there is none, which can happen
320 // when doing a session restore.
321 void UpdateBackForwardCacheNotRestoredReasons(
322 NavigationRequest* navigation_request);
323
danakjc492bf82020-09-09 20:02:44324 void set_unique_id(int unique_id) { unique_id_ = unique_id; }
325
326 void set_started_from_context_menu(bool started_from_context_menu) {
327 started_from_context_menu_ = started_from_context_menu;
328 }
329
330 bool has_started_from_context_menu() const {
331 return started_from_context_menu_;
332 }
333
334 // The SiteInstance represents which pages must share processes. This is a
335 // reference counted pointer to a shared SiteInstance.
336 //
337 // Note that the SiteInstance should usually not be changed after it is set,
338 // but this may happen if the NavigationEntry was cloned and needs to use a
339 // different SiteInstance.
danakjc492bf82020-09-09 20:02:44340 SiteInstanceImpl* site_instance() const {
341 return frame_tree_->frame_entry->site_instance();
342 }
343
344 // The |source_site_instance| is used to identify the SiteInstance of the
345 // frame that initiated the navigation. It is set on the
346 // FrameNavigationEntry for the main frame.
347 void set_source_site_instance(
348 scoped_refptr<SiteInstanceImpl> source_site_instance) {
349 root_node()->frame_entry->set_source_site_instance(
350 source_site_instance.get());
351 }
352
353 void set_page_type(PageType page_type) { page_type_ = page_type; }
354
355 bool has_virtual_url() const { return !virtual_url_.is_empty(); }
356
357 bool update_virtual_url_with_url() const {
358 return update_virtual_url_with_url_;
359 }
360 void set_update_virtual_url_with_url(bool update) {
361 update_virtual_url_with_url_ = update;
362 }
363
364 // Extra headers (separated by \r\n) to send during the request.
365 void set_extra_headers(const std::string& extra_headers) {
366 extra_headers_ = extra_headers;
367 }
368 const std::string& extra_headers() const { return extra_headers_; }
369
370 // Whether this (pending) navigation is renderer-initiated. Resets to false
371 // for all types of navigations after commit.
372 void set_is_renderer_initiated(bool is_renderer_initiated) {
373 is_renderer_initiated_ = is_renderer_initiated;
374 }
375 bool is_renderer_initiated() const { return is_renderer_initiated_; }
376
377 void set_user_typed_url(const GURL& user_typed_url) {
378 user_typed_url_ = user_typed_url;
379 }
380
danakjf26536bf2020-09-10 00:46:13381 // The RestoreType for this entry. This is set if the entry was restored. This
danakjc492bf82020-09-09 20:02:44382 // is set to RestoreType::NONE once the entry is loaded.
383 void set_restore_type(RestoreType type) { restore_type_ = type; }
384 RestoreType restore_type() const { return restore_type_; }
385
386 // The ReloadType for this entry. This is set when a reload is requested.
387 // This is set to ReloadType::NONE if the entry isn't for a reload, or once
388 // the entry is loaded.
389 void set_reload_type(ReloadType type) { reload_type_ = type; }
390 ReloadType reload_type() const { return reload_type_; }
391
danakjc492bf82020-09-09 20:02:44392 // Whether this (pending) navigation should clear the session history. Resets
393 // to false after commit.
394 bool should_clear_history_list() const { return should_clear_history_list_; }
395 void set_should_clear_history_list(bool should_clear_history_list) {
396 should_clear_history_list_ = should_clear_history_list;
397 }
398
399 // Indicates which FrameTreeNode to navigate. Currently only used if the
400 // --site-per-process flag is passed.
Avi Drissmanbd153642024-09-03 18:58:05401 FrameTreeNodeId frame_tree_node_id() const { return frame_tree_node_id_; }
402 void set_frame_tree_node_id(FrameTreeNodeId frame_tree_node_id) {
danakjc492bf82020-09-09 20:02:44403 frame_tree_node_id_ = frame_tree_node_id;
404 }
405
406 // Returns the history URL for a data URL to use in Blink.
407 GURL GetHistoryURLForDataURL();
408
409 // These flags are set when the navigation controller gets notified of an SSL
410 // error while a navigation is pending.
411 void set_ssl_error(bool error) { ssl_error_ = error; }
412 bool ssl_error() const { return ssl_error_; }
413
414 bool has_user_gesture() const { return has_user_gesture_; }
415
416 void set_has_user_gesture(bool has_user_gesture) {
417 has_user_gesture_ = has_user_gesture;
418 }
419
420 void set_isolation_info(const net::IsolationInfo& isolation_info) {
421 isolation_info_ = isolation_info;
422 }
423
Arthur Sonzognic686e8f2024-01-11 08:36:37424 const std::optional<net::IsolationInfo>& isolation_info() const {
danakjc492bf82020-09-09 20:02:44425 return isolation_info_;
426 }
427
428 // Stores a record of the what was committed in this NavigationEntry's main
429 // frame before it was replaced (e.g. by history.replaceState()).
430 void set_replaced_entry_data(const ReplacedNavigationEntryData& data) {
431 replaced_entry_data_ = data;
432 }
433
434 // See comment for should_skip_on_back_forward_ui_.
435 bool should_skip_on_back_forward_ui() const {
436 return should_skip_on_back_forward_ui_;
437 }
438
439 void set_should_skip_on_back_forward_ui(bool should_skip) {
440 should_skip_on_back_forward_ui_ = should_skip;
441 }
442
443 BackForwardCacheMetrics* back_forward_cache_metrics() {
444 return back_forward_cache_metrics_.get();
445 }
446
Yuzu Saijoa725585f2022-11-28 04:14:03447 scoped_refptr<BackForwardCacheMetrics> TakeBackForwardCacheMetrics() {
448 return std::move(back_forward_cache_metrics_);
449 }
450
danakjc492bf82020-09-09 20:02:44451 void set_back_forward_cache_metrics(
452 scoped_refptr<BackForwardCacheMetrics> metrics) {
453 DCHECK(metrics);
454 DCHECK(!back_forward_cache_metrics_);
455 back_forward_cache_metrics_ = metrics;
456 }
457
Rakina Zata Amnif297a802022-01-18 03:53:43458 // Whether this NavigationEntry is the initial NavigationEntry or not, and
459 // whether it's for the initial empty document or the synchronously
460 // committed about:blank document. The original initial NavigationEntry is
461 // created when the FrameTree is created, so it might not be associated with
462 // any navigation, but represents a placeholder NavigationEntry for the
463 // "initial empty document", which commits in the renderer on frame creation
464 // but doesn't notify the browser of the commit. However, more initial
465 // NavigationEntries might be created after that in response to navigations,
466 // and update or replace the original NavigationEntry. The initial
467 // NavigationEntry will only get replaced with a non-initial NavigationEntry
468 // by the first navigation that satisfies all of the following conditions:
469 // 1. Happens on the main frame
470 // 2. Classified as NEW_ENTRY (won't reuse the NavigationEntry)
471 // 3. Is not the synchronous about:blank commit
472 // So the "initial" status will be retained/copied to the new
473 // NavigationEntry on subframe navigations, or when the NavigationEntry is
474 // reused/classified as EXISTING_ENTRY (same-document navigations,
475 // renderer-initiated reloads), or on the synchronous about:blank commit.
476 // Some other important properties of initial NavigationEntries:
477 // - The initial NavigationEntry always gets reused or replaced on the next
478 // navigation (potentially by another initial NavigationEntry), so if there
479 // is an initial NavigationEntry in the session history, it must be the only
480 // NavigationEntry (as it is impossible to append to session history if the
481 // initial NavigationEntry exists), which means it's not possible to do
482 // a history navigation to an initial NavigationEntry.
483 // - The initial NavigationEntry never gets restored on session restore,
484 // because we never restore tabs with only the initial NavigationEntry.
485 enum class InitialNavigationEntryState {
486 // An initial NavigationEntry for the initial empty document or a
487 // renderer-reloaded initial empty document.
488 kInitialNotForSynchronousAboutBlank,
489 // An initial NavigationEntry for the synchronously committed about:blank
490 // document.
491 kInitialForSynchronousAboutBlank,
492 // Not an initial NavigationEntry.
493 kNonInitial
494 };
495
496 bool IsInitialEntryNotForSynchronousAboutBlank() {
497 return initial_navigation_entry_state_ ==
498 InitialNavigationEntryState::kInitialNotForSynchronousAboutBlank;
499 }
500
501 bool IsInitialEntryForSynchronousAboutBlank() {
502 return initial_navigation_entry_state_ ==
503 InitialNavigationEntryState::kInitialForSynchronousAboutBlank;
504 }
505
506 void set_initial_navigation_entry_state(
507 InitialNavigationEntryState initial_navigation_entry_state) {
508 initial_navigation_entry_state_ = initial_navigation_entry_state;
509 }
510
511 InitialNavigationEntryState initial_navigation_entry_state() {
512 return initial_navigation_entry_state_;
Rakina Zata Amnia4e27222021-12-22 01:05:00513 }
514
William Liu525ec5a12024-06-13 12:47:54515 NavigationTransitionData& navigation_transition_data() {
516 return navigation_transition_data_;
517 }
518 const NavigationTransitionData& navigation_transition_data() const {
519 return navigation_transition_data_;
William Liu7bedaf8e2024-05-16 17:15:32520 }
521
danakjc492bf82020-09-09 20:02:44522 private:
Nate Chapin9f169072021-06-09 19:32:37523 std::unique_ptr<NavigationEntryImpl> CloneAndReplaceInternal(
524 scoped_refptr<FrameNavigationEntry> frame_entry,
525 bool clone_children_of_target,
526 FrameTreeNode* target_frame_tree_node,
527 FrameTreeNode* root_frame_tree_node,
Nate Chapin214a86a2021-06-21 20:35:57528 NavigationEntryRestoreContextImpl* restore_context,
Nate Chapin9f169072021-06-09 19:32:37529 ClonePolicy clone_policy) const;
530
danakjc492bf82020-09-09 20:02:44531 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
532 // Session/Tab restore save portions of this class so that it can be recreated
533 // later. If you add a new field that needs to be persisted you'll have to
534 // update SessionService/TabRestoreService and Android WebView
535 // state_serializer.cc appropriately.
536 // For all new fields, update |Clone| and possibly |ResetForCommit|.
537 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
538
539 // Tree of FrameNavigationEntries, one for each frame on the page.
Nate Chapin9f169072021-06-09 19:32:37540 // FrameNavigationEntries may be shared with other NavigationEntries;
541 // TreeNodes are not shared.
danakjc492bf82020-09-09 20:02:44542 std::unique_ptr<TreeNode> frame_tree_;
543
544 // See the accessors above for descriptions.
545 int unique_id_;
546 PageType page_type_;
547 GURL virtual_url_;
548 bool update_virtual_url_with_url_;
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58549 std::u16string title_;
Stanley Honf83c4b8b2025-01-08 00:52:30550 // The application title is optional and may be empty. If set to a non-empty
551 // value, a web app displayed in an app window may use this string instead of
552 // the regular title. See
Haben Foto533aa352024-01-09 22:01:16553 // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/DocumentSubtitle/explainer.md
Stanley Honf83c4b8b2025-01-08 00:52:30554 std::optional<std::u16string> application_title_;
danakjc492bf82020-09-09 20:02:44555 FaviconStatus favicon_;
556 SSLStatus ssl_;
557 ui::PageTransition transition_type_;
558 GURL user_typed_url_;
559 RestoreType restore_type_;
560 GURL original_request_url_;
561 bool is_overriding_user_agent_;
562 base::Time timestamp_;
563 int http_status_code_;
564
565 // This member is not persisted with session restore because it is transient.
566 // If the post request succeeds, this field is cleared since the same
567 // information is stored in PageState. It is also only shallow copied with
568 // compiler provided copy constructor. Cleared in |ResetForCommit|.
569 scoped_refptr<network::ResourceRequestBody> post_data_;
570
571 // This member is not persisted with session restore.
572 std::string extra_headers_;
573
574 // Used for specifying base URL for pages loaded via data URLs. Only used and
575 // persisted by Android WebView.
576 GURL base_url_for_data_url_;
577
Xiaohan Wang7f8052e02022-01-14 18:44:28578#if BUILDFLAG(IS_ANDROID)
danakjc492bf82020-09-09 20:02:44579 // Used for passing really big data URLs from browser to renderers. Only used
580 // and persisted by Android WebView.
581 scoped_refptr<const base::RefCountedString> data_url_as_string_;
582#endif
583
584 // Whether the entry, while loading, was created for a renderer-initiated
585 // navigation. This dictates whether the URL should be displayed before the
586 // navigation commits. It is cleared in |ResetForCommit| and not persisted.
587 bool is_renderer_initiated_;
588
589 // This is a cached version of the result of GetTitleForDisplay. It prevents
590 // us from having to do URL formatting on the URL every time the title is
591 // displayed. When the URL, virtual URL, or title is set, this should be
592 // cleared to force a refresh.
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58593 mutable std::u16string cached_display_title_;
danakjc492bf82020-09-09 20:02:44594
danakjc492bf82020-09-09 20:02:44595 // This is set to true when this entry's navigation should clear the session
596 // history both on the renderer and browser side. The browser side history
597 // won't be cleared until the renderer has committed this navigation. This
598 // entry is not persisted by the session restore system, as it is always
599 // cleared in |ResetForCommit|.
600 bool should_clear_history_list_;
601
602 // Set when this entry should be able to access local file:// resources. This
603 // value is not needed after the entry commits and is not persisted.
604 bool can_load_local_resources_;
605
Avi Drissmanbd153642024-09-03 18:58:05606 // If valid, this indicates which FrameTreeNode to navigate. This field is
danakjc492bf82020-09-09 20:02:44607 // not persisted because it is experimental and only used when the
608 // --site-per-process flag is passed. It is cleared in |ResetForCommit|
609 // because we only use it while the navigation is pending.
610 // TODO(creis): Move this to FrameNavigationEntry.
Avi Drissmanbd153642024-09-03 18:58:05611 FrameTreeNodeId frame_tree_node_id_;
danakjc492bf82020-09-09 20:02:44612
613 // Whether the URL load carries a user gesture.
614 bool has_user_gesture_;
615
616 // Used to store ReloadType for the entry. This is ReloadType::NONE for
617 // non-reload navigations. Reset at commit and not persisted.
618 ReloadType reload_type_;
619
620 // Determine if the navigation was started within a context menu.
621 bool started_from_context_menu_;
622
623 // Set to true if the navigation controller gets notified about a SSL error
624 // for a pending navigation. Defaults to false.
625 bool ssl_error_;
626
627 // The net::IsolationInfo for this NavigationEntry. If provided, this
628 // determines the IsolationInfo to be used when navigating to this
629 // NavigationEntry; otherwise, it is determined based on the navigating frame
630 // and top frame origins. For example, this is used for view-source.
Arthur Sonzognic686e8f2024-01-11 08:36:37631 std::optional<net::IsolationInfo> isolation_info_;
danakjc492bf82020-09-09 20:02:44632
633 // Stores information about the entry prior to being replaced (e.g.
634 // history.replaceState()). It is preserved after commit (session sync for
635 // offline analysis) but should not be persisted. The concept is valid for
636 // subframe navigations but we only need to track it for main frames, that's
637 // why the field is listed here.
Arthur Sonzognic686e8f2024-01-11 08:36:37638 std::optional<ReplacedNavigationEntryData> replaced_entry_data_;
danakjc492bf82020-09-09 20:02:44639
640 // Set to true if this page does a navigation without ever receiving a user
641 // gesture. If true, it will be skipped on subsequent back/forward button
642 // clicks. This is to intervene against pages that manipulate the history such
643 // that the user is not able to go back to the last site they interacted with.
644 // Navigation here implies both client side redirects and history.pushState
645 // calls.
646 // It is always false the first time an entry's navigation is committed and
647 // is also reset to false if an entry is reused for any subsequent
648 // navigations.
649 // TODO(shivanisha): Persist this field once the intervention is stable.
650 bool should_skip_on_back_forward_ui_;
651
652 // TODO(altimin, crbug.com/933147): Remove this logic after we are done
653 // with implement back-forward cache.
654 // It is preserved at commit but not persisted.
655 scoped_refptr<BackForwardCacheMetrics> back_forward_cache_metrics_;
Rakina Zata Amniafd3c6582021-11-30 06:19:17656
Rakina Zata Amnif297a802022-01-18 03:53:43657 // See comment for the enum for explanation.
658 InitialNavigationEntryState initial_navigation_entry_state_ =
659 InitialNavigationEntryState::kNonInitial;
William Liu7bedaf8e2024-05-16 17:15:32660
William Liu525ec5a12024-06-13 12:47:54661 // Information about a navigation transition. See the comments on the class
662 // for details.
663 NavigationTransitionData navigation_transition_data_;
danakjc492bf82020-09-09 20:02:44664};
665
666} // namespace content
667
668#endif // CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_ENTRY_IMPL_H_