Vibration API: convert implementation to java mojo-service.
[chromium-blink-merge.git] / content / browser / geofencing / geofencing_service.cc
blobc9ea83d893fe361aec3837351057ca0a46493d67
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/geofencing/geofencing_service.h"
7 #include "base/location.h"
8 #include "base/memory/singleton.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/browser/geofencing/geofencing_provider.h"
12 #include "content/browser/geofencing/geofencing_registration_delegate.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
16 namespace content {
18 namespace {
20 void RunSoon(const base::Closure& callback) {
21 if (!callback.is_null())
22 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
25 } // namespace
27 struct GeofencingServiceImpl::Registration {
28 Registration();
29 Registration(const blink::WebCircularGeofencingRegion& region,
30 int64 geofencing_registration_id,
31 GeofencingRegistrationDelegate* delegate);
33 blink::WebCircularGeofencingRegion region;
34 int64 geofencing_registration_id;
35 GeofencingRegistrationDelegate* delegate;
37 enum RegistrationState {
38 // In progress of being registered with provider.
39 STATE_REGISTERING,
40 // Currently registered with provider.
41 STATE_REGISTERED,
42 // In progress of being registered with provider, but should be unregistered
43 // and deleted.
44 STATE_SHOULD_UNREGISTER_AND_DELETE,
45 // Not currently registered with provider, but still an active registration.
46 STATE_UNREGISTERED
48 RegistrationState state;
51 GeofencingServiceImpl::Registration::Registration()
52 : geofencing_registration_id(-1),
53 delegate(nullptr),
54 state(STATE_UNREGISTERED) {
57 GeofencingServiceImpl::Registration::Registration(
58 const blink::WebCircularGeofencingRegion& region,
59 int64 geofencing_registration_id,
60 GeofencingRegistrationDelegate* delegate)
61 : region(region),
62 geofencing_registration_id(geofencing_registration_id),
63 delegate(delegate),
64 state(STATE_REGISTERING) {
67 GeofencingServiceImpl::GeofencingServiceImpl() : next_registration_id_(0) {
70 GeofencingServiceImpl::~GeofencingServiceImpl() {
73 GeofencingServiceImpl* GeofencingServiceImpl::GetInstance() {
74 DCHECK_CURRENTLY_ON(BrowserThread::IO);
75 return Singleton<GeofencingServiceImpl>::get();
78 bool GeofencingServiceImpl::IsServiceAvailable() {
79 DCHECK_CURRENTLY_ON(BrowserThread::IO);
80 return EnsureProvider();
83 int64 GeofencingServiceImpl::RegisterRegion(
84 const blink::WebCircularGeofencingRegion& region,
85 GeofencingRegistrationDelegate* delegate) {
86 DCHECK_CURRENTLY_ON(BrowserThread::IO);
88 int64 geofencing_registration_id = GetNextId();
89 registrations_[geofencing_registration_id] =
90 Registration(region, geofencing_registration_id, delegate);
92 if (!EnsureProvider()) {
93 RunSoon(
94 base::Bind(&GeofencingServiceImpl::NotifyRegistrationFinished,
95 base::Unretained(this),
96 geofencing_registration_id,
97 GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE));
98 return geofencing_registration_id;
101 provider_->RegisterRegion(
102 geofencing_registration_id,
103 region,
104 base::Bind(&GeofencingServiceImpl::NotifyRegistrationFinished,
105 base::Unretained(this),
106 geofencing_registration_id));
107 return geofencing_registration_id;
110 void GeofencingServiceImpl::UnregisterRegion(int64 geofencing_registration_id) {
111 DCHECK_CURRENTLY_ON(BrowserThread::IO);
113 RegistrationsMap::iterator registration_iterator =
114 registrations_.find(geofencing_registration_id);
115 DCHECK(registration_iterator != registrations_.end());
117 if (!EnsureProvider())
118 return;
120 switch (registration_iterator->second.state) {
121 case Registration::STATE_REGISTERED:
122 provider_->UnregisterRegion(geofencing_registration_id);
123 // fallthru
124 case Registration::STATE_UNREGISTERED:
125 registrations_.erase(registration_iterator);
126 break;
127 case Registration::STATE_REGISTERING:
128 // Update state, NotifyRegistrationFinished will take care of actually
129 // unregistering.
130 registration_iterator->second.state =
131 Registration::STATE_SHOULD_UNREGISTER_AND_DELETE;
132 break;
133 case Registration::STATE_SHOULD_UNREGISTER_AND_DELETE:
134 // Should not happen.
135 NOTREACHED();
136 break;
140 void GeofencingServiceImpl::SetProviderForTesting(
141 scoped_ptr<GeofencingProvider> provider) {
142 DCHECK(!provider_.get());
143 provider_ = provider.Pass();
146 int GeofencingServiceImpl::RegistrationCountForTesting() {
147 return registrations_.size();
150 bool GeofencingServiceImpl::EnsureProvider() {
151 DCHECK_CURRENTLY_ON(BrowserThread::IO);
153 if (!provider_) {
154 // TODO(mek): Create platform specific provider.
155 return false;
157 return true;
160 int64 GeofencingServiceImpl::GetNextId() {
161 DCHECK_CURRENTLY_ON(BrowserThread::IO);
163 return next_registration_id_++;
166 void GeofencingServiceImpl::NotifyRegistrationFinished(
167 int64 geofencing_registration_id,
168 GeofencingStatus status) {
169 DCHECK_CURRENTLY_ON(BrowserThread::IO);
171 RegistrationsMap::iterator registration_iterator =
172 registrations_.find(geofencing_registration_id);
173 DCHECK(registration_iterator != registrations_.end());
174 DCHECK(registration_iterator->second.state ==
175 Registration::STATE_REGISTERING ||
176 registration_iterator->second.state ==
177 Registration::STATE_SHOULD_UNREGISTER_AND_DELETE);
179 if (registration_iterator->second.state ==
180 Registration::STATE_SHOULD_UNREGISTER_AND_DELETE) {
181 // Don't call delegate, but unregister with provider if registration was
182 // succesfull.
183 if (status == GEOFENCING_STATUS_OK) {
184 provider_->UnregisterRegion(geofencing_registration_id);
186 registrations_.erase(registration_iterator);
187 return;
190 // Normal case, mark as registered and call delegate.
191 registration_iterator->second.state = Registration::STATE_REGISTERED;
192 registration_iterator->second.delegate->RegistrationFinished(
193 geofencing_registration_id, status);
195 if (status != GEOFENCING_STATUS_OK) {
196 // Registration failed, remove from our book-keeping.
197 registrations_.erase(registration_iterator);
201 } // namespace content