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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
content / browser / background_fetch / background_fetch_scheduler.h [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_
#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "base/containers/circular_deque.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/background_fetch/background_fetch_data_manager_observer.h"
#include "content/browser/background_fetch/background_fetch_event_dispatcher.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h"
namespace blink {
class StorageKey;
} // namespace blink
namespace content {
class BackgroundFetchDataManager;
class BackgroundFetchDelegateProxy;
class BackgroundFetchJobController;
class BackgroundFetchRegistrationId;
class BackgroundFetchRegistrationNotifier;
class BackgroundFetchRequestInfo;
class DevToolsBackgroundServicesContextImpl;
// Maintains a list of Controllers and chooses which ones should launch new
// downloads.
class CONTENT_EXPORT BackgroundFetchScheduler
: public BackgroundFetchDataManagerObserver,
public ServiceWorkerContextCoreObserver {
public:
BackgroundFetchScheduler(
BackgroundFetchContext* background_fetch_context,
BackgroundFetchDataManager* data_manager,
BackgroundFetchRegistrationNotifier* registration_notifier,
BackgroundFetchDelegateProxy* delegate_proxy,
DevToolsBackgroundServicesContextImpl& devtools_context,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
BackgroundFetchScheduler(const BackgroundFetchScheduler&) = delete;
BackgroundFetchScheduler& operator=(const BackgroundFetchScheduler&) = delete;
~BackgroundFetchScheduler() override;
// Aborts the background fetch identified by |registration_id|.
// Must only be used for background fetches aborted by the developer,
// other cases are handled elsewhere.
void Abort(
const BackgroundFetchRegistrationId& registration_id,
blink::mojom::BackgroundFetchFailureReason failure_reason,
blink::mojom::BackgroundFetchRegistrationService::AbortCallback callback);
// BackgroundFetchDataManagerObserver implementation.
void OnRegistrationCreated(
const BackgroundFetchRegistrationId& registration_id,
const blink::mojom::BackgroundFetchRegistrationData& registration_data,
blink::mojom::BackgroundFetchOptionsPtr options,
const SkBitmap& icon,
int num_requests,
bool start_paused,
net::IsolationInfo isolation_info) override;
void OnRegistrationLoadedAtStartup(
const BackgroundFetchRegistrationId& registration_id,
const blink::mojom::BackgroundFetchRegistrationData& registration_data,
blink::mojom::BackgroundFetchOptionsPtr options,
const SkBitmap& icon,
int num_completed_requests,
int num_requests,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests,
std::optional<net::IsolationInfo> isolation_info) override;
void OnServiceWorkerDatabaseCorrupted(
int64_t service_worker_registration_id) override;
void OnRegistrationQueried(
const BackgroundFetchRegistrationId& registration_id,
blink::mojom::BackgroundFetchRegistrationData* registration_data)
override;
void OnRequestCompleted(const std::string& unique_id,
blink::mojom::FetchAPIRequestPtr request,
blink::mojom::FetchAPIResponsePtr response) override;
// ServiceWorkerContextCoreObserver implementation.
void OnRegistrationDeleted(int64_t registration_id,
const GURL& pattern,
const blink::StorageKey& key) override;
void OnStorageWiped() override;
// Called by BackgroundFetchContext during shutdown.
void Shutdown();
private:
friend class BackgroundFetchJobControllerTest;
friend class BackgroundFetchSchedulerTest;
enum class Event;
// Schedules a download, if possible, and returns whether successful.
bool ScheduleDownload();
// Helper method to abandon ongoing fetches for a given service worker.
// Abandons all of them if |service_worker_registration_id| is set to
// blink::mojom::kInvalidServiceWorkerRegistrationId.
void AbortFetches(int64_t service_worker_registration_id);
// Returns the active job controller, if any, for |registration_id| or
// |unique_id|. Returns nullptr if the job isn't currently active.
BackgroundFetchJobController* GetActiveController(
const BackgroundFetchRegistrationId& registration_id);
BackgroundFetchJobController* GetActiveController(
const std::string& unique_id);
std::unique_ptr<BackgroundFetchJobController> CreateInitializedController(
const BackgroundFetchRegistrationId& registration_id,
const blink::mojom::BackgroundFetchRegistrationData& registration_data,
blink::mojom::BackgroundFetchOptionsPtr options,
const SkBitmap& icon,
int num_completed_requests,
int num_requests,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests,
bool start_paused,
std::optional<net::IsolationInfo> isolation_info);
void DidStartRequest(const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchRequestInfo* request_info);
void DidCompleteRequest(
const BackgroundFetchRegistrationId& registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info);
void FinishJob(
const BackgroundFetchRegistrationId& registration_id,
blink::mojom::BackgroundFetchFailureReason failure_reason,
base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback);
void DidMarkForDeletion(
const BackgroundFetchRegistrationId& registration_id,
bool job_started,
base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
blink::mojom::BackgroundFetchError error,
blink::mojom::BackgroundFetchFailureReason failure_reason);
void CleanupRegistration(
const BackgroundFetchRegistrationId& registration_id);
void DispatchClickEvent(const std::string& unique_id);
// Information needed to send over to the
// DevToolsBackgroundServicesContextImpl. |event| is an enum describing the
// stage of the fetch. |request_info| is nullptr if not available at the
// moment. Any additional data to log can be passed through the |metadata|
// map.
void LogBackgroundFetchEventForDevTools(
Event event,
const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchRequestInfo* request_info,
std::map<std::string, std::string> metadata = {});
// Owned by BackgroundFetchContext.
raw_ptr<BackgroundFetchDataManager, DanglingUntriaged> data_manager_;
raw_ptr<BackgroundFetchRegistrationNotifier> registration_notifier_;
raw_ptr<BackgroundFetchDelegateProxy, DanglingUntriaged> delegate_proxy_;
raw_ptr<DevToolsBackgroundServicesContextImpl> devtools_context_;
BackgroundFetchEventDispatcher event_dispatcher_;
// The order in which to process the job controllers.
base::circular_deque<BackgroundFetchRegistrationId> controller_ids_;
// Map from background fetch registration |unique_id|s to active job
// controllers. Must be destroyed before |data_manager_|, |scheduler_| and
// |registration_notifier_|.
std::map<std::string, std::unique_ptr<BackgroundFetchJobController>>
job_controllers_;
// The current fetch job controllers that are being processed.
base::circular_deque<BackgroundFetchJobController*> active_controllers_;
struct RegistrationData {
RegistrationData(
const BackgroundFetchRegistrationId& registration_id,
blink::mojom::BackgroundFetchRegistrationDataPtr registration);
~RegistrationData();
BackgroundFetchRegistrationId registration_id;
blink::mojom::BackgroundFetchRegistrationDataPtr registration;
// Wheter all processing is completed and this data is safe to erase now.
bool processing_completed = false;
};
// Map from |unique_id|s to the registration data.
// An entry in here means the fetch has completed. This information is needed
// after the fetch has completed to dispatch the backgroundfetchclick event.
// TODO(crbug.com/41397180): Clean this up when the UI is no longer showing.
std::map<std::string, std::unique_ptr<RegistrationData>> completed_fetches_;
// Scheduling params - Finch configurable.
int max_running_downloads_;
int max_active_registrations_;
int num_active_registrations_ = 0;
int num_running_downloads_ = 0;
base::WeakPtrFactory<BackgroundFetchScheduler> weak_ptr_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_