1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_MANAGER_H_
6 #define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_MANAGER_H_
13 #include "base/callback_forward.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/memory/weak_ptr.h"
17 #include "content/browser/background_sync/background_sync.pb.h"
18 #include "content/browser/background_sync/background_sync_registration.h"
19 #include "content/browser/background_sync/background_sync_registration_handle.h"
20 #include "content/browser/background_sync/background_sync_status.h"
21 #include "content/browser/cache_storage/cache_storage_scheduler.h"
22 #include "content/browser/service_worker/service_worker_context_observer.h"
23 #include "content/browser/service_worker/service_worker_storage.h"
24 #include "content/common/background_sync_service.mojom.h"
25 #include "content/common/content_export.h"
26 #include "content/common/service_worker/service_worker_status_code.h"
31 class BackgroundSyncNetworkObserver
;
32 class BackgroundSyncPowerObserver
;
33 class ServiceWorkerContextWrapper
;
35 // BackgroundSyncManager manages and stores the set of background sync
36 // registrations across all registered service workers for a profile.
37 // Registrations are stored along with their associated Service Worker
38 // registration in ServiceWorkerStorage. If the ServiceWorker is unregistered,
39 // the sync registrations are removed. This class expects to be run on the IO
40 // thread. The asynchronous methods are executed sequentially.
42 // TODO(jkarlin): Check permissions when registering, scheduling, and firing
43 // background sync. In the meantime, --enable-service-worker-sync is required to
45 // TODO(jkarlin): Unregister syncs when permission is revoked.
46 // TODO(jkarlin): Create a background sync scheduler to actually run the
48 // TODO(jkarlin): Keep the browser alive if "Let Google Chrome Run in the
49 // Background" is true and a sync is registered.
50 class CONTENT_EXPORT BackgroundSyncManager
51 : NON_EXPORTED_BASE(public ServiceWorkerContextObserver
) {
53 using StatusCallback
= base::Callback
<void(BackgroundSyncStatus
)>;
54 using StatusAndRegistrationCallback
=
55 base::Callback
<void(BackgroundSyncStatus
,
56 scoped_ptr
<BackgroundSyncRegistrationHandle
>)>;
57 using StatusAndStateCallback
=
58 base::Callback
<void(BackgroundSyncStatus
, BackgroundSyncState
)>;
59 using StatusAndRegistrationsCallback
= base::Callback
<void(
61 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>>)>;
63 static scoped_ptr
<BackgroundSyncManager
> Create(
64 const scoped_refptr
<ServiceWorkerContextWrapper
>& service_worker_context
);
65 ~BackgroundSyncManager() override
;
67 // Stores the given background sync registration and adds it to the scheduling
68 // queue. It will overwrite an existing registration with the same tag and
69 // periodicity unless they're identical (save for the id). Calls |callback|
70 // with BACKGROUND_SYNC_STATUS_OK and the accepted registration on success.
71 // The accepted registration will have a unique id. It may also have altered
72 // parameters if the user or UA chose different parameters than those
74 void Register(int64 sw_registration_id
,
75 const BackgroundSyncRegistrationOptions
& options
,
76 bool requested_from_service_worker
,
77 const StatusAndRegistrationCallback
& callback
);
79 // Finds the background sync registration associated with
80 // |sw_registration_id| with periodicity |periodicity|. Calls
81 // |callback| with BACKGROUND_SYNC_STATUS_NOT_FOUND if it doesn't exist. Calls
82 // |callback| with BACKGROUND_SYNC_STATUS_OK on success.
83 void GetRegistration(int64 sw_registration_id
,
84 const std::string
& sync_registration_tag
,
85 SyncPeriodicity periodicity
,
86 const StatusAndRegistrationCallback
& callback
);
88 void GetRegistrations(int64 sw_registration_id
,
89 SyncPeriodicity periodicity
,
90 const StatusAndRegistrationsCallback
& callback
);
92 // Given a HandleId |handle_id|, return a new handle for the same
94 scoped_ptr
<BackgroundSyncRegistrationHandle
> DuplicateRegistrationHandle(
95 BackgroundSyncRegistrationHandle::HandleId handle_id
);
97 // ServiceWorkerContextObserver overrides.
98 void OnRegistrationDeleted(int64 registration_id
,
99 const GURL
& pattern
) override
;
100 void OnStorageWiped() override
;
103 // A registration might be referenced by the client longer than
104 // the BackgroundSyncManager needs to keep track of it (e.g., the event has
105 // finished firing). The BackgroundSyncManager reference counts its
106 // registrations internally and every BackgroundSyncRegistrationHandle has a
107 // unique handle id which maps to a locally maintained (in
108 // client_registration_ids_) scoped_refptr.
109 class RefCountedRegistration
;
111 explicit BackgroundSyncManager(
112 const scoped_refptr
<ServiceWorkerContextWrapper
>& context
);
114 // Init must be called before any public member function. Only call it once.
117 // The following methods are virtual for testing.
118 virtual void StoreDataInBackend(
119 int64 sw_registration_id
,
121 const std::string
& backend_key
,
122 const std::string
& data
,
123 const ServiceWorkerStorage::StatusCallback
& callback
);
124 virtual void GetDataFromBackend(
125 const std::string
& backend_key
,
126 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback
&
128 virtual void FireOneShotSync(
129 BackgroundSyncRegistrationHandle::HandleId handle_id
,
130 const scoped_refptr
<ServiceWorkerVersion
>& active_version
,
131 const ServiceWorkerVersion::StatusCallback
& callback
);
134 friend class BackgroundSyncManagerTest
;
135 friend class BackgroundSyncRegistrationHandle
;
137 class RegistrationKey
{
139 explicit RegistrationKey(const BackgroundSyncRegistration
& registration
);
140 explicit RegistrationKey(const BackgroundSyncRegistrationOptions
& options
);
141 RegistrationKey(const std::string
& tag
, SyncPeriodicity periodicity
);
142 RegistrationKey(const RegistrationKey
& other
) = default;
143 RegistrationKey
& operator=(const RegistrationKey
& other
) = default;
145 bool operator<(const RegistrationKey
& rhs
) const {
146 return value_
< rhs
.value_
;
153 struct BackgroundSyncRegistrations
{
154 using RegistrationMap
=
155 std::map
<RegistrationKey
, scoped_refptr
<RefCountedRegistration
>>;
157 BackgroundSyncRegistrations();
158 ~BackgroundSyncRegistrations();
160 RegistrationMap registration_map
;
161 BackgroundSyncRegistration::RegistrationId next_id
;
165 using PermissionStatusCallback
= base::Callback
<void(bool)>;
166 using SWIdToRegistrationsMap
= std::map
<int64
, BackgroundSyncRegistrations
>;
168 static const size_t kMaxTagLength
= 10240;
170 scoped_ptr
<BackgroundSyncRegistrationHandle
> CreateRegistrationHandle(
171 const scoped_refptr
<RefCountedRegistration
>& registration
);
173 // Returns the BackgroundSyncRegistration corresponding to |handle_id|.
174 // Returns nullptr if the registration is not found.
175 BackgroundSyncRegistration
* GetRegistrationForHandle(
176 BackgroundSyncRegistrationHandle::HandleId handle_id
) const;
178 // The BackgroundSyncManager holds references to registrations that have
179 // active Handles. The handles must call this on destruction.
180 void ReleaseRegistrationHandle(
181 BackgroundSyncRegistrationHandle::HandleId handle_id
);
183 // Disable the manager. Already queued operations will abort once they start
184 // to run (in their impl methods). Future operations will not queue. Any
185 // registrations are cleared from memory and the backend (if it's still
186 // functioning). The manager will reenable itself once it receives the
187 // OnStorageWiped message or on browser restart.
188 void DisableAndClearManager(const base::Closure
& callback
);
189 void DisableAndClearDidGetRegistrations(
190 const base::Closure
& callback
,
191 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
192 ServiceWorkerStatusCode status
);
193 void DisableAndClearManagerClearedOne(const base::Closure
& barrier_closure
,
194 ServiceWorkerStatusCode status
);
196 // Returns the existing registration or nullptr if it cannot be found.
197 RefCountedRegistration
* LookupActiveRegistration(
198 int64 sw_registration_id
,
199 const RegistrationKey
& registration_key
);
201 // Write all registrations for a given |sw_registration_id| to persistent
203 void StoreRegistrations(int64 sw_registration_id
,
204 const ServiceWorkerStorage::StatusCallback
& callback
);
206 // Removes the active registration if it is in the map.
207 void RemoveActiveRegistration(int64 sw_registration_id
,
208 const RegistrationKey
& registration_key
);
210 void AddActiveRegistration(
211 int64 sw_registration_id
,
213 const scoped_refptr
<RefCountedRegistration
>& sync_registration
);
215 void InitImpl(const base::Closure
& callback
);
216 void InitDidGetDataFromBackend(
217 const base::Closure
& callback
,
218 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
219 ServiceWorkerStatusCode status
);
221 // Register callbacks
222 void RegisterImpl(int64 sw_registration_id
,
223 const BackgroundSyncRegistrationOptions
& options
,
224 bool requested_from_service_worker
,
225 const StatusAndRegistrationCallback
& callback
);
226 void RegisterDidStore(
227 int64 sw_registration_id
,
228 const scoped_refptr
<RefCountedRegistration
>& new_registration_ref
,
229 const StatusAndRegistrationCallback
& callback
,
230 ServiceWorkerStatusCode status
);
232 // Removes the background sync with periodicity |periodicity| and id
233 // |sync_registration_id|. Calls |callback| with
234 // BACKGROUND_SYNC_STATUS_NOT_FOUND if no match is found. Calls |callback|
235 // with BACKGROUND_SYNC_STATUS_OK on success.
236 void Unregister(int64 sw_registration_id
,
237 SyncPeriodicity periodicity
,
238 BackgroundSyncRegistrationHandle::HandleId handle_id
,
239 const StatusCallback
& callback
);
241 int64 sw_registration_id
,
242 const RegistrationKey
& key
,
243 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
244 SyncPeriodicity periodicity
,
245 const StatusCallback
& callback
);
246 void UnregisterDidStore(int64 sw_registration_id
,
247 SyncPeriodicity periodicity
,
248 const StatusCallback
& callback
,
249 ServiceWorkerStatusCode status
);
251 // NotifyWhenDone and its callbacks. See
252 // BackgroundSyncRegistrationHandle::NotifyWhenDone for detailed
254 void NotifyWhenDone(BackgroundSyncRegistrationHandle::HandleId handle_id
,
255 const StatusAndStateCallback
& callback
);
256 void NotifyWhenDoneImpl(
257 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
,
258 const StatusAndStateCallback
& callback
);
259 void NotifyWhenDoneDidFinish(const StatusAndStateCallback
& callback
,
260 BackgroundSyncState status
);
262 // GetRegistration callbacks
263 void GetRegistrationImpl(int64 sw_registration_id
,
264 const RegistrationKey
& registration_key
,
265 const StatusAndRegistrationCallback
& callback
);
267 // GetRegistrations callbacks
268 void GetRegistrationsImpl(int64 sw_registration_id
,
269 SyncPeriodicity periodicity
,
270 const StatusAndRegistrationsCallback
& callback
);
272 bool AreOptionConditionsMet(const BackgroundSyncRegistrationOptions
& options
);
273 bool IsRegistrationReadyToFire(
274 const BackgroundSyncRegistration
& registration
);
276 // Schedules pending registrations to run in the future. For one-shots this
277 // means keeping the browser alive so that network connectivity events can be
278 // seen (on Android the browser is instead woken up the next time it goes
279 // online). For periodic syncs this means creating an alarm.
280 void SchedulePendingRegistrations();
282 // FireReadyEvents and callbacks
283 void FireReadyEvents();
284 void FireReadyEventsImpl(const base::Closure
& callback
);
285 void FireReadyEventsDidFindRegistration(
286 const RegistrationKey
& registration_key
,
287 BackgroundSyncRegistration::RegistrationId registration_id
,
288 const base::Closure
& event_fired_callback
,
289 const base::Closure
& event_completed_callback
,
290 ServiceWorkerStatusCode service_worker_status
,
291 const scoped_refptr
<ServiceWorkerRegistration
>&
292 service_worker_registration
);
294 // Called when a sync event has completed.
296 const scoped_refptr
<ServiceWorkerRegistration
>&
297 service_worker_registration
,
298 int64 service_worker_id
,
299 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
,
300 const base::Closure
& callback
,
301 ServiceWorkerStatusCode status_code
);
302 void EventCompleteImpl(
303 int64 service_worker_id
,
304 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
,
305 ServiceWorkerStatusCode status_code
,
306 const base::Closure
& callback
);
307 void EventCompleteDidStore(int64 service_worker_id
,
308 const base::Closure
& callback
,
309 ServiceWorkerStatusCode status_code
);
311 // Called when all sync events have completed.
312 static void OnAllSyncEventsCompleted(const base::TimeTicks
& start_time
,
313 int number_of_batched_sync_events
);
315 // OnRegistrationDeleted callbacks
316 void OnRegistrationDeletedImpl(int64 registration_id
,
317 const base::Closure
& callback
);
319 // OnStorageWiped callbacks
320 void OnStorageWipedImpl(const base::Closure
& callback
);
322 void OnNetworkChanged();
323 void OnPowerChanged();
325 // Operation Scheduling callback and convenience functions.
326 template <typename CallbackT
, typename
... Params
>
327 void CompleteOperationCallback(const CallbackT
& callback
,
328 Params
... parameters
);
329 void CompleteStatusAndRegistrationCallback(
330 StatusAndRegistrationCallback callback
,
331 BackgroundSyncStatus status
,
332 scoped_ptr
<BackgroundSyncRegistrationHandle
> result
);
333 void CompleteStatusAndRegistrationsCallback(
334 StatusAndRegistrationsCallback callback
,
335 BackgroundSyncStatus status
,
336 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>> results
);
337 base::Closure
MakeEmptyCompletion();
338 base::Closure
MakeClosureCompletion(const base::Closure
& callback
);
339 StatusAndRegistrationCallback
MakeStatusAndRegistrationCompletion(
340 const StatusAndRegistrationCallback
& callback
);
341 StatusAndRegistrationsCallback
MakeStatusAndRegistrationsCompletion(
342 const StatusAndRegistrationsCallback
& callback
);
343 BackgroundSyncManager::StatusCallback
MakeStatusCompletion(
344 const StatusCallback
& callback
);
346 SWIdToRegistrationsMap active_registrations_
;
347 CacheStorageScheduler op_scheduler_
;
348 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context_
;
351 scoped_ptr
<BackgroundSyncNetworkObserver
> network_observer_
;
352 scoped_ptr
<BackgroundSyncPowerObserver
> power_observer_
;
354 // The registrations that clients have handles to.
355 IDMap
<scoped_refptr
<RefCountedRegistration
>, IDMapOwnPointer
>
356 registration_handle_ids_
;
358 base::WeakPtrFactory
<BackgroundSyncManager
> weak_ptr_factory_
;
360 DISALLOW_COPY_AND_ASSIGN(BackgroundSyncManager
);
363 } // namespace content
365 #endif // CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_MANAGER_H_