Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 1 | // Copyright 2023 The Chromium Authors |
| 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_DOCUMENT_ASSOCIATED_DATA_H_ |
| 6 | #define CONTENT_BROWSER_RENDERER_HOST_DOCUMENT_ASSOCIATED_DATA_H_ |
| 7 | |
| 8 | #include <memory> |
| 9 | #include <optional> |
| 10 | #include <vector> |
| 11 | |
Nan Lin | 389716b | 2025-02-28 22:59:23 | [diff] [blame] | 12 | #include "base/containers/queue.h" |
| 13 | #include "base/functional/callback_forward.h" |
Ali Hijazi | e63cbaf6 | 2023-12-20 19:29:35 | [diff] [blame] | 14 | #include "base/memory/raw_ptr.h" |
Daniel Cheng | f549b26 | 2024-09-06 01:29:24 | [diff] [blame] | 15 | #include "base/memory/safe_ref.h" |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 16 | #include "base/memory/scoped_refptr.h" |
| 17 | #include "base/memory/weak_ptr.h" |
| 18 | #include "base/supports_user_data.h" |
| 19 | #include "base/types/pass_key.h" |
| 20 | #include "base/unguessable_token.h" |
Ming-Ying Chung | ae4dbb7 | 2023-12-07 05:32:37 | [diff] [blame] | 21 | #include "content/browser/loader/keep_alive_url_loader_service.h" |
Chris Fredrickson | 2b6b8c0 | 2025-05-09 16:15:35 | [diff] [blame] | 22 | #include "net/cookies/cookie_setting_override.h" |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 23 | #include "third_party/blink/public/common/tokens/tokens.h" |
Mike Jackson | 82654a3a | 2025-02-13 07:48:22 | [diff] [blame] | 24 | #include "third_party/blink/public/mojom/confidence_level.mojom.h" |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 25 | #include "url/gurl.h" |
| 26 | |
| 27 | namespace content { |
| 28 | |
| 29 | namespace internal { |
| 30 | class DocumentServiceBase; |
| 31 | } |
| 32 | |
| 33 | class NavigationOrDocumentHandle; |
| 34 | class PageImpl; |
| 35 | class RenderFrameHostImpl; |
| 36 | |
| 37 | // Container for arbitrary document-associated feature-specific data. Should |
| 38 | // be reset when committing a cross-document navigation in this |
| 39 | // RenderFrameHost. RenderFrameHostImpl stores internal members here |
| 40 | // directly while consumers of RenderFrameHostImpl should store data via |
| 41 | // GetDocumentUserData(). Please refer to the description at |
| 42 | // content/public/browser/document_user_data.h for more details. |
| 43 | class DocumentAssociatedData : public base::SupportsUserData { |
| 44 | public: |
| 45 | // Helper for looking up a RenderFrameHostImpl based on the DocumentToken. |
| 46 | // Restricted to RenderFrameHostImpl, which performs additional security |
| 47 | // checks. |
| 48 | static RenderFrameHostImpl* GetDocumentFromToken( |
| 49 | base::PassKey<RenderFrameHostImpl>, |
| 50 | const blink::DocumentToken& token); |
| 51 | |
| 52 | explicit DocumentAssociatedData(RenderFrameHostImpl& document, |
| 53 | const blink::DocumentToken& token); |
| 54 | ~DocumentAssociatedData() override; |
| 55 | DocumentAssociatedData(const DocumentAssociatedData&) = delete; |
| 56 | DocumentAssociatedData& operator=(const DocumentAssociatedData&) = delete; |
| 57 | |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 58 | // An opaque token that uniquely identifies the document currently |
| 59 | // associated with this RenderFrameHost. Note that in the case of |
| 60 | // speculative RenderFrameHost that has not yet committed, the renderer side |
| 61 | // will not have a document with a matching token! |
| 62 | const blink::DocumentToken& token() const { return token_; } |
| 63 | |
| 64 | // The Page object associated with the main document. It is nullptr for |
| 65 | // subframes. |
| 66 | PageImpl* owned_page() { return owned_page_.get(); } |
| 67 | |
| 68 | const PageImpl* owned_page() const { return owned_page_.get(); } |
| 69 | |
| 70 | // Indicates whether `blink::mojom::DidDispatchDOMContentLoadedEvent` was |
| 71 | // called for this document or not. |
| 72 | bool dom_content_loaded() const { return dom_content_loaded_; } |
| 73 | void MarkDomContentLoaded() { dom_content_loaded_ = true; } |
| 74 | |
Thomas Lukaszewicz | 689b637 | 2024-09-12 03:11:15 | [diff] [blame] | 75 | // Indicates whether a discard request has been dispatched for the current |
| 76 | // document. |
| 77 | bool is_discarded() const { return is_discarded_; } |
| 78 | void MarkDiscarded() { is_discarded_ = true; } |
| 79 | |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 80 | // Prerender2: |
| 81 | // |
| 82 | // The URL that `blink.mojom.LocalFrameHost::DidFinishLoad()` passed to |
| 83 | // DidFinishLoad, nullopt if DidFinishLoad wasn't called for this document |
| 84 | // or this document is not in prerendering. This is used to defer and |
| 85 | // dispatch DidFinishLoad notification on prerender activation. |
| 86 | const std::optional<GURL>& pending_did_finish_load_url_for_prerendering() |
| 87 | const { |
| 88 | return pending_did_finish_load_url_for_prerendering_; |
| 89 | } |
| 90 | void set_pending_did_finish_load_url_for_prerendering(const GURL& url) { |
| 91 | pending_did_finish_load_url_for_prerendering_.emplace(url); |
| 92 | } |
| 93 | void reset_pending_did_finish_load_url_for_prerendering() { |
| 94 | pending_did_finish_load_url_for_prerendering_.reset(); |
| 95 | } |
| 96 | |
Hiroki Nakagawa | 8b0fc985 | 2024-11-05 06:00:54 | [diff] [blame] | 97 | // Indicates whether `RenderFrameHostImpl::DidStopLoading` was called for this |
| 98 | // document while it's prerendering. This is used to defer and dispatch |
| 99 | // `WebContentsObserver::DidStopLoading` notification on prerender activation. |
| 100 | bool pending_did_stop_loading_for_prerendering() const { |
| 101 | return pending_did_stop_loading_for_prerendering_; |
| 102 | } |
| 103 | void set_pending_did_stop_loading_for_prerendering() { |
| 104 | pending_did_stop_loading_for_prerendering_ = true; |
| 105 | } |
| 106 | |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 107 | // Reporting API: |
| 108 | // |
| 109 | // Contains the reporting source token for this document, which will be |
| 110 | // associated with the reporting endpoint configuration in the network |
| 111 | // service, as well as with any reports which are queued by this document. |
| 112 | const base::UnguessableToken& reporting_source() const { |
| 113 | return token_.value(); |
| 114 | } |
| 115 | |
| 116 | // "Owned" but not with std::unique_ptr, as a DocumentServiceBase is |
| 117 | // allowed to delete itself directly. |
Ali Hijazi | e63cbaf6 | 2023-12-20 19:29:35 | [diff] [blame] | 118 | std::vector<raw_ptr<internal::DocumentServiceBase, VectorExperimental>>& |
| 119 | services() { |
| 120 | return services_; |
| 121 | } |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 122 | |
| 123 | // This handle supports a seamless transfer from a navigation to a committed |
| 124 | // document. |
| 125 | const scoped_refptr<NavigationOrDocumentHandle>& |
| 126 | navigation_or_document_handle() const { |
| 127 | return navigation_or_document_handle_; |
| 128 | } |
| 129 | void set_navigation_or_document_handle( |
| 130 | scoped_refptr<NavigationOrDocumentHandle> handle); |
| 131 | |
| 132 | // See comments for |RenderFrameHostImpl::GetDevToolsNavigationToken()| for |
| 133 | // more details. |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 134 | const std::optional<base::UnguessableToken>& devtools_navigation_token() |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 135 | const { |
| 136 | return devtools_navigation_token_; |
| 137 | } |
| 138 | |
| 139 | void set_devtools_navigation_token( |
| 140 | const base::UnguessableToken& devtools_navigation_token) { |
| 141 | devtools_navigation_token_ = devtools_navigation_token; |
| 142 | } |
| 143 | |
Mike Jackson | 82654a3a | 2025-02-13 07:48:22 | [diff] [blame] | 144 | blink::mojom::ConfidenceLevel navigation_confidence() const { |
| 145 | return confidence_level_; |
| 146 | } |
| 147 | void set_navigation_confidence( |
| 148 | blink::mojom::ConfidenceLevel confidence_level) { |
| 149 | confidence_level_ = confidence_level; |
| 150 | } |
| 151 | |
Ming-Ying Chung | ae4dbb7 | 2023-12-07 05:32:37 | [diff] [blame] | 152 | // fetch keepalive handing: |
| 153 | // |
| 154 | // Contains the weak pointer to the FactoryContext of the in-browser |
| 155 | // URLLoaderFactory implementation used by this document. |
| 156 | base::WeakPtr<KeepAliveURLLoaderService::FactoryContext> |
| 157 | keep_alive_url_loader_factory_context() const { |
| 158 | return keep_alive_url_loader_factory_context_; |
| 159 | } |
| 160 | void set_keep_alive_url_loader_factory_context( |
| 161 | base::WeakPtr<KeepAliveURLLoaderService::FactoryContext> |
| 162 | factory_context) { |
| 163 | DCHECK(!keep_alive_url_loader_factory_context_); |
| 164 | keep_alive_url_loader_factory_context_ = factory_context; |
| 165 | } |
| 166 | |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 167 | // Produces weak pointers to the hosting RenderFrameHostImpl. This is |
| 168 | // invalidated whenever DocumentAssociatedData is destroyed, due to |
| 169 | // RenderFrameHost deletion or cross-document navigation. |
Daniel Cheng | f549b26 | 2024-09-06 01:29:24 | [diff] [blame] | 170 | base::SafeRef<RenderFrameHostImpl> GetSafeRef() { |
| 171 | return weak_factory_.GetSafeRef(); |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 172 | } |
| 173 | |
Daniel Cheng | f549b26 | 2024-09-06 01:29:24 | [diff] [blame] | 174 | base::WeakPtr<RenderFrameHostImpl> GetWeakPtr() { |
| 175 | return weak_factory_.GetWeakPtr(); |
| 176 | } |
| 177 | |
| 178 | void AddService(internal::DocumentServiceBase* service, |
| 179 | base::PassKey<internal::DocumentServiceBase>); |
| 180 | void RemoveService(internal::DocumentServiceBase* service, |
| 181 | base::PassKey<internal::DocumentServiceBase>); |
| 182 | |
Nan Lin | 389716b | 2025-02-28 22:59:23 | [diff] [blame] | 183 | // Add `callback` to the callback queue to be run after prerendered page |
| 184 | // activation. |
| 185 | void AddPostPrerenderingActivationStep(base::OnceClosure callback); |
| 186 | |
| 187 | // Run callback queue for post-prerendering activation. |
| 188 | void RunPostPrerenderingActivationSteps(); |
Nan Lin | c643c96 | 2025-02-21 01:47:43 | [diff] [blame] | 189 | |
Chris Fredrickson | 2b6b8c0 | 2025-05-09 16:15:35 | [diff] [blame] | 190 | net::CookieSettingOverrides cookie_setting_overrides() const { |
| 191 | return cookie_setting_overrides_; |
| 192 | } |
| 193 | void PutCookieSettingOverride( |
| 194 | net::CookieSettingOverride cookie_setting_override); |
| 195 | void RemoveCookieSettingOverride( |
| 196 | net::CookieSettingOverride cookie_setting_override); |
| 197 | |
Dominic Farolino | 5be0bdc | 2025-08-12 18:28:24 | [diff] [blame] | 198 | std::map<std::string, std::string>& crash_storage_map() { |
| 199 | return crash_storage_map_; |
| 200 | } |
| 201 | |
| 202 | std::optional<uint64_t> crash_storage_requested_length() { |
| 203 | return crash_storage_requested_length_; |
| 204 | } |
| 205 | void set_crash_storage_requested_length(uint64_t length) { |
| 206 | crash_storage_requested_length_ = length; |
| 207 | } |
| 208 | |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 209 | private: |
| 210 | const blink::DocumentToken token_; |
| 211 | std::unique_ptr<PageImpl> owned_page_; |
| 212 | bool dom_content_loaded_ = false; |
Thomas Lukaszewicz | 689b637 | 2024-09-12 03:11:15 | [diff] [blame] | 213 | bool is_discarded_ = false; |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 214 | std::optional<GURL> pending_did_finish_load_url_for_prerendering_; |
Hiroki Nakagawa | 8b0fc985 | 2024-11-05 06:00:54 | [diff] [blame] | 215 | bool pending_did_stop_loading_for_prerendering_ = false; |
Ali Hijazi | e63cbaf6 | 2023-12-20 19:29:35 | [diff] [blame] | 216 | std::vector<raw_ptr<internal::DocumentServiceBase, VectorExperimental>> |
| 217 | services_; |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 218 | scoped_refptr<NavigationOrDocumentHandle> navigation_or_document_handle_; |
| 219 | std::optional<base::UnguessableToken> devtools_navigation_token_; |
Mike Jackson | 82654a3a | 2025-02-13 07:48:22 | [diff] [blame] | 220 | blink::mojom::ConfidenceLevel confidence_level_ = |
| 221 | blink::mojom::ConfidenceLevel::kHigh; |
Ming-Ying Chung | ae4dbb7 | 2023-12-07 05:32:37 | [diff] [blame] | 222 | base::WeakPtr<KeepAliveURLLoaderService::FactoryContext> |
| 223 | keep_alive_url_loader_factory_context_; |
Nan Lin | 389716b | 2025-02-28 22:59:23 | [diff] [blame] | 224 | // The callback queue for post-prerendering activation. |
| 225 | base::queue<base::OnceClosure> post_prerendering_activation_callbacks_; |
Chris Fredrickson | 2b6b8c0 | 2025-05-09 16:15:35 | [diff] [blame] | 226 | // The base set of overrides used by this document. This may be |
| 227 | // augmented/modified before being returned via |
| 228 | // `RenderFrameHostImpl::GetCookieSettingOverrides`. |
| 229 | net::CookieSettingOverrides cookie_setting_overrides_; |
Dominic Farolino | 5be0bdc | 2025-08-12 18:28:24 | [diff] [blame] | 230 | // This is written to by the `SetCrashReportStorageKey()` IPC, with data |
| 231 | // supplied by the renderer, and read from during |
| 232 | // `RenderFrameHostImpl::MaybeGenerateCrashReport()`, to supplement crash |
| 233 | // reports with this data. |
| 234 | std::map<std::string, std::string> crash_storage_map_; |
| 235 | // For now, this member is *only* used to track whether initialization has |
| 236 | // already occurred via this method. It will be more useful soon when it is |
| 237 | // used by `SetCrashReportStorageKey()` to actually enforce a cap on the |
| 238 | // number of bytes written to the backing crash report storage memory (for |
| 239 | // now, this is `crash_storage_map_`, but in the future it could be a shared |
| 240 | // memory region; see https://crrev.com/c/6788146 which is exploring this). |
| 241 | std::optional<uint64_t> crash_storage_requested_length_; |
Daniel Cheng | 69e45da | 2023-11-13 02:03:05 | [diff] [blame] | 242 | |
| 243 | base::WeakPtrFactory<RenderFrameHostImpl> weak_factory_; |
| 244 | }; |
| 245 | |
| 246 | } // namespace content |
| 247 | |
| 248 | #endif // CONTENT_BROWSER_RENDERER_HOST_DOCUMENT_ASSOCIATED_DATA_H_ |