File: first_party_sets_navigation_throttle.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; 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,755 bytes parent folder | download | duplicates (5)
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 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h"

#include <memory>
#include <utility>

#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/first_party_sets/first_party_sets_policy_service.h"
#include "chrome/browser/first_party_sets/first_party_sets_policy_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "net/base/features.h"

namespace first_party_sets {

namespace {

using ThrottleCheckResult = content::NavigationThrottle::ThrottleCheckResult;

void RecordResumeOnTimeout(bool is_timeout) {
  base::UmaHistogramBoolean("FirstPartySets.NavigationThrottle.ResumeOnTimeout",
                            is_timeout);
}

}  // namespace

FirstPartySetsNavigationThrottle::FirstPartySetsNavigationThrottle(
    content::NavigationThrottleRegistry& registry,
    FirstPartySetsPolicyService& service)
    : content::NavigationThrottle(registry), service_(service) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

FirstPartySetsNavigationThrottle::~FirstPartySetsNavigationThrottle() = default;

ThrottleCheckResult FirstPartySetsNavigationThrottle::WillStartRequest() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (service_->is_enabled() && !service_->is_ready()) {
    service_->RegisterThrottleResumeCallback(
        base::BindOnce(&FirstPartySetsNavigationThrottle::OnReadyToResume,
                       weak_factory_.GetWeakPtr()));
    // Setup timer
    resume_navigation_timer_.Start(
        FROM_HERE,
        net::features::kWaitForFirstPartySetsInitNavigationThrottleTimeout
            .Get(),
        base::BindOnce(&FirstPartySetsNavigationThrottle::OnTimeOut,
                       weak_factory_.GetWeakPtr()));

    CHECK(!throttle_navigation_timer_.has_value());
    throttle_navigation_timer_ = {base::ElapsedTimer()};

    return content::NavigationThrottle::DEFER;
  }
  return content::NavigationThrottle::PROCEED;
}

const char* FirstPartySetsNavigationThrottle::GetNameForLogging() {
  return "FirstPartySetsNavigationThrottle";
}

// static
void FirstPartySetsNavigationThrottle::MaybeCreateAndAdd(
    content::NavigationThrottleRegistry& registry) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  content::NavigationHandle& navigation_handle = registry.GetNavigationHandle();
  Profile* profile = Profile::FromBrowserContext(
      navigation_handle.GetWebContents()->GetBrowserContext());
  // The `service` might be null for some irregular profiles.
  // TODO(crbug.com/40233408): regular profiles and guest sessions
  // aren't mutually exclusive on ChromeOS.
  if (!profile->IsRegularProfile() || profile->IsGuestSession()) {
    return;
  }

  FirstPartySetsPolicyService* service =
      FirstPartySetsPolicyServiceFactory::GetForBrowserContext(profile);
  CHECK(service);
  if (service->is_ready() ||
      !base::FeatureList::IsEnabled(
          net::features::kWaitForFirstPartySetsInit) ||
      net::features::kWaitForFirstPartySetsInitNavigationThrottleTimeout.Get()
          .is_zero() ||
      navigation_handle.GetParentFrameOrOuterDocument()) {
    return;
  }
  registry.AddThrottle(
      std::make_unique<FirstPartySetsNavigationThrottle>(registry, *service));
}

void FirstPartySetsNavigationThrottle::OnTimeOut() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(!resume_navigation_timer_.IsRunning());
  RecordResumeOnTimeout(true);
  Resume();
}

void FirstPartySetsNavigationThrottle::OnReadyToResume() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // If the timer is not running, that means the timeout has occurred and the
  // navigation has been resumed by `OnTimeOut`, so we don't need to resume
  // again.
  if (!resume_navigation_timer_.IsRunning()) {
    CHECK(resumed_);
    return;
  }
  // Stop the timer to make sure we won't try to resume again due to hitting
  // the timeout.
  resume_navigation_timer_.Stop();
  RecordResumeOnTimeout(false);
  Resume();
}

void FirstPartySetsNavigationThrottle::Resume() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(!resumed_);
  resumed_ = true;

  CHECK(throttle_navigation_timer_.has_value());
  base::UmaHistogramTimes("FirstPartySets.NavigationThrottle.ResumeDelta",
                          throttle_navigation_timer_->Elapsed());
  NavigationThrottle::Resume();
}

}  // namespace first_party_sets