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/content_export.h"
25 #include "content/common/service_worker/service_worker_status_code.h"
30 class BackgroundSyncNetworkObserver
;
31 class BackgroundSyncPowerObserver
;
32 class ServiceWorkerContextWrapper
;
34 // BackgroundSyncManager manages and stores the set of background sync
35 // registrations across all registered service workers for a profile.
36 // Registrations are stored along with their associated Service Worker
37 // registration in ServiceWorkerStorage. If the ServiceWorker is unregistered,
38 // the sync registrations are removed. This class expects to be run on the IO
39 // thread. The asynchronous methods are executed sequentially.
41 // TODO(jkarlin): Check permissions when registering, scheduling, and firing
42 // background sync. In the meantime, --enable-service-worker-sync is required to
44 // TODO(jkarlin): Unregister syncs when permission is revoked.
45 // TODO(jkarlin): Create a background sync scheduler to actually run the
47 // TODO(jkarlin): Keep the browser alive if "Let Google Chrome Run in the
48 // Background" is true and a sync is registered.
49 class CONTENT_EXPORT BackgroundSyncManager
50 : NON_EXPORTED_BASE(public ServiceWorkerContextObserver
) {
52 using StatusCallback
= base::Callback
<void(BackgroundSyncStatus
)>;
53 using StatusAndRegistrationCallback
=
54 base::Callback
<void(BackgroundSyncStatus
,
55 scoped_ptr
<BackgroundSyncRegistrationHandle
>)>;
56 using StatusAndRegistrationsCallback
= base::Callback
<void(
58 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>>)>;
60 static scoped_ptr
<BackgroundSyncManager
> Create(
61 const scoped_refptr
<ServiceWorkerContextWrapper
>& service_worker_context
);
62 ~BackgroundSyncManager() override
;
64 // Stores the given background sync registration and adds it to the scheduling
65 // queue. It will overwrite an existing registration with the same tag and
66 // periodicity unless they're identical (save for the id). Calls |callback|
67 // with BACKGROUND_SYNC_STATUS_OK and the accepted registration on success.
68 // The accepted registration will have a unique id. It may also have altered
69 // parameters if the user or UA chose different parameters than those
71 void Register(int64 sw_registration_id
,
72 const BackgroundSyncRegistrationOptions
& options
,
73 bool requested_from_service_worker
,
74 const StatusAndRegistrationCallback
& callback
);
76 // Finds the background sync registration associated with
77 // |sw_registration_id| with periodicity |periodicity|. Calls
78 // |callback| with BACKGROUND_SYNC_STATUS_NOT_FOUND if it doesn't exist. Calls
79 // |callback| with BACKGROUND_SYNC_STATUS_OK on success.
80 void GetRegistration(int64 sw_registration_id
,
81 const std::string
& sync_registration_tag
,
82 SyncPeriodicity periodicity
,
83 const StatusAndRegistrationCallback
& callback
);
85 void GetRegistrations(int64 sw_registration_id
,
86 SyncPeriodicity periodicity
,
87 const StatusAndRegistrationsCallback
& callback
);
89 // Given a HandleId |handle_id|, return a new handle for the same
91 scoped_ptr
<BackgroundSyncRegistrationHandle
> DuplicateRegistrationHandle(
92 BackgroundSyncRegistrationHandle::HandleId handle_id
);
94 // ServiceWorkerContextObserver overrides.
95 void OnRegistrationDeleted(int64 registration_id
,
96 const GURL
& pattern
) override
;
97 void OnStorageWiped() override
;
100 // A registration might be referenced by the client longer than
101 // the BackgroundSyncManager needs to keep track of it (e.g., the event has
102 // finished firing). The BackgroundSyncManager reference counts its
103 // registrations internally and every BackgroundSyncRegistrationHandle has a
104 // unique handle id which maps to a locally maintained (in
105 // client_registration_ids_) scoped_refptr.
106 class RefCountedRegistration
;
108 explicit BackgroundSyncManager(
109 const scoped_refptr
<ServiceWorkerContextWrapper
>& context
);
111 // Init must be called before any public member function. Only call it once.
114 // The following methods are virtual for testing.
115 virtual void StoreDataInBackend(
116 int64 sw_registration_id
,
118 const std::string
& backend_key
,
119 const std::string
& data
,
120 const ServiceWorkerStorage::StatusCallback
& callback
);
121 virtual void GetDataFromBackend(
122 const std::string
& backend_key
,
123 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback
&
125 virtual void FireOneShotSync(
126 BackgroundSyncRegistrationHandle::HandleId handle_id
,
127 const scoped_refptr
<ServiceWorkerVersion
>& active_version
,
128 const ServiceWorkerVersion::StatusCallback
& callback
);
131 friend class BackgroundSyncRegistrationHandle
;
133 class RegistrationKey
{
135 explicit RegistrationKey(const BackgroundSyncRegistration
& registration
);
136 explicit RegistrationKey(const BackgroundSyncRegistrationOptions
& options
);
137 RegistrationKey(const std::string
& tag
, SyncPeriodicity periodicity
);
138 RegistrationKey(const RegistrationKey
& other
) = default;
139 RegistrationKey
& operator=(const RegistrationKey
& other
) = default;
141 bool operator<(const RegistrationKey
& rhs
) const {
142 return value_
< rhs
.value_
;
149 struct BackgroundSyncRegistrations
{
150 using RegistrationMap
=
151 std::map
<RegistrationKey
, scoped_refptr
<RefCountedRegistration
>>;
153 BackgroundSyncRegistrations();
154 ~BackgroundSyncRegistrations();
156 RegistrationMap registration_map
;
157 BackgroundSyncRegistration::RegistrationId next_id
;
161 using PermissionStatusCallback
= base::Callback
<void(bool)>;
162 using SWIdToRegistrationsMap
= std::map
<int64
, BackgroundSyncRegistrations
>;
164 scoped_ptr
<BackgroundSyncRegistrationHandle
> CreateRegistrationHandle(
165 const scoped_refptr
<RefCountedRegistration
>& registration
);
167 // Returns the BackgroundSyncRegistration corresponding to |handle_id|.
168 // Returns nullptr if the registration is not found.
169 BackgroundSyncRegistration
* GetRegistrationForHandle(
170 BackgroundSyncRegistrationHandle::HandleId handle_id
) const;
172 // The BackgroundSyncManager holds references to registrations that have
173 // active Handles. The handles must call this on destruction.
174 void ReleaseRegistrationHandle(
175 BackgroundSyncRegistrationHandle::HandleId handle_id
);
177 // Disable the manager. Already queued operations will abort once they start
178 // to run (in their impl methods). Future operations will not queue. Any
179 // registrations are cleared from memory and the backend (if it's still
180 // functioning). The manager will reenable itself once it receives the
181 // OnStorageWiped message or on browser restart.
182 void DisableAndClearManager(const base::Closure
& callback
);
183 void DisableAndClearDidGetRegistrations(
184 const base::Closure
& callback
,
185 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
186 ServiceWorkerStatusCode status
);
187 void DisableAndClearManagerClearedOne(const base::Closure
& barrier_closure
,
188 ServiceWorkerStatusCode status
);
190 // Returns the existing registration or nullptr if it cannot be found.
191 RefCountedRegistration
* LookupActiveRegistration(
192 int64 sw_registration_id
,
193 const RegistrationKey
& registration_key
);
195 // Write all registrations for a given |sw_registration_id| to persistent
197 void StoreRegistrations(int64 sw_registration_id
,
198 const ServiceWorkerStorage::StatusCallback
& callback
);
200 // Removes the active registration if it is in the map.
201 void RemoveActiveRegistration(int64 sw_registration_id
,
202 const RegistrationKey
& registration_key
);
204 void AddActiveRegistration(
205 int64 sw_registration_id
,
207 const scoped_refptr
<RefCountedRegistration
>& sync_registration
);
209 void InitImpl(const base::Closure
& callback
);
210 void InitDidGetDataFromBackend(
211 const base::Closure
& callback
,
212 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
213 ServiceWorkerStatusCode status
);
215 // Register callbacks
216 void RegisterImpl(int64 sw_registration_id
,
217 const BackgroundSyncRegistrationOptions
& options
,
218 bool requested_from_service_worker
,
219 const StatusAndRegistrationCallback
& callback
);
220 void RegisterDidStore(
221 int64 sw_registration_id
,
222 const scoped_refptr
<RefCountedRegistration
>& new_registration_ref
,
223 const StatusAndRegistrationCallback
& callback
,
224 ServiceWorkerStatusCode status
);
226 // Removes the background sync with periodicity |periodicity| and id
227 // |sync_registration_id|. Calls |callback| with
228 // BACKGROUND_SYNC_STATUS_NOT_FOUND if no match is found. Calls |callback|
229 // with BACKGROUND_SYNC_STATUS_OK on success.
230 void Unregister(int64 sw_registration_id
,
231 SyncPeriodicity periodicity
,
232 BackgroundSyncRegistrationHandle::HandleId handle_id
,
233 const StatusCallback
& callback
);
235 int64 sw_registration_id
,
236 const RegistrationKey
& key
,
237 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
238 SyncPeriodicity periodicity
,
239 const StatusCallback
& callback
);
240 void UnregisterDidStore(int64 sw_registration_id
,
241 SyncPeriodicity periodicity
,
242 const StatusCallback
& callback
,
243 ServiceWorkerStatusCode status
);
245 // GetRegistration callbacks
246 void GetRegistrationImpl(int64 sw_registration_id
,
247 const RegistrationKey
& registration_key
,
248 const StatusAndRegistrationCallback
& callback
);
250 // GetRegistrations callbacks
251 void GetRegistrationsImpl(int64 sw_registration_id
,
252 SyncPeriodicity periodicity
,
253 const StatusAndRegistrationsCallback
& callback
);
255 bool AreOptionConditionsMet(const BackgroundSyncRegistrationOptions
& options
);
256 bool IsRegistrationReadyToFire(
257 const BackgroundSyncRegistration
& registration
);
259 // Schedules pending registrations to run in the future. For one-shots this
260 // means keeping the browser alive so that network connectivity events can be
261 // seen (on Android the browser is instead woken up the next time it goes
262 // online). For periodic syncs this means creating an alarm.
263 void SchedulePendingRegistrations();
265 // FireReadyEvents and callbacks
266 void FireReadyEvents();
267 void FireReadyEventsImpl(const base::Closure
& callback
);
268 void FireReadyEventsDidFindRegistration(
269 const RegistrationKey
& registration_key
,
270 BackgroundSyncRegistration::RegistrationId registration_id
,
271 const base::Closure
& event_fired_callback
,
272 const base::Closure
& event_completed_callback
,
273 ServiceWorkerStatusCode service_worker_status
,
274 const scoped_refptr
<ServiceWorkerRegistration
>&
275 service_worker_registration
);
277 // Called when a sync event has completed.
279 const scoped_refptr
<ServiceWorkerRegistration
>&
280 service_worker_registration
,
281 int64 service_worker_id
,
282 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
,
283 const base::Closure
& callback
,
284 ServiceWorkerStatusCode status_code
);
285 void EventCompleteImpl(
286 int64 service_worker_id
,
287 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
,
288 ServiceWorkerStatusCode status_code
,
289 const base::Closure
& callback
);
290 void EventCompleteDidStore(int64 service_worker_id
,
291 const base::Closure
& callback
,
292 ServiceWorkerStatusCode status_code
);
294 // Called when all sync events have completed.
295 static void OnAllSyncEventsCompleted(const base::TimeTicks
& start_time
,
296 int number_of_batched_sync_events
);
298 // OnRegistrationDeleted callbacks
299 void OnRegistrationDeletedImpl(int64 registration_id
,
300 const base::Closure
& callback
);
302 // OnStorageWiped callbacks
303 void OnStorageWipedImpl(const base::Closure
& callback
);
305 void OnNetworkChanged();
306 void OnPowerChanged();
308 // Operation Scheduling callback and convenience functions.
309 template <typename CallbackT
, typename
... Params
>
310 void CompleteOperationCallback(const CallbackT
& callback
,
311 Params
... parameters
);
312 void CompleteStatusAndRegistrationCallback(
313 StatusAndRegistrationCallback callback
,
314 BackgroundSyncStatus status
,
315 scoped_ptr
<BackgroundSyncRegistrationHandle
> result
);
316 void CompleteStatusAndRegistrationsCallback(
317 StatusAndRegistrationsCallback callback
,
318 BackgroundSyncStatus status
,
319 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>> results
);
320 base::Closure
MakeEmptyCompletion();
321 base::Closure
MakeClosureCompletion(const base::Closure
& callback
);
322 StatusAndRegistrationCallback
MakeStatusAndRegistrationCompletion(
323 const StatusAndRegistrationCallback
& callback
);
324 StatusAndRegistrationsCallback
MakeStatusAndRegistrationsCompletion(
325 const StatusAndRegistrationsCallback
& callback
);
326 BackgroundSyncManager::StatusCallback
MakeStatusCompletion(
327 const StatusCallback
& callback
);
329 SWIdToRegistrationsMap active_registrations_
;
330 CacheStorageScheduler op_scheduler_
;
331 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context_
;
334 scoped_ptr
<BackgroundSyncNetworkObserver
> network_observer_
;
335 scoped_ptr
<BackgroundSyncPowerObserver
> power_observer_
;
337 // The registrations that clients have handles to.
338 IDMap
<scoped_refptr
<RefCountedRegistration
>, IDMapOwnPointer
>
339 registration_handle_ids_
;
341 base::WeakPtrFactory
<BackgroundSyncManager
> weak_ptr_factory_
;
343 DISALLOW_COPY_AND_ASSIGN(BackgroundSyncManager
);
346 } // namespace content
348 #endif // CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_MANAGER_H_