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_
11 #include "base/callback_forward.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "content/browser/background_sync/background_sync.pb.h"
15 #include "content/browser/cache_storage/cache_storage_scheduler.h"
16 #include "content/browser/service_worker/service_worker_context_observer.h"
17 #include "content/browser/service_worker/service_worker_storage.h"
18 #include "content/common/content_export.h"
19 #include "content/common/service_worker/service_worker_status_code.h"
24 class BackgroundSyncNetworkObserver
;
25 class BackgroundSyncPowerObserver
;
26 class ServiceWorkerContextWrapper
;
28 // BackgroundSyncManager manages and stores the set of background sync
29 // registrations across all registered service workers for a profile.
30 // Registrations are stored along with their associated Service Worker
31 // registration in ServiceWorkerStorage. If the ServiceWorker is unregistered,
32 // the sync registrations are removed. This class expects to be run on the IO
33 // thread. The asynchronous methods are executed sequentially.
35 // TODO(jkarlin): Check permissions when registering, scheduling, and firing
36 // background sync. In the meantime, --enable-service-worker-sync is required to
38 // TODO(jkarlin): Unregister syncs when permission is revoked.
39 // TODO(jkarlin): Create a background sync scheduler to actually run the
41 // TODO(jkarlin): Keep the browser alive if "Let Google Chrome Run in the
42 // Background" is true and a sync is registered.
43 class CONTENT_EXPORT BackgroundSyncManager
44 : NON_EXPORTED_BASE(public ServiceWorkerContextObserver
) {
50 ERROR_TYPE_NO_SERVICE_WORKER
53 // TODO(jkarlin): Remove this and use the struct from IPC messages once it
55 struct CONTENT_EXPORT BackgroundSyncRegistration
{
56 using RegistrationId
= int64
;
57 static const RegistrationId kInvalidRegistrationId
;
58 static const RegistrationId kInitialId
;
59 BackgroundSyncRegistration() {}
61 bool Equals(const BackgroundSyncRegistration
& other
) const {
62 return this->tag
== other
.tag
&& this->periodicity
== other
.periodicity
&&
63 this->min_period
== other
.min_period
&&
64 network_state
== other
.network_state
&&
65 power_state
== other
.power_state
;
68 // Registrations options from the specification
71 SyncNetworkState network_state
= NETWORK_STATE_ONLINE
;
72 SyncPowerState power_state
= POWER_STATE_AVOID_DRAINING
;
74 // Implementation specific members
75 RegistrationId id
= kInvalidRegistrationId
;
76 SyncPeriodicity periodicity
= SYNC_ONE_SHOT
;
77 SyncState sync_state
= SYNC_STATE_PENDING
;
80 using StatusCallback
= base::Callback
<void(ErrorType
)>;
81 using StatusAndRegistrationCallback
=
82 base::Callback
<void(ErrorType
, const BackgroundSyncRegistration
&)>;
83 using StatusAndRegistrationsCallback
=
84 base::Callback
<void(ErrorType
,
85 const std::vector
<BackgroundSyncRegistration
>&)>;
87 static scoped_ptr
<BackgroundSyncManager
> Create(
88 const scoped_refptr
<ServiceWorkerContextWrapper
>& service_worker_context
);
89 ~BackgroundSyncManager() override
;
91 // Stores the given background sync registration and adds it to the scheduling
92 // queue. It will overwrite an existing registration with the same tag and
93 // periodicity unless they're identical (save for the id). Calls |callback|
94 // with ErrorTypeOK and the accepted registration on success. The accepted
95 // registration will have a unique id. It may also have altered parameters if
96 // the user or UA chose different parameters than those supplied.
97 void Register(int64 sw_registration_id
,
98 const BackgroundSyncRegistration
& sync_registration
,
99 const StatusAndRegistrationCallback
& callback
);
101 // Removes the background sync with tag |sync_registration_tag|, periodicity
102 // |periodicity|, and id |sync_registration_id|. Calls |callback| with
103 // ErrorTypeNotFound if no match is found. Calls |callback| with ErrorTypeOK
106 int64 sw_registration_id
,
107 const std::string
& sync_registration_tag
,
108 SyncPeriodicity periodicity
,
109 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
110 const StatusCallback
& callback
);
112 // Finds the background sync registration associated with
113 // |sw_registration_id| with periodicity |periodicity|. Calls
114 // |callback| with ErrorTypeNotFound if it doesn't exist. Calls |callback|
115 // with ErrorTypeOK on success.
116 void GetRegistration(int64 sw_registration_id
,
117 const std::string
& sync_registration_tag
,
118 SyncPeriodicity periodicity
,
119 const StatusAndRegistrationCallback
& callback
);
121 void GetRegistrations(int64 sw_registration_id
,
122 SyncPeriodicity periodicity
,
123 const StatusAndRegistrationsCallback
& callback
);
125 // ServiceWorkerContextObserver overrides.
126 void OnRegistrationDeleted(int64 registration_id
,
127 const GURL
& pattern
) override
;
128 void OnStorageWiped() override
;
131 explicit BackgroundSyncManager(
132 const scoped_refptr
<ServiceWorkerContextWrapper
>& context
);
134 // Init must be called before any public member function. Only call it once.
137 // The following methods are virtual for testing.
138 virtual void StoreDataInBackend(
139 int64 sw_registration_id
,
141 const std::string
& backend_key
,
142 const std::string
& data
,
143 const ServiceWorkerStorage::StatusCallback
& callback
);
144 virtual void GetDataFromBackend(
145 const std::string
& backend_key
,
146 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback
&
148 virtual void FireOneShotSync(
149 const scoped_refptr
<ServiceWorkerVersion
>& active_version
,
150 const ServiceWorkerVersion::StatusCallback
& callback
);
153 class RegistrationKey
{
155 explicit RegistrationKey(const BackgroundSyncRegistration
& registration
);
156 RegistrationKey(const std::string
& tag
, SyncPeriodicity periodicity
);
157 RegistrationKey(const RegistrationKey
& other
) = default;
158 RegistrationKey
& operator=(const RegistrationKey
& other
) = default;
160 bool operator<(const RegistrationKey
& rhs
) const {
161 return value_
< rhs
.value_
;
168 struct BackgroundSyncRegistrations
{
169 using RegistrationMap
=
170 std::map
<RegistrationKey
, BackgroundSyncRegistration
>;
172 BackgroundSyncRegistrations();
173 ~BackgroundSyncRegistrations();
175 RegistrationMap registration_map
;
176 BackgroundSyncRegistration::RegistrationId next_id
;
180 using PermissionStatusCallback
= base::Callback
<void(bool)>;
181 using SWIdToRegistrationsMap
= std::map
<int64
, BackgroundSyncRegistrations
>;
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 in |existing_registration| if it is not
198 BackgroundSyncRegistration
* LookupRegistration(
199 int64 sw_registration_id
,
200 const RegistrationKey
& registration_key
);
202 // Store all registrations for a given |sw_registration_id|.
203 void StoreRegistrations(int64 sw_registration_id
,
204 const ServiceWorkerStorage::StatusCallback
& callback
);
206 // Removes the registration if it is in the map.
207 void RemoveRegistrationFromMap(int64 sw_registration_id
,
208 const RegistrationKey
& registration_key
);
210 void AddRegistrationToMap(
211 int64 sw_registration_id
,
213 const BackgroundSyncRegistration
& 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 BackgroundSyncRegistration
& sync_registration
,
224 const StatusAndRegistrationCallback
& callback
);
225 void RegisterDidStore(int64 sw_registration_id
,
226 const BackgroundSyncRegistration
& sync_registration
,
227 const StatusAndRegistrationCallback
& callback
,
228 ServiceWorkerStatusCode status
);
230 // Unregister callbacks
232 int64 sw_registration_id
,
233 const RegistrationKey
& registration_key
,
234 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
235 const StatusCallback
& callback
);
236 void UnregisterDidStore(
237 int64 sw_registration_id
,
238 const StatusCallback
& callback
,
239 ServiceWorkerStatusCode status
);
241 // GetRegistration callbacks
242 void GetRegistrationImpl(int64 sw_registration_id
,
243 const RegistrationKey
& registration_key
,
244 const StatusAndRegistrationCallback
& callback
);
246 // GetRegistrations callbacks
247 void GetRegistrationsImpl(int64 sw_registration_id
,
248 SyncPeriodicity periodicity
,
249 const StatusAndRegistrationsCallback
& callback
);
251 bool IsRegistrationReadyToFire(
252 const BackgroundSyncRegistration
& registration
);
254 // Schedules pending registrations to run in the future. For one-shots this
255 // means keeping the browser alive so that network connectivity events can be
256 // seen (on Android the browser is instead woken up the next time it goes
257 // online). For periodic syncs this means creating an alarm.
258 void SchedulePendingRegistrations();
260 // FireReadyEvents and callbacks
261 void FireReadyEvents();
262 void FireReadyEventsImpl(const base::Closure
& callback
);
263 void FireReadyEventsDidFindRegistration(
264 const RegistrationKey
& registration_key
,
265 BackgroundSyncRegistration::RegistrationId registration_id
,
266 const base::Closure
& callback
,
267 ServiceWorkerStatusCode service_worker_status
,
268 const scoped_refptr
<ServiceWorkerRegistration
>&
269 service_worker_registration
);
271 // Called when a sync event has completed.
273 const scoped_refptr
<ServiceWorkerRegistration
>&
274 service_worker_registration
,
275 int64 service_worker_id
,
276 const RegistrationKey
& key
,
277 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
278 ServiceWorkerStatusCode status_code
);
279 void EventCompleteImpl(
280 int64 service_worker_id
,
281 const RegistrationKey
& key
,
282 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
283 ServiceWorkerStatusCode status_code
,
284 const base::Closure
& callback
);
285 void EventCompleteDidStore(int64 service_worker_id
,
286 const base::Closure
& callback
,
287 ServiceWorkerStatusCode status_code
);
289 // OnRegistrationDeleted callbacks
290 void OnRegistrationDeletedImpl(int64 registration_id
,
291 const base::Closure
& callback
);
293 // OnStorageWiped callbacks
294 void OnStorageWipedImpl(const base::Closure
& callback
);
296 void OnNetworkChanged();
297 void OnPowerChanged();
299 // Operation Scheduling callback and convenience functions.
300 template <typename CallbackT
, typename
... Params
>
301 void CompleteOperationCallback(const CallbackT
& callback
,
302 Params
... parameters
);
303 base::Closure
MakeEmptyCompletion();
304 StatusAndRegistrationCallback
MakeStatusAndRegistrationCompletion(
305 const StatusAndRegistrationCallback
& callback
);
306 StatusAndRegistrationsCallback
MakeStatusAndRegistrationsCompletion(
307 const StatusAndRegistrationsCallback
& callback
);
308 BackgroundSyncManager::StatusCallback
MakeStatusCompletion(
309 const StatusCallback
& callback
);
311 SWIdToRegistrationsMap sw_to_registrations_map_
;
312 CacheStorageScheduler op_scheduler_
;
313 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context_
;
316 scoped_ptr
<BackgroundSyncNetworkObserver
> network_observer_
;
317 scoped_ptr
<BackgroundSyncPowerObserver
> power_observer_
;
319 base::WeakPtrFactory
<BackgroundSyncManager
> weak_ptr_factory_
;
321 DISALLOW_COPY_AND_ASSIGN(BackgroundSyncManager
);
324 } // namespace content
326 #endif // CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_MANAGER_H_