blob: 9bf71ba4e9c98eea090beddc38060082b87dddb9 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2022 The Chromium Authors
Sreeja Kamishetty530e8c22022-06-11 02:20:162// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Sreeja Kamishetty8ef652b2022-06-22 22:43:175#ifndef CONTENT_BROWSER_PRELOADING_PRELOADING_ATTEMPT_IMPL_H_
6#define CONTENT_BROWSER_PRELOADING_PRELOADING_ATTEMPT_IMPL_H_
Sreeja Kamishetty530e8c22022-06-11 02:20:167
Arthur Sonzognic686e8f2024-01-11 08:36:378#include <optional>
Kevin McNee98e068a2024-04-09 20:12:349#include <vector>
Arthur Sonzognic686e8f2024-01-11 08:36:3710
William Liu60e005f2023-01-18 16:17:2211#include "base/timer/elapsed_timer.h"
Simon Pelchatd32e4082022-06-17 15:34:0812#include "content/public/browser/preloading.h"
Sreeja Kamishetty530e8c22022-06-11 02:20:1613#include "content/public/browser/preloading_data.h"
Sreeja Kamishetty530e8c22022-06-11 02:20:1614#include "services/metrics/public/cpp/ukm_source_id.h"
Adithya Srinivasan38e0c402023-07-19 16:12:5815#include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom-shared.h"
Sreeja Kamishetty530e8c22022-06-11 02:20:1616#include "url/gurl.h"
17
18namespace content {
19
Sreeja Kamishetty26e40d22022-10-17 17:54:3520namespace test {
21class PreloadingAttemptAccessor;
22}
23
Sreeja Kamishetty530e8c22022-06-11 02:20:1624class CONTENT_EXPORT PreloadingAttemptImpl : public PreloadingAttempt {
25 public:
26 ~PreloadingAttemptImpl() override;
27
28 // PreloadingAttempt implementation:
29 void SetEligibility(PreloadingEligibility eligibility) override;
Simon Pelchatd32e4082022-06-17 15:34:0830 void SetHoldbackStatus(PreloadingHoldbackStatus holdback_status) override;
Simon Pelchat9ed3e992023-02-17 01:16:1631 bool ShouldHoldback() override;
Sreeja Kamishetty530e8c22022-06-11 02:20:1632 void SetTriggeringOutcome(
33 PreloadingTriggeringOutcome triggering_outcome) override;
Simon Pelchat113f7b412022-06-28 23:42:2734 void SetFailureReason(PreloadingFailureReason reason) override;
Sreeja Kamishetty21a07bc2022-07-29 04:00:0435 base::WeakPtr<PreloadingAttempt> GetWeakPtr() override;
Sreeja Kamishetty530e8c22022-06-11 02:20:1636
Simon Pelchat9ed3e992023-02-17 01:16:1637 // Records UKMs for both Preloading_Attempt and
Sreeja Kamishetty530e8c22022-06-11 02:20:1638 // Preloading_Attempt_PreviousPrimaryPage. Metrics for both these are same.
39 // Only difference is that the Preloading_Attempt_PreviousPrimaryPage UKM is
40 // associated with the WebContents primary page that triggered the preloading
41 // attempt. This is done to easily analyze the impact of the preloading
Sreeja Kamishettyac12140e2022-07-14 22:16:5142 // attempt on the primary visible page. Here `navigated_page` represent the
43 // ukm::SourceId of the navigated page. If the navigation doesn't happen this
Simon Pelchat9ed3e992023-02-17 01:16:1644 // could be invalid. This must be called after the page load ends and we know
45 // if the attempt was accurate.
William Liu238a9e52023-01-23 20:32:4046 void RecordPreloadingAttemptMetrics(ukm::SourceId navigated_page);
Sreeja Kamishettyac12140e2022-07-14 22:16:5147
Hiroki Nakagawaab70984b2024-05-24 07:04:3448 void SetNoVarySearchMatchPredicate(
49 PreloadingURLMatchCallback no_vary_search_match_predicate);
50
Sreeja Kamishettyac12140e2022-07-14 22:16:5151 // Sets `is_accurate_triggering_` to true if `navigated_url` matches the
William Liu60e005f2023-01-18 16:17:2252 // predicate URL logic. It also records `time_to_next_navigation_`.
Sreeja Kamishettyac12140e2022-07-14 22:16:5153 void SetIsAccurateTriggering(const GURL& navigated_url);
Sreeja Kamishetty530e8c22022-06-11 02:20:1654
Iman Saboori6a245ec2023-02-22 20:03:2055 bool IsAccurateTriggering() const { return is_accurate_triggering_; }
56
kenoss5df53e052024-06-17 06:59:5257 PreloadingAttemptImpl(
58 const PreloadingPredictor& creating_predictor,
59 const PreloadingPredictor& enacting_predictor,
60 PreloadingType preloading_type,
61 ukm::SourceId triggered_primary_page_source_id,
62 PreloadingURLMatchCallback url_match_predicate,
kenoss5df53e052024-06-17 06:59:5263 uint32_t sampling_seed);
Sreeja Kamishetty530e8c22022-06-11 02:20:1664
Kevin McNee98e068a2024-04-09 20:12:3465 std::vector<PreloadingPredictor> GetPredictors() const;
William Liu238a9e52023-01-23 20:32:4066
Iman Saboori6a245ec2023-02-22 20:03:2067 PreloadingType preloading_type() const { return preloading_type_; }
68
Adithya Srinivasan38e0c402023-07-19 16:12:5869 void SetSpeculationEagerness(blink::mojom::SpeculationEagerness eagerness);
70
Liviu Tinta91202302023-09-26 17:49:1171 // Describes what type of checks we had to do to identify if the attempt's
72 // URL is or is not under a Service Worker.
73 enum class ServiceWorkerRegisteredCheck {
74 // These values are persisted to logs. Entries should not be renumbered and
75 // numeric values should never be reused.
76
77 // The origin doesn't have any Service Workers registered.
78 kOriginOnly = 0,
79 // The origin has at least one Service Worker registered and we had to
80 // perform a path test to identify if the attempt's URL is under a
81 // registered Service Worker.
82 kPath = 1,
83 kMaxValue = kPath
84 };
85 static constexpr double kServiceWorkerRegisteredCheckDurationBucketSpacing =
86 1.15;
87 void SetServiceWorkerRegisteredCheck(ServiceWorkerRegisteredCheck check);
88 void SetServiceWorkerRegisteredCheckDuration(base::TimeDelta duration);
89
Sreeja Kamishetty530e8c22022-06-11 02:20:1690 private:
Sreeja Kamishetty26e40d22022-10-17 17:54:3591 friend class test::PreloadingAttemptAccessor;
92
William Liu238a9e52023-01-23 20:32:4093 void RecordPreloadingAttemptUMA();
94
Sreeja Kamishetty530e8c22022-06-11 02:20:1695 // Reason why the preloading attempt failed, this is similar to specific
96 // preloading logging reason. Zero as a failure reason signifies no reason is
97 // specified. This value is casted from preloading specific enum to int64_t
98 // instead of having an enum declaration for each case.
Simon Pelchatd32e4082022-06-17 15:34:0899 PreloadingFailureReason failure_reason_ =
100 PreloadingFailureReason::kUnspecified;
Sreeja Kamishetty530e8c22022-06-11 02:20:16101
102 // Specifies the eligibility status for this PreloadingAttempt.
103 PreloadingEligibility eligibility_ = PreloadingEligibility::kUnspecified;
104
Simon Pelchatd32e4082022-06-17 15:34:08105 PreloadingHoldbackStatus holdback_status_ =
106 PreloadingHoldbackStatus::kUnspecified;
107
Sreeja Kamishetty530e8c22022-06-11 02:20:16108 // Specifies the triggering outcome for this PreloadingAttempt.
109 PreloadingTriggeringOutcome triggering_outcome_ =
110 PreloadingTriggeringOutcome::kUnspecified;
111
112 // Preloading predictor of this PreloadingAttempt.
Kevin McNee98e068a2024-04-09 20:12:34113 const PreloadingPredictor creating_predictor_;
114 const PreloadingPredictor enacting_predictor_;
Sreeja Kamishetty530e8c22022-06-11 02:20:16115
116 // PreloadingType this attempt is associated with.
117 const PreloadingType preloading_type_;
118
119 // Holds the ukm::SourceId of the triggered primary page of this preloading
120 // attempt.
121 const ukm::SourceId triggered_primary_page_source_id_;
122
123 // Triggers can specify their own predicate for judging whether two URLs are
124 // considered as pointing to the same destination.
125 const PreloadingURLMatchCallback url_match_predicate_;
Sreeja Kamishettyac12140e2022-07-14 22:16:51126
Hiroki Nakagawaab70984b2024-05-24 07:04:34127 // Set when a predicted page provides No-Vary-Search header.
128 PreloadingURLMatchCallback no_vary_search_match_predicate_;
129
Sreeja Kamishettyac12140e2022-07-14 22:16:51130 // Set to true if this PreloadingAttempt was used for the next navigation.
131 bool is_accurate_triggering_ = false;
Sreeja Kamishetty21a07bc2022-07-29 04:00:04132
William Liu60e005f2023-01-18 16:17:22133 // Records when the preloading attempt began, for computing times.
134 const base::ElapsedTimer elapsed_timer_;
135
136 // The time between the creation of the attempt and the start of the next
137 // navigation, whether accurate or not. The latency is reported as standard
138 // buckets, of 1.15 spacing.
Arthur Sonzognic686e8f2024-01-11 08:36:37139 std::optional<base::TimeDelta> time_to_next_navigation_;
William Liu60e005f2023-01-18 16:17:22140
141 // Represents the duration between the attempt creation and its
142 // `triggering_outcome_` becoming `kReady`. The latency is reported as
143 // standard buckets, of 1.15 spacing.
Arthur Sonzognic686e8f2024-01-11 08:36:37144 std::optional<base::TimeDelta> ready_time_;
William Liu60e005f2023-01-18 16:17:22145
Simon Pelchatecd98362023-07-19 22:31:41146 // The random seed used to determine if a preloading attempt should be sampled
147 // in UKM logs. We use a different random seed for each session (that is the
148 // source of randomness for sampling) and then hash that seed with the UKM
149 // source ID so that all attempts for a given source ID use the same random
150 // value to determine sampling. This allows all PreloadingAttempt for a given
151 // (preloading_type, predictor) in a page load to be sampled in or out
152 // together.
Simon Pelchat9ed3e992023-02-17 01:16:16153 uint32_t sampling_seed_;
154
Adithya Srinivasan38e0c402023-07-19 16:12:58155 // Eagerness of this preloading attempt (specified by a speculation rule).
156 // This is only set for attempts that are triggered by speculation rules.
Arthur Sonzognic686e8f2024-01-11 08:36:37157 std::optional<blink::mojom::SpeculationEagerness> eagerness_ = std::nullopt;
Adithya Srinivasan38e0c402023-07-19 16:12:58158
Liviu Tinta91202302023-09-26 17:49:11159 // Describes the type of check we did for to find out if the attempt's URL
160 // is under a Service Worker's path. The simplest check is: does the URL's
161 // origin have any registered service workers or not, the more complicated
162 // check is: given the URL's origin has service workers registered, is the
163 // URL under one of these Service Workers.
164 // This is only set for prefetch attempts that are triggered by speculation
165 // rules.
Arthur Sonzognic686e8f2024-01-11 08:36:37166 std::optional<ServiceWorkerRegisteredCheck> service_worker_registered_check_ =
167 std::nullopt;
168 std::optional<base::TimeDelta> service_worker_registered_check_duration_ =
169 std::nullopt;
Liviu Tinta91202302023-09-26 17:49:11170
Sreeja Kamishetty21a07bc2022-07-29 04:00:04171 base::WeakPtrFactory<PreloadingAttemptImpl> weak_factory_{this};
Sreeja Kamishetty530e8c22022-06-11 02:20:16172};
173
174// Used when DCHECK_STATE_TRANSITION triggers.
175CONTENT_EXPORT std::ostream& operator<<(std::ostream& o,
176 const PreloadingTriggeringOutcome& s);
177
178} // namespace content
179
Sreeja Kamishetty8ef652b2022-06-22 22:43:17180#endif // CONTENT_BROWSER_PRELOADING_PRELOADING_ATTEMPT_IMPL_H_