blob: 6142277b9c97b978f1cbc80361d420380d47e56f [file] [log] [blame]
Taiyo Mizuhashi94ce74f2025-01-28 04:20:141// Copyright 2025 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/preloading/prefetch/prefetch_handle_impl.h"
6
kenossccc35892025-06-09 13:09:477#include "base/functional/callback.h"
Taiyo Mizuhashi94ce74f2025-01-28 04:20:148#include "content/browser/browser_context_impl.h"
kenossccc35892025-06-09 13:09:479#include "content/browser/preloading/prefetch/prefetch_response_reader.h"
Taiyo Mizuhashi94ce74f2025-01-28 04:20:1410#include "content/browser/preloading/prefetch/prefetch_service.h"
11#include "content/browser/preloading/prefetch/prefetch_type.h"
12#include "content/public/browser/preloading_data.h"
13#include "content/public/browser/web_contents.h"
kenossb4e57f72025-06-16 08:28:4014#include "services/network/public/cpp/url_loader_completion_status.h"
kenossccc35892025-06-09 13:09:4715#include "services/network/public/mojom/url_response_head.mojom.h"
Taiyo Mizuhashi94ce74f2025-01-28 04:20:1416
17namespace content {
18
kenossb4e57f72025-06-16 08:28:4019PrefetchContainerObserver::PrefetchContainerObserver() = default;
kenossccc35892025-06-09 13:09:4720
21PrefetchContainerObserver::~PrefetchContainerObserver() = default;
22
kenossb4e57f72025-06-16 08:28:4023void PrefetchContainerObserver::SetOnPrefetchHeadReceivedCallback(
24 base::RepeatingCallback<void(const network::mojom::URLResponseHead&)>
25 on_prefetch_head_received) {
26 on_prefetch_head_received_ = std::move(on_prefetch_head_received);
27}
28
29void PrefetchContainerObserver::SetOnPrefetchCompletedOrFailedCallback(
30 base::RepeatingCallback<
31 void(const network::URLLoaderCompletionStatus& completion_status,
32 const std::optional<int>& response_code)>
33 on_prefetch_completed_or_failed) {
34 on_prefetch_completed_or_failed_ = std::move(on_prefetch_completed_or_failed);
35}
36
kenossccc35892025-06-09 13:09:4737void PrefetchContainerObserver::OnWillBeDestroyed(
38 PrefetchContainer& prefetch_container) {}
39
40void PrefetchContainerObserver::OnGotInitialEligibility(
41 PrefetchContainer& prefetch_container,
42 PreloadingEligibility eligibility) {}
43
44void PrefetchContainerObserver::OnDeterminedHead(
45 PrefetchContainer& prefetch_container) {
kenossb4e57f72025-06-16 08:28:4046 if (on_prefetch_head_received_) {
47 // This condition will be used in a callback provided in the future.
48 // See
49 // https://chromium-review.googlesource.com/c/chromium/src/+/6615559/comment/3f439d19_8c9cf99a
50 //
51 // TODO(crbug.com/400761083): Use the callback.
52 if (prefetch_container.GetNonRedirectResponseReader() &&
53 prefetch_container.GetNonRedirectResponseReader()->load_state() ==
54 PrefetchResponseReader::LoadState::kResponseReceived) {
55 on_prefetch_head_received_.Run(*prefetch_container.GetNonRedirectHead());
56 }
57 }
58}
59
60void PrefetchContainerObserver::OnPrefetchCompletedOrFailed(
Hiroshige Hayashizaki6a103bad2025-07-11 02:15:3261 PrefetchContainer& prefetch_container,
kenossb4e57f72025-06-16 08:28:4062 const network::URLLoaderCompletionStatus& completion_status,
63 const std::optional<int>& response_code) {
Hiroshige Hayashizakidb5f1962025-07-14 22:38:2064 // `IsDecoy()` check is added to preserve the existing behavior.
65 // https://crbug.com/400761083
66 if (prefetch_container.IsDecoy()) {
67 return;
68 }
kenossb4e57f72025-06-16 08:28:4069 if (on_prefetch_completed_or_failed_) {
70 on_prefetch_completed_or_failed_.Run(completion_status, response_code);
kenossccc35892025-06-09 13:09:4771 }
72}
73
Taiyo Mizuhashi94ce74f2025-01-28 04:20:1474PrefetchHandleImpl::PrefetchHandleImpl(
75 base::WeakPtr<PrefetchService> prefetch_service,
76 base::WeakPtr<PrefetchContainer> prefetch_container)
77 : prefetch_service_(std::move(prefetch_service)),
kenossb4e57f72025-06-16 08:28:4078 prefetch_container_(std::move(prefetch_container)) {
79 CHECK(prefetch_service_);
80 // Note that `prefetch_container_` can be nullptr.
81
82 if (prefetch_container_) {
83 prefetch_container_->AddObserver(&prefetch_container_observer_);
84 }
85}
Taiyo Mizuhashi94ce74f2025-01-28 04:20:1486
87PrefetchHandleImpl::~PrefetchHandleImpl() {
kenossb4e57f72025-06-16 08:28:4088 if (prefetch_container_) {
89 prefetch_container_->RemoveObserver(&prefetch_container_observer_);
90 }
91
Taiyo Mizuhashi94ce74f2025-01-28 04:20:1492 // Notify `PrefetchService` that the corresponding `PrefetchContainer` is no
93 // longer needed. `PrefetchService` might release the container and its
94 // corresponding resources by its decision with best-effort.
95 if (prefetch_service_) {
96 // TODO(crbug.com/390329781): Consider setting appropriate
97 // PrefetchStatus/PreloadingAttempt.
Hiroshige Hayashizaki22be5e4c2025-03-07 21:39:5998 if (prefetch_status_on_release_started_prefetch_ && prefetch_container_) {
99 switch (prefetch_container_->GetLoadState()) {
100 case PrefetchContainer::LoadState::kNotStarted:
101 case PrefetchContainer::LoadState::kEligible:
102 case PrefetchContainer::LoadState::kFailedIneligible:
103 case PrefetchContainer::LoadState::kFailedHeldback:
104 break;
105 case PrefetchContainer::LoadState::kStarted:
Hiroshige Hayashizaki6b7035c02025-07-18 21:06:32106 case PrefetchContainer::LoadState::kDeterminedHead:
107 case PrefetchContainer::LoadState::kCompletedOrFailed:
Hiroshige Hayashizaki22be5e4c2025-03-07 21:39:59108 prefetch_container_->SetPrefetchStatus(
109 *prefetch_status_on_release_started_prefetch_);
110 break;
111 }
112 }
Taiyo Mizuhashi94ce74f2025-01-28 04:20:14113 prefetch_service_->MayReleasePrefetch(prefetch_container_);
114 }
115}
116
kenossb4e57f72025-06-16 08:28:40117void PrefetchHandleImpl::SetOnPrefetchHeadReceivedCallback(
kenossccc35892025-06-09 13:09:47118 base::RepeatingCallback<void(const network::mojom::URLResponseHead&)>
119 on_prefetch_head_received) {
kenossb4e57f72025-06-16 08:28:40120 prefetch_container_observer_.SetOnPrefetchHeadReceivedCallback(
kenossccc35892025-06-09 13:09:47121 std::move(on_prefetch_head_received));
kenossb4e57f72025-06-16 08:28:40122}
123
124void PrefetchHandleImpl::SetOnPrefetchCompletedOrFailedCallback(
125 base::RepeatingCallback<
126 void(const network::URLLoaderCompletionStatus& completion_status,
127 const std::optional<int>& response_code)>
128 on_prefetch_completed_or_failed) {
129 prefetch_container_observer_.SetOnPrefetchCompletedOrFailedCallback(
130 std::move(on_prefetch_completed_or_failed));
kenossccc35892025-06-09 13:09:47131}
132
kenoss451c5112025-03-12 02:17:21133bool PrefetchHandleImpl::IsAlive() const {
134 return static_cast<bool>(prefetch_container_);
135}
136
Hiroshige Hayashizaki22be5e4c2025-03-07 21:39:59137void PrefetchHandleImpl::SetPrefetchStatusOnReleaseStartedPrefetch(
138 PrefetchStatus prefetch_status_on_release_started_prefetch) {
139 CHECK(!prefetch_status_on_release_started_prefetch_);
140 prefetch_status_on_release_started_prefetch_ =
141 prefetch_status_on_release_started_prefetch;
142}
143
Taiyo Mizuhashi94ce74f2025-01-28 04:20:14144} // namespace content