Index: content/browser/geofencing/geofencing_manager.cc |
diff --git a/content/browser/geofencing/geofencing_manager.cc b/content/browser/geofencing/geofencing_manager.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a10614b10e5ff0b1cc7d89826c5dce7642727ade |
--- /dev/null |
+++ b/content/browser/geofencing/geofencing_manager.cc |
@@ -0,0 +1,203 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/geofencing/geofencing_manager.h" |
+ |
+#include "base/callback.h" |
+#include "base/memory/singleton.h" |
+#include "content/browser/geofencing/geofencing_provider.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h" |
+ |
+namespace content { |
+ |
+struct GeofencingManager::Registration { |
+ Registration() : registration_id(-1), is_active(false) {} |
+ explicit Registration(const blink::WebCircularGeofencingRegion& region); |
+ |
+ blink::WebCircularGeofencingRegion region; |
+ |
+ // Registration id as returned by the GeofencingProvider, set to -1 if not |
+ // currently registered with the provider. |
+ int registration_id; |
+ |
+ // Flag to indicate if this registration has completed, and thus should be |
+ // included in calls to GetRegisteredRegions. |
+ bool is_active; |
+}; |
+ |
+GeofencingManager::Registration::Registration( |
+ const blink::WebCircularGeofencingRegion& region) |
+ : region(region), registration_id(-1), is_active(false) { |
+} |
+ |
+GeofencingManager::GeofencingManager() { |
+} |
+ |
+GeofencingManager::~GeofencingManager() { |
+} |
+ |
+GeofencingManager* GeofencingManager::GetInstance() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ return Singleton<GeofencingManager>::get(); |
+} |
+ |
+void GeofencingManager::RegisterRegion( |
+ int64 service_worker_registration_id, |
+ const std::string& region_id, |
+ const blink::WebCircularGeofencingRegion& region, |
+ const StatusCallback& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ // TODO(mek): Validate region_id and region. |
+ |
+ if (!provider_.get()) { |
+ callback.Run(GeofencingStatus:: |
+ GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE); |
+ return; |
+ } |
+ |
+ if (FindRegistration(service_worker_registration_id, region_id)) { |
+ // Already registered, return an error. |
+ callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR); |
+ return; |
+ } |
+ |
+ // Add registration, but don't mark it as active yet. This prevents duplicate |
+ // registrations. |
+ AddRegistration(service_worker_registration_id, region_id, region); |
+ |
+ // Register with provider. |
+ provider_->RegisterRegion( |
+ region, |
+ base::Bind(&GeofencingManager::RegisterRegionCompleted, |
+ base::Unretained(this), |
+ callback, |
+ service_worker_registration_id, |
+ region_id)); |
+} |
+ |
+void GeofencingManager::UnregisterRegion(int64 service_worker_registration_id, |
+ const std::string& region_id, |
+ const StatusCallback& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ // TODO(mek): Validate region_id. |
+ |
+ if (!provider_.get()) { |
+ callback.Run(GeofencingStatus:: |
+ GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE); |
+ return; |
+ } |
+ |
+ Registration* registration = |
+ FindRegistration(service_worker_registration_id, region_id); |
+ if (!registration) { |
+ // Not registered, return an error/ |
+ callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR); |
+ return; |
+ } |
+ |
+ if (!registration->is_active) { |
+ // Started registration, but not completed yet, error. |
+ callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR); |
+ return; |
+ } |
+ |
+ if (registration->registration_id != -1) { |
+ provider_->UnregisterRegion(registration->registration_id); |
+ } |
+ ClearRegistration(service_worker_registration_id, region_id); |
+ callback.Run(GeofencingStatus::GEOFENCING_STATUS_OK); |
+} |
+ |
+GeofencingStatus GeofencingManager::GetRegisteredRegions( |
+ int64 service_worker_registration_id, |
+ std::map<std::string, blink::WebCircularGeofencingRegion>* result) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ CHECK(result); |
+ |
+ if (!provider_.get()) { |
+ return GeofencingStatus:: |
+ GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE; |
+ } |
+ |
+ // populate result |
+ result->clear(); |
+ Registrations::iterator service_worker_it = |
+ registrations_.find(service_worker_registration_id); |
+ if (service_worker_it == registrations_.end()) |
+ return GeofencingStatus::GEOFENCING_STATUS_OK; |
+ for (IdRegistrationMap::iterator it = service_worker_it->second.begin(); |
+ it != service_worker_it->second.end(); |
+ ++it) { |
+ if (it->second.is_active) |
+ (*result)[it->first] = it->second.region; |
+ } |
+ return GeofencingStatus::GEOFENCING_STATUS_OK; |
+} |
+ |
+void GeofencingManager::RegisterRegionCompleted( |
+ const GeofencingManager::StatusCallback& callback, |
+ int64 service_worker_registration_id, |
+ const std::string& region_id, |
+ GeofencingStatus status, |
+ int registration_id) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ if (status != GEOFENCING_STATUS_OK) { |
+ ClearRegistration(service_worker_registration_id, region_id); |
+ callback.Run(status); |
+ return; |
+ } |
+ |
+ Registration* registration = |
+ FindRegistration(service_worker_registration_id, region_id); |
+ DCHECK(registration); |
+ registration->registration_id = registration_id; |
+ registration->is_active = true; |
+ callback.Run(GeofencingStatus::GEOFENCING_STATUS_OK); |
+} |
+ |
+void GeofencingManager::SetProviderForTests( |
+ scoped_ptr<GeofencingProvider> provider) { |
+ DCHECK(!provider_.get()); |
+ provider_ = provider.Pass(); |
+} |
+ |
+GeofencingManager::Registration* GeofencingManager::FindRegistration( |
+ int64 service_worker_registration_id, |
+ const std::string& region_id) { |
+ Registrations::iterator service_worker_it = |
+ registrations_.find(service_worker_registration_id); |
+ if (service_worker_it == registrations_.end()) |
+ return nullptr; |
+ IdRegistrationMap::iterator registration_it = |
+ service_worker_it->second.find(region_id); |
+ if (registration_it == service_worker_it->second.end()) |
+ return nullptr; |
+ return ®istration_it->second; |
+} |
+ |
+GeofencingManager::Registration& GeofencingManager::AddRegistration( |
+ int64 service_worker_registration_id, |
+ const std::string& region_id, |
+ const blink::WebCircularGeofencingRegion& region) { |
+ auto result = registrations_[service_worker_registration_id].insert( |
+ std::make_pair(region_id, Registration(region))); |
+ DCHECK(result.second); |
+ return result.first->second; |
+} |
+ |
+void GeofencingManager::ClearRegistration(int64 service_worker_registration_id, |
+ const std::string& region_id) { |
+ Registrations::iterator service_worker_it = |
+ registrations_.find(service_worker_registration_id); |
+ if (service_worker_it == registrations_.end()) |
+ return; |
+ service_worker_it->second.erase(region_id); |
+ if (service_worker_it->second.size() == 0) |
+ registrations_.erase(service_worker_it); |
+} |
+ |
+} // namespace content |