| 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..94b0f25dcedf5a7d8ad5ab6c9ca3c1e898b56726
|
| --- /dev/null
|
| +++ b/content/browser/geofencing/geofencing_manager.cc
|
| @@ -0,0 +1,252 @@
|
| +// 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 <algorithm>
|
| +
|
| +#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"
|
| +#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;
|
| +
|
| + 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;
|
| +
|
| + // Flag to indicate if this registration has completed, and thus should be
|
| + // included in calls to GetRegisteredRegions.
|
| + bool is_active;
|
| +};
|
| +
|
| +GeofencingManager::Registration::Registration() : key(nullptr, -1, GURL(), "") {
|
| +}
|
| +
|
| +GeofencingManager::Registration::Registration(
|
| + const RegistrationKey& key,
|
| + const blink::WebCircularGeofencingRegion& region)
|
| + : key(key), region(region), registration_id(-1), is_active(false) {
|
| +}
|
| +
|
| +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;
|
| + }
|
| +
|
| + private:
|
| + const RegistrationKey& key_;
|
| +};
|
| +
|
| +GeofencingManager::GeofencingManager() {
|
| +}
|
| +
|
| +GeofencingManager::~GeofencingManager() {
|
| +}
|
| +
|
| +GeofencingManager* GeofencingManager::GetInstance() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + return Singleton<GeofencingManager>::get();
|
| +}
|
| +
|
| +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) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| +
|
| + // TODO(mek): Validate region_id and region.
|
| +
|
| + if (!provider_.get()) {
|
| + callback.Run(GeofencingStatus::
|
| + GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE);
|
| + return;
|
| + }
|
| +
|
| + RegistrationKey key(browser_context,
|
| + service_worker_registration_id,
|
| + service_worker_origin,
|
| + region_id);
|
| + if (FindRegistration(key)) {
|
| + // 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(key, region);
|
| +
|
| + // Register with provider.
|
| + provider_->RegisterRegion(
|
| + region,
|
| + base::Bind(&GeofencingManager::RegisterRegionCompleted,
|
| + base::Unretained(this),
|
| + callback,
|
| + key));
|
| +}
|
| +
|
| +void GeofencingManager::UnregisterRegion(BrowserContext* browser_context,
|
| + int64 service_worker_registration_id,
|
| + const GURL& service_worker_origin,
|
| + 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);
|
| + return;
|
| + }
|
| +
|
| + RegistrationKey key(browser_context,
|
| + service_worker_registration_id,
|
| + service_worker_origin,
|
| + region_id);
|
| + Registration* registration = FindRegistration(key);
|
| + 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(key);
|
| + callback.Run(GeofencingStatus::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;
|
| + }
|
| +
|
| + // 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;
|
| + }
|
| + }
|
| + return GeofencingStatus::GEOFENCING_STATUS_OK;
|
| +}
|
| +
|
| +void GeofencingManager::RegisterRegionCompleted(const StatusCallback& callback,
|
| + const RegistrationKey& key,
|
| + GeofencingStatus status,
|
| + int registration_id) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + if (status != GEOFENCING_STATUS_OK) {
|
| + ClearRegistration(key);
|
| + callback.Run(status);
|
| + return;
|
| + }
|
| +
|
| + Registration* registration = FindRegistration(key);
|
| + 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(
|
| + const RegistrationKey& key) {
|
| + std::vector<Registration>::iterator it = std::find_if(
|
| + registrations_.begin(), registrations_.end(), RegistrationMatches(key));
|
| + if (it == registrations_.end())
|
| + return nullptr;
|
| + return &*it;
|
| +}
|
| +
|
| +GeofencingManager::Registration& GeofencingManager::AddRegistration(
|
| + const RegistrationKey& key,
|
| + const blink::WebCircularGeofencingRegion& region) {
|
| + DCHECK(!FindRegistration(key));
|
| + registrations_.push_back(Registration(key, region));
|
| + return registrations_.back();
|
| +}
|
| +
|
| +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);
|
| +}
|
| +
|
| +} // namespace content
|
|
|