| 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
|
|
|