blob: fe3ee7a65f6cfb295c999d2bd92ad66df2ab8e7d [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_NAVIGATOR_H_
6#define CONTENT_BROWSER_RENDERER_HOST_NAVIGATOR_H_
7
8#include <memory>
Arthur Sonzognic686e8f2024-01-11 08:36:379#include <optional>
danakjc492bf82020-09-09 20:02:4410
Keishi Hattori0e45c022021-11-27 09:25:5211#include "base/memory/raw_ptr.h"
danakjc492bf82020-09-09 20:02:4412#include "base/memory/ref_counted.h"
Carlos Caballero40b0efd2021-01-26 11:55:0013#include "content/browser/renderer_host/navigation_controller_impl.h"
danakjc492bf82020-09-09 20:02:4414#include "content/common/content_export.h"
15#include "content/common/navigation_client.mojom.h"
danakjc492bf82020-09-09 20:02:4416#include "content/public/browser/navigation_controller.h"
Rakina Zata Amni58681c62024-06-25 06:32:1317#include "content/public/browser/navigation_discard_reason.h"
danakjc492bf82020-09-09 20:02:4418#include "mojo/public/cpp/bindings/pending_associated_remote.h"
19#include "mojo/public/cpp/bindings/pending_remote.h"
W. James MacLean443ef3e2024-07-16 13:42:3420#include "net/storage_access_api/status.h"
Gyuyoung Kim38e63632021-01-14 13:11:3921#include "third_party/blink/public/common/navigation/impression.h"
Gyuyoung Kimd85bd892021-04-13 02:11:5522#include "third_party/blink/public/mojom/frame/triggering_event_info.mojom-shared.h"
Yao Xiao720ef9d62022-12-09 05:18:2923#include "third_party/blink/public/mojom/navigation/navigation_initiator_activation_and_ad_status.mojom.h"
Minggang Wangb9f3fa92021-07-01 15:30:3124#include "third_party/blink/public/mojom/navigation/navigation_params.mojom-forward.h"
danakjc492bf82020-09-09 20:02:4425#include "ui/base/window_open_disposition.h"
26
27class GURL;
danakjc492bf82020-09-09 20:02:4428
29namespace base {
30class TimeTicks;
31}
32
33namespace network {
34class ResourceRequestBody;
35}
36
37namespace content {
38
Carlos Caballero40b0efd2021-01-26 11:55:0039class BrowserContext;
danakjc492bf82020-09-09 20:02:4440class FrameNavigationEntry;
Carlos Caballero40b0efd2021-01-26 11:55:0041class FrameTree;
danakjc492bf82020-09-09 20:02:4442class FrameTreeNode;
Carlos Caballero40b0efd2021-01-26 11:55:0043class NavigationControllerDelegate;
danakjc492bf82020-09-09 20:02:4444class NavigationEntryImpl;
45class NavigationRequest;
Carlos Caballero40b0efd2021-01-26 11:55:0046class NavigatorDelegate;
danakjc492bf82020-09-09 20:02:4447class PrefetchedSignedExchangeCache;
48class RenderFrameHostImpl;
danakjc492bf82020-09-09 20:02:4449struct LoadCommittedDetails;
W. James MacLean46cf26212020-10-01 16:43:3750struct UrlInfo;
danakjc492bf82020-09-09 20:02:4451
52// Navigator is responsible for performing navigations in nodes of the
53// FrameTree. Its lifetime is bound to the FrameTree.
54class CONTENT_EXPORT Navigator {
55 public:
Carlos Caballero40b0efd2021-01-26 11:55:0056 Navigator(BrowserContext* browser_context,
57 FrameTree& frame_tree,
58 NavigatorDelegate* delegate,
59 NavigationControllerDelegate* navigation_controller_delegate);
Peter Boström828b9022021-09-21 02:28:4360
61 Navigator(const Navigator&) = delete;
62 Navigator& operator=(const Navigator&) = delete;
63
danakjc492bf82020-09-09 20:02:4464 ~Navigator();
65
66 // This method verifies that a navigation to |url| doesn't commit into a WebUI
67 // process if it is not allowed to. Callers of this method should take one of
68 // two actions if the method returns false:
69 // * When called from browser process logic (e.g. NavigationRequest), this
70 // indicates issues with the navigation logic and the browser process must
71 // be terminated to avoid security issues.
72 // * If the codepath is processing an IPC message from a renderer process,
73 // then the renderer process is misbehaving and must be terminated.
74 // TODO(nasko): Remove the is_renderer_initiated_check parameter when callers
75 // of this method are migrated to use CHECK instead of DumpWithoutCrashing.
Daniel Cheng9c9fa1a2022-01-14 03:42:1176 [[nodiscard]] static bool CheckWebUIRendererDoesNotDisplayNormalURL(
danakjc492bf82020-09-09 20:02:4477 RenderFrameHostImpl* render_frame_host,
W. James MacLean46cf26212020-10-01 16:43:3778 const UrlInfo& url_info,
danakjc492bf82020-09-09 20:02:4479 bool is_renderer_initiated_check);
80
81 static bool ShouldIgnoreIncomingRendererRequest(
82 const NavigationRequest* ongoing_navigation_request,
83 bool has_user_gesture);
84
85 // Returns the delegate of this Navigator.
86 NavigatorDelegate* GetDelegate();
87
danakjc492bf82020-09-09 20:02:4488 // Notifications coming from the RenderFrameHosts ----------------------------
89
danakjc492bf82020-09-09 20:02:4490 // The RenderFrameHostImpl has committed a navigation. The Navigator is
91 // responsible for resetting |navigation_request| at the end of this method
92 // and should not attempt to keep it alive. Note: it is possible that
93 // |navigation_request| is not the NavigationRequest stored in the
94 // RenderFrameHost that just committed. This happens for example when a
95 // same-page navigation commits while another navigation is ongoing. The
96 // Navigator should use the NavigationRequest provided by this method and not
97 // attempt to access the RenderFrameHost's NavigationsRequests.
98 void DidNavigate(RenderFrameHostImpl* render_frame_host,
arthursonzogni73fe3212020-11-17 13:24:0799 const mojom::DidCommitProvisionalLoadParams& params,
danakjc492bf82020-09-09 20:02:44100 std::unique_ptr<NavigationRequest> navigation_request,
101 bool was_within_same_document);
102
103 // Called on a newly created subframe during a history navigation. The browser
104 // process looks up the corresponding FrameNavigationEntry for the new frame
105 // navigates it in the correct process. Returns false if the
106 // FrameNavigationEntry can't be found or the navigation fails.
107 bool StartHistoryNavigationInNewSubframe(
108 RenderFrameHostImpl* render_frame_host,
Hiroshige Hayashizaki5466bfe82023-05-17 00:34:33109 mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client,
110 blink::LocalFrameToken initiator_frame_token,
Charlie Reisf4d51f402025-05-23 18:00:49111 int initiator_process_id,
112 base::TimeTicks actual_navigation_start);
danakjc492bf82020-09-09 20:02:44113
114 // Navigation requests -------------------------------------------------------
115
116 // Called by the NavigationController to cause the Navigator to navigate to
117 // |navigation_request|. The NavigationController should be called back with
118 // RendererDidNavigate on success or DiscardPendingEntry on failure. The
119 // callbacks should be called in a future iteration of the message loop.
120 void Navigate(std::unique_ptr<NavigationRequest> request,
Lukasz Anforowicz9ee83c272020-12-01 20:14:05121 ReloadType reload_type);
danakjc492bf82020-09-09 20:02:44122
123 // The RenderFrameHostImpl has received a request to open a URL with the
124 // specified |disposition|.
125 void RequestOpenURL(
126 RenderFrameHostImpl* render_frame_host,
127 const GURL& url,
Chris Hamilton83272dc2021-02-23 00:24:02128 const blink::LocalFrameToken* initiator_frame_token,
Antonio Sartori9a82f6f32020-12-14 09:22:45129 int initiator_process_id,
Arthur Sonzognic686e8f2024-01-11 08:36:37130 const std::optional<url::Origin>& initiator_origin,
131 const std::optional<GURL>& initiator_base_url,
danakjc492bf82020-09-09 20:02:44132 const scoped_refptr<network::ResourceRequestBody>& post_body,
133 const std::string& extra_headers,
134 const Referrer& referrer,
135 WindowOpenDisposition disposition,
136 bool should_replace_current_entry,
137 bool user_gesture,
Gyuyoung Kim16a12f52020-12-19 04:24:26138 blink::mojom::TriggeringEventInfo triggering_event_info,
danakjc492bf82020-09-09 20:02:44139 const std::string& href_translate,
140 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
Kevin McNee64556382024-06-27 22:05:03141 const std::optional<blink::Impression>& impression,
142 bool has_rel_opener);
danakjc492bf82020-09-09 20:02:44143
144 // Called when a document requests a navigation in another document through a
Dave Tapuska2402595f2022-08-03 16:24:21145 // `blink::RemoteFrame`. If `method` is "POST", then `post_body` needs to
146 // specify the request body, otherwise `post_body` should be null.
danakjc492bf82020-09-09 20:02:44147 void NavigateFromFrameProxy(
148 RenderFrameHostImpl* render_frame_host,
149 const GURL& url,
Chris Hamilton83272dc2021-02-23 00:24:02150 const blink::LocalFrameToken* initiator_frame_token,
Antonio Sartori9a82f6f32020-12-14 09:22:45151 int initiator_process_id,
danakjc492bf82020-09-09 20:02:44152 const url::Origin& initiator_origin,
Arthur Sonzognic686e8f2024-01-11 08:36:37153 const std::optional<GURL>& initiator_base_url,
danakjc492bf82020-09-09 20:02:44154 SiteInstance* source_site_instance,
155 const Referrer& referrer,
156 ui::PageTransition page_transition,
157 bool should_replace_current_entry,
Yeunjoo Choi3df791a2021-02-17 07:07:25158 blink::NavigationDownloadPolicy download_policy,
danakjc492bf82020-09-09 20:02:44159 const std::string& method,
160 scoped_refptr<network::ResourceRequestBody> post_body,
161 const std::string& extra_headers,
162 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
Antonio Sartori2f763d9d2021-04-21 10:04:14163 network::mojom::SourceLocationPtr source_location,
danakjc492bf82020-09-09 20:02:44164 bool has_user_gesture,
jongdeok.kim5de823b32022-06-14 04:37:50165 bool is_form_submission,
Arthur Sonzognic686e8f2024-01-11 08:36:37166 const std::optional<blink::Impression>& impression,
Yao Xiao720ef9d62022-12-09 05:18:29167 blink::mojom::NavigationInitiatorActivationAndAdStatus
168 initiator_activation_and_ad_status,
Charlie Reise1d9b8182025-04-02 04:32:12169 base::TimeTicks actual_navigation_start_time,
Nan Lin944e9b4e2022-04-12 13:51:22170 base::TimeTicks navigation_start_time,
Garrett Tanzer405f3402022-07-21 20:12:49171 bool is_embedder_initiated_fenced_frame_navigation = false,
Garrett Tanzerbb8db412022-09-27 21:59:46172 bool is_unfenced_top_navigation = false,
Sergey Poromovdd557c12023-03-01 11:28:45173 bool force_new_browsing_instance = false,
Camillia Smith Barnes6a643962023-03-03 00:28:58174 bool is_container_initiated = false,
Kevin McNee64556382024-06-27 22:05:03175 bool has_rel_opener = false,
W. James MacLean443ef3e2024-07-16 13:42:34176 net::StorageAccessApiStatus storage_access_api_status =
177 net::StorageAccessApiStatus::kNone,
Arthur Sonzognic686e8f2024-01-11 08:36:37178 std::optional<std::u16string> embedder_shared_storage_context =
179 std::nullopt);
danakjc492bf82020-09-09 20:02:44180
181 // Called after BeforeUnloadCompleted callback is invoked from the renderer.
Charlie Reis9e20dd12025-01-02 20:11:53182 // If `frame_tree_node` has a NavigationRequest waiting for the renderer
danakjc492bf82020-09-09 20:02:44183 // response, then the request is either started or canceled, depending on the
Charlie Reis9e20dd12025-01-02 20:11:53184 // value of `proceed`. If `for_legacy` is true, then this beforeunload flow
185 // was only used to post a task and no beforeunload handlers were run. If
186 // `showed_dialog` is true, then a beforeunload dialog was displayed.
danakjc492bf82020-09-09 20:02:44187 void BeforeUnloadCompleted(FrameTreeNode* frame_tree_node,
188 bool proceed,
Charlie Reis9e20dd12025-01-02 20:11:53189 const base::TimeTicks& proceed_time,
190 bool for_legacy,
191 bool showed_dialog);
danakjc492bf82020-09-09 20:02:44192
193 // Used to start a new renderer-initiated navigation, following a
194 // BeginNavigation IPC from the renderer.
195 void OnBeginNavigation(
196 FrameTreeNode* frame_tree_node,
Minggang Wangb9f3fa92021-07-01 15:30:31197 blink::mojom::CommonNavigationParamsPtr common_params,
198 blink::mojom::BeginNavigationParamsPtr begin_params,
danakjc492bf82020-09-09 20:02:44199 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
200 mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client,
danakjc492bf82020-09-09 20:02:44201 scoped_refptr<PrefetchedSignedExchangeCache>
202 prefetched_signed_exchange_cache,
Hiroshige Hayashizaki5466bfe82023-05-17 00:34:33203 int initiator_process_id,
Rakina Zata Amniaf55b5b62022-07-19 23:11:03204 mojo::PendingReceiver<mojom::NavigationRendererCancellationListener>
205 renderer_cancellation_listener);
danakjc492bf82020-09-09 20:02:44206
207 // Used to restart a navigation that was thought to be same-document in
208 // cross-document mode.
209 void RestartNavigationAsCrossDocument(
210 std::unique_ptr<NavigationRequest> navigation_request);
211
Rakina Zata Amnif8f2bb62022-11-23 05:54:32212 // Cancels the NavigationRequest owned by |frame_tree_node|. Note that this
213 // will only cancel NavigationRequests that haven't reached the "pending
214 // commit" stage yet, as after that the NavigationRequests will no longer be
215 // owned by the FrameTreeNode.
Daniel Cheng390e2a72022-09-28 06:07:53216 void CancelNavigation(FrameTreeNode* frame_tree_node,
217 NavigationDiscardReason reason);
danakjc492bf82020-09-09 20:02:44218
danakjc492bf82020-09-09 20:02:44219 // Called to record the time it took to execute the beforeunload hook for the
Scott Violetb1dd54592021-11-17 03:28:51220 // current navigation. See RenderFrameHostImpl::SendBeforeUnload() for details
221 // on `for_legacy`.
danakjc492bf82020-09-09 20:02:44222 void LogBeforeUnloadTime(base::TimeTicks renderer_before_unload_start_time,
223 base::TimeTicks renderer_before_unload_end_time,
Scott Violetb1dd54592021-11-17 03:28:51224 base::TimeTicks before_unload_sent_time,
225 bool for_legacy);
danakjc492bf82020-09-09 20:02:44226
Katie Dillone893d00f2021-01-22 23:06:43227 // Called to record the time that the RenderFrameHost told the renderer to
228 // commit the current navigation.
229 void LogCommitNavigationSent();
230
Carlos Caballero04aab362021-02-15 17:38:16231 // Returns the NavigationController associated with this Navigator.
Carlos Caballero40b0efd2021-01-26 11:55:00232 NavigationControllerImpl& controller() { return controller_; }
Elad Alon32044f532025-03-04 22:16:03233 const NavigationControllerImpl& controller() const { return controller_; }
danakjc492bf82020-09-09 20:02:44234
Liam Bradyedb866e2025-01-22 22:28:13235 void SetWillNavigateFromFrameProxyCallbackForTesting(
236 const base::RepeatingClosure& callback);
237
danakjc492bf82020-09-09 20:02:44238 private:
239 friend class NavigatorTestWithBrowserSideNavigation;
240
241 // Holds data used to track browser side navigation metrics.
242 struct NavigationMetricsData;
243
244 void RecordNavigationMetrics(
245 const LoadCommittedDetails& details,
arthursonzogni73fe3212020-11-17 13:24:07246 const mojom::DidCommitProvisionalLoadParams& params,
Rakina Zata Amni6345d2f2021-02-12 04:07:57247 SiteInstance* site_instance,
248 const GURL& original_request_url);
danakjc492bf82020-09-09 20:02:44249
250 // Called when a renderer initiated navigation has started. Returns the
251 // pending NavigationEntry to be used. Either null or a new one owned
252 // NavigationController.
253 NavigationEntryImpl* GetNavigationEntryForRendererInitiatedNavigation(
Minggang Wangb9f3fa92021-07-01 15:30:31254 const blink::mojom::CommonNavigationParams& common_params,
Charlie Reisf39757b2023-01-09 17:41:56255 FrameTreeNode* frame_tree_node,
256 bool override_user_agent);
danakjc492bf82020-09-09 20:02:44257
258 // Called to record the time it took to execute beforeunload handlers for
259 // renderer-inititated navigations. It records the time it took to execute
260 // beforeunload handlers in the renderer process before sending the
261 // BeginNavigation IPC.
262 void LogRendererInitiatedBeforeUnloadTime(
263 base::TimeTicks renderer_before_unload_start_time,
264 base::TimeTicks renderer_before_unload_end_time);
265
266 // The NavigationController that will keep track of session history for all
267 // RenderFrameHost objects using this Navigator.
Carlos Caballero40b0efd2021-01-26 11:55:00268 NavigationControllerImpl controller_;
danakjc492bf82020-09-09 20:02:44269
270 // Used to notify the object embedding this Navigator about navigation
271 // events. Can be nullptr in tests.
Keishi Hattori0e45c022021-11-27 09:25:52272 raw_ptr<NavigatorDelegate> delegate_;
danakjc492bf82020-09-09 20:02:44273
Charlie Reis76bf805d2023-01-04 20:06:40274 // Tracks metrics for each navigation.
275 std::unique_ptr<Navigator::NavigationMetricsData> metrics_data_;
Liam Bradyedb866e2025-01-22 22:28:13276
277 // Called every time NavigateFromFrameProxy() is called.
278 base::RepeatingClosure will_navigate_from_frame_proxy_callback_for_testing_;
danakjc492bf82020-09-09 20:02:44279};
280
281} // namespace content
282
283#endif // CONTENT_BROWSER_RENDERER_HOST_NAVIGATOR_H_