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_manager.h"
7 #include "base/barrier_closure.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "content/browser/background_sync/background_sync_metrics.h"
13 #include "content/browser/background_sync/background_sync_network_observer.h"
14 #include "content/browser/background_sync/background_sync_power_observer.h"
15 #include "content/browser/background_sync/background_sync_registration_handle.h"
16 #include "content/browser/background_sync/background_sync_registration_options.h"
17 #include "content/browser/service_worker/service_worker_context_wrapper.h"
18 #include "content/browser/service_worker/service_worker_storage.h"
19 #include "content/public/browser/browser_thread.h"
21 #if defined(OS_ANDROID)
22 #include "content/browser/android/background_sync_launcher_android.h"
27 class BackgroundSyncManager::RefCountedRegistration
28 : public base::RefCounted
<RefCountedRegistration
> {
30 BackgroundSyncRegistration
* value() { return ®istration_
; }
31 const BackgroundSyncRegistration
* value() const { return ®istration_
; }
34 friend class base::RefCounted
<RefCountedRegistration
>;
35 ~RefCountedRegistration() = default;
37 BackgroundSyncRegistration registration_
;
42 const char kBackgroundSyncUserDataKey
[] = "BackgroundSyncUserData";
44 void PostErrorResponse(
45 BackgroundSyncStatus status
,
46 const BackgroundSyncManager::StatusAndRegistrationCallback
& callback
) {
47 base::ThreadTaskRunnerHandle::Get()->PostTask(
51 base::Passed(scoped_ptr
<BackgroundSyncRegistrationHandle
>().Pass())));
56 BackgroundSyncManager::BackgroundSyncRegistrations::
57 BackgroundSyncRegistrations()
58 : next_id(BackgroundSyncRegistration::kInitialId
) {
61 BackgroundSyncManager::BackgroundSyncRegistrations::
62 ~BackgroundSyncRegistrations() {
66 scoped_ptr
<BackgroundSyncManager
> BackgroundSyncManager::Create(
67 const scoped_refptr
<ServiceWorkerContextWrapper
>& service_worker_context
) {
68 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
70 BackgroundSyncManager
* sync_manager
=
71 new BackgroundSyncManager(service_worker_context
);
73 return make_scoped_ptr(sync_manager
);
76 BackgroundSyncManager::~BackgroundSyncManager() {
77 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
79 service_worker_context_
->RemoveObserver(this);
82 BackgroundSyncManager::RegistrationKey::RegistrationKey(
83 const BackgroundSyncRegistration
& registration
)
84 : RegistrationKey(registration
.options()->tag
,
85 registration
.options()->periodicity
) {
88 BackgroundSyncManager::RegistrationKey::RegistrationKey(
89 const BackgroundSyncRegistrationOptions
& options
)
90 : RegistrationKey(options
.tag
, options
.periodicity
) {
93 BackgroundSyncManager::RegistrationKey::RegistrationKey(
94 const std::string
& tag
,
95 SyncPeriodicity periodicity
)
96 : value_(periodicity
== SYNC_ONE_SHOT
? "o_" + tag
: "p_" + tag
) {
99 void BackgroundSyncManager::Register(
100 int64 sw_registration_id
,
101 const BackgroundSyncRegistrationOptions
& options
,
102 bool requested_from_service_worker
,
103 const StatusAndRegistrationCallback
& callback
) {
104 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
106 // For UMA, determine here whether the sync could fire immediately
107 BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire
=
108 AreOptionConditionsMet(options
)
109 ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE
110 : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE
;
113 BackgroundSyncMetrics::CountRegister(
114 options
.periodicity
, registration_could_fire
,
115 BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE
,
116 BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
117 PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR
, callback
);
121 op_scheduler_
.ScheduleOperation(base::Bind(
122 &BackgroundSyncManager::RegisterImpl
, weak_ptr_factory_
.GetWeakPtr(),
123 sw_registration_id
, options
, requested_from_service_worker
,
124 MakeStatusAndRegistrationCompletion(callback
)));
127 void BackgroundSyncManager::GetRegistration(
128 int64 sw_registration_id
,
129 const std::string
& sync_registration_tag
,
130 SyncPeriodicity periodicity
,
131 const StatusAndRegistrationCallback
& callback
) {
132 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
135 PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR
, callback
);
139 RegistrationKey
registration_key(sync_registration_tag
, periodicity
);
141 op_scheduler_
.ScheduleOperation(base::Bind(
142 &BackgroundSyncManager::GetRegistrationImpl
,
143 weak_ptr_factory_
.GetWeakPtr(), sw_registration_id
, registration_key
,
144 MakeStatusAndRegistrationCompletion(callback
)));
147 void BackgroundSyncManager::GetRegistrations(
148 int64 sw_registration_id
,
149 SyncPeriodicity periodicity
,
150 const StatusAndRegistrationsCallback
& callback
) {
151 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
154 base::ThreadTaskRunnerHandle::Get()->PostTask(
157 callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
,
159 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>>()
164 op_scheduler_
.ScheduleOperation(
165 base::Bind(&BackgroundSyncManager::GetRegistrationsImpl
,
166 weak_ptr_factory_
.GetWeakPtr(), sw_registration_id
,
167 periodicity
, MakeStatusAndRegistrationsCompletion(callback
)));
170 // Given a HandleId |handle_id|, return a new handle for the same
172 scoped_ptr
<BackgroundSyncRegistrationHandle
>
173 BackgroundSyncManager::DuplicateRegistrationHandle(
174 BackgroundSyncRegistrationHandle::HandleId handle_id
) {
175 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
177 scoped_refptr
<RefCountedRegistration
>* ref_registration
=
178 registration_handle_ids_
.Lookup(handle_id
);
179 if (!ref_registration
)
180 return scoped_ptr
<BackgroundSyncRegistrationHandle
>();
181 return CreateRegistrationHandle(ref_registration
->get());
184 void BackgroundSyncManager::OnRegistrationDeleted(int64 registration_id
,
185 const GURL
& pattern
) {
186 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
188 // Operations already in the queue will either fail when they write to storage
189 // or return stale results based on registrations loaded in memory. This is
190 // inconsequential since the service worker is gone.
191 op_scheduler_
.ScheduleOperation(base::Bind(
192 &BackgroundSyncManager::OnRegistrationDeletedImpl
,
193 weak_ptr_factory_
.GetWeakPtr(), registration_id
, MakeEmptyCompletion()));
196 void BackgroundSyncManager::OnStorageWiped() {
197 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
199 // Operations already in the queue will either fail when they write to storage
200 // or return stale results based on registrations loaded in memory. This is
201 // inconsequential since the service workers are gone.
202 op_scheduler_
.ScheduleOperation(
203 base::Bind(&BackgroundSyncManager::OnStorageWipedImpl
,
204 weak_ptr_factory_
.GetWeakPtr(), MakeEmptyCompletion()));
207 BackgroundSyncManager::BackgroundSyncManager(
208 const scoped_refptr
<ServiceWorkerContextWrapper
>& service_worker_context
)
209 : service_worker_context_(service_worker_context
),
211 weak_ptr_factory_(this) {
212 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
214 service_worker_context_
->AddObserver(this);
216 network_observer_
.reset(new BackgroundSyncNetworkObserver(
217 base::Bind(&BackgroundSyncManager::OnNetworkChanged
,
218 weak_ptr_factory_
.GetWeakPtr())));
219 power_observer_
.reset(new BackgroundSyncPowerObserver(base::Bind(
220 &BackgroundSyncManager::OnPowerChanged
, weak_ptr_factory_
.GetWeakPtr())));
223 void BackgroundSyncManager::Init() {
224 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
225 DCHECK(!op_scheduler_
.ScheduledOperations());
228 op_scheduler_
.ScheduleOperation(base::Bind(&BackgroundSyncManager::InitImpl
,
229 weak_ptr_factory_
.GetWeakPtr(),
230 MakeEmptyCompletion()));
233 void BackgroundSyncManager::InitImpl(const base::Closure
& callback
) {
234 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
237 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
238 base::Bind(callback
));
243 kBackgroundSyncUserDataKey
,
244 base::Bind(&BackgroundSyncManager::InitDidGetDataFromBackend
,
245 weak_ptr_factory_
.GetWeakPtr(), callback
));
248 void BackgroundSyncManager::InitDidGetDataFromBackend(
249 const base::Closure
& callback
,
250 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
251 ServiceWorkerStatusCode status
) {
252 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
254 if (status
!= SERVICE_WORKER_OK
&& status
!= SERVICE_WORKER_ERROR_NOT_FOUND
) {
255 LOG(ERROR
) << "BackgroundSync failed to init due to backend failure.";
256 DisableAndClearManager(base::Bind(callback
));
260 bool corruption_detected
= false;
261 for (const std::pair
<int64
, std::string
>& data
: user_data
) {
262 BackgroundSyncRegistrationsProto registrations_proto
;
263 if (registrations_proto
.ParseFromString(data
.second
)) {
264 BackgroundSyncRegistrations
* registrations
=
265 &active_registrations_
[data
.first
];
266 registrations
->next_id
= registrations_proto
.next_registration_id();
267 registrations
->origin
= GURL(registrations_proto
.origin());
269 for (int i
= 0, max
= registrations_proto
.registration_size(); i
< max
;
271 const BackgroundSyncRegistrationProto
& registration_proto
=
272 registrations_proto
.registration(i
);
274 if (registration_proto
.id() >= registrations
->next_id
) {
275 corruption_detected
= true;
279 RegistrationKey
registration_key(registration_proto
.tag(),
280 registration_proto
.periodicity());
282 scoped_refptr
<RefCountedRegistration
> ref_registration(
283 new RefCountedRegistration());
284 registrations
->registration_map
[registration_key
] = ref_registration
;
285 BackgroundSyncRegistration
* registration
= ref_registration
->value();
287 BackgroundSyncRegistrationOptions
* options
= registration
->options();
288 options
->tag
= registration_proto
.tag();
289 options
->periodicity
= registration_proto
.periodicity();
290 options
->min_period
= registration_proto
.min_period();
291 options
->network_state
= registration_proto
.network_state();
292 options
->power_state
= registration_proto
.power_state();
294 registration
->set_id(registration_proto
.id());
298 if (corruption_detected
)
302 if (corruption_detected
) {
303 LOG(ERROR
) << "Corruption detected in background sync backend";
304 DisableAndClearManager(base::Bind(callback
));
310 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
311 base::Bind(callback
));
314 void BackgroundSyncManager::RegisterImpl(
315 int64 sw_registration_id
,
316 const BackgroundSyncRegistrationOptions
& options
,
317 bool requested_from_service_worker
,
318 const StatusAndRegistrationCallback
& callback
) {
319 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
321 // For UMA, determine here whether the sync could fire immediately
322 BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire
=
323 AreOptionConditionsMet(options
)
324 ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE
325 : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE
;
328 BackgroundSyncMetrics::CountRegister(
329 options
.periodicity
, registration_could_fire
,
330 BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE
,
331 BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
332 PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR
, callback
);
336 if (options
.tag
.length() > kMaxTagLength
) {
337 BackgroundSyncMetrics::CountRegister(
338 options
.periodicity
, registration_could_fire
,
339 BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE
,
340 BACKGROUND_SYNC_STATUS_NOT_ALLOWED
);
341 PostErrorResponse(BACKGROUND_SYNC_STATUS_NOT_ALLOWED
, callback
);
345 ServiceWorkerRegistration
* sw_registration
=
346 service_worker_context_
->GetLiveRegistration(sw_registration_id
);
347 if (!sw_registration
|| !sw_registration
->active_version()) {
348 BackgroundSyncMetrics::CountRegister(
349 options
.periodicity
, registration_could_fire
,
350 BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE
,
351 BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER
);
352 PostErrorResponse(BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER
, callback
);
356 if (requested_from_service_worker
&&
357 !sw_registration
->active_version()->HasWindowClients()) {
358 PostErrorResponse(BACKGROUND_SYNC_STATUS_NOT_ALLOWED
, callback
);
362 RefCountedRegistration
* existing_registration_ref
=
363 LookupActiveRegistration(sw_registration_id
, RegistrationKey(options
));
364 if (existing_registration_ref
&&
365 existing_registration_ref
->value()->options()->Equals(options
)) {
366 BackgroundSyncRegistration
* existing_registration
=
367 existing_registration_ref
->value();
368 if (existing_registration
->sync_state() == BACKGROUND_SYNC_STATE_FAILED
) {
369 existing_registration
->set_sync_state(BACKGROUND_SYNC_STATE_PENDING
);
372 base::Bind(&BackgroundSyncManager::RegisterDidStore
,
373 weak_ptr_factory_
.GetWeakPtr(), sw_registration_id
,
374 make_scoped_refptr(existing_registration_ref
), callback
));
378 // Record the duplicated registration
379 BackgroundSyncMetrics::CountRegister(
380 existing_registration
->options()->periodicity
, registration_could_fire
,
381 BackgroundSyncMetrics::REGISTRATION_IS_DUPLICATE
,
382 BACKGROUND_SYNC_STATUS_OK
);
384 base::ThreadTaskRunnerHandle::Get()->PostTask(
387 callback
, BACKGROUND_SYNC_STATUS_OK
,
389 CreateRegistrationHandle(existing_registration_ref
).Pass())));
393 scoped_refptr
<RefCountedRegistration
> new_ref_registration(
394 new RefCountedRegistration());
395 BackgroundSyncRegistration
* new_registration
= new_ref_registration
->value();
397 *new_registration
->options() = options
;
399 BackgroundSyncRegistrations
* registrations
=
400 &active_registrations_
[sw_registration_id
];
401 new_registration
->set_id(registrations
->next_id
++);
403 AddActiveRegistration(sw_registration_id
,
404 sw_registration
->pattern().GetOrigin(),
405 new_ref_registration
);
409 base::Bind(&BackgroundSyncManager::RegisterDidStore
,
410 weak_ptr_factory_
.GetWeakPtr(), sw_registration_id
,
411 new_ref_registration
, callback
));
414 void BackgroundSyncManager::DisableAndClearManager(
415 const base::Closure
& callback
) {
416 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
419 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
420 base::Bind(callback
));
425 active_registrations_
.clear();
427 // Delete all backend entries. The memory representation of registered syncs
428 // may be out of sync with storage (e.g., due to corruption detection on
429 // loading from storage), so reload the registrations from storage again.
431 kBackgroundSyncUserDataKey
,
432 base::Bind(&BackgroundSyncManager::DisableAndClearDidGetRegistrations
,
433 weak_ptr_factory_
.GetWeakPtr(), callback
));
436 void BackgroundSyncManager::DisableAndClearDidGetRegistrations(
437 const base::Closure
& callback
,
438 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
439 ServiceWorkerStatusCode status
) {
440 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
442 if (status
!= SERVICE_WORKER_OK
|| user_data
.empty()) {
443 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
444 base::Bind(callback
));
448 base::Closure barrier_closure
=
449 base::BarrierClosure(user_data
.size(), base::Bind(callback
));
451 for (const auto& sw_id_and_regs
: user_data
) {
452 service_worker_context_
->ClearRegistrationUserData(
453 sw_id_and_regs
.first
, kBackgroundSyncUserDataKey
,
454 base::Bind(&BackgroundSyncManager::DisableAndClearManagerClearedOne
,
455 weak_ptr_factory_
.GetWeakPtr(), barrier_closure
));
459 void BackgroundSyncManager::DisableAndClearManagerClearedOne(
460 const base::Closure
& barrier_closure
,
461 ServiceWorkerStatusCode status
) {
462 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
464 // The status doesn't matter at this point, there is nothing else to be done.
465 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
466 base::Bind(barrier_closure
));
469 BackgroundSyncManager::RefCountedRegistration
*
470 BackgroundSyncManager::LookupActiveRegistration(
471 int64 sw_registration_id
,
472 const RegistrationKey
& registration_key
) {
473 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
475 SWIdToRegistrationsMap::iterator it
=
476 active_registrations_
.find(sw_registration_id
);
477 if (it
== active_registrations_
.end())
480 BackgroundSyncRegistrations
& registrations
= it
->second
;
481 DCHECK_LE(BackgroundSyncRegistration::kInitialId
, registrations
.next_id
);
482 DCHECK(!registrations
.origin
.is_empty());
484 auto key_and_registration_iter
=
485 registrations
.registration_map
.find(registration_key
);
486 if (key_and_registration_iter
== registrations
.registration_map
.end())
489 return key_and_registration_iter
->second
.get();
492 void BackgroundSyncManager::StoreRegistrations(
493 int64 sw_registration_id
,
494 const ServiceWorkerStorage::StatusCallback
& callback
) {
495 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
497 // Serialize the data.
498 const BackgroundSyncRegistrations
& registrations
=
499 active_registrations_
[sw_registration_id
];
500 BackgroundSyncRegistrationsProto registrations_proto
;
501 registrations_proto
.set_next_registration_id(registrations
.next_id
);
502 registrations_proto
.set_origin(registrations
.origin
.spec());
504 for (const auto& key_and_registration
: registrations
.registration_map
) {
505 const BackgroundSyncRegistration
& registration
=
506 *key_and_registration
.second
->value();
507 BackgroundSyncRegistrationProto
* registration_proto
=
508 registrations_proto
.add_registration();
509 registration_proto
->set_id(registration
.id());
510 registration_proto
->set_tag(registration
.options()->tag
);
511 registration_proto
->set_periodicity(registration
.options()->periodicity
);
512 registration_proto
->set_min_period(registration
.options()->min_period
);
513 registration_proto
->set_network_state(
514 registration
.options()->network_state
);
515 registration_proto
->set_power_state(registration
.options()->power_state
);
517 std::string serialized
;
518 bool success
= registrations_proto
.SerializeToString(&serialized
);
521 StoreDataInBackend(sw_registration_id
, registrations
.origin
,
522 kBackgroundSyncUserDataKey
, serialized
, callback
);
525 void BackgroundSyncManager::RegisterDidStore(
526 int64 sw_registration_id
,
527 const scoped_refptr
<RefCountedRegistration
>& new_registration_ref
,
528 const StatusAndRegistrationCallback
& callback
,
529 ServiceWorkerStatusCode status
) {
530 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
532 const BackgroundSyncRegistration
* new_registration
=
533 new_registration_ref
->value();
535 // For UMA, determine here whether the sync could fire immediately
536 BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire
=
537 AreOptionConditionsMet(*new_registration
->options())
538 ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE
539 : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE
;
541 if (status
== SERVICE_WORKER_ERROR_NOT_FOUND
) {
542 // The service worker registration is gone.
543 BackgroundSyncMetrics::CountRegister(
544 new_registration
->options()->periodicity
, registration_could_fire
,
545 BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE
,
546 BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
547 active_registrations_
.erase(sw_registration_id
);
548 PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR
, callback
);
552 if (status
!= SERVICE_WORKER_OK
) {
553 LOG(ERROR
) << "BackgroundSync failed to store registration due to backend "
555 BackgroundSyncMetrics::CountRegister(
556 new_registration
->options()->periodicity
, registration_could_fire
,
557 BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE
,
558 BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
559 DisableAndClearManager(base::Bind(
560 callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
,
561 base::Passed(scoped_ptr
<BackgroundSyncRegistrationHandle
>().Pass())));
565 BackgroundSyncMetrics::CountRegister(
566 new_registration
->options()->periodicity
, registration_could_fire
,
567 BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE
,
568 BACKGROUND_SYNC_STATUS_OK
);
570 base::ThreadTaskRunnerHandle::Get()->PostTask(
573 callback
, BACKGROUND_SYNC_STATUS_OK
,
575 CreateRegistrationHandle(new_registration_ref
.get()).Pass())));
578 void BackgroundSyncManager::RemoveActiveRegistration(
579 int64 sw_registration_id
,
580 const RegistrationKey
& registration_key
) {
581 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
582 DCHECK(LookupActiveRegistration(sw_registration_id
, registration_key
));
584 BackgroundSyncRegistrations
* registrations
=
585 &active_registrations_
[sw_registration_id
];
587 registrations
->registration_map
.erase(registration_key
);
590 void BackgroundSyncManager::AddActiveRegistration(
591 int64 sw_registration_id
,
593 const scoped_refptr
<RefCountedRegistration
>& sync_registration
) {
594 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
595 DCHECK(sync_registration
->value()->IsValid());
597 BackgroundSyncRegistrations
* registrations
=
598 &active_registrations_
[sw_registration_id
];
599 registrations
->origin
= origin
;
601 RegistrationKey
registration_key(*sync_registration
->value());
602 registrations
->registration_map
[registration_key
] = sync_registration
;
605 void BackgroundSyncManager::StoreDataInBackend(
606 int64 sw_registration_id
,
608 const std::string
& backend_key
,
609 const std::string
& data
,
610 const ServiceWorkerStorage::StatusCallback
& callback
) {
611 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
613 service_worker_context_
->StoreRegistrationUserData(
614 sw_registration_id
, origin
, backend_key
, data
, callback
);
617 void BackgroundSyncManager::GetDataFromBackend(
618 const std::string
& backend_key
,
619 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback
&
621 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
623 service_worker_context_
->GetUserDataForAllRegistrations(backend_key
,
627 void BackgroundSyncManager::FireOneShotSync(
628 BackgroundSyncRegistrationHandle::HandleId handle_id
,
629 const scoped_refptr
<ServiceWorkerVersion
>& active_version
,
630 const ServiceWorkerVersion::StatusCallback
& callback
) {
631 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
632 DCHECK(active_version
);
634 // The ServiceWorkerVersion doesn't know when the client (javascript) is done
635 // with the registration so don't give it a BackgroundSyncRegistrationHandle.
636 // Once the render process gets the handle_id it can create its own handle
637 // (with a new unique handle id).
638 active_version
->DispatchSyncEvent(handle_id
, callback
);
641 scoped_ptr
<BackgroundSyncRegistrationHandle
>
642 BackgroundSyncManager::CreateRegistrationHandle(
643 const scoped_refptr
<RefCountedRegistration
>& registration
) {
644 scoped_refptr
<RefCountedRegistration
>* ptr
=
645 new scoped_refptr
<RefCountedRegistration
>(registration
);
647 // Registration handles have unique handle ids. The handle id maps to an
648 // internal RefCountedRegistration (which has the persistent registration id)
650 // registration_reference_ids_.
651 BackgroundSyncRegistrationHandle::HandleId handle_id
=
652 registration_handle_ids_
.Add(ptr
);
654 return make_scoped_ptr(new BackgroundSyncRegistrationHandle(
655 weak_ptr_factory_
.GetWeakPtr(), handle_id
));
658 BackgroundSyncRegistration
* BackgroundSyncManager::GetRegistrationForHandle(
659 BackgroundSyncRegistrationHandle::HandleId handle_id
) const {
660 scoped_refptr
<RefCountedRegistration
>* ref_registration
=
661 registration_handle_ids_
.Lookup(handle_id
);
662 if (!ref_registration
)
664 return (*ref_registration
)->value();
667 void BackgroundSyncManager::ReleaseRegistrationHandle(
668 BackgroundSyncRegistrationHandle::HandleId handle_id
) {
669 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
670 DCHECK(registration_handle_ids_
.Lookup(handle_id
));
671 registration_handle_ids_
.Remove(handle_id
);
674 void BackgroundSyncManager::Unregister(
675 int64 sw_registration_id
,
676 SyncPeriodicity periodicity
,
677 BackgroundSyncRegistrationHandle::HandleId handle_id
,
678 const StatusCallback
& callback
) {
679 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
682 BackgroundSyncMetrics::CountUnregister(
683 periodicity
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
684 base::ThreadTaskRunnerHandle::Get()->PostTask(
685 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
));
689 BackgroundSyncRegistration
* registration
=
690 GetRegistrationForHandle(handle_id
);
691 DCHECK(registration
);
693 op_scheduler_
.ScheduleOperation(base::Bind(
694 &BackgroundSyncManager::UnregisterImpl
, weak_ptr_factory_
.GetWeakPtr(),
695 sw_registration_id
, RegistrationKey(*registration
), registration
->id(),
696 periodicity
, MakeStatusCompletion(callback
)));
699 void BackgroundSyncManager::UnregisterImpl(
700 int64 sw_registration_id
,
701 const RegistrationKey
& registration_key
,
702 BackgroundSyncRegistration::RegistrationId sync_registration_id
,
703 SyncPeriodicity periodicity
,
704 const StatusCallback
& callback
) {
705 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
708 BackgroundSyncMetrics::CountUnregister(
709 periodicity
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
710 base::ThreadTaskRunnerHandle::Get()->PostTask(
711 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
));
715 RefCountedRegistration
* existing_registration
=
716 LookupActiveRegistration(sw_registration_id
, registration_key
);
718 if (!existing_registration
||
719 existing_registration
->value()->id() != sync_registration_id
) {
720 BackgroundSyncMetrics::CountUnregister(periodicity
,
721 BACKGROUND_SYNC_STATUS_NOT_FOUND
);
722 base::ThreadTaskRunnerHandle::Get()->PostTask(
723 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_NOT_FOUND
));
727 DCHECK(!existing_registration
->value()->HasCompleted());
729 bool firing
= existing_registration
->value()->sync_state() ==
730 BACKGROUND_SYNC_STATE_FIRING
||
731 existing_registration
->value()->sync_state() ==
732 BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING
;
734 existing_registration
->value()->set_sync_state(
735 firing
? BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING
736 : BACKGROUND_SYNC_STATE_UNREGISTERED
);
739 // If the registration is currently firing then wait to run
740 // RunDoneCallbacks until after it has finished as it might
741 // change state to SUCCESS first.
742 existing_registration
->value()->RunDoneCallbacks();
745 RemoveActiveRegistration(sw_registration_id
, registration_key
);
747 StoreRegistrations(sw_registration_id
,
748 base::Bind(&BackgroundSyncManager::UnregisterDidStore
,
749 weak_ptr_factory_
.GetWeakPtr(),
750 sw_registration_id
, periodicity
, callback
));
753 void BackgroundSyncManager::UnregisterDidStore(int64 sw_registration_id
,
754 SyncPeriodicity periodicity
,
755 const StatusCallback
& callback
,
756 ServiceWorkerStatusCode status
) {
757 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
759 if (status
== SERVICE_WORKER_ERROR_NOT_FOUND
) {
760 // ServiceWorker was unregistered.
761 BackgroundSyncMetrics::CountUnregister(
762 periodicity
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
763 active_registrations_
.erase(sw_registration_id
);
764 base::ThreadTaskRunnerHandle::Get()->PostTask(
765 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
));
769 if (status
!= SERVICE_WORKER_OK
) {
770 LOG(ERROR
) << "BackgroundSync failed to unregister due to backend failure.";
771 BackgroundSyncMetrics::CountUnregister(
772 periodicity
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
);
773 DisableAndClearManager(
774 base::Bind(callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
));
778 BackgroundSyncMetrics::CountUnregister(periodicity
,
779 BACKGROUND_SYNC_STATUS_OK
);
780 base::ThreadTaskRunnerHandle::Get()->PostTask(
781 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_OK
));
784 void BackgroundSyncManager::NotifyWhenDone(
785 BackgroundSyncRegistrationHandle::HandleId handle_id
,
786 const StatusAndStateCallback
& callback
) {
787 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
790 base::ThreadTaskRunnerHandle::Get()->PostTask(
791 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
,
792 BACKGROUND_SYNC_STATE_FAILED
));
796 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
=
797 DuplicateRegistrationHandle(handle_id
);
799 op_scheduler_
.ScheduleOperation(
800 base::Bind(&BackgroundSyncManager::NotifyWhenDoneImpl
,
801 weak_ptr_factory_
.GetWeakPtr(),
802 base::Passed(registration_handle
.Pass()), callback
));
805 void BackgroundSyncManager::NotifyWhenDoneImpl(
806 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
,
807 const StatusAndStateCallback
& callback
) {
808 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
809 DCHECK_EQ(SYNC_ONE_SHOT
, registration_handle
->options()->periodicity
);
812 base::ThreadTaskRunnerHandle::Get()->PostTask(
813 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
,
814 BACKGROUND_SYNC_STATE_FAILED
));
818 if (!registration_handle
->registration()->HasCompleted()) {
819 registration_handle
->registration()->AddDoneCallback(
820 base::Bind(&BackgroundSyncManager::NotifyWhenDoneDidFinish
,
821 weak_ptr_factory_
.GetWeakPtr(), callback
));
822 op_scheduler_
.CompleteOperationAndRunNext();
826 base::ThreadTaskRunnerHandle::Get()->PostTask(
827 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_OK
,
828 registration_handle
->sync_state()));
829 op_scheduler_
.CompleteOperationAndRunNext();
832 void BackgroundSyncManager::NotifyWhenDoneDidFinish(
833 const StatusAndStateCallback
& callback
,
834 BackgroundSyncState sync_state
) {
835 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
838 base::ThreadTaskRunnerHandle::Get()->PostTask(
839 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
,
840 BACKGROUND_SYNC_STATE_FAILED
));
844 callback
.Run(BACKGROUND_SYNC_STATUS_OK
, sync_state
);
847 void BackgroundSyncManager::GetRegistrationImpl(
848 int64 sw_registration_id
,
849 const RegistrationKey
& registration_key
,
850 const StatusAndRegistrationCallback
& callback
) {
851 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
854 PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR
, callback
);
858 RefCountedRegistration
* registration
=
859 LookupActiveRegistration(sw_registration_id
, registration_key
);
861 PostErrorResponse(BACKGROUND_SYNC_STATUS_NOT_FOUND
, callback
);
865 base::ThreadTaskRunnerHandle::Get()->PostTask(
867 base::Bind(callback
, BACKGROUND_SYNC_STATUS_OK
,
868 base::Passed(CreateRegistrationHandle(registration
).Pass())));
871 void BackgroundSyncManager::GetRegistrationsImpl(
872 int64 sw_registration_id
,
873 SyncPeriodicity periodicity
,
874 const StatusAndRegistrationsCallback
& callback
) {
875 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
877 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>> out_registrations(
878 new ScopedVector
<BackgroundSyncRegistrationHandle
>());
881 base::ThreadTaskRunnerHandle::Get()->PostTask(
882 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_STORAGE_ERROR
,
883 base::Passed(out_registrations
.Pass())));
887 SWIdToRegistrationsMap::iterator it
=
888 active_registrations_
.find(sw_registration_id
);
890 if (it
!= active_registrations_
.end()) {
891 const BackgroundSyncRegistrations
& registrations
= it
->second
;
892 for (const auto& tag_and_registration
: registrations
.registration_map
) {
893 RefCountedRegistration
* registration
= tag_and_registration
.second
.get();
894 if (registration
->value()->options()->periodicity
== periodicity
) {
895 out_registrations
->push_back(
896 CreateRegistrationHandle(registration
).release());
901 base::ThreadTaskRunnerHandle::Get()->PostTask(
902 FROM_HERE
, base::Bind(callback
, BACKGROUND_SYNC_STATUS_OK
,
903 base::Passed(out_registrations
.Pass())));
906 bool BackgroundSyncManager::AreOptionConditionsMet(
907 const BackgroundSyncRegistrationOptions
& options
) {
908 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
909 return network_observer_
->NetworkSufficient(options
.network_state
) &&
910 power_observer_
->PowerSufficient(options
.power_state
);
913 bool BackgroundSyncManager::IsRegistrationReadyToFire(
914 const BackgroundSyncRegistration
& registration
) {
915 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
917 // TODO(jkarlin): Add support for firing periodic registrations.
918 if (registration
.options()->periodicity
== SYNC_PERIODIC
)
921 if (registration
.sync_state() != BACKGROUND_SYNC_STATE_PENDING
)
924 DCHECK_EQ(SYNC_ONE_SHOT
, registration
.options()->periodicity
);
926 return AreOptionConditionsMet(*registration
.options());
929 void BackgroundSyncManager::SchedulePendingRegistrations() {
930 #if defined(OS_ANDROID)
931 bool keep_browser_alive_for_one_shot
= false;
933 for (const auto& sw_id_and_registrations
: active_registrations_
) {
934 for (const auto& key_and_registration
:
935 sw_id_and_registrations
.second
.registration_map
) {
936 const BackgroundSyncRegistration
& registration
=
937 *key_and_registration
.second
->value();
938 if (registration
.sync_state() == BACKGROUND_SYNC_STATE_PENDING
) {
939 if (registration
.options()->periodicity
== SYNC_ONE_SHOT
) {
940 keep_browser_alive_for_one_shot
= true;
942 // TODO(jkarlin): Support keeping the browser alive for periodic
949 // TODO(jkarlin): Use the context's path instead of the 'this' pointer as an
950 // identifier. See crbug.com/489705.
951 BrowserThread::PostTask(
952 BrowserThread::UI
, FROM_HERE
,
953 base::Bind(&BackgroundSyncLauncherAndroid::LaunchBrowserWhenNextOnline
,
954 this, keep_browser_alive_for_one_shot
));
956 // TODO(jkarlin): Toggle Chrome's background mode.
960 void BackgroundSyncManager::FireReadyEvents() {
961 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
966 op_scheduler_
.ScheduleOperation(
967 base::Bind(&BackgroundSyncManager::FireReadyEventsImpl
,
968 weak_ptr_factory_
.GetWeakPtr(), MakeEmptyCompletion()));
971 void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure
& callback
) {
972 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
975 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
976 base::Bind(callback
));
980 // Find the registrations that are ready to run.
981 std::vector
<std::pair
<int64
, RegistrationKey
>> sw_id_and_keys_to_fire
;
983 for (auto& sw_id_and_registrations
: active_registrations_
) {
984 const int64 service_worker_id
= sw_id_and_registrations
.first
;
985 for (auto& key_and_registration
:
986 sw_id_and_registrations
.second
.registration_map
) {
987 BackgroundSyncRegistration
* registration
=
988 key_and_registration
.second
->value();
989 if (IsRegistrationReadyToFire(*registration
)) {
990 sw_id_and_keys_to_fire
.push_back(
991 std::make_pair(service_worker_id
, key_and_registration
.first
));
992 // The state change is not saved to persistent storage because
993 // if the sync event is killed mid-sync then it should return to
994 // SYNC_STATE_PENDING.
995 registration
->set_sync_state(BACKGROUND_SYNC_STATE_FIRING
);
1000 // If there are no registrations currently ready, then just run |callback|.
1001 // Otherwise, fire them all, and record the result when done.
1002 if (sw_id_and_keys_to_fire
.size() == 0) {
1003 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
1004 base::Bind(callback
));
1006 base::TimeTicks start_time
= base::TimeTicks::Now();
1008 // Fire the sync event of the ready registrations and run |callback| once
1009 // they're all done.
1010 base::Closure events_fired_barrier_closure
= base::BarrierClosure(
1011 sw_id_and_keys_to_fire
.size(), base::Bind(callback
));
1013 // Record the total time taken after all events have run to completion.
1014 base::Closure events_completed_barrier_closure
=
1015 base::BarrierClosure(sw_id_and_keys_to_fire
.size(),
1016 base::Bind(&OnAllSyncEventsCompleted
, start_time
,
1017 sw_id_and_keys_to_fire
.size()));
1019 for (const auto& sw_id_and_key
: sw_id_and_keys_to_fire
) {
1020 int64 service_worker_id
= sw_id_and_key
.first
;
1021 const RefCountedRegistration
* registration
=
1022 LookupActiveRegistration(service_worker_id
, sw_id_and_key
.second
);
1023 DCHECK(registration
);
1025 service_worker_context_
->FindRegistrationForId(
1026 service_worker_id
, active_registrations_
[service_worker_id
].origin
,
1027 base::Bind(&BackgroundSyncManager::FireReadyEventsDidFindRegistration
,
1028 weak_ptr_factory_
.GetWeakPtr(), sw_id_and_key
.second
,
1029 registration
->value()->id(), events_fired_barrier_closure
,
1030 events_completed_barrier_closure
));
1034 SchedulePendingRegistrations();
1037 void BackgroundSyncManager::FireReadyEventsDidFindRegistration(
1038 const RegistrationKey
& registration_key
,
1039 BackgroundSyncRegistration::RegistrationId registration_id
,
1040 const base::Closure
& event_fired_callback
,
1041 const base::Closure
& event_completed_callback
,
1042 ServiceWorkerStatusCode service_worker_status
,
1043 const scoped_refptr
<ServiceWorkerRegistration
>&
1044 service_worker_registration
) {
1045 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1046 if (service_worker_status
!= SERVICE_WORKER_OK
) {
1047 base::ThreadTaskRunnerHandle::Get()->PostTask(
1048 FROM_HERE
, base::Bind(event_fired_callback
));
1049 base::ThreadTaskRunnerHandle::Get()->PostTask(
1050 FROM_HERE
, base::Bind(event_completed_callback
));
1054 RefCountedRegistration
* registration
= LookupActiveRegistration(
1055 service_worker_registration
->id(), registration_key
);
1056 DCHECK(registration
);
1058 // Create a handle and keep it until the sync event completes. The client can
1059 // acquire its own handle for longer-term use.
1060 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
=
1061 CreateRegistrationHandle(registration
);
1063 BackgroundSyncRegistrationHandle::HandleId handle_id
=
1064 registration_handle
->handle_id();
1066 handle_id
, service_worker_registration
->active_version(),
1068 &BackgroundSyncManager::EventComplete
, weak_ptr_factory_
.GetWeakPtr(),
1069 service_worker_registration
, service_worker_registration
->id(),
1070 base::Passed(registration_handle
.Pass()), event_completed_callback
));
1072 base::ThreadTaskRunnerHandle::Get()->PostTask(
1073 FROM_HERE
, base::Bind(event_fired_callback
));
1076 // |service_worker_registration| is just to keep the registration alive
1077 // while the event is firing.
1078 void BackgroundSyncManager::EventComplete(
1079 const scoped_refptr
<ServiceWorkerRegistration
>& service_worker_registration
,
1080 int64 service_worker_id
,
1081 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
,
1082 const base::Closure
& callback
,
1083 ServiceWorkerStatusCode status_code
) {
1084 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1088 op_scheduler_
.ScheduleOperation(base::Bind(
1089 &BackgroundSyncManager::EventCompleteImpl
, weak_ptr_factory_
.GetWeakPtr(),
1090 service_worker_id
, base::Passed(registration_handle
.Pass()), status_code
,
1091 MakeClosureCompletion(callback
)));
1094 void BackgroundSyncManager::EventCompleteImpl(
1095 int64 service_worker_id
,
1096 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
,
1097 ServiceWorkerStatusCode status_code
,
1098 const base::Closure
& callback
) {
1099 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1102 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
1103 base::Bind(callback
));
1107 BackgroundSyncRegistration
* registration
=
1108 registration_handle
->registration();
1109 DCHECK(registration
);
1111 // The event ran to completion, we should count it, no matter what happens
1113 BackgroundSyncMetrics::RecordEventResult(registration
->options()->periodicity
,
1114 status_code
== SERVICE_WORKER_OK
);
1116 if (registration
->options()->periodicity
== SYNC_ONE_SHOT
) {
1117 if (status_code
!= SERVICE_WORKER_OK
) {
1118 // TODO(jkarlin): Insert retry logic here. Be sure to check if the state
1119 // is UNREGISTERED_WHILE_FIRING first. If so then set the state to failed
1120 // if it was already out of retry attempts otherwise keep the state as
1121 // unregistered. Then call RunDoneCallbacks(); (crbug.com/501838)
1122 // TODO(jkarlin): Fire the sync event on the next page load controlled
1124 // this registration. (crbug.com/479665)
1125 registration
->set_sync_state(BACKGROUND_SYNC_STATE_FAILED
);
1126 registration
->RunDoneCallbacks();
1128 registration
->set_sync_state(BACKGROUND_SYNC_STATE_SUCCESS
);
1129 registration
->RunDoneCallbacks();
1131 RegistrationKey
key(*registration
);
1132 // Remove the registration if it's still active.
1133 RefCountedRegistration
* active_registration
=
1134 LookupActiveRegistration(service_worker_id
, key
);
1135 if (active_registration
&&
1136 active_registration
->value()->id() == registration
->id()) {
1137 RemoveActiveRegistration(service_worker_id
, key
);
1141 // TODO(jkarlin): Add support for running periodic syncs. (crbug.com/479674)
1147 base::Bind(&BackgroundSyncManager::EventCompleteDidStore
,
1148 weak_ptr_factory_
.GetWeakPtr(), service_worker_id
, callback
));
1151 void BackgroundSyncManager::EventCompleteDidStore(
1152 int64 service_worker_id
,
1153 const base::Closure
& callback
,
1154 ServiceWorkerStatusCode status_code
) {
1155 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1157 if (status_code
== SERVICE_WORKER_ERROR_NOT_FOUND
) {
1158 // The registration is gone.
1159 active_registrations_
.erase(service_worker_id
);
1160 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
1161 base::Bind(callback
));
1165 if (status_code
!= SERVICE_WORKER_OK
) {
1166 LOG(ERROR
) << "BackgroundSync failed to store registration due to backend "
1168 DisableAndClearManager(base::Bind(callback
));
1172 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
1173 base::Bind(callback
));
1177 void BackgroundSyncManager::OnAllSyncEventsCompleted(
1178 const base::TimeTicks
& start_time
,
1179 int number_of_batched_sync_events
) {
1180 // Record the combined time taken by all sync events.
1181 BackgroundSyncMetrics::RecordBatchSyncEventComplete(
1182 base::TimeTicks::Now() - start_time
, number_of_batched_sync_events
);
1185 void BackgroundSyncManager::OnRegistrationDeletedImpl(
1186 int64 registration_id
,
1187 const base::Closure
& callback
) {
1188 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1190 // The backend (ServiceWorkerStorage) will delete the data, so just delete the
1191 // memory representation here.
1192 active_registrations_
.erase(registration_id
);
1193 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
1194 base::Bind(callback
));
1197 void BackgroundSyncManager::OnStorageWipedImpl(const base::Closure
& callback
) {
1198 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1200 active_registrations_
.clear();
1205 void BackgroundSyncManager::OnNetworkChanged() {
1206 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1211 void BackgroundSyncManager::OnPowerChanged() {
1212 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1217 // TODO(jkarlin): Figure out how to pass scoped_ptrs with this.
1218 template <typename CallbackT
, typename
... Params
>
1219 void BackgroundSyncManager::CompleteOperationCallback(const CallbackT
& callback
,
1220 Params
... parameters
) {
1221 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1223 callback
.Run(parameters
...);
1224 op_scheduler_
.CompleteOperationAndRunNext();
1227 void BackgroundSyncManager::CompleteStatusAndRegistrationCallback(
1228 StatusAndRegistrationCallback callback
,
1229 BackgroundSyncStatus status
,
1230 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
) {
1231 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1233 callback
.Run(status
, registration_handle
.Pass());
1234 op_scheduler_
.CompleteOperationAndRunNext();
1237 void BackgroundSyncManager::CompleteStatusAndRegistrationsCallback(
1238 StatusAndRegistrationsCallback callback
,
1239 BackgroundSyncStatus status
,
1240 scoped_ptr
<ScopedVector
<BackgroundSyncRegistrationHandle
>>
1241 registration_handles
) {
1242 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1244 callback
.Run(status
, registration_handles
.Pass());
1245 op_scheduler_
.CompleteOperationAndRunNext();
1248 base::Closure
BackgroundSyncManager::MakeEmptyCompletion() {
1249 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1251 return MakeClosureCompletion(base::Bind(base::DoNothing
));
1254 base::Closure
BackgroundSyncManager::MakeClosureCompletion(
1255 const base::Closure
& callback
) {
1256 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1259 &BackgroundSyncManager::CompleteOperationCallback
<base::Closure
>,
1260 weak_ptr_factory_
.GetWeakPtr(), callback
);
1263 BackgroundSyncManager::StatusAndRegistrationCallback
1264 BackgroundSyncManager::MakeStatusAndRegistrationCompletion(
1265 const StatusAndRegistrationCallback
& callback
) {
1266 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1269 &BackgroundSyncManager::CompleteStatusAndRegistrationCallback
,
1270 weak_ptr_factory_
.GetWeakPtr(), callback
);
1273 BackgroundSyncManager::StatusAndRegistrationsCallback
1274 BackgroundSyncManager::MakeStatusAndRegistrationsCompletion(
1275 const StatusAndRegistrationsCallback
& callback
) {
1276 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1279 &BackgroundSyncManager::CompleteStatusAndRegistrationsCallback
,
1280 weak_ptr_factory_
.GetWeakPtr(), callback
);
1283 BackgroundSyncManager::StatusCallback
1284 BackgroundSyncManager::MakeStatusCompletion(const StatusCallback
& callback
) {
1285 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
1288 &BackgroundSyncManager::CompleteOperationCallback
<StatusCallback
,
1289 BackgroundSyncStatus
>,
1290 weak_ptr_factory_
.GetWeakPtr(), callback
);
1293 } // namespace content