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
);
139 BackgroundSyncManager
* background_sync_manager
=
140 background_sync_context_
->background_sync_manager();
141 DCHECK(background_sync_manager
);
143 BackgroundSyncRegistrationHandle
* registration
=
144 active_handles_
.Lookup(handle_id
);
146 callback
.Run(BACKGROUND_SYNC_ERROR_NOT_ALLOWED
);
150 registration
->Unregister(
152 base::Bind(&BackgroundSyncServiceImpl::OnUnregisterResult
,
153 weak_ptr_factory_
.GetWeakPtr(), callback
));
156 void BackgroundSyncServiceImpl::GetRegistration(
157 BackgroundSyncPeriodicity periodicity
,
158 const mojo::String
& tag
,
159 int64_t sw_registration_id
,
160 const GetRegistrationCallback
& callback
) {
161 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
162 BackgroundSyncManager
* background_sync_manager
=
163 background_sync_context_
->background_sync_manager();
164 DCHECK(background_sync_manager
);
165 background_sync_manager
->GetRegistration(
166 sw_registration_id
, tag
.get(), static_cast<SyncPeriodicity
>(periodicity
),
167 base::Bind(&BackgroundSyncServiceImpl::OnRegisterResult
,
168 weak_ptr_factory_
.GetWeakPtr(), callback
));
171 void BackgroundSyncServiceImpl::GetRegistrations(
172 BackgroundSyncPeriodicity periodicity
,
173 int64_t sw_registration_id
,
174 const GetRegistrationsCallback
& callback
) {
175 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
176 BackgroundSyncManager
* background_sync_manager
=
177 background_sync_context_
->background_sync_manager();
178 DCHECK(background_sync_manager
);
179 background_sync_manager
->GetRegistrations(
180 sw_registration_id
, static_cast<SyncPeriodicity
>(periodicity
),
181 base::Bind(&BackgroundSyncServiceImpl::OnGetRegistrationsResult
,
182 weak_ptr_factory_
.GetWeakPtr(), callback
));
185 void BackgroundSyncServiceImpl::GetPermissionStatus(
186 BackgroundSyncPeriodicity periodicity
,
187 int64_t sw_registration_id
,
188 const GetPermissionStatusCallback
& callback
) {
189 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
191 // TODO(iclelland): Implement a real policy. This is a stub implementation.
192 // OneShot: crbug.com/482091
193 // Periodic: crbug.com/482093
194 callback
.Run(BACKGROUND_SYNC_ERROR_NONE
, PERMISSION_STATUS_GRANTED
);
197 void BackgroundSyncServiceImpl::DuplicateRegistrationHandle(
198 BackgroundSyncRegistrationHandle::HandleId handle_id
,
199 const DuplicateRegistrationHandleCallback
& callback
) {
200 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
201 BackgroundSyncManager
* background_sync_manager
=
202 background_sync_context_
->background_sync_manager();
203 DCHECK(background_sync_manager
);
205 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
=
206 background_sync_manager
->DuplicateRegistrationHandle(handle_id
);
208 BackgroundSyncRegistrationHandle
* handle_ptr
= registration_handle
.get();
210 if (!registration_handle
) {
211 callback
.Run(BACKGROUND_SYNC_ERROR_NOT_FOUND
,
212 SyncRegistrationPtr(content::SyncRegistration::New()));
216 active_handles_
.AddWithID(registration_handle
.release(),
217 handle_ptr
->handle_id());
218 SyncRegistrationPtr mojoResult
= ToMojoRegistration(*handle_ptr
);
219 callback
.Run(BACKGROUND_SYNC_ERROR_NONE
, mojoResult
.Pass());
222 void BackgroundSyncServiceImpl::ReleaseRegistration(
223 BackgroundSyncRegistrationHandle::HandleId handle_id
) {
224 if (!active_handles_
.Lookup(handle_id
)) {
225 // TODO(jkarlin): Abort client.
226 LOG(WARNING
) << "Client attempted to release non-existing registration";
230 active_handles_
.Remove(handle_id
);
233 void BackgroundSyncServiceImpl::OnRegisterResult(
234 const RegisterCallback
& callback
,
235 BackgroundSyncStatus status
,
236 scoped_ptr
<BackgroundSyncRegistrationHandle
> result
) {
237 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
238 BackgroundSyncRegistrationHandle
* result_ptr
= result
.get();
240 if (status
!= BACKGROUND_SYNC_STATUS_OK
) {
241 callback
.Run(static_cast<content::BackgroundSyncError
>(status
),
242 SyncRegistrationPtr(content::SyncRegistration::New()));
246 active_handles_
.AddWithID(result
.release(), result_ptr
->handle_id());
247 SyncRegistrationPtr mojoResult
= ToMojoRegistration(*result_ptr
);
248 callback
.Run(static_cast<content::BackgroundSyncError
>(status
),
252 void BackgroundSyncServiceImpl::OnUnregisterResult(
253 const UnregisterCallback
& callback
,
254 BackgroundSyncStatus status
) {
255 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
256 callback
.Run(static_cast<content::BackgroundSyncError
>(status
));
259 void BackgroundSyncServiceImpl::OnGetRegistrationsResult(
260 const GetRegistrationsCallback
& callback
,
261 BackgroundSyncStatus status
,
262 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>>
263 result_registrations
) {
264 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
265 mojo::Array
<content::SyncRegistrationPtr
> mojo_registrations(0);
266 for (BackgroundSyncRegistrationHandle
* registration
: *result_registrations
) {
267 active_handles_
.AddWithID(registration
, registration
->handle_id());
268 mojo_registrations
.push_back(ToMojoRegistration(*registration
));
271 result_registrations
->weak_clear();
273 callback
.Run(static_cast<content::BackgroundSyncError
>(status
),
274 mojo_registrations
.Pass());
277 } // namespace content