blob: 60b8c49b626a04e3a5313866aa6a40cfffbca138 [file] [log] [blame]
danakjc492bf82020-09-09 20:02:441// Copyright 2013 The Chromium Authors. All rights reserved.
2// 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>
9
10#include "base/macros.h"
11#include "base/memory/ref_counted.h"
12#include "content/common/content_export.h"
13#include "content/common/navigation_client.mojom.h"
14#include "content/common/navigation_params.h"
15#include "content/common/navigation_params.mojom.h"
16#include "content/public/browser/navigation_controller.h"
17#include "content/public/common/impression.h"
18#include "mojo/public/cpp/bindings/pending_associated_remote.h"
19#include "mojo/public/cpp/bindings/pending_remote.h"
20#include "third_party/blink/public/common/loader/previews_state.h"
21#include "third_party/blink/public/common/navigation/triggering_event_info.h"
22#include "third_party/blink/public/mojom/frame/navigation_initiator.mojom.h"
23#include "ui/base/window_open_disposition.h"
24
25class GURL;
danakjc492bf82020-09-09 20:02:4426
27namespace base {
28class TimeTicks;
29}
30
31namespace network {
32class ResourceRequestBody;
33}
34
35namespace content {
36
37class FrameNavigationEntry;
38class FrameTreeNode;
39class NavigationControllerImpl;
40class NavigatorDelegate;
41class NavigationEntryImpl;
42class NavigationRequest;
43class PrefetchedSignedExchangeCache;
44class RenderFrameHostImpl;
45class WebBundleHandleTracker;
46struct LoadCommittedDetails;
W. James MacLean46cf26212020-10-01 16:43:3747struct UrlInfo;
danakjc492bf82020-09-09 20:02:4448
49// Navigator is responsible for performing navigations in nodes of the
50// FrameTree. Its lifetime is bound to the FrameTree.
51class CONTENT_EXPORT Navigator {
52 public:
53 Navigator(NavigationControllerImpl* navigation_controller,
54 NavigatorDelegate* delegate);
55 ~Navigator();
56
57 // This method verifies that a navigation to |url| doesn't commit into a WebUI
58 // process if it is not allowed to. Callers of this method should take one of
59 // two actions if the method returns false:
60 // * When called from browser process logic (e.g. NavigationRequest), this
61 // indicates issues with the navigation logic and the browser process must
62 // be terminated to avoid security issues.
63 // * If the codepath is processing an IPC message from a renderer process,
64 // then the renderer process is misbehaving and must be terminated.
65 // TODO(nasko): Remove the is_renderer_initiated_check parameter when callers
66 // of this method are migrated to use CHECK instead of DumpWithoutCrashing.
67 static WARN_UNUSED_RESULT bool CheckWebUIRendererDoesNotDisplayNormalURL(
68 RenderFrameHostImpl* render_frame_host,
W. James MacLean46cf26212020-10-01 16:43:3769 const UrlInfo& url_info,
danakjc492bf82020-09-09 20:02:4470 bool is_renderer_initiated_check);
71
72 static bool ShouldIgnoreIncomingRendererRequest(
73 const NavigationRequest* ongoing_navigation_request,
74 bool has_user_gesture);
75
76 // Returns the delegate of this Navigator.
77 NavigatorDelegate* GetDelegate();
78
79 // Returns the NavigationController associated with this Navigator.
80 NavigationController* GetController();
81
82 // Notifications coming from the RenderFrameHosts ----------------------------
83
84 // The RenderFrameHostImpl has failed to load the document.
85 void DidFailLoadWithError(RenderFrameHostImpl* render_frame_host,
86 const GURL& url,
87 int error_code);
88
89 // The RenderFrameHostImpl has committed a navigation. The Navigator is
90 // responsible for resetting |navigation_request| at the end of this method
91 // and should not attempt to keep it alive. Note: it is possible that
92 // |navigation_request| is not the NavigationRequest stored in the
93 // RenderFrameHost that just committed. This happens for example when a
94 // same-page navigation commits while another navigation is ongoing. The
95 // Navigator should use the NavigationRequest provided by this method and not
96 // attempt to access the RenderFrameHost's NavigationsRequests.
97 void DidNavigate(RenderFrameHostImpl* render_frame_host,
arthursonzogni73fe3212020-11-17 13:24:0798 const mojom::DidCommitProvisionalLoadParams& params,
danakjc492bf82020-09-09 20:02:4499 std::unique_ptr<NavigationRequest> navigation_request,
100 bool was_within_same_document);
101
102 // Called on a newly created subframe during a history navigation. The browser
103 // process looks up the corresponding FrameNavigationEntry for the new frame
104 // navigates it in the correct process. Returns false if the
105 // FrameNavigationEntry can't be found or the navigation fails.
106 bool StartHistoryNavigationInNewSubframe(
107 RenderFrameHostImpl* render_frame_host,
108 mojo::PendingAssociatedRemote<mojom::NavigationClient>*
109 navigation_client);
110
111 // Navigation requests -------------------------------------------------------
112
113 // Called by the NavigationController to cause the Navigator to navigate to
114 // |navigation_request|. The NavigationController should be called back with
115 // RendererDidNavigate on success or DiscardPendingEntry on failure. The
116 // callbacks should be called in a future iteration of the message loop.
117 void Navigate(std::unique_ptr<NavigationRequest> request,
118 ReloadType reload_type,
119 RestoreType restore_type);
120
121 // The RenderFrameHostImpl has received a request to open a URL with the
122 // specified |disposition|.
123 void RequestOpenURL(
124 RenderFrameHostImpl* render_frame_host,
125 const GURL& url,
126 const GlobalFrameRoutingId& initiator_routing_id,
127 const base::Optional<url::Origin>& initiator_origin,
128 const scoped_refptr<network::ResourceRequestBody>& post_body,
129 const std::string& extra_headers,
130 const Referrer& referrer,
131 WindowOpenDisposition disposition,
132 bool should_replace_current_entry,
133 bool user_gesture,
134 blink::TriggeringEventInfo triggering_event_info,
135 const std::string& href_translate,
136 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
137 const base::Optional<Impression>& impression);
138
139 // Called when a document requests a navigation in another document through a
140 // RenderFrameProxy. If |method| is "POST", then |post_body| needs to specify
141 // the request body, otherwise |post_body| should be null.
142 void NavigateFromFrameProxy(
143 RenderFrameHostImpl* render_frame_host,
144 const GURL& url,
145 const GlobalFrameRoutingId& initiator_routing_id,
146 const url::Origin& initiator_origin,
147 SiteInstance* source_site_instance,
148 const Referrer& referrer,
149 ui::PageTransition page_transition,
150 bool should_replace_current_entry,
151 NavigationDownloadPolicy download_policy,
152 const std::string& method,
153 scoped_refptr<network::ResourceRequestBody> post_body,
154 const std::string& extra_headers,
155 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
156 bool has_user_gesture,
157 const base::Optional<Impression>& impression);
158
159 // Called after BeforeUnloadCompleted callback is invoked from the renderer.
160 // If |frame_tree_node| has a NavigationRequest waiting for the renderer
161 // response, then the request is either started or canceled, depending on the
162 // value of |proceed|.
163 void BeforeUnloadCompleted(FrameTreeNode* frame_tree_node,
164 bool proceed,
165 const base::TimeTicks& proceed_time);
166
167 // Used to start a new renderer-initiated navigation, following a
168 // BeginNavigation IPC from the renderer.
169 void OnBeginNavigation(
170 FrameTreeNode* frame_tree_node,
171 mojom::CommonNavigationParamsPtr common_params,
172 mojom::BeginNavigationParamsPtr begin_params,
173 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
174 mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client,
175 mojo::PendingRemote<blink::mojom::NavigationInitiator>
176 navigation_initiator,
177 scoped_refptr<PrefetchedSignedExchangeCache>
178 prefetched_signed_exchange_cache,
179 std::unique_ptr<WebBundleHandleTracker> web_bundle_handle_tracker);
180
181 // Used to restart a navigation that was thought to be same-document in
182 // cross-document mode.
183 void RestartNavigationAsCrossDocument(
184 std::unique_ptr<NavigationRequest> navigation_request);
185
186 // Cancel a NavigationRequest for |frame_tree_node|.
187 void CancelNavigation(FrameTreeNode* frame_tree_node);
188
189 // Called when the network stack started handling the navigation request
190 // so that the |timestamp| when it happened can be recorded into an histogram.
191 // The |url| is used to verify we're tracking the correct navigation.
192 // TODO(carlosk): Remove the URL parameter and rename this method to better
193 // suit naming conventions.
194 void LogResourceRequestTime(base::TimeTicks timestamp, const GURL& url);
195
196 // Called to record the time it took to execute the beforeunload hook for the
197 // current navigation.
198 void LogBeforeUnloadTime(base::TimeTicks renderer_before_unload_start_time,
199 base::TimeTicks renderer_before_unload_end_time,
200 base::TimeTicks before_unload_sent_time);
201
202 NavigationControllerImpl* controller() { return controller_; }
203
204 private:
205 friend class NavigatorTestWithBrowserSideNavigation;
206
207 // Holds data used to track browser side navigation metrics.
208 struct NavigationMetricsData;
209
210 void RecordNavigationMetrics(
211 const LoadCommittedDetails& details,
arthursonzogni73fe3212020-11-17 13:24:07212 const mojom::DidCommitProvisionalLoadParams& params,
danakjc492bf82020-09-09 20:02:44213 SiteInstance* site_instance);
214
215 // Called when a renderer initiated navigation has started. Returns the
216 // pending NavigationEntry to be used. Either null or a new one owned
217 // NavigationController.
218 NavigationEntryImpl* GetNavigationEntryForRendererInitiatedNavigation(
219 const mojom::CommonNavigationParams& common_params,
220 FrameTreeNode* frame_tree_node);
221
222 // Called to record the time it took to execute beforeunload handlers for
223 // renderer-inititated navigations. It records the time it took to execute
224 // beforeunload handlers in the renderer process before sending the
225 // BeginNavigation IPC.
226 void LogRendererInitiatedBeforeUnloadTime(
227 base::TimeTicks renderer_before_unload_start_time,
228 base::TimeTicks renderer_before_unload_end_time);
229
230 // The NavigationController that will keep track of session history for all
231 // RenderFrameHost objects using this Navigator.
232 // TODO(nasko): Move ownership of the NavigationController from
233 // WebContentsImpl to this class.
234 NavigationControllerImpl* controller_;
235
236 // Used to notify the object embedding this Navigator about navigation
237 // events. Can be nullptr in tests.
238 NavigatorDelegate* delegate_;
239
240 std::unique_ptr<Navigator::NavigationMetricsData> navigation_data_;
241
242 DISALLOW_COPY_AND_ASSIGN(Navigator);
243};
244
245} // namespace content
246
247#endif // CONTENT_BROWSER_RENDERER_HOST_NAVIGATOR_H_