Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: device/geolocation/geolocation_provider_impl.cc

Issue 2192683003: Revert of Reland: Geolocation: move from content/browser to device/ (patchset #2 id:20001 of https:… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2810
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "device/geolocation/geolocation_provider_impl.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/lazy_instance.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/memory/singleton.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "device/geolocation/geolocation_delegate.h"
18 #include "device/geolocation/location_arbitrator_impl.h"
19
20 namespace device {
21
22 namespace {
23 base::LazyInstance<std::unique_ptr<GeolocationDelegate>>::Leaky g_delegate =
24 LAZY_INSTANCE_INITIALIZER;
25 } // anonymous namespace
26
27 // static
28 GeolocationProvider* GeolocationProvider::GetInstance() {
29 return GeolocationProviderImpl::GetInstance();
30 }
31
32 // static
33 void GeolocationProvider::SetGeolocationDelegate(
34 GeolocationDelegate* delegate) {
35 DCHECK(!g_delegate.Get());
36 g_delegate.Get().reset(delegate);
37 }
38
39 std::unique_ptr<GeolocationProvider::Subscription>
40 GeolocationProviderImpl::AddLocationUpdateCallback(
41 const LocationUpdateCallback& callback,
42 bool enable_high_accuracy) {
43 DCHECK(main_task_runner_->BelongsToCurrentThread());
44 std::unique_ptr<GeolocationProvider::Subscription> subscription;
45 if (enable_high_accuracy) {
46 subscription = high_accuracy_callbacks_.Add(callback);
47 } else {
48 subscription = low_accuracy_callbacks_.Add(callback);
49 }
50
51 OnClientsChanged();
52 if (position_.Validate() ||
53 position_.error_code != Geoposition::ERROR_CODE_NONE) {
54 callback.Run(position_);
55 }
56
57 return subscription;
58 }
59
60 void GeolocationProviderImpl::UserDidOptIntoLocationServices() {
61 DCHECK(main_task_runner_->BelongsToCurrentThread());
62 bool was_permission_granted = user_did_opt_into_location_services_;
63 user_did_opt_into_location_services_ = true;
64 if (IsRunning() && !was_permission_granted)
65 InformProvidersPermissionGranted();
66 }
67
68 void GeolocationProviderImpl::OverrideLocationForTesting(
69 const Geoposition& position) {
70 DCHECK(main_task_runner_->BelongsToCurrentThread());
71 ignore_location_updates_ = true;
72 NotifyClients(position);
73 }
74
75 void GeolocationProviderImpl::OnLocationUpdate(const Geoposition& position) {
76 DCHECK(OnGeolocationThread());
77 // Will be true only in testing.
78 if (ignore_location_updates_)
79 return;
80 main_task_runner_->PostTask(
81 FROM_HERE, base::Bind(&GeolocationProviderImpl::NotifyClients,
82 base::Unretained(this), position));
83 }
84
85 // static
86 GeolocationProviderImpl* GeolocationProviderImpl::GetInstance() {
87 return base::Singleton<GeolocationProviderImpl>::get();
88 }
89
90 GeolocationProviderImpl::GeolocationProviderImpl()
91 : base::Thread("Geolocation"),
92 user_did_opt_into_location_services_(false),
93 ignore_location_updates_(false),
94 main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
95 DCHECK(main_task_runner_->BelongsToCurrentThread());
96 high_accuracy_callbacks_.set_removal_callback(
97 base::Bind(&GeolocationProviderImpl::OnClientsChanged,
98 base::Unretained(this)));
99 low_accuracy_callbacks_.set_removal_callback(
100 base::Bind(&GeolocationProviderImpl::OnClientsChanged,
101 base::Unretained(this)));
102 }
103
104 GeolocationProviderImpl::~GeolocationProviderImpl() {
105 Stop();
106 DCHECK(!arbitrator_);
107 }
108
109 bool GeolocationProviderImpl::OnGeolocationThread() const {
110 return task_runner()->BelongsToCurrentThread();
111 }
112
113 void GeolocationProviderImpl::OnClientsChanged() {
114 DCHECK(main_task_runner_->BelongsToCurrentThread());
115 base::Closure task;
116 if (high_accuracy_callbacks_.empty() && low_accuracy_callbacks_.empty()) {
117 DCHECK(IsRunning());
118 if (!ignore_location_updates_) {
119 // We have no more observers, so we clear the cached geoposition so that
120 // when the next observer is added we will not provide a stale position.
121 position_ = Geoposition();
122 }
123 task = base::Bind(&GeolocationProviderImpl::StopProviders,
124 base::Unretained(this));
125 } else {
126 if (!IsRunning()) {
127 Start();
128 if (user_did_opt_into_location_services_)
129 InformProvidersPermissionGranted();
130 }
131 // Determine a set of options that satisfies all clients.
132 bool enable_high_accuracy = !high_accuracy_callbacks_.empty();
133
134 // Send the current options to the providers as they may have changed.
135 task = base::Bind(&GeolocationProviderImpl::StartProviders,
136 base::Unretained(this), enable_high_accuracy);
137 }
138
139 task_runner()->PostTask(FROM_HERE, task);
140 }
141
142 void GeolocationProviderImpl::StopProviders() {
143 DCHECK(OnGeolocationThread());
144 DCHECK(arbitrator_);
145 arbitrator_->StopProviders();
146 }
147
148 void GeolocationProviderImpl::StartProviders(bool enable_high_accuracy) {
149 DCHECK(OnGeolocationThread());
150 DCHECK(arbitrator_);
151 arbitrator_->StartProviders(enable_high_accuracy);
152 }
153
154 void GeolocationProviderImpl::InformProvidersPermissionGranted() {
155 DCHECK(IsRunning());
156 if (!OnGeolocationThread()) {
157 task_runner()->PostTask(
158 FROM_HERE,
159 base::Bind(&GeolocationProviderImpl::InformProvidersPermissionGranted,
160 base::Unretained(this)));
161 return;
162 }
163 DCHECK(OnGeolocationThread());
164 DCHECK(arbitrator_);
165 arbitrator_->OnPermissionGranted();
166 }
167
168 void GeolocationProviderImpl::NotifyClients(const Geoposition& position) {
169 DCHECK(main_task_runner_->BelongsToCurrentThread());
170 DCHECK(position.Validate() ||
171 position.error_code != Geoposition::ERROR_CODE_NONE);
172 position_ = position;
173 high_accuracy_callbacks_.Notify(position_);
174 low_accuracy_callbacks_.Notify(position_);
175 }
176
177 void GeolocationProviderImpl::Init() {
178 DCHECK(OnGeolocationThread());
179 DCHECK(!arbitrator_);
180 arbitrator_ = CreateArbitrator();
181 }
182
183 void GeolocationProviderImpl::CleanUp() {
184 DCHECK(OnGeolocationThread());
185 arbitrator_.reset();
186 }
187
188 std::unique_ptr<LocationArbitrator>
189 GeolocationProviderImpl::CreateArbitrator() {
190 LocationArbitratorImpl::LocationUpdateCallback callback = base::Bind(
191 &GeolocationProviderImpl::OnLocationUpdate, base::Unretained(this));
192 // Use the embedder's |g_delegate| or fall back to the default one.
193 if (!g_delegate.Get())
194 g_delegate.Get().reset(new GeolocationDelegate);
195
196 return base::WrapUnique(
197 new LocationArbitratorImpl(callback, g_delegate.Get().get()));
198 }
199
200 } // namespace device
OLDNEW
« no previous file with comments | « device/geolocation/geolocation_provider_impl.h ('k') | device/geolocation/geolocation_provider_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698