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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
content / public / browser / service_worker_context.h [blame]
// Copyright 2014 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_PUBLIC_BROWSER_SERVICE_WORKER_CONTEXT_H_
#define CONTENT_PUBLIC_BROWSER_SERVICE_WORKER_CONTEXT_H_
#include <optional>
#include <set>
#include <string>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/observer_list_types.h"
#include "base/task/sequenced_task_runner.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/service_worker_external_request_result.h"
#include "content/public/browser/service_worker_external_request_timeout_type.h"
#include "content/public/browser/service_worker_running_info.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/messaging/transferable_message.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom-forward.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration_options.mojom-forward.h"
namespace base {
class Uuid;
}
namespace blink {
class AssociatedInterfaceProvider;
class StorageKey;
} // namespace blink
namespace service_manager {
class InterfaceProvider;
}
namespace url {
class Origin;
} // namespace url
class GURL;
namespace content {
class ServiceWorkerContextObserver;
struct ServiceWorkerRunningInfo;
struct StorageUsageInfo;
enum class ServiceWorkerCapability {
NO_SERVICE_WORKER,
SERVICE_WORKER_NO_FETCH_HANDLER,
SERVICE_WORKER_WITH_FETCH_HANDLER,
};
// Used for UMA. Append only.
enum class StartServiceWorkerForNavigationHintResult {
// The service worker started successfully.
STARTED = 0,
// The service worker was already running.
ALREADY_RUNNING = 1,
// There was no service worker registration for the given URL.
NO_SERVICE_WORKER_REGISTRATION = 2,
// There was no active service worker for the given URL.
NO_ACTIVE_SERVICE_WORKER_VERSION = 3,
// The service worker for the given URL had no fetch event handler.
NO_FETCH_HANDLER = 4,
// Something failed.
FAILED = 5,
// Add new result to record here.
kMaxValue = FAILED,
};
// A callback invoked with the result of executing script in a service worker
// context.
using ServiceWorkerScriptExecutionCallback =
base::OnceCallback<void(base::Value value,
const std::optional<std::string>& error)>;
// An observer very similar to `ServiceWorkerContextCoreObserver`, but meant to
// only be used by extension service workers. Its methods are called
// synchronously with changes in //content.
class ServiceWorkerContextObserverSynchronous : public base::CheckedObserver {
public:
// Called when the service worker with id `version_id` has stopped running.
virtual void OnStopped(int64_t version_id,
const ServiceWorkerRunningInfo& worker_info) {}
// TODO(crbug.com/334940006): Add the rest of the extensions methods
// (OnRegistrationStored(), OnReportConsoleMessage(), OnDestruct()) and adapt
// `ServiceWorkerTaskQueue` to use this observer exclusively.
};
// Represents the per-StoragePartition service worker data.
//
// See service_worker_context_wrapper.cc for the implementation
// of ServiceWorkerContext and ServiceWorkerContextWrapper (the
// primary implementation of this abstract class).
//
// All methods must be called on the UI thread.
class CONTENT_EXPORT ServiceWorkerContext {
public:
using ResultCallback = base::OnceCallback<void(bool success)>;
using GetInstalledRegistrationOriginsCallback =
base::OnceCallback<void(const std::vector<url::Origin>& origins)>;
using GetUsageInfoCallback =
base::OnceCallback<void(const std::vector<StorageUsageInfo>& usage_info)>;
using CheckHasServiceWorkerCallback =
base::OnceCallback<void(ServiceWorkerCapability capability)>;
using StatusCodeCallback =
base::OnceCallback<void(blink::ServiceWorkerStatusCode status_code)>;
using StartServiceWorkerForNavigationHintCallback = base::OnceCallback<void(
StartServiceWorkerForNavigationHintResult result)>;
using WarmUpServiceWorkerCallback = base::OnceClosure;
using StartWorkerCallback = base::OnceCallback<
void(int64_t version_id, int process_id, int thread_id)>;
// Returns true if |url| is within the service worker |scope|.
static bool ScopeMatches(const GURL& scope, const GURL& url);
// Runs a |task| on task |runner| making sure that
// |service_worker_context| is alive while the task is being run.
static void RunTask(scoped_refptr<base::SequencedTaskRunner> runner,
const base::Location& from_here,
ServiceWorkerContext* service_worker_context,
base::OnceClosure task);
// Returns the delay from navigation to starting an update of a service
// worker's script.
static base::TimeDelta GetUpdateDelay();
// Add/remove an observer that is asynchronously notified.
virtual void AddObserver(ServiceWorkerContextObserver* observer) = 0;
virtual void RemoveObserver(ServiceWorkerContextObserver* observer) = 0;
// Add/remove an observer that is synchronously notified.
virtual void AddSyncObserver(
ServiceWorkerContextObserverSynchronous* observer) {}
virtual void RemoveSyncObserver(
ServiceWorkerContextObserverSynchronous* observer) {}
// Equivalent to calling navigator.serviceWorker.register(script_url,
// options) for a given `key`. `callback` is passed true when the JS promise
// is fulfilled or false when the JS promise is rejected.
//
// The registration can fail if:
// * `script_url` is on a different origin from `scope`
// * Fetching `script_url` fails.
// * `script_url` fails to parse or its top-level execution fails.
// * Something unexpected goes wrong, like a renderer crash or a full disk.
virtual void RegisterServiceWorker(
const GURL& script_url,
const blink::StorageKey& key,
const blink::mojom::ServiceWorkerRegistrationOptions& options,
StatusCodeCallback callback) = 0;
// Equivalent to calling ServiceWorkerRegistration#unregister on the
// registration for `scope`.
//
// Unregistration can fail if:
// * No registration exists for `scope`.
// * Something unexpected goes wrong, like a renderer crash.
//
// `callback` provides the status code result of the unregistration.
// `blink::ServiceWorkerStatusCode::kOk` means the request to unregister was
// sent. It does not mean the worker has been fully unregistered though.
virtual void UnregisterServiceWorker(const GURL& scope,
const blink::StorageKey& key,
StatusCodeCallback callback) = 0;
// As above, but clears the service worker registration immediately rather
// than waiting if the service worker is active and has controllees.
virtual void UnregisterServiceWorkerImmediately(
const GURL& scope,
const blink::StorageKey& key,
StatusCodeCallback callback) = 0;
// Mechanism for embedder to increment/decrement ref count of a service
// worker.
//
// Embedders can call StartingExternalRequest() while it is performing some
// work with the worker. The worker is considered to be working until embedder
// calls FinishedExternalRequest(). This ensures that content/ does not
// shut the worker down while embedder is expecting the worker to be kept
// alive.
virtual ServiceWorkerExternalRequestResult StartingExternalRequest(
int64_t service_worker_version_id,
ServiceWorkerExternalRequestTimeoutType timeout_type,
const base::Uuid& request_uuid) = 0;
virtual ServiceWorkerExternalRequestResult FinishedExternalRequest(
int64_t service_worker_version_id,
const base::Uuid& request_uuid) = 0;
// Returns the pending external request count for the worker with the
// specified `key`.
virtual size_t CountExternalRequestsForTest(const blink::StorageKey& key) = 0;
// Executes the given `script` in the context of the worker specified by the
// given `service_worker_version_id`. If non-empty, `callback` is invoked
// with the result of the script. See also service_worker.mojom.
virtual bool ExecuteScriptForTest(
const std::string& script,
int64_t service_worker_version_id,
ServiceWorkerScriptExecutionCallback callback) = 0;
// Whether `key` has any registrations. Uninstalling and uninstalled
// registrations do not cause this to return true, that is, only registrations
// with status ServiceWorkerRegistration::Status::kIntact are considered, such
// as even if the corresponding live registrations may still exist. Also,
// returns true if it doesn't know (registrations are not yet initialized).
virtual bool MaybeHasRegistrationForStorageKey(
const blink::StorageKey& key) = 0;
// Used in response to browsing data and quota manager requests to get
// the per-StorageKey size and last time used data.
virtual void GetAllStorageKeysInfo(GetUsageInfoCallback callback) = 0;
// Deletes all registrations for `key` and clears all service workers
// belonging to the registrations. All clients controlled by those service
// workers will lose their controllers immediately after this operation.
virtual void DeleteForStorageKey(const blink::StorageKey& key,
ResultCallback callback) = 0;
// Returns ServiceWorkerCapability describing existence and properties of a
// Service Worker registration matching `url` and `key`. In case the service
// worker is being installed as of calling this method, it will wait for the
// installation to finish before coming back with the result.
virtual void CheckHasServiceWorker(
const GURL& url,
const blink::StorageKey& key,
CheckHasServiceWorkerCallback callback) = 0;
// Stops all running service workers and unregisters all service worker
// registrations. This method is used in web tests to make sure that the
// existing service worker will not affect the succeeding tests.
virtual void ClearAllServiceWorkersForTest(base::OnceClosure callback) = 0;
// Starts the active worker of the registration for the given `scope` and
// `key`. If there is no active worker, starts the installing worker.
// `info_callback` is passed information about the started worker if
// successful, otherwise `failure_callback` is passed information about the
// error.
//
// There is no guarantee about whether the callback is called synchronously or
// asynchronously.
virtual void StartWorkerForScope(const GURL& scope,
const blink::StorageKey& key,
StartWorkerCallback info_callback,
StatusCodeCallback failure_callback) = 0;
// Starts the active worker of the registration for the given `scope` and
// `key` and dispatches the given `message` to the service worker.
// `result_callback` is passed a success boolean indicating whether the
// message was dispatched successfully.
virtual void StartServiceWorkerAndDispatchMessage(
const GURL& scope,
const blink::StorageKey& key,
blink::TransferableMessage message,
ResultCallback result_callback) = 0;
// Starts the service worker for `document_url` and `key`. Called when a
// navigation to that URL is predicted to occur soon.
virtual void StartServiceWorkerForNavigationHint(
const GURL& document_url,
const blink::StorageKey& key,
StartServiceWorkerForNavigationHintCallback callback) = 0;
// Warms up the service worker for `document_url` and `key`. Called when a
// navigation to that URL is predicted to occur soon. Unlike
// StartServiceWorkerForNavigationHint, this function doesn't evaluate the
// service worker script. Instead, this function prepares renderer process,
// mojo connections, loading scripts from disk without evaluating the script.
virtual void WarmUpServiceWorker(const GURL& document_url,
const blink::StorageKey& key,
WarmUpServiceWorkerCallback callback) = 0;
// Stops all running workers on the given `key`.
virtual void StopAllServiceWorkersForStorageKey(
const blink::StorageKey& key) = 0;
// Stops all running service workers.
virtual void StopAllServiceWorkers(base::OnceClosure callback) = 0;
// Gets info about all running workers.
virtual const base::flat_map<int64_t /* version_id */,
ServiceWorkerRunningInfo>&
GetRunningServiceWorkerInfos() = 0;
// Returns true if the ServiceWorkerVersion for `service_worker_version_id` is
// live and starting.
virtual bool IsLiveStartingServiceWorker(
int64_t service_worker_version_id) = 0;
// Returns true if the ServiceWorkerVersion for `service_worker_version_id` is
// live and running.
virtual bool IsLiveRunningServiceWorker(
int64_t service_worker_version_id) = 0;
// Returns the InterfaceProvider for the worker specified by
// `service_worker_version_id`. The caller can use InterfaceProvider to bind
// interfaces exposed by the Service Worker. CHECKs if
// `IsLiveRunningServiceWorker()` returns false.
virtual service_manager::InterfaceProvider& GetRemoteInterfaces(
int64_t service_worker_version_id) = 0;
// Returns the AssociatedInterfaceProvider for the worker specified by
// `service_worker_version_id`. The caller can use InterfaceProvider to bind
// interfaces exposed by the Service Worker. CHECKs if
// `IsLiveRunningServiceWorker()` returns false.
virtual blink::AssociatedInterfaceProvider& GetRemoteAssociatedInterfaces(
int64_t service_worker_version_id) = 0;
// Sets the devtools force update on page load flag for service workers. See
// ServiceWorkerContextCore::force_update_on_page_load() for details.
virtual void SetForceUpdateOnPageLoadForTesting(
bool force_update_on_page_load) = 0;
protected:
ServiceWorkerContext() {}
virtual ~ServiceWorkerContext() {}
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_SERVICE_WORKER_CONTEXT_H_