Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / background_sync / background_sync_service_impl.cc
blobb8c03df798b7abba2e6f0ab90a4d0c8964c1e5c6
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"
13 namespace content {
15 namespace {
17 // TODO(iclelland): Move these converters to mojo::TypeConverter template
18 // specializations.
20 BackgroundSyncRegistrationOptions ToBackgroundSyncRegistrationOptions(
21 const SyncRegistrationPtr& in) {
22 BackgroundSyncRegistrationOptions out;
24 out.tag = in->tag;
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);
29 return out;
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);
40 out->power_state =
41 static_cast<content::BackgroundSyncPowerState>(in.options()->power_state);
42 out->network_state = static_cast<content::BackgroundSyncNetworkState>(
43 in.options()->network_state);
44 return out.Pass();
47 } // namespace
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), \
52 mismatching_enums)
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);
142 if (!registration) {
143 callback.Run(BACKGROUND_SYNC_ERROR_NOT_ALLOWED);
144 return;
147 registration->Unregister(
148 sw_registration_id,
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()));
210 return;
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";
224 return;
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);
236 if (!registration) {
237 callback.Run(BACKGROUND_SYNC_ERROR_NOT_ALLOWED,
238 BACKGROUND_SYNC_STATE_FAILED);
239 return;
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()));
257 return;
260 active_handles_.AddWithID(result.release(), result_ptr->handle_id());
261 SyncRegistrationPtr mojoResult = ToMojoRegistration(*result_ptr);
262 callback.Run(static_cast<content::BackgroundSyncError>(status),
263 mojoResult.Pass());
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