Chromium Code Reviews| Index: content/browser/background_sync/background_sync_manager.cc |
| diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc |
| index 018bbae5ab270ecfc3905a191a9fbb48dd63cb93..2969437b93bef79ec91b8f2f3ab6542cc0517131 100644 |
| --- a/content/browser/background_sync/background_sync_manager.cc |
| +++ b/content/browser/background_sync/background_sync_manager.cc |
| @@ -12,6 +12,7 @@ |
| #include "content/browser/background_sync/background_sync_metrics.h" |
| #include "content/browser/background_sync/background_sync_network_observer.h" |
| #include "content/browser/background_sync/background_sync_power_observer.h" |
| +#include "content/browser/background_sync/background_sync_registration_handle.h" |
| #include "content/browser/background_sync/background_sync_registration_options.h" |
| #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| #include "content/browser/service_worker/service_worker_storage.h" |
| @@ -21,11 +22,23 @@ |
| #include "content/browser/android/background_sync_launcher_android.h" |
| #endif |
| +namespace content { |
| + |
| namespace { |
| + |
| const char kBackgroundSyncUserDataKey[] = "BackgroundSyncUserData"; |
| + |
| +void PostErrorResponse( |
| + BackgroundSyncStatus status, |
| + const BackgroundSyncManager::StatusAndRegistrationCallback& callback) { |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, |
| + base::Bind( |
| + callback, status, |
| + base::Passed(scoped_ptr<BackgroundSyncRegistrationHandle>().Pass()))); |
| } |
| -namespace content { |
| +} // namespace |
| BackgroundSyncManager::BackgroundSyncRegistrations:: |
| BackgroundSyncRegistrations() |
| @@ -50,6 +63,11 @@ scoped_ptr<BackgroundSyncManager> BackgroundSyncManager::Create( |
| BackgroundSyncManager::~BackgroundSyncManager() { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + // This could race in the extremely unlikely case that the |
| + // BackgroundSyncManager is deleted before a dispatched sync request is able |
| + // to call BackgroundSyncServiceImpl::TrackRegistration. |
| + DCHECK(registration_handle_ids_.IsEmpty()); |
| + |
| service_worker_context_->RemoveObserver(this); |
| } |
| @@ -87,9 +105,7 @@ void BackgroundSyncManager::Register( |
| options.periodicity, registration_could_fire, |
| BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE, |
| BACKGROUND_SYNC_STATUS_STORAGE_ERROR); |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| - BackgroundSyncRegistration())); |
| + PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback); |
| return; |
| } |
| @@ -99,30 +115,6 @@ void BackgroundSyncManager::Register( |
| MakeStatusAndRegistrationCompletion(callback))); |
| } |
| -void BackgroundSyncManager::Unregister( |
| - int64 sw_registration_id, |
| - const std::string& sync_registration_tag, |
| - SyncPeriodicity periodicity, |
| - BackgroundSyncRegistration::RegistrationId sync_registration_id, |
| - const StatusCallback& callback) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - |
| - if (disabled_) { |
| - BackgroundSyncMetrics::CountUnregister( |
| - periodicity, BACKGROUND_SYNC_STATUS_STORAGE_ERROR); |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR)); |
| - return; |
| - } |
| - |
| - RegistrationKey registration_key(sync_registration_tag, periodicity); |
| - |
| - op_scheduler_.ScheduleOperation(base::Bind( |
| - &BackgroundSyncManager::UnregisterImpl, weak_ptr_factory_.GetWeakPtr(), |
| - sw_registration_id, registration_key, sync_registration_id, periodicity, |
| - MakeStatusCompletion(callback))); |
| -} |
| - |
| void BackgroundSyncManager::GetRegistration( |
| int64 sw_registration_id, |
| const std::string& sync_registration_tag, |
| @@ -131,9 +123,7 @@ void BackgroundSyncManager::GetRegistration( |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| if (disabled_) { |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| - BackgroundSyncRegistration())); |
| + PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback); |
| return; |
| } |
| @@ -153,8 +143,12 @@ void BackgroundSyncManager::GetRegistrations( |
| if (disabled_) { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| - std::vector<BackgroundSyncRegistration>())); |
| + FROM_HERE, |
| + base::Bind( |
| + callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| + base::Passed( |
| + scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>>() |
| + .Pass()))); |
| return; |
| } |
| @@ -164,6 +158,23 @@ void BackgroundSyncManager::GetRegistrations( |
| periodicity, MakeStatusAndRegistrationsCompletion(callback))); |
| } |
| +const BackgroundSyncRegistration* |
| +BackgroundSyncManager::GetRegistrationForHandle( |
| + BackgroundSyncRegistrationHandle::HandleId handle_id) const { |
| + scoped_refptr<const RefCountedRegistration>* ref_registration = |
| + registration_handle_ids_.Lookup(handle_id); |
| + if (!ref_registration) |
| + return nullptr; |
| + return (*ref_registration)->value(); |
| +} |
| + |
| +void BackgroundSyncManager::ReleaseHandleId( |
| + BackgroundSyncRegistrationHandle::HandleId handle_id) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DCHECK(registration_handle_ids_.Lookup(handle_id)); |
| + registration_handle_ids_.Remove(handle_id); |
| +} |
| + |
| void BackgroundSyncManager::OnRegistrationDeleted(int64 registration_id, |
| const GURL& pattern) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| @@ -261,8 +272,11 @@ void BackgroundSyncManager::InitDidGetDataFromBackend( |
| RegistrationKey registration_key(registration_proto.tag(), |
| registration_proto.periodicity()); |
| - BackgroundSyncRegistration* registration = |
| - ®istrations->registration_map[registration_key]; |
| + |
| + scoped_refptr<RefCountedRegistration> ref_registration( |
| + new RefCountedRegistration()); |
| + registrations->registration_map[registration_key] = ref_registration; |
| + BackgroundSyncRegistration* registration = ref_registration->value(); |
| BackgroundSyncRegistrationOptions* options = registration->options(); |
| options->tag = registration_proto.tag(); |
| @@ -315,9 +329,7 @@ void BackgroundSyncManager::RegisterImpl( |
| options.periodicity, registration_could_fire, |
| BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE, |
| BACKGROUND_SYNC_STATUS_STORAGE_ERROR); |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| - BackgroundSyncRegistration())); |
| + PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback); |
| return; |
| } |
| @@ -328,31 +340,28 @@ void BackgroundSyncManager::RegisterImpl( |
| options.periodicity, registration_could_fire, |
| BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE, |
| BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER); |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, |
| - base::Bind(callback, BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER, |
| - BackgroundSyncRegistration())); |
| + PostErrorResponse(BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER, callback); |
| return; |
| } |
| if (!sw_registration->active_version()->HasWindowClients()) { |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_NOT_ALLOWED, |
| - BackgroundSyncRegistration())); |
| + PostErrorResponse(BACKGROUND_SYNC_STATUS_NOT_ALLOWED, callback); |
| return; |
| } |
| - BackgroundSyncRegistration* existing_registration = |
| + RefCountedRegistration* existing_registration_ref = |
| LookupRegistration(sw_registration_id, RegistrationKey(options)); |
| - if (existing_registration && |
| - existing_registration->options()->Equals(options)) { |
| + if (existing_registration_ref && |
| + existing_registration_ref->value()->options()->Equals(options)) { |
| + BackgroundSyncRegistration* existing_registration = |
| + existing_registration_ref->value(); |
| if (existing_registration->sync_state() == SYNC_STATE_FAILED) { |
| existing_registration->set_sync_state(SYNC_STATE_PENDING); |
| StoreRegistrations( |
| sw_registration_id, |
| base::Bind(&BackgroundSyncManager::RegisterDidStore, |
| weak_ptr_factory_.GetWeakPtr(), sw_registration_id, |
| - *existing_registration, callback)); |
| + make_scoped_refptr(existing_registration_ref), callback)); |
| return; |
| } |
| @@ -363,27 +372,33 @@ void BackgroundSyncManager::RegisterImpl( |
| BACKGROUND_SYNC_STATUS_OK); |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_OK, |
| - *existing_registration)); |
| + FROM_HERE, |
| + base::Bind( |
| + callback, BACKGROUND_SYNC_STATUS_OK, |
| + base::Passed( |
| + CreateRegistrationHandle(*existing_registration_ref).Pass()))); |
| return; |
| } |
| - BackgroundSyncRegistration new_registration; |
| - *new_registration.options() = options; |
| + scoped_refptr<RefCountedRegistration> new_ref_registration( |
|
michaeln
2015/08/21 02:39:24
Is it possible for there to be handle to a registr
jkarlin
2015/08/25 17:32:58
Yes, but it will have a different registration id.
|
| + new RefCountedRegistration()); |
| + BackgroundSyncRegistration* new_registration = new_ref_registration->value(); |
| + |
| + *new_registration->options() = options; |
| BackgroundSyncRegistrations* registrations = |
| &sw_to_registrations_map_[sw_registration_id]; |
| - new_registration.set_id(registrations->next_id++); |
| + new_registration->set_id(registrations->next_id++); |
| AddRegistrationToMap(sw_registration_id, |
| sw_registration->pattern().GetOrigin(), |
| - new_registration); |
| + new_ref_registration); |
| StoreRegistrations( |
| sw_registration_id, |
| base::Bind(&BackgroundSyncManager::RegisterDidStore, |
| weak_ptr_factory_.GetWeakPtr(), sw_registration_id, |
| - new_registration, callback)); |
| + new_ref_registration, callback)); |
| } |
| void BackgroundSyncManager::DisableAndClearManager( |
| @@ -441,7 +456,8 @@ void BackgroundSyncManager::DisableAndClearManagerClearedOne( |
| base::Bind(barrier_closure)); |
| } |
| -BackgroundSyncRegistration* BackgroundSyncManager::LookupRegistration( |
| +BackgroundSyncManager::RefCountedRegistration* |
| +BackgroundSyncManager::LookupRegistration( |
| int64 sw_registration_id, |
| const RegistrationKey& registration_key) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| @@ -460,7 +476,7 @@ BackgroundSyncRegistration* BackgroundSyncManager::LookupRegistration( |
| if (key_and_registration_iter == registrations.registration_map.end()) |
| return nullptr; |
| - return &key_and_registration_iter->second; |
| + return key_and_registration_iter->second.get(); |
| } |
| void BackgroundSyncManager::StoreRegistrations( |
| @@ -477,7 +493,7 @@ void BackgroundSyncManager::StoreRegistrations( |
| for (const auto& key_and_registration : registrations.registration_map) { |
| const BackgroundSyncRegistration& registration = |
| - key_and_registration.second; |
| + *key_and_registration.second->value(); |
| BackgroundSyncRegistrationProto* registration_proto = |
| registrations_proto.add_registration(); |
| registration_proto->set_id(registration.id()); |
| @@ -499,27 +515,28 @@ void BackgroundSyncManager::StoreRegistrations( |
| void BackgroundSyncManager::RegisterDidStore( |
| int64 sw_registration_id, |
| - const BackgroundSyncRegistration& new_registration, |
| + const scoped_refptr<RefCountedRegistration>& new_registration_ref, |
| const StatusAndRegistrationCallback& callback, |
| ServiceWorkerStatusCode status) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + const BackgroundSyncRegistration* new_registration = |
| + new_registration_ref->value(); |
| + |
| // For UMA, determine here whether the sync could fire immediately |
| BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire = |
| - AreOptionConditionsMet(*new_registration.options()) |
| + AreOptionConditionsMet(*new_registration->options()) |
| ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE |
| : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE; |
| if (status == SERVICE_WORKER_ERROR_NOT_FOUND) { |
| // The service worker registration is gone. |
| BackgroundSyncMetrics::CountRegister( |
| - new_registration.options()->periodicity, registration_could_fire, |
| + new_registration->options()->periodicity, registration_could_fire, |
| BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE, |
| BACKGROUND_SYNC_STATUS_STORAGE_ERROR); |
| sw_to_registrations_map_.erase(sw_registration_id); |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| - BackgroundSyncRegistration())); |
| + PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback); |
| return; |
| } |
| @@ -527,23 +544,25 @@ void BackgroundSyncManager::RegisterDidStore( |
| LOG(ERROR) << "BackgroundSync failed to store registration due to backend " |
| "failure."; |
| BackgroundSyncMetrics::CountRegister( |
| - new_registration.options()->periodicity, registration_could_fire, |
| + new_registration->options()->periodicity, registration_could_fire, |
| BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE, |
| BACKGROUND_SYNC_STATUS_STORAGE_ERROR); |
| - DisableAndClearManager(base::Bind(callback, |
| - BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| - BackgroundSyncRegistration())); |
| + DisableAndClearManager(base::Bind( |
| + callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| + base::Passed(scoped_ptr<BackgroundSyncRegistrationHandle>().Pass()))); |
| return; |
| } |
| BackgroundSyncMetrics::CountRegister( |
| - new_registration.options()->periodicity, registration_could_fire, |
| + new_registration->options()->periodicity, registration_could_fire, |
| BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE, |
| BACKGROUND_SYNC_STATUS_OK); |
| FireReadyEvents(); |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, |
| - base::Bind(callback, BACKGROUND_SYNC_STATUS_OK, new_registration)); |
| + base::Bind(callback, BACKGROUND_SYNC_STATUS_OK, |
| + base::Passed( |
| + CreateRegistrationHandle(*new_registration_ref).Pass()))); |
| } |
| void BackgroundSyncManager::RemoveRegistrationFromMap( |
| @@ -561,15 +580,15 @@ void BackgroundSyncManager::RemoveRegistrationFromMap( |
| void BackgroundSyncManager::AddRegistrationToMap( |
| int64 sw_registration_id, |
| const GURL& origin, |
| - const BackgroundSyncRegistration& sync_registration) { |
| + const scoped_refptr<RefCountedRegistration>& sync_registration) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - DCHECK(sync_registration.IsValid()); |
| + DCHECK(sync_registration->value()->IsValid()); |
| BackgroundSyncRegistrations* registrations = |
| &sw_to_registrations_map_[sw_registration_id]; |
| registrations->origin = origin; |
| - RegistrationKey registration_key(sync_registration); |
| + RegistrationKey registration_key(*sync_registration->value()); |
| registrations->registration_map[registration_key] = sync_registration; |
| } |
| @@ -596,20 +615,68 @@ void BackgroundSyncManager::GetDataFromBackend( |
| } |
| void BackgroundSyncManager::FireOneShotSync( |
| - const BackgroundSyncRegistration& registration, |
| + const RefCountedRegistration& registration, |
| const scoped_refptr<ServiceWorkerVersion>& active_version, |
| const ServiceWorkerVersion::StatusCallback& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - active_version->DispatchSyncEvent( |
| - mojo::ConvertTo<SyncRegistrationPtr>(registration), callback); |
| + // The ServiceWorkerVersion doesn't know when the client (javascript) is done |
| + // with the registration so don't give it a BackgroundSyncRegistrationHandle. |
| + // The render process must call BackgroundSyncServiceImpl::TrackRegistration |
| + // which creates the corresponding BackgroundSyncRegistrationHandle. In the |
| + // unlikely event that the render process is killed before TrackRegistration |
| + // is called, the manager will hold the reference until it is destroyed. |
| + // The ~BackgroundSyncManager DCHECKS verify that this is uncommon. |
| + SyncRegistrationPtr sync_registration = |
| + mojo::ConvertTo<SyncRegistrationPtr>(*registration.value()); |
| + scoped_refptr<const RefCountedRegistration>* ptr = |
| + new scoped_refptr<const RefCountedRegistration>(®istration); |
| + sync_registration->id = registration_handle_ids_.Add(ptr); |
| + |
| + active_version->DispatchSyncEvent(sync_registration.Pass(), callback); |
| +} |
| + |
| +scoped_ptr<BackgroundSyncRegistrationHandle> |
| +BackgroundSyncManager::CreateRegistrationHandle( |
| + const RefCountedRegistration& registration) { |
| + scoped_refptr<const RefCountedRegistration>* ptr = |
| + new scoped_refptr<const RefCountedRegistration>(®istration); |
| + |
| + // Registration handles have unique handle ids. The handle id maps to an |
| + // internal RefCountedRegistration (which has the persistent registration id) |
| + // via |
| + // registration_reference_ids_. |
| + BackgroundSyncRegistrationHandle::HandleId handle_id = |
| + registration_handle_ids_.Add(ptr); |
| + |
| + return make_scoped_ptr(new BackgroundSyncRegistrationHandle(this, handle_id)); |
| +} |
| + |
| +void BackgroundSyncManager::Unregister( |
| + int64 sw_registration_id, |
| + SyncPeriodicity periodicity, |
| + BackgroundSyncRegistrationHandle::HandleId handle_id, |
| + const StatusCallback& callback) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + if (disabled_) { |
| + BackgroundSyncMetrics::CountUnregister( |
| + periodicity, BACKGROUND_SYNC_STATUS_STORAGE_ERROR); |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR)); |
| + return; |
| + } |
| + |
| + op_scheduler_.ScheduleOperation( |
| + base::Bind(&BackgroundSyncManager::UnregisterImpl, |
|
michaeln
2015/08/21 02:39:24
What prevents ReleaseHandleId(xxx) from happening
jkarlin
2015/08/25 17:32:58
Thanks for that catch. Resolved by reverting Unreg
|
| + weak_ptr_factory_.GetWeakPtr(), sw_registration_id, |
| + periodicity, handle_id, MakeStatusCompletion(callback))); |
| } |
| void BackgroundSyncManager::UnregisterImpl( |
| int64 sw_registration_id, |
| - const RegistrationKey& registration_key, |
| - BackgroundSyncRegistration::RegistrationId sync_registration_id, |
| SyncPeriodicity periodicity, |
| + BackgroundSyncRegistrationHandle::HandleId handle_id, |
| const StatusCallback& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| @@ -621,10 +688,21 @@ void BackgroundSyncManager::UnregisterImpl( |
| return; |
| } |
| - const BackgroundSyncRegistration* existing_registration = |
| + scoped_refptr<const RefCountedRegistration>* handle_ref = |
| + registration_handle_ids_.Lookup(handle_id); |
| + DCHECK(handle_ref); |
| + |
| + const BackgroundSyncRegistration* handle_registration = |
| + (*handle_ref)->value(); |
| + |
| + RegistrationKey registration_key(handle_registration->options()->tag, |
| + periodicity); |
| + |
| + const RefCountedRegistration* existing_registration = |
| LookupRegistration(sw_registration_id, registration_key); |
| + |
| if (!existing_registration || |
| - existing_registration->id() != sync_registration_id) { |
| + existing_registration->value()->id() != handle_registration->id()) { |
| BackgroundSyncMetrics::CountUnregister(periodicity, |
| BACKGROUND_SYNC_STATUS_NOT_FOUND); |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| @@ -678,24 +756,21 @@ void BackgroundSyncManager::GetRegistrationImpl( |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| if (disabled_) { |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| - BackgroundSyncRegistration())); |
| + PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback); |
| return; |
| } |
| - const BackgroundSyncRegistration* out_registration = |
| + const RefCountedRegistration* registration = |
| LookupRegistration(sw_registration_id, registration_key); |
| - if (!out_registration) { |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_NOT_FOUND, |
| - BackgroundSyncRegistration())); |
| + if (!registration) { |
| + PostErrorResponse(BACKGROUND_SYNC_STATUS_NOT_FOUND, callback); |
| return; |
| } |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, |
| - base::Bind(callback, BACKGROUND_SYNC_STATUS_OK, *out_registration)); |
| + base::Bind(callback, BACKGROUND_SYNC_STATUS_OK, |
| + base::Passed(CreateRegistrationHandle(*registration).Pass()))); |
| } |
| void BackgroundSyncManager::GetRegistrationsImpl( |
| @@ -704,12 +779,13 @@ void BackgroundSyncManager::GetRegistrationsImpl( |
| const StatusAndRegistrationsCallback& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - std::vector<BackgroundSyncRegistration> out_registrations; |
| + scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>> out_registrations( |
| + new ScopedVector<BackgroundSyncRegistrationHandle>()); |
| if (disabled_) { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR, |
| - out_registrations)); |
| + base::Passed(out_registrations.Pass()))); |
| return; |
| } |
| @@ -719,16 +795,18 @@ void BackgroundSyncManager::GetRegistrationsImpl( |
| if (it != sw_to_registrations_map_.end()) { |
| const BackgroundSyncRegistrations& registrations = it->second; |
| for (const auto& tag_and_registration : registrations.registration_map) { |
| - const BackgroundSyncRegistration& registration = |
| - tag_and_registration.second; |
| - if (registration.options()->periodicity == periodicity) |
| - out_registrations.push_back(registration); |
| + const RefCountedRegistration& registration = |
| + *tag_and_registration.second.get(); |
| + if (registration.value()->options()->periodicity == periodicity) { |
| + out_registrations->push_back( |
| + CreateRegistrationHandle(registration).release()); |
| + } |
| } |
| } |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, |
| - base::Bind(callback, BACKGROUND_SYNC_STATUS_OK, out_registrations)); |
| + FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_OK, |
| + base::Passed(out_registrations.Pass()))); |
| } |
| bool BackgroundSyncManager::AreOptionConditionsMet( |
| @@ -762,7 +840,7 @@ void BackgroundSyncManager::SchedulePendingRegistrations() { |
| for (const auto& key_and_registration : |
| sw_id_and_registrations.second.registration_map) { |
| const BackgroundSyncRegistration& registration = |
| - key_and_registration.second; |
| + *key_and_registration.second->value(); |
| if (registration.sync_state() == SYNC_STATE_PENDING) { |
| if (registration.options()->periodicity == SYNC_ONE_SHOT) { |
| keep_browser_alive_for_one_shot = true; |
| @@ -812,7 +890,8 @@ void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure& callback) { |
| const int64 service_worker_id = sw_id_and_registrations.first; |
| for (auto& key_and_registration : |
| sw_id_and_registrations.second.registration_map) { |
| - BackgroundSyncRegistration* registration = &key_and_registration.second; |
| + BackgroundSyncRegistration* registration = |
| + key_and_registration.second->value(); |
| if (IsRegistrationReadyToFire(*registration)) { |
| sw_id_and_keys_to_fire.push_back( |
| std::make_pair(service_worker_id, key_and_registration.first)); |
| @@ -845,14 +924,15 @@ void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure& callback) { |
| for (const auto& sw_id_and_key : sw_id_and_keys_to_fire) { |
| int64 service_worker_id = sw_id_and_key.first; |
| - const BackgroundSyncRegistration* registration = |
| + const RefCountedRegistration* registration = |
| LookupRegistration(service_worker_id, sw_id_and_key.second); |
| + DCHECK(registration); |
| service_worker_context_->FindRegistrationForId( |
| service_worker_id, sw_to_registrations_map_[service_worker_id].origin, |
| base::Bind(&BackgroundSyncManager::FireReadyEventsDidFindRegistration, |
| weak_ptr_factory_.GetWeakPtr(), sw_id_and_key.second, |
| - registration->id(), events_fired_barrier_closure, |
| + registration->value()->id(), events_fired_barrier_closure, |
| events_completed_barrier_closure)); |
| } |
| } |
| @@ -877,8 +957,9 @@ void BackgroundSyncManager::FireReadyEventsDidFindRegistration( |
| return; |
| } |
| - BackgroundSyncRegistration* registration = |
| + const RefCountedRegistration* registration = |
| LookupRegistration(service_worker_registration->id(), registration_key); |
| + DCHECK(registration); |
| FireOneShotSync( |
| *registration, service_worker_registration->active_version(), |
| @@ -924,14 +1005,17 @@ void BackgroundSyncManager::EventCompleteImpl( |
| return; |
| } |
| - BackgroundSyncRegistration* registration = |
| + RefCountedRegistration* registration_ref = |
| LookupRegistration(service_worker_id, key); |
| - if (!registration || registration->id() != sync_registration_id) { |
| + if (!registration_ref || |
| + registration_ref->value()->id() != sync_registration_id) { |
| base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| base::Bind(callback)); |
| return; |
| } |
| + BackgroundSyncRegistration* registration = registration_ref->value(); |
| + |
| // The event ran to completion, we should count it, no matter what happens |
| // from here. |
| BackgroundSyncMetrics::RecordEventResult(registration->options()->periodicity, |
| @@ -1023,6 +1107,7 @@ void BackgroundSyncManager::OnPowerChanged() { |
| FireReadyEvents(); |
| } |
| +// TODO(jkarlin): Figure out how to pass scoped_ptrs with this. |
| template <typename CallbackT, typename... Params> |
| void BackgroundSyncManager::CompleteOperationCallback(const CallbackT& callback, |
| Params... parameters) { |
| @@ -1032,6 +1117,26 @@ void BackgroundSyncManager::CompleteOperationCallback(const CallbackT& callback, |
| op_scheduler_.CompleteOperationAndRunNext(); |
| } |
| +void BackgroundSyncManager::CompleteStatusAndRegistrationCallback( |
| + StatusAndRegistrationCallback callback, |
| + BackgroundSyncStatus status, |
| + scoped_ptr<BackgroundSyncRegistrationHandle> result) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + callback.Run(status, result.Pass()); |
| + op_scheduler_.CompleteOperationAndRunNext(); |
| +} |
| + |
| +void BackgroundSyncManager::CompleteStatusAndRegistrationsCallback( |
| + StatusAndRegistrationsCallback callback, |
| + BackgroundSyncStatus status, |
| + scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>> results) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + callback.Run(status, results.Pass()); |
| + op_scheduler_.CompleteOperationAndRunNext(); |
| +} |
| + |
| base::Closure BackgroundSyncManager::MakeEmptyCompletion() { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| @@ -1052,10 +1157,9 @@ BackgroundSyncManager::MakeStatusAndRegistrationCompletion( |
| const StatusAndRegistrationCallback& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - return base::Bind(&BackgroundSyncManager::CompleteOperationCallback< |
| - StatusAndRegistrationCallback, BackgroundSyncStatus, |
| - const BackgroundSyncRegistration&>, |
| - weak_ptr_factory_.GetWeakPtr(), callback); |
| + return base::Bind( |
| + &BackgroundSyncManager::CompleteStatusAndRegistrationCallback, |
| + weak_ptr_factory_.GetWeakPtr(), callback); |
| } |
| BackgroundSyncManager::StatusAndRegistrationsCallback |
| @@ -1063,10 +1167,9 @@ BackgroundSyncManager::MakeStatusAndRegistrationsCompletion( |
| const StatusAndRegistrationsCallback& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - return base::Bind(&BackgroundSyncManager::CompleteOperationCallback< |
| - StatusAndRegistrationsCallback, BackgroundSyncStatus, |
| - const std::vector<BackgroundSyncRegistration>&>, |
| - weak_ptr_factory_.GetWeakPtr(), callback); |
| + return base::Bind( |
| + &BackgroundSyncManager::CompleteStatusAndRegistrationsCallback, |
| + weak_ptr_factory_.GetWeakPtr(), callback); |
| } |
| BackgroundSyncManager::StatusCallback |