Index: content/browser/geofencing/geofencing_manager.cc |
diff --git a/content/browser/geofencing/geofencing_manager.cc b/content/browser/geofencing/geofencing_manager.cc |
index 94b0f25dcedf5a7d8ad5ab6c9ca3c1e898b56726..33afae5ef02d8948b9a4775a85d36923222f2b21 100644 |
--- a/content/browser/geofencing/geofencing_manager.cc |
+++ b/content/browser/geofencing/geofencing_manager.cc |
@@ -7,97 +7,90 @@ |
#include <algorithm> |
#include "base/callback.h" |
-#include "base/memory/singleton.h" |
-#include "content/browser/geofencing/geofencing_provider.h" |
+#include "content/browser/geofencing/geofencing_service.h" |
+#include "content/browser/service_worker/service_worker_context_wrapper.h" |
#include "content/public/browser/browser_thread.h" |
#include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h" |
-#include "url/gurl.h" |
namespace content { |
-struct GeofencingManager::RegistrationKey { |
- RegistrationKey(BrowserContext* browser_context, |
- int64 service_worker_registration_id, |
- const GURL& service_worker_origin, |
- const std::string& region_id); |
- |
- BrowserContext* browser_context; |
+struct GeofencingManager::Registration { |
+ Registration(int64 service_worker_registration_id, |
+ const std::string& region_id, |
+ const blink::WebCircularGeofencingRegion& region, |
+ const StatusCallback& callback, |
+ int64 geofencing_registration_id); |
int64 service_worker_registration_id; |
- GURL service_worker_origin; |
- |
std::string region_id; |
-}; |
- |
-GeofencingManager::RegistrationKey::RegistrationKey( |
- BrowserContext* browser_context, |
- int64 service_worker_registration_id, |
- const GURL& service_worker_origin, |
- const std::string& region_id) |
- : browser_context(browser_context), |
- service_worker_registration_id(service_worker_registration_id), |
- service_worker_origin(service_worker_origin), |
- region_id(region_id) { |
-} |
- |
-struct GeofencingManager::Registration { |
- Registration(); |
- Registration(const RegistrationKey& key, |
- const blink::WebCircularGeofencingRegion& region); |
- |
- RegistrationKey key; |
blink::WebCircularGeofencingRegion region; |
- // Registration id as returned by the GeofencingProvider, set to -1 if not |
- // currently registered with the provider. |
- int registration_id; |
+ // Registration ID as returned by the |GeofencingService|. |
+ int64 geofencing_registration_id; |
+ |
+ // Callback to call when registration is completed. This field is reset when |
+ // registration is complete. |
+ StatusCallback registration_callback; |
- // Flag to indicate if this registration has completed, and thus should be |
+ // Returns true if registration has been completed, and thus should be |
// included in calls to GetRegisteredRegions. |
- bool is_active; |
+ bool is_active() const { return registration_callback.is_null(); } |
}; |
-GeofencingManager::Registration::Registration() : key(nullptr, -1, GURL(), "") { |
+GeofencingManager::Registration::Registration( |
+ int64 service_worker_registration_id, |
+ const std::string& region_id, |
+ const blink::WebCircularGeofencingRegion& region, |
+ const GeofencingManager::StatusCallback& callback, |
+ int64 geofencing_registration_id) |
+ : service_worker_registration_id(service_worker_registration_id), |
+ region_id(region_id), |
+ region(region), |
+ geofencing_registration_id(geofencing_registration_id), |
+ registration_callback(callback) { |
} |
-GeofencingManager::Registration::Registration( |
- const RegistrationKey& key, |
- const blink::WebCircularGeofencingRegion& region) |
- : key(key), region(region), registration_id(-1), is_active(false) { |
+GeofencingManager::GeofencingManager( |
+ const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context) |
+ : service_(nullptr), service_worker_context_(service_worker_context) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
} |
-class GeofencingManager::RegistrationMatches { |
- public: |
- RegistrationMatches(const RegistrationKey& key) : key_(key) {} |
- |
- bool operator()(const Registration& registration) { |
- return registration.key.browser_context == key_.browser_context && |
- registration.key.service_worker_registration_id == |
- key_.service_worker_registration_id && |
- registration.key.service_worker_origin == |
- key_.service_worker_origin && |
- registration.key.region_id == key_.region_id; |
- } |
+GeofencingManager::~GeofencingManager() { |
+} |
- private: |
- const RegistrationKey& key_; |
-}; |
+void GeofencingManager::Init() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ BrowserThread::PostTask(BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&GeofencingManager::InitOnIO, this)); |
+} |
-GeofencingManager::GeofencingManager() { |
+void GeofencingManager::Shutdown() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ BrowserThread::PostTask(BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&GeofencingManager::ShutdownOnIO, this)); |
} |
-GeofencingManager::~GeofencingManager() { |
+void GeofencingManager::InitOnIO() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ service_ = GeofencingServiceImpl::GetInstance(); |
} |
-GeofencingManager* GeofencingManager::GetInstance() { |
+void GeofencingManager::ShutdownOnIO() { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- return Singleton<GeofencingManager>::get(); |
+ // Clean up all registrations with the |GeofencingService|. |
+ // TODO(mek): This will need to change to support geofence registrations that |
+ // outlive the browser, although removing the references to this |
+ // |GeofencingManager| from the |GeofencingService| will still be needed. |
+ for (const auto& registration : registrations_by_id_) { |
+ service_->UnregisterRegion(registration.first); |
+ } |
} |
void GeofencingManager::RegisterRegion( |
- BrowserContext* browser_context, |
int64 service_worker_registration_id, |
- const GURL& service_worker_origin, |
const std::string& region_id, |
const blink::WebCircularGeofencingRegion& region, |
const StatusCallback& callback) { |
@@ -105,148 +98,148 @@ void GeofencingManager::RegisterRegion( |
// TODO(mek): Validate region_id and region. |
- if (!provider_.get()) { |
- callback.Run(GeofencingStatus:: |
- GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE); |
+ if (!service_->IsServiceAvailable()) { |
+ callback.Run(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE); |
return; |
} |
- RegistrationKey key(browser_context, |
- service_worker_registration_id, |
- service_worker_origin, |
- region_id); |
- if (FindRegistration(key)) { |
+ if (FindRegistration(service_worker_registration_id, region_id)) { |
// Already registered, return an error. |
- callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR); |
+ // TODO(mek): Use a more specific error code. |
+ callback.Run(GEOFENCING_STATUS_ERROR); |
return; |
} |
- // Add registration, but don't mark it as active yet. This prevents duplicate |
- // registrations. |
- AddRegistration(key, region); |
- |
- // Register with provider. |
- provider_->RegisterRegion( |
- region, |
- base::Bind(&GeofencingManager::RegisterRegionCompleted, |
- base::Unretained(this), |
- callback, |
- key)); |
+ AddRegistration(service_worker_registration_id, |
+ region_id, |
+ region, |
+ callback, |
+ service_->RegisterRegion(region, this)); |
} |
-void GeofencingManager::UnregisterRegion(BrowserContext* browser_context, |
- int64 service_worker_registration_id, |
- const GURL& service_worker_origin, |
+void GeofencingManager::UnregisterRegion(int64 service_worker_registration_id, |
const std::string& region_id, |
const StatusCallback& callback) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
// TODO(mek): Validate region_id. |
- if (!provider_.get()) { |
- callback.Run(GeofencingStatus:: |
- GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE); |
+ if (!service_->IsServiceAvailable()) { |
+ callback.Run(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE); |
return; |
} |
- RegistrationKey key(browser_context, |
- service_worker_registration_id, |
- service_worker_origin, |
- region_id); |
- Registration* registration = FindRegistration(key); |
+ Registration* registration = |
+ FindRegistration(service_worker_registration_id, region_id); |
if (!registration) { |
- // Not registered, return an error/ |
- callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR); |
+ // Not registered, return an error. |
+ callback.Run(GEOFENCING_STATUS_UNREGISTRATION_FAILED_NOT_REGISTERED); |
return; |
} |
- if (!registration->is_active) { |
+ if (!registration->is_active()) { |
// Started registration, but not completed yet, error. |
- callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR); |
+ callback.Run(GEOFENCING_STATUS_UNREGISTRATION_FAILED_NOT_REGISTERED); |
return; |
} |
- if (registration->registration_id != -1) { |
- provider_->UnregisterRegion(registration->registration_id); |
- } |
- ClearRegistration(key); |
- callback.Run(GeofencingStatus::GEOFENCING_STATUS_OK); |
+ service_->UnregisterRegion(registration->geofencing_registration_id); |
+ ClearRegistration(registration); |
+ callback.Run(GEOFENCING_STATUS_OK); |
} |
GeofencingStatus GeofencingManager::GetRegisteredRegions( |
- BrowserContext* browser_context, |
int64 service_worker_registration_id, |
- const GURL& service_worker_origin, |
std::map<std::string, blink::WebCircularGeofencingRegion>* result) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
CHECK(result); |
- if (!provider_.get()) { |
- return GeofencingStatus:: |
- GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE; |
+ if (!service_->IsServiceAvailable()) { |
+ return GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE; |
} |
// Populate result, filtering out inactive registrations. |
result->clear(); |
- for (const auto& registration : registrations_) { |
- if (registration.key.browser_context == browser_context && |
- registration.key.service_worker_registration_id == |
- service_worker_registration_id && |
- registration.key.service_worker_origin == service_worker_origin && |
- registration.is_active) { |
- (*result)[registration.key.region_id] = registration.region; |
- } |
+ ServiceWorkerRegistrationsMap::iterator registrations = |
+ registrations_.find(service_worker_registration_id); |
+ if (registrations == registrations_.end()) |
+ return GEOFENCING_STATUS_OK; |
+ for (const auto& registration : registrations->second) { |
+ if (registration.second.is_active()) |
+ (*result)[registration.first] = registration.second.region; |
} |
- return GeofencingStatus::GEOFENCING_STATUS_OK; |
+ return GEOFENCING_STATUS_OK; |
} |
-void GeofencingManager::RegisterRegionCompleted(const StatusCallback& callback, |
- const RegistrationKey& key, |
- GeofencingStatus status, |
- int registration_id) { |
+void GeofencingManager::RegistrationFinished(int64 geofencing_registration_id, |
+ GeofencingStatus status) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- if (status != GEOFENCING_STATUS_OK) { |
- ClearRegistration(key); |
- callback.Run(status); |
- return; |
- } |
- |
- Registration* registration = FindRegistration(key); |
+ Registration* registration = FindRegistrationById(geofencing_registration_id); |
DCHECK(registration); |
- registration->registration_id = registration_id; |
- registration->is_active = true; |
- callback.Run(GeofencingStatus::GEOFENCING_STATUS_OK); |
-} |
+ DCHECK(!registration->is_active()); |
+ registration->registration_callback.Run(status); |
+ registration->registration_callback.Reset(); |
-void GeofencingManager::SetProviderForTests( |
- scoped_ptr<GeofencingProvider> provider) { |
- DCHECK(!provider_.get()); |
- provider_ = provider.Pass(); |
+ // If the registration wasn't succesful, remove it from our storage. |
+ if (status != GEOFENCING_STATUS_OK) |
+ ClearRegistration(registration); |
} |
GeofencingManager::Registration* GeofencingManager::FindRegistration( |
- const RegistrationKey& key) { |
- std::vector<Registration>::iterator it = std::find_if( |
- registrations_.begin(), registrations_.end(), RegistrationMatches(key)); |
- if (it == registrations_.end()) |
+ int64 service_worker_registration_id, |
+ const std::string& region_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ ServiceWorkerRegistrationsMap::iterator registrations_iterator = |
+ registrations_.find(service_worker_registration_id); |
+ if (registrations_iterator == registrations_.end()) |
+ return nullptr; |
+ RegionIdRegistrationMap::iterator registration = |
+ registrations_iterator->second.find(region_id); |
+ if (registration == registrations_iterator->second.end()) |
return nullptr; |
- return &*it; |
+ return ®istration->second; |
+} |
+ |
+GeofencingManager::Registration* GeofencingManager::FindRegistrationById( |
+ int64 geofencing_registration_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ RegistrationIdRegistrationMap::iterator registration_iterator = |
+ registrations_by_id_.find(geofencing_registration_id); |
+ if (registration_iterator == registrations_by_id_.end()) |
+ return nullptr; |
+ return ®istration_iterator->second->second; |
} |
GeofencingManager::Registration& GeofencingManager::AddRegistration( |
- const RegistrationKey& key, |
- const blink::WebCircularGeofencingRegion& region) { |
- DCHECK(!FindRegistration(key)); |
- registrations_.push_back(Registration(key, region)); |
- return registrations_.back(); |
+ int64 service_worker_registration_id, |
+ const std::string& region_id, |
+ const blink::WebCircularGeofencingRegion& region, |
+ const StatusCallback& callback, |
+ int64 geofencing_registration_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ DCHECK(!FindRegistration(service_worker_registration_id, region_id)); |
+ RegionIdRegistrationMap::iterator registration = |
+ registrations_[service_worker_registration_id] |
+ .insert(std::make_pair(region_id, |
+ Registration(service_worker_registration_id, |
+ region_id, |
+ region, |
+ callback, |
+ geofencing_registration_id))) |
+ .first; |
+ registrations_by_id_[geofencing_registration_id] = registration; |
+ return registration->second; |
} |
-void GeofencingManager::ClearRegistration(const RegistrationKey& key) { |
- std::vector<Registration>::iterator it = std::find_if( |
- registrations_.begin(), registrations_.end(), RegistrationMatches(key)); |
- if (it == registrations_.end()) |
- return; |
- registrations_.erase(it); |
+void GeofencingManager::ClearRegistration(Registration* registration) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ registrations_by_id_.erase(registration->geofencing_registration_id); |
+ ServiceWorkerRegistrationsMap::iterator registrations_iterator = |
+ registrations_.find(registration->service_worker_registration_id); |
+ DCHECK(registrations_iterator != registrations_.end()); |
+ registrations_iterator->second.erase(registration->region_id); |
+ if (registrations_iterator->second.empty()) |
+ registrations_.erase(registrations_iterator); |
} |
} // namespace content |