blob: 23fd3069d650a0a20ed6b1a9592e33c5babfe611 [file] [log] [blame]
Daniel Cheng69e45da2023-11-13 02:03:051// 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#include "content/browser/renderer_host/document_associated_data.h"
6
Daniel Chengf549b262024-09-06 01:29:247#include <utility>
8
Daniel Cheng69e45da2023-11-13 02:03:059#include "base/check.h"
Nan Lin389716b2025-02-28 22:59:2310#include "base/check_op.h"
Daniel Cheng69e45da2023-11-13 02:03:0511#include "base/containers/map_util.h"
Nan Lin389716b2025-02-28 22:59:2312#include "base/containers/queue.h"
13#include "base/functional/callback_forward.h"
David Sandersf583e502025-02-03 01:55:0014#include "base/metrics/histogram_functions.h"
Daniel Cheng69e45da2023-11-13 02:03:0515#include "base/no_destructor.h"
16#include "content/browser/navigation_or_document_handle.h"
17#include "content/browser/renderer_host/frame_tree.h"
18#include "content/browser/renderer_host/page_factory.h"
19#include "content/browser/renderer_host/render_frame_host_impl.h"
20#include "content/public/browser/document_service.h"
21#include "content/public/browser/document_service_internal.h"
Nan Lin389716b2025-02-28 22:59:2322#include "content/public/browser/render_frame_host.h"
Chris Fredrickson2b6b8c02025-05-09 16:15:3523#include "net/cookies/cookie_setting_override.h"
Daniel Cheng0d143e52025-04-03 19:43:1624#include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
Daniel Cheng69e45da2023-11-13 02:03:0525#include "third_party/blink/public/common/tokens/tokens.h"
26
27namespace content {
28
29namespace {
30auto& GetDocumentTokenMap() {
Daniel Cheng0d143e52025-04-03 19:43:1631 static base::NoDestructor<
32 absl::flat_hash_map<blink::DocumentToken, RenderFrameHostImpl*>>
Daniel Cheng69e45da2023-11-13 02:03:0533 map;
34 return *map;
35}
36} // namespace
37
38RenderFrameHostImpl* DocumentAssociatedData::GetDocumentFromToken(
39 base::PassKey<RenderFrameHostImpl>,
40 const blink::DocumentToken& token) {
41 return base::FindPtrOrNull(GetDocumentTokenMap(), token);
42}
43
44DocumentAssociatedData::DocumentAssociatedData(
45 RenderFrameHostImpl& document,
46 const blink::DocumentToken& token)
47 : token_(token), weak_factory_(&document) {
48 auto [_, inserted] = GetDocumentTokenMap().insert({token_, &document});
49 CHECK(inserted);
50
51 // Only create page object for the main document as the PageImpl is 1:1 with
52 // main document.
53 if (!document.GetParent()) {
54 PageDelegate* page_delegate = document.frame_tree()->page_delegate();
55 DCHECK(page_delegate);
56 owned_page_ = PageFactory::Create(document, *page_delegate);
57 }
58}
59
Daniel Cheng69e45da2023-11-13 02:03:0560DocumentAssociatedData::~DocumentAssociatedData() {
Rakina Zata Amni50805f22024-09-11 06:23:5061 TRACE_EVENT0("navigation", "DocumentAssociatedData::~DocumentAssociatedData");
62 base::ScopedUmaHistogramTimer histogram_timer(
63 "Navigation.DocumentAssociatedDataDestructor");
Daniel Chengf549b262024-09-06 01:29:2464 decltype(services_) services;
65 std::swap(services_, services);
66 for (auto& service : services) {
67 service->WillBeDestroyed(
68 DocumentServiceDestructionReason::kEndOfDocumentLifetime);
69 service->ResetAndDeleteThisInternal({});
70 }
Daniel Cheng69e45da2023-11-13 02:03:0571
72 // Explicitly clear all user data here, so that the other fields of
73 // DocumentAssociatedData are still valid while user data is being destroyed.
74 ClearAllUserData();
75
Alex Kalugincc9dc3c2024-03-07 06:54:3276 // Explicitly clear all PageUserData here before destruction of |owned_page_|
77 // (A std::unique_ptr's stored pointer value is (intentionally) undefined
78 // during destruction (e.g. it could be nullptr)), so that |owned_page_| and
79 // the other fields of DocumentAssociatedData are still valid and accessible
80 // from RenderFrameHost interface while its page user data is being destroyed.
81 if (owned_page_) {
82 owned_page_->ClearAllUserData();
83 }
84
Daniel Cheng69e45da2023-11-13 02:03:0585 // Last in case any DocumentService / DocumentUserData service destructors try
86 // to look up RenderFrameHosts by DocumentToken.
87 CHECK_EQ(1u, GetDocumentTokenMap().erase(token_));
88}
89
90void DocumentAssociatedData::set_navigation_or_document_handle(
91 scoped_refptr<NavigationOrDocumentHandle> handle) {
92 navigation_or_document_handle_ = std::move(handle);
93}
94
Daniel Chengf549b262024-09-06 01:29:2495void DocumentAssociatedData::AddService(
96 internal::DocumentServiceBase* service,
97 base::PassKey<internal::DocumentServiceBase>) {
98 services_.push_back(service);
99}
100
101void DocumentAssociatedData::RemoveService(
102 internal::DocumentServiceBase* service,
103 base::PassKey<internal::DocumentServiceBase>) {
104 std::erase(services_, service);
105}
106
Nan Lin389716b2025-02-28 22:59:23107void DocumentAssociatedData::AddPostPrerenderingActivationStep(
108 base::OnceClosure callback) {
109 CHECK_EQ(GetSafeRef()->GetLifecycleState(),
110 RenderFrameHost::LifecycleState::kPrerendering);
111 post_prerendering_activation_callbacks_.push(std::move(callback));
112}
113
114void DocumentAssociatedData::RunPostPrerenderingActivationSteps() {
115 CHECK_NE(GetSafeRef()->GetLifecycleState(),
116 RenderFrameHost::LifecycleState::kPrerendering);
117 while (!post_prerendering_activation_callbacks_.empty()) {
118 std::move(post_prerendering_activation_callbacks_.front()).Run();
119 post_prerendering_activation_callbacks_.pop();
Nan Linc643c962025-02-21 01:47:43120 }
121}
122
Chris Fredrickson2b6b8c02025-05-09 16:15:35123void DocumentAssociatedData::PutCookieSettingOverride(
124 net::CookieSettingOverride cookie_setting_override) {
125 cookie_setting_overrides_.Put(cookie_setting_override);
126}
127
128void DocumentAssociatedData::RemoveCookieSettingOverride(
129 net::CookieSettingOverride cookie_setting_override) {
130 cookie_setting_overrides_.Remove(cookie_setting_override);
131}
132
Daniel Cheng69e45da2023-11-13 02:03:05133} // namespace content