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 ServiceWorkerContextWrapper
;
27 // BackgroundSyncManager manages and stores the set of background sync
28 // registrations across all registered service workers for a profile.
29 // Registrations are stored along with their associated Service Worker
30 // registration in ServiceWorkerStorage. If the ServiceWorker is unregistered,
31 // the sync registrations are removed. This class expects to be run on the IO
32 // thread. The asynchronous methods are executed sequentially.
34 // TODO(jkarlin): Check permissions when registering, scheduling, and firing
35 // background sync. In the meantime, --enable-service-worker-sync is required to
37 // TODO(jkarlin): Unregister syncs when permission is revoked.
38 // TODO(jkarlin): Create a background sync scheduler to actually run the
40 // TODO(jkarlin): Keep the browser alive if "Let Google Chrome Run in the
41 // Background" is true and a sync is registered.
42 class CONTENT_EXPORT BackgroundSyncManager
43 : NON_EXPORTED_BASE(public ServiceWorkerContextObserver
) {
51 // TODO(jkarlin): Remove this and use the struct from IPC messages once it
53 struct CONTENT_EXPORT BackgroundSyncRegistration
{
54 using RegistrationId
= int64
;
55 static const RegistrationId kInvalidRegistrationId
;
56 static const RegistrationId kInitialId
;
57 BackgroundSyncRegistration() {}
59 bool Equals(const BackgroundSyncRegistration
& other
) const {
60 return this->tag
== other
.tag
&& this->periodicity
== other
.periodicity
&&
61 this->min_period
== other
.min_period
&&
62 network_state
== other
.network_state
&&
63 power_state
== other
.power_state
;
66 RegistrationId id
= kInvalidRegistrationId
;
68 SyncPeriodicity periodicity
= SYNC_ONE_SHOT
;
70 SyncNetworkState network_state
= NETWORK_STATE_ONLINE
;
71 SyncPowerState power_state
= POWER_STATE_AVOID_DRAINING
;
74 using StatusCallback
= base::Callback
<void(ErrorType
)>;
75 using StatusAndRegistrationCallback
=
76 base::Callback
<void(ErrorType
, const BackgroundSyncRegistration
&)>;
78 static scoped_ptr
<BackgroundSyncManager
> Create(
79 const scoped_refptr
<ServiceWorkerContextWrapper
>& service_worker_context
);
80 ~BackgroundSyncManager() override
;
82 // Stores the given background sync registration and adds it to the scheduling
83 // queue. It will overwrite an existing registration with the same tag and
84 // periodicity unless they're identical (save for the id). Calls |callback|
85 // with ErrorTypeOK and the accepted registration on success. The accepted
86 // registration will have a unique id. It may also have altered parameters if
87 // the user or UA chose different parameters than those supplied.
88 void Register(const GURL
& origin
,
89 int64 sw_registration_id
,
90 const BackgroundSyncRegistration
& sync_registration
,
91 const StatusAndRegistrationCallback
& callback
);
93 // Removes the background sync with tag |sync_registration_tag|, periodicity
94 // |periodicity|, and id |sync_registration_id|. Calls |callback| with
95 // ErrorTypeNotFound if no match is found. Calls |callback| with ErrorTypeOK
99 int64 sw_registration_id
,
100 const std::string
& sync_registration_tag
,
101 SyncPeriodicity periodicity
,
102 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
103 const StatusCallback
& callback
);
105 // Finds the background sync registration associated with
106 // |sw_registration_id| with periodicity |periodicity|. Calls
107 // |callback| with ErrorTypeNotFound if it doesn't exist. Calls |callback|
108 // with ErrorTypeOK on success.
109 void GetRegistration(const GURL
& origin
,
110 int64 sw_registration_id
,
111 const std::string sync_registration_tag
,
112 SyncPeriodicity periodicity
,
113 const StatusAndRegistrationCallback
& callback
);
115 // ServiceWorkerContextObserver overrides.
116 void OnRegistrationDeleted(int64 registration_id
,
117 const GURL
& pattern
) override
;
118 void OnStorageWiped() override
;
121 explicit BackgroundSyncManager(
122 const scoped_refptr
<ServiceWorkerContextWrapper
>& context
);
124 // Init must be called before any public member function. Only call it once.
127 // The following methods are virtual for testing.
128 virtual void StoreDataInBackend(
129 int64 sw_registration_id
,
131 const std::string
& backend_key
,
132 const std::string
& data
,
133 const ServiceWorkerStorage::StatusCallback
& callback
);
134 virtual void GetDataFromBackend(
135 const std::string
& backend_key
,
136 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback
&
140 class RegistrationKey
{
142 explicit RegistrationKey(const BackgroundSyncRegistration
& registration
);
143 RegistrationKey(const std::string
& tag
, SyncPeriodicity periodicity
);
144 RegistrationKey(const RegistrationKey
& other
) = default;
145 RegistrationKey
& operator=(const RegistrationKey
& other
) = default;
147 bool operator<(const RegistrationKey
& rhs
) const {
148 return value_
< rhs
.value_
;
155 struct BackgroundSyncRegistrations
{
156 using RegistrationMap
=
157 std::map
<RegistrationKey
, BackgroundSyncRegistration
>;
159 BackgroundSyncRegistrations();
160 ~BackgroundSyncRegistrations();
162 RegistrationMap registration_map
;
163 BackgroundSyncRegistration::RegistrationId next_id
;
167 using PermissionStatusCallback
= base::Callback
<void(bool)>;
168 using SWIdToRegistrationsMap
= std::map
<int64
, BackgroundSyncRegistrations
>;
170 // Disable the manager. Already queued operations will abort once they start
171 // to run (in their impl methods). Future operations will not queue. Any
172 // registrations are cleared from memory and the backend (if it's still
173 // functioning). The manager will reenable itself once it receives the
174 // OnStorageWiped message or on browser restart.
175 void DisableAndClearManager(const base::Closure
& callback
);
176 void DisableAndClearDidGetRegistrations(
177 const base::Closure
& callback
,
178 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
179 ServiceWorkerStatusCode status
);
180 void DisableAndClearManagerClearedOne(const base::Closure
& barrier_closure
,
181 ServiceWorkerStatusCode status
);
183 // Returns the existing registration in |existing_registration| if it is not
185 BackgroundSyncRegistration
* LookupRegistration(
186 int64 sw_registration_id
,
187 const RegistrationKey
& registration_key
);
189 // Store all registrations for a given |sw_registration_id|.
190 void StoreRegistrations(int64 sw_registration_id
,
191 const ServiceWorkerStorage::StatusCallback
& callback
);
193 // Removes the registration if it is in the map.
194 void RemoveRegistrationFromMap(int64 sw_registration_id
,
195 const RegistrationKey
& registration_key
);
197 void AddRegistrationToMap(
198 int64 sw_registration_id
,
200 const BackgroundSyncRegistration
& sync_registration
);
202 void InitImpl(const base::Closure
& callback
);
203 void InitDidGetDataFromBackend(
204 const base::Closure
& callback
,
205 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
206 ServiceWorkerStatusCode status
);
208 // Register callbacks
209 void RegisterImpl(const GURL
& origin
,
210 int64 sw_registration_id
,
211 const BackgroundSyncRegistration
& sync_registration
,
212 const StatusAndRegistrationCallback
& callback
);
213 void RegisterDidStore(int64 sw_registration_id
,
214 const BackgroundSyncRegistration
& sync_registration
,
215 const StatusAndRegistrationCallback
& callback
,
216 ServiceWorkerStatusCode status
);
218 // Unregister callbacks
221 int64 sw_registration_id
,
222 const RegistrationKey
& registration_key
,
223 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
224 const StatusCallback
& callback
);
225 void UnregisterDidStore(
226 int64 sw_registration_id
,
227 const StatusCallback
& callback
,
228 ServiceWorkerStatusCode status
);
230 // GetRegistration callbacks
231 void GetRegistrationImpl(const GURL
& origin
,
232 int64 sw_registration_id
,
233 const RegistrationKey
& registration_key
,
234 const StatusAndRegistrationCallback
& callback
);
236 // OnRegistrationDeleted callbacks
237 void OnRegistrationDeletedImpl(int64 registration_id
,
238 const base::Closure
& callback
);
240 // OnStorageWiped callbacks
241 void OnStorageWipedImpl(const base::Closure
& callback
);
243 void OnNetworkChanged();
245 // Operation Scheduling callbacks
246 void PendingStatusAndRegistrationCallback(
247 const StatusAndRegistrationCallback
& callback
,
249 const BackgroundSyncRegistration
& sync_registration
);
250 void PendingStatusCallback(const StatusCallback
& callback
, ErrorType error
);
251 void PendingClosure(const base::Closure
& closure
);
253 StatusAndRegistrationCallback
MakeStatusAndRegistrationCompletion(
254 const StatusAndRegistrationCallback
& callback
);
255 BackgroundSyncManager::StatusCallback
MakeStatusCompletion(
256 const StatusCallback
& callback
);
257 base::Closure
MakeEmptyCompletion();
259 SWIdToRegistrationsMap sw_to_registrations_map_
;
260 CacheStorageScheduler op_scheduler_
;
261 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context_
;
264 scoped_ptr
<BackgroundSyncNetworkObserver
> network_observer_
;
266 base::WeakPtrFactory
<BackgroundSyncManager
> weak_ptr_factory_
;
268 DISALLOW_COPY_AND_ASSIGN(BackgroundSyncManager
);
271 } // namespace content
273 #endif // CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_MANAGER_H_