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 6ba38b57924d1e0dbe2ded9e8775ea56e176531d..98dab1ac4b9452b187f838209b6c5a27735f43a0 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,36 @@ |
#include "content/browser/android/background_sync_launcher_android.h" |
#endif |
+namespace content { |
+ |
+class BackgroundSyncManager::RefCountedRegistration |
+ : public base::RefCounted<RefCountedRegistration> { |
+ public: |
+ BackgroundSyncRegistration* value() { return ®istration_; } |
+ const BackgroundSyncRegistration* value() const { return ®istration_; } |
+ |
+ private: |
+ friend class base::RefCounted<RefCountedRegistration>; |
+ ~RefCountedRegistration() = default; |
+ |
+ BackgroundSyncRegistration registration_; |
+}; |
+ |
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() |
@@ -88,9 +114,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; |
} |
@@ -100,30 +124,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, |
@@ -132,9 +132,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; |
} |
@@ -154,8 +152,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; |
} |
@@ -165,6 +167,20 @@ void BackgroundSyncManager::GetRegistrations( |
periodicity, MakeStatusAndRegistrationsCompletion(callback))); |
} |
+// Given a HandleId |handle_id|, return a new handle for the same |
+// registration. |
+scoped_ptr<BackgroundSyncRegistrationHandle> |
+BackgroundSyncManager::DuplicateRegistrationHandle( |
+ BackgroundSyncRegistrationHandle::HandleId handle_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
+ scoped_refptr<RefCountedRegistration>* ref_registration = |
+ registration_handle_ids_.Lookup(handle_id); |
+ if (!ref_registration) |
+ return scoped_ptr<BackgroundSyncRegistrationHandle>(); |
+ return CreateRegistrationHandle(ref_registration->get()); |
+} |
+ |
void BackgroundSyncManager::OnRegistrationDeleted(int64 registration_id, |
const GURL& pattern) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
@@ -246,7 +262,7 @@ void BackgroundSyncManager::InitDidGetDataFromBackend( |
BackgroundSyncRegistrationsProto registrations_proto; |
if (registrations_proto.ParseFromString(data.second)) { |
BackgroundSyncRegistrations* registrations = |
- &sw_to_registrations_map_[data.first]; |
+ &active_registrations_[data.first]; |
registrations->next_id = registrations_proto.next_registration_id(); |
registrations->origin = GURL(registrations_proto.origin()); |
@@ -262,8 +278,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(); |
@@ -317,9 +336,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; |
} |
@@ -330,32 +347,29 @@ 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 (requested_from_service_worker && |
!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 = |
- LookupRegistration(sw_registration_id, RegistrationKey(options)); |
- if (existing_registration && |
- existing_registration->options()->Equals(options)) { |
+ RefCountedRegistration* existing_registration_ref = |
+ LookupActiveRegistration(sw_registration_id, RegistrationKey(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; |
} |
@@ -366,27 +380,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( |
+ 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++); |
+ &active_registrations_[sw_registration_id]; |
+ new_registration->set_id(registrations->next_id++); |
- AddRegistrationToMap(sw_registration_id, |
- sw_registration->pattern().GetOrigin(), |
- new_registration); |
+ AddActiveRegistration(sw_registration_id, |
+ sw_registration->pattern().GetOrigin(), |
+ 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( |
@@ -400,7 +420,7 @@ void BackgroundSyncManager::DisableAndClearManager( |
} |
disabled_ = true; |
- sw_to_registrations_map_.clear(); |
+ active_registrations_.clear(); |
// Delete all backend entries. The memory representation of registered syncs |
// may be out of sync with storage (e.g., due to corruption detection on |
@@ -444,14 +464,15 @@ void BackgroundSyncManager::DisableAndClearManagerClearedOne( |
base::Bind(barrier_closure)); |
} |
-BackgroundSyncRegistration* BackgroundSyncManager::LookupRegistration( |
+BackgroundSyncManager::RefCountedRegistration* |
+BackgroundSyncManager::LookupActiveRegistration( |
int64 sw_registration_id, |
const RegistrationKey& registration_key) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
SWIdToRegistrationsMap::iterator it = |
- sw_to_registrations_map_.find(sw_registration_id); |
- if (it == sw_to_registrations_map_.end()) |
+ active_registrations_.find(sw_registration_id); |
+ if (it == active_registrations_.end()) |
return nullptr; |
BackgroundSyncRegistrations& registrations = it->second; |
@@ -463,7 +484,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( |
@@ -473,14 +494,14 @@ void BackgroundSyncManager::StoreRegistrations( |
// Serialize the data. |
const BackgroundSyncRegistrations& registrations = |
- sw_to_registrations_map_[sw_registration_id]; |
+ active_registrations_[sw_registration_id]; |
BackgroundSyncRegistrationsProto registrations_proto; |
registrations_proto.set_next_registration_id(registrations.next_id); |
registrations_proto.set_origin(registrations.origin.spec()); |
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()); |
@@ -502,27 +523,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())); |
+ active_registrations_.erase(sw_registration_id); |
+ PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback); |
return; |
} |
@@ -530,49 +552,52 @@ 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.get()).Pass()))); |
} |
-void BackgroundSyncManager::RemoveRegistrationFromMap( |
+void BackgroundSyncManager::RemoveActiveRegistration( |
int64 sw_registration_id, |
const RegistrationKey& registration_key) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- DCHECK(LookupRegistration(sw_registration_id, registration_key)); |
+ DCHECK(LookupActiveRegistration(sw_registration_id, registration_key)); |
BackgroundSyncRegistrations* registrations = |
- &sw_to_registrations_map_[sw_registration_id]; |
+ &active_registrations_[sw_registration_id]; |
registrations->registration_map.erase(registration_key); |
} |
-void BackgroundSyncManager::AddRegistrationToMap( |
+void BackgroundSyncManager::AddActiveRegistration( |
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]; |
+ &active_registrations_[sw_registration_id]; |
registrations->origin = origin; |
- RegistrationKey registration_key(sync_registration); |
+ RegistrationKey registration_key(*sync_registration->value()); |
registrations->registration_map[registration_key] = sync_registration; |
} |
@@ -599,13 +624,75 @@ void BackgroundSyncManager::GetDataFromBackend( |
} |
void BackgroundSyncManager::FireOneShotSync( |
- const BackgroundSyncRegistration& registration, |
+ BackgroundSyncRegistrationHandle::HandleId handle_id, |
const scoped_refptr<ServiceWorkerVersion>& active_version, |
const ServiceWorkerVersion::StatusCallback& callback) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ DCHECK(active_version); |
+ |
+ // The ServiceWorkerVersion doesn't know when the client (javascript) is done |
+ // with the registration so don't give it a BackgroundSyncRegistrationHandle. |
+ // Once the render process gets the handle_id it can create its own handle |
+ // (with a new unique handle id). |
+ active_version->DispatchSyncEvent(handle_id, callback); |
+} |
+ |
+scoped_ptr<BackgroundSyncRegistrationHandle> |
+BackgroundSyncManager::CreateRegistrationHandle( |
+ const scoped_refptr<RefCountedRegistration>& registration) { |
+ scoped_refptr<RefCountedRegistration>* ptr = |
+ new scoped_refptr<RefCountedRegistration>(registration); |
+ |
+ // 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( |
+ weak_ptr_factory_.GetWeakPtr(), handle_id)); |
+} |
+ |
+BackgroundSyncRegistration* BackgroundSyncManager::GetRegistrationForHandle( |
+ BackgroundSyncRegistrationHandle::HandleId handle_id) const { |
+ scoped_refptr<RefCountedRegistration>* ref_registration = |
+ registration_handle_ids_.Lookup(handle_id); |
+ if (!ref_registration) |
+ return nullptr; |
+ return (*ref_registration)->value(); |
+} |
+ |
+void BackgroundSyncManager::ReleaseRegistrationHandle( |
+ BackgroundSyncRegistrationHandle::HandleId handle_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ DCHECK(registration_handle_ids_.Lookup(handle_id)); |
+ registration_handle_ids_.Remove(handle_id); |
+} |
+ |
+void BackgroundSyncManager::Unregister( |
+ int64 sw_registration_id, |
+ SyncPeriodicity periodicity, |
+ BackgroundSyncRegistrationHandle::HandleId handle_id, |
+ const StatusCallback& callback) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- active_version->DispatchSyncEvent( |
- mojo::ConvertTo<SyncRegistrationPtr>(registration), callback); |
+ 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; |
+ } |
+ |
+ BackgroundSyncRegistration* registration = |
+ GetRegistrationForHandle(handle_id); |
+ DCHECK(registration); |
+ |
+ op_scheduler_.ScheduleOperation(base::Bind( |
+ &BackgroundSyncManager::UnregisterImpl, weak_ptr_factory_.GetWeakPtr(), |
+ sw_registration_id, RegistrationKey(*registration), registration->id(), |
+ periodicity, MakeStatusCompletion(callback))); |
} |
void BackgroundSyncManager::UnregisterImpl( |
@@ -624,10 +711,11 @@ void BackgroundSyncManager::UnregisterImpl( |
return; |
} |
- const BackgroundSyncRegistration* existing_registration = |
- LookupRegistration(sw_registration_id, registration_key); |
+ const RefCountedRegistration* existing_registration = |
+ LookupActiveRegistration(sw_registration_id, registration_key); |
+ |
if (!existing_registration || |
- existing_registration->id() != sync_registration_id) { |
+ existing_registration->value()->id() != sync_registration_id) { |
BackgroundSyncMetrics::CountUnregister(periodicity, |
BACKGROUND_SYNC_STATUS_NOT_FOUND); |
base::ThreadTaskRunnerHandle::Get()->PostTask( |
@@ -635,7 +723,7 @@ void BackgroundSyncManager::UnregisterImpl( |
return; |
} |
- RemoveRegistrationFromMap(sw_registration_id, registration_key); |
+ RemoveActiveRegistration(sw_registration_id, registration_key); |
StoreRegistrations(sw_registration_id, |
base::Bind(&BackgroundSyncManager::UnregisterDidStore, |
@@ -653,7 +741,7 @@ void BackgroundSyncManager::UnregisterDidStore(int64 sw_registration_id, |
// ServiceWorker was unregistered. |
BackgroundSyncMetrics::CountUnregister( |
periodicity, BACKGROUND_SYNC_STATUS_STORAGE_ERROR); |
- sw_to_registrations_map_.erase(sw_registration_id); |
+ active_registrations_.erase(sw_registration_id); |
base::ThreadTaskRunnerHandle::Get()->PostTask( |
FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR)); |
return; |
@@ -681,24 +769,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 = |
- LookupRegistration(sw_registration_id, registration_key); |
- if (!out_registration) { |
- base::ThreadTaskRunnerHandle::Get()->PostTask( |
- FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_NOT_FOUND, |
- BackgroundSyncRegistration())); |
+ RefCountedRegistration* registration = |
+ LookupActiveRegistration(sw_registration_id, registration_key); |
+ 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( |
@@ -707,31 +792,33 @@ 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; |
} |
SWIdToRegistrationsMap::iterator it = |
- sw_to_registrations_map_.find(sw_registration_id); |
+ active_registrations_.find(sw_registration_id); |
- if (it != sw_to_registrations_map_.end()) { |
+ if (it != active_registrations_.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); |
+ 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( |
@@ -761,11 +848,11 @@ void BackgroundSyncManager::SchedulePendingRegistrations() { |
#if defined(OS_ANDROID) |
bool keep_browser_alive_for_one_shot = false; |
- for (const auto& sw_id_and_registrations : sw_to_registrations_map_) { |
+ for (const auto& sw_id_and_registrations : active_registrations_) { |
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; |
@@ -811,11 +898,12 @@ void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure& callback) { |
// Find the registrations that are ready to run. |
std::vector<std::pair<int64, RegistrationKey>> sw_id_and_keys_to_fire; |
- for (auto& sw_id_and_registrations : sw_to_registrations_map_) { |
+ for (auto& sw_id_and_registrations : active_registrations_) { |
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)); |
@@ -848,14 +936,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 = |
- LookupRegistration(service_worker_id, sw_id_and_key.second); |
+ const RefCountedRegistration* registration = |
+ LookupActiveRegistration(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, |
+ service_worker_id, active_registrations_[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)); |
} |
} |
@@ -880,15 +969,23 @@ void BackgroundSyncManager::FireReadyEventsDidFindRegistration( |
return; |
} |
- BackgroundSyncRegistration* registration = |
- LookupRegistration(service_worker_registration->id(), registration_key); |
+ RefCountedRegistration* registration = LookupActiveRegistration( |
+ service_worker_registration->id(), registration_key); |
+ DCHECK(registration); |
+ |
+ // Create a handle and keep it until the sync event completes. The client can |
+ // acquire its own handle for longer-term use. |
+ scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle = |
+ CreateRegistrationHandle(registration); |
+ BackgroundSyncRegistrationHandle::HandleId handle_id = |
+ registration_handle->handle_id(); |
FireOneShotSync( |
- *registration, service_worker_registration->active_version(), |
- base::Bind(&BackgroundSyncManager::EventComplete, |
- weak_ptr_factory_.GetWeakPtr(), service_worker_registration, |
- service_worker_registration->id(), registration_key, |
- registration_id, event_completed_callback)); |
+ handle_id, service_worker_registration->active_version(), |
+ base::Bind( |
+ &BackgroundSyncManager::EventComplete, weak_ptr_factory_.GetWeakPtr(), |
+ service_worker_registration, service_worker_registration->id(), |
+ base::Passed(registration_handle.Pass()), event_completed_callback)); |
base::ThreadTaskRunnerHandle::Get()->PostTask( |
FROM_HERE, base::Bind(event_fired_callback)); |
@@ -899,8 +996,7 @@ void BackgroundSyncManager::FireReadyEventsDidFindRegistration( |
void BackgroundSyncManager::EventComplete( |
const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, |
int64 service_worker_id, |
- const RegistrationKey& key, |
- BackgroundSyncRegistration::RegistrationId sync_registration_id, |
+ scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle, |
const base::Closure& callback, |
ServiceWorkerStatusCode status_code) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
@@ -909,14 +1005,13 @@ void BackgroundSyncManager::EventComplete( |
op_scheduler_.ScheduleOperation(base::Bind( |
&BackgroundSyncManager::EventCompleteImpl, weak_ptr_factory_.GetWeakPtr(), |
- service_worker_id, key, sync_registration_id, status_code, |
+ service_worker_id, base::Passed(registration_handle.Pass()), status_code, |
MakeClosureCompletion(callback))); |
} |
void BackgroundSyncManager::EventCompleteImpl( |
int64 service_worker_id, |
- const RegistrationKey& key, |
- BackgroundSyncRegistration::RegistrationId sync_registration_id, |
+ scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle, |
ServiceWorkerStatusCode status_code, |
const base::Closure& callback) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
@@ -928,12 +1023,8 @@ void BackgroundSyncManager::EventCompleteImpl( |
} |
BackgroundSyncRegistration* registration = |
- LookupRegistration(service_worker_id, key); |
- if (!registration || registration->id() != sync_registration_id) { |
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
- base::Bind(callback)); |
- return; |
- } |
+ registration_handle->registration(); |
+ DCHECK(registration); |
// The event ran to completion, we should count it, no matter what happens |
// from here. |
@@ -946,8 +1037,13 @@ void BackgroundSyncManager::EventCompleteImpl( |
// this registration. (crbug.com/479665) |
registration->set_sync_state(SYNC_STATE_FAILED); |
} else { |
- registration = nullptr; |
- RemoveRegistrationFromMap(service_worker_id, key); |
+ RegistrationKey key(*registration); |
+ // Remove the registration if it's still active. |
+ RefCountedRegistration* active_registration = |
+ LookupActiveRegistration(service_worker_id, key); |
+ if (active_registration && |
+ active_registration->value()->id() == registration->id()) |
+ RemoveActiveRegistration(service_worker_id, key); |
} |
} else { |
// TODO(jkarlin): Add support for running periodic syncs. (crbug.com/479674) |
@@ -968,7 +1064,7 @@ void BackgroundSyncManager::EventCompleteDidStore( |
if (status_code == SERVICE_WORKER_ERROR_NOT_FOUND) { |
// The registration is gone. |
- sw_to_registrations_map_.erase(service_worker_id); |
+ active_registrations_.erase(service_worker_id); |
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
base::Bind(callback)); |
return; |
@@ -1001,7 +1097,7 @@ void BackgroundSyncManager::OnRegistrationDeletedImpl( |
// The backend (ServiceWorkerStorage) will delete the data, so just delete the |
// memory representation here. |
- sw_to_registrations_map_.erase(registration_id); |
+ active_registrations_.erase(registration_id); |
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
base::Bind(callback)); |
} |
@@ -1009,7 +1105,7 @@ void BackgroundSyncManager::OnRegistrationDeletedImpl( |
void BackgroundSyncManager::OnStorageWipedImpl(const base::Closure& callback) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- sw_to_registrations_map_.clear(); |
+ active_registrations_.clear(); |
disabled_ = false; |
InitImpl(callback); |
} |
@@ -1026,6 +1122,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) { |
@@ -1035,6 +1132,27 @@ void BackgroundSyncManager::CompleteOperationCallback(const CallbackT& callback, |
op_scheduler_.CompleteOperationAndRunNext(); |
} |
+void BackgroundSyncManager::CompleteStatusAndRegistrationCallback( |
+ StatusAndRegistrationCallback callback, |
+ BackgroundSyncStatus status, |
+ scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
+ callback.Run(status, registration_handle.Pass()); |
+ op_scheduler_.CompleteOperationAndRunNext(); |
+} |
+ |
+void BackgroundSyncManager::CompleteStatusAndRegistrationsCallback( |
+ StatusAndRegistrationsCallback callback, |
+ BackgroundSyncStatus status, |
+ scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>> |
+ registration_handles) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
+ callback.Run(status, registration_handles.Pass()); |
+ op_scheduler_.CompleteOperationAndRunNext(); |
+} |
+ |
base::Closure BackgroundSyncManager::MakeEmptyCompletion() { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
@@ -1055,10 +1173,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 |
@@ -1066,10 +1183,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 |