File: document_associated_data.cc

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (133 lines) | stat: -rw-r--r-- 4,891 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/document_associated_data.h"

#include <utility>

#include "base/check.h"
#include "base/check_op.h"
#include "base/containers/map_util.h"
#include "base/containers/queue.h"
#include "base/functional/callback_forward.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "content/browser/navigation_or_document_handle.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/page_factory.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/document_service.h"
#include "content/public/browser/document_service_internal.h"
#include "content/public/browser/render_frame_host.h"
#include "net/cookies/cookie_setting_override.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
#include "third_party/blink/public/common/tokens/tokens.h"

namespace content {

namespace {
auto& GetDocumentTokenMap() {
  static base::NoDestructor<
      absl::flat_hash_map<blink::DocumentToken, RenderFrameHostImpl*>>
      map;
  return *map;
}
}  // namespace

RenderFrameHostImpl* DocumentAssociatedData::GetDocumentFromToken(
    base::PassKey<RenderFrameHostImpl>,
    const blink::DocumentToken& token) {
  return base::FindPtrOrNull(GetDocumentTokenMap(), token);
}

DocumentAssociatedData::DocumentAssociatedData(
    RenderFrameHostImpl& document,
    const blink::DocumentToken& token)
    : token_(token), weak_factory_(&document) {
  auto [_, inserted] = GetDocumentTokenMap().insert({token_, &document});
  CHECK(inserted);

  // Only create page object for the main document as the PageImpl is 1:1 with
  // main document.
  if (!document.GetParent()) {
    PageDelegate* page_delegate = document.frame_tree()->page_delegate();
    DCHECK(page_delegate);
    owned_page_ = PageFactory::Create(document, *page_delegate);
  }
}

DocumentAssociatedData::~DocumentAssociatedData() {
  TRACE_EVENT0("navigation", "DocumentAssociatedData::~DocumentAssociatedData");
  base::ScopedUmaHistogramTimer histogram_timer(
      "Navigation.DocumentAssociatedDataDestructor");
  decltype(services_) services;
  std::swap(services_, services);
  for (auto& service : services) {
    service->WillBeDestroyed(
        DocumentServiceDestructionReason::kEndOfDocumentLifetime);
    service->ResetAndDeleteThisInternal({});
  }

  // Explicitly clear all user data here, so that the other fields of
  // DocumentAssociatedData are still valid while user data is being destroyed.
  ClearAllUserData();

  // Explicitly clear all PageUserData here before destruction of |owned_page_|
  // (A std::unique_ptr's stored pointer value is (intentionally) undefined
  // during destruction (e.g. it could be nullptr)), so that |owned_page_| and
  // the other fields of DocumentAssociatedData are still valid and accessible
  // from RenderFrameHost interface while its page user data is being destroyed.
  if (owned_page_) {
    owned_page_->ClearAllUserData();
  }

  // Last in case any DocumentService / DocumentUserData service destructors try
  // to look up RenderFrameHosts by DocumentToken.
  CHECK_EQ(1u, GetDocumentTokenMap().erase(token_));
}

void DocumentAssociatedData::set_navigation_or_document_handle(
    scoped_refptr<NavigationOrDocumentHandle> handle) {
  navigation_or_document_handle_ = std::move(handle);
}

void DocumentAssociatedData::AddService(
    internal::DocumentServiceBase* service,
    base::PassKey<internal::DocumentServiceBase>) {
  services_.push_back(service);
}

void DocumentAssociatedData::RemoveService(
    internal::DocumentServiceBase* service,
    base::PassKey<internal::DocumentServiceBase>) {
  std::erase(services_, service);
}

void DocumentAssociatedData::AddPostPrerenderingActivationStep(
    base::OnceClosure callback) {
  CHECK_EQ(GetSafeRef()->GetLifecycleState(),
           RenderFrameHost::LifecycleState::kPrerendering);
  post_prerendering_activation_callbacks_.push(std::move(callback));
}

void DocumentAssociatedData::RunPostPrerenderingActivationSteps() {
  CHECK_NE(GetSafeRef()->GetLifecycleState(),
           RenderFrameHost::LifecycleState::kPrerendering);
  while (!post_prerendering_activation_callbacks_.empty()) {
    std::move(post_prerendering_activation_callbacks_.front()).Run();
    post_prerendering_activation_callbacks_.pop();
  }
}

void DocumentAssociatedData::PutCookieSettingOverride(
    net::CookieSettingOverride cookie_setting_override) {
  cookie_setting_overrides_.Put(cookie_setting_override);
}

void DocumentAssociatedData::RemoveCookieSettingOverride(
    net::CookieSettingOverride cookie_setting_override) {
  cookie_setting_overrides_.Remove(cookie_setting_override);
}

}  // namespace content