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 #include "content/browser/background_sync/background_sync_service_impl.h"
7 #include "background_sync_registration_handle.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/stl_util.h"
10 #include "content/browser/background_sync/background_sync_context_impl.h"
11 #include "content/public/browser/browser_thread.h"
17 // TODO(iclelland): Move these converters to mojo::TypeConverter template
20 BackgroundSyncRegistrationOptions
ToBackgroundSyncRegistrationOptions(
21 const SyncRegistrationPtr
& in
) {
22 BackgroundSyncRegistrationOptions out
;
25 out
.min_period
= in
->min_period_ms
;
26 out
.power_state
= static_cast<SyncPowerState
>(in
->power_state
);
27 out
.network_state
= static_cast<SyncNetworkState
>(in
->network_state
);
28 out
.periodicity
= static_cast<SyncPeriodicity
>(in
->periodicity
);
32 SyncRegistrationPtr
ToMojoRegistration(
33 const BackgroundSyncRegistrationHandle
& in
) {
34 SyncRegistrationPtr
out(content::SyncRegistration::New());
35 out
->handle_id
= in
.handle_id();
36 out
->tag
= in
.options()->tag
;
37 out
->min_period_ms
= in
.options()->min_period
;
38 out
->periodicity
= static_cast<content::BackgroundSyncPeriodicity
>(
39 in
.options()->periodicity
);
41 static_cast<content::BackgroundSyncPowerState
>(in
.options()->power_state
);
42 out
->network_state
= static_cast<content::BackgroundSyncNetworkState
>(
43 in
.options()->network_state
);
49 #define COMPILE_ASSERT_MATCHING_ENUM(mojo_name, manager_name) \
50 COMPILE_ASSERT(static_cast<int>(content::mojo_name) == \
51 static_cast<int>(content::manager_name), \
54 // TODO(iclelland): Move these tests somewhere else
55 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_ERROR_NONE
,
56 BACKGROUND_SYNC_STATUS_OK
);
57 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_ERROR_STORAGE
,
58 BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
59 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_ERROR_NOT_FOUND
,
60 BACKGROUND_SYNC_STATUS_NOT_FOUND
);
61 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_ERROR_NO_SERVICE_WORKER
,
62 BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER
);
63 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_ERROR_NOT_ALLOWED
,
64 BACKGROUND_SYNC_STATUS_NOT_ALLOWED
);
65 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_ERROR_MAX
,
66 BACKGROUND_SYNC_STATUS_NOT_ALLOWED
);
68 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_NETWORK_STATE_ANY
,
69 SyncNetworkState::NETWORK_STATE_ANY
);
70 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_NETWORK_STATE_AVOID_CELLULAR
,
71 SyncNetworkState::NETWORK_STATE_AVOID_CELLULAR
);
72 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_NETWORK_STATE_ONLINE
,
73 SyncNetworkState::NETWORK_STATE_ONLINE
);
74 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_NETWORK_STATE_MAX
,
75 SyncNetworkState::NETWORK_STATE_ONLINE
);
77 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_POWER_STATE_AUTO
,
78 SyncPowerState::POWER_STATE_AUTO
);
79 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_POWER_STATE_AVOID_DRAINING
,
80 SyncPowerState::POWER_STATE_AVOID_DRAINING
);
81 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_POWER_STATE_MAX
,
82 SyncPowerState::POWER_STATE_AVOID_DRAINING
);
84 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_PERIODICITY_PERIODIC
,
85 SyncPeriodicity::SYNC_PERIODIC
);
86 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_PERIODICITY_ONE_SHOT
,
87 SyncPeriodicity::SYNC_ONE_SHOT
);
88 COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_PERIODICITY_MAX
,
89 SyncPeriodicity::SYNC_ONE_SHOT
);
91 BackgroundSyncServiceImpl::~BackgroundSyncServiceImpl() {
92 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
93 DCHECK(background_sync_context_
->background_sync_manager());
96 BackgroundSyncServiceImpl::BackgroundSyncServiceImpl(
97 BackgroundSyncContextImpl
* background_sync_context
,
98 mojo::InterfaceRequest
<BackgroundSyncService
> request
)
99 : background_sync_context_(background_sync_context
),
100 binding_(this, request
.Pass()),
101 weak_ptr_factory_(this) {
102 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
103 DCHECK(background_sync_context
);
105 binding_
.set_connection_error_handler(
106 base::Bind(&BackgroundSyncServiceImpl::OnConnectionError
,
107 base::Unretained(this) /* the channel is owned by this */));
110 void BackgroundSyncServiceImpl::OnConnectionError() {
111 background_sync_context_
->ServiceHadConnectionError(this);
112 // |this| is now deleted.
115 void BackgroundSyncServiceImpl::Register(content::SyncRegistrationPtr options
,
116 int64_t sw_registration_id
,
117 bool requested_from_service_worker
,
118 const RegisterCallback
& callback
) {
119 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
121 BackgroundSyncRegistrationOptions mgr_options
=
122 ToBackgroundSyncRegistrationOptions(options
);
124 BackgroundSyncManager
* background_sync_manager
=
125 background_sync_context_
->background_sync_manager();
126 DCHECK(background_sync_manager
);
127 background_sync_manager
->Register(
128 sw_registration_id
, mgr_options
, requested_from_service_worker
,
129 base::Bind(&BackgroundSyncServiceImpl::OnRegisterResult
,
130 weak_ptr_factory_
.GetWeakPtr(), callback
));
133 void BackgroundSyncServiceImpl::Unregister(
134 BackgroundSyncPeriodicity periodicity
,
135 BackgroundSyncRegistrationHandle::HandleId handle_id
,
136 int64_t sw_registration_id
,
137 const UnregisterCallback
& callback
) {
138 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
140 BackgroundSyncRegistrationHandle
* registration
=
141 active_handles_
.Lookup(handle_id
);
143 callback
.Run(BACKGROUND_SYNC_ERROR_NOT_ALLOWED
);
147 registration
->Unregister(
149 base::Bind(&BackgroundSyncServiceImpl::OnUnregisterResult
,
150 weak_ptr_factory_
.GetWeakPtr(), callback
));
153 void BackgroundSyncServiceImpl::GetRegistration(
154 BackgroundSyncPeriodicity periodicity
,
155 const mojo::String
& tag
,
156 int64_t sw_registration_id
,
157 const GetRegistrationCallback
& callback
) {
158 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
159 BackgroundSyncManager
* background_sync_manager
=
160 background_sync_context_
->background_sync_manager();
161 DCHECK(background_sync_manager
);
162 background_sync_manager
->GetRegistration(
163 sw_registration_id
, tag
.get(), static_cast<SyncPeriodicity
>(periodicity
),
164 base::Bind(&BackgroundSyncServiceImpl::OnRegisterResult
,
165 weak_ptr_factory_
.GetWeakPtr(), callback
));
168 void BackgroundSyncServiceImpl::GetRegistrations(
169 BackgroundSyncPeriodicity periodicity
,
170 int64_t sw_registration_id
,
171 const GetRegistrationsCallback
& callback
) {
172 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
173 BackgroundSyncManager
* background_sync_manager
=
174 background_sync_context_
->background_sync_manager();
175 DCHECK(background_sync_manager
);
176 background_sync_manager
->GetRegistrations(
177 sw_registration_id
, static_cast<SyncPeriodicity
>(periodicity
),
178 base::Bind(&BackgroundSyncServiceImpl::OnGetRegistrationsResult
,
179 weak_ptr_factory_
.GetWeakPtr(), callback
));
182 void BackgroundSyncServiceImpl::GetPermissionStatus(
183 BackgroundSyncPeriodicity periodicity
,
184 int64_t sw_registration_id
,
185 const GetPermissionStatusCallback
& callback
) {
186 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
188 // TODO(iclelland): Implement a real policy. This is a stub implementation.
189 // OneShot: crbug.com/482091
190 // Periodic: crbug.com/482093
191 callback
.Run(BACKGROUND_SYNC_ERROR_NONE
, PERMISSION_STATUS_GRANTED
);
194 void BackgroundSyncServiceImpl::DuplicateRegistrationHandle(
195 BackgroundSyncRegistrationHandle::HandleId handle_id
,
196 const DuplicateRegistrationHandleCallback
& callback
) {
197 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
198 BackgroundSyncManager
* background_sync_manager
=
199 background_sync_context_
->background_sync_manager();
200 DCHECK(background_sync_manager
);
202 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
=
203 background_sync_manager
->DuplicateRegistrationHandle(handle_id
);
205 BackgroundSyncRegistrationHandle
* handle_ptr
= registration_handle
.get();
207 if (!registration_handle
) {
208 callback
.Run(BACKGROUND_SYNC_ERROR_NOT_FOUND
,
209 SyncRegistrationPtr(content::SyncRegistration::New()));
213 active_handles_
.AddWithID(registration_handle
.release(),
214 handle_ptr
->handle_id());
215 SyncRegistrationPtr mojoResult
= ToMojoRegistration(*handle_ptr
);
216 callback
.Run(BACKGROUND_SYNC_ERROR_NONE
, mojoResult
.Pass());
219 void BackgroundSyncServiceImpl::ReleaseRegistration(
220 BackgroundSyncRegistrationHandle::HandleId handle_id
) {
221 if (!active_handles_
.Lookup(handle_id
)) {
222 // TODO(jkarlin): Abort client.
223 LOG(WARNING
) << "Client attempted to release non-existing registration";
227 active_handles_
.Remove(handle_id
);
230 void BackgroundSyncServiceImpl::NotifyWhenDone(
231 BackgroundSyncRegistrationHandle::HandleId handle_id
,
232 const NotifyWhenDoneCallback
& callback
) {
233 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
234 BackgroundSyncRegistrationHandle
* registration
=
235 active_handles_
.Lookup(handle_id
);
237 callback
.Run(BACKGROUND_SYNC_ERROR_NOT_ALLOWED
,
238 BACKGROUND_SYNC_STATE_FAILED
);
242 registration
->NotifyWhenDone(
243 base::Bind(&BackgroundSyncServiceImpl::OnNotifyWhenDoneResult
,
244 weak_ptr_factory_
.GetWeakPtr(), callback
));
247 void BackgroundSyncServiceImpl::OnRegisterResult(
248 const RegisterCallback
& callback
,
249 BackgroundSyncStatus status
,
250 scoped_ptr
<BackgroundSyncRegistrationHandle
> result
) {
251 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
252 BackgroundSyncRegistrationHandle
* result_ptr
= result
.get();
254 if (status
!= BACKGROUND_SYNC_STATUS_OK
) {
255 callback
.Run(static_cast<content::BackgroundSyncError
>(status
),
256 SyncRegistrationPtr(content::SyncRegistration::New()));
260 active_handles_
.AddWithID(result
.release(), result_ptr
->handle_id());
261 SyncRegistrationPtr mojoResult
= ToMojoRegistration(*result_ptr
);
262 callback
.Run(static_cast<content::BackgroundSyncError
>(status
),
266 void BackgroundSyncServiceImpl::OnUnregisterResult(
267 const UnregisterCallback
& callback
,
268 BackgroundSyncStatus status
) {
269 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
270 callback
.Run(static_cast<content::BackgroundSyncError
>(status
));
273 void BackgroundSyncServiceImpl::OnGetRegistrationsResult(
274 const GetRegistrationsCallback
& callback
,
275 BackgroundSyncStatus status
,
276 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>>
277 result_registrations
) {
278 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
279 mojo::Array
<content::SyncRegistrationPtr
> mojo_registrations(0);
280 for (BackgroundSyncRegistrationHandle
* registration
: *result_registrations
) {
281 active_handles_
.AddWithID(registration
, registration
->handle_id());
282 mojo_registrations
.push_back(ToMojoRegistration(*registration
));
285 result_registrations
->weak_clear();
287 callback
.Run(static_cast<content::BackgroundSyncError
>(status
),
288 mojo_registrations
.Pass());
291 void BackgroundSyncServiceImpl::OnNotifyWhenDoneResult(
292 const NotifyWhenDoneCallback
& callback
,
293 BackgroundSyncStatus status
,
294 BackgroundSyncState sync_state
) {
295 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
296 callback
.Run(static_cast<content::BackgroundSyncError
>(status
), sync_state
);
299 } // namespace content