OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/geolocation/network_location_provider.h" | 5 #include "device/geolocation/network_location_provider.h" |
6 | 6 |
| 7 #include <utility> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/location.h" | 10 #include "base/location.h" |
9 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
10 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
11 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
12 #include "base/time/time.h" | 14 #include "base/time/time.h" |
13 #include "device/geolocation/access_token_store.h" | 15 #include "device/geolocation/access_token_store.h" |
14 | 16 |
15 namespace device { | 17 namespace device { |
16 namespace { | 18 namespace { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 url_context_getter, url, | 123 url_context_getter, url, |
122 base::Bind(&NetworkLocationProvider::OnLocationResponse, | 124 base::Bind(&NetworkLocationProvider::OnLocationResponse, |
123 base::Unretained(this)))); | 125 base::Unretained(this)))); |
124 } | 126 } |
125 | 127 |
126 NetworkLocationProvider::~NetworkLocationProvider() { | 128 NetworkLocationProvider::~NetworkLocationProvider() { |
127 StopProvider(); | 129 StopProvider(); |
128 } | 130 } |
129 | 131 |
130 // LocationProvider implementation | 132 // LocationProvider implementation |
131 void NetworkLocationProvider::GetPosition(Geoposition* position) { | 133 const Geoposition& NetworkLocationProvider::GetPosition() { |
132 DCHECK(position); | 134 return position_; |
133 *position = position_; | |
134 } | |
135 | |
136 void NetworkLocationProvider::RequestRefresh() { | |
137 // TODO(joth): When called via the public (base class) interface, this should | |
138 // poke each data provider to get them to expedite their next scan. | |
139 // Whilst in the delayed start, only send request if all data is ready. | |
140 // TODO(mcasas): consider not using HasWeakPtrs() https://crbug.com/629158. | |
141 if (!weak_factory_.HasWeakPtrs() || is_wifi_data_complete_) { | |
142 RequestPosition(); | |
143 } | |
144 } | 135 } |
145 | 136 |
146 void NetworkLocationProvider::OnPermissionGranted() { | 137 void NetworkLocationProvider::OnPermissionGranted() { |
147 const bool was_permission_granted = is_permission_granted_; | 138 const bool was_permission_granted = is_permission_granted_; |
148 is_permission_granted_ = true; | 139 is_permission_granted_ = true; |
149 if (!was_permission_granted && IsStarted()) { | 140 if (!was_permission_granted && IsStarted()) { |
150 RequestRefresh(); | 141 RequestPosition(); |
151 } | 142 } |
152 } | 143 } |
153 | 144 |
154 void NetworkLocationProvider::OnWifiDataUpdate() { | 145 void NetworkLocationProvider::OnWifiDataUpdate() { |
155 DCHECK(wifi_data_provider_manager_); | 146 DCHECK(wifi_data_provider_manager_); |
156 is_wifi_data_complete_ = wifi_data_provider_manager_->GetData(&wifi_data_); | 147 is_wifi_data_complete_ = wifi_data_provider_manager_->GetData(&wifi_data_); |
157 OnWifiDataUpdated(); | 148 OnWifiDataUpdated(); |
158 } | 149 } |
159 | 150 |
160 void NetworkLocationProvider::OnLocationResponse( | 151 void NetworkLocationProvider::OnLocationResponse( |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 if (is_wifi_data_complete_) | 196 if (is_wifi_data_complete_) |
206 OnWifiDataUpdated(); | 197 OnWifiDataUpdated(); |
207 return true; | 198 return true; |
208 } | 199 } |
209 | 200 |
210 void NetworkLocationProvider::OnWifiDataUpdated() { | 201 void NetworkLocationProvider::OnWifiDataUpdated() { |
211 DCHECK(CalledOnValidThread()); | 202 DCHECK(CalledOnValidThread()); |
212 wifi_timestamp_ = base::Time::Now(); | 203 wifi_timestamp_ = base::Time::Now(); |
213 | 204 |
214 is_new_data_available_ = is_wifi_data_complete_; | 205 is_new_data_available_ = is_wifi_data_complete_; |
215 RequestRefresh(); | 206 RequestPosition(); |
216 } | 207 } |
217 | 208 |
218 void NetworkLocationProvider::StopProvider() { | 209 void NetworkLocationProvider::StopProvider() { |
219 DCHECK(CalledOnValidThread()); | 210 DCHECK(CalledOnValidThread()); |
220 if (IsStarted()) { | 211 if (IsStarted()) { |
221 wifi_data_provider_manager_->Unregister(&wifi_data_update_callback_); | 212 wifi_data_provider_manager_->Unregister(&wifi_data_update_callback_); |
222 } | 213 } |
223 wifi_data_provider_manager_ = nullptr; | 214 wifi_data_provider_manager_ = nullptr; |
224 weak_factory_.InvalidateWeakPtrs(); | 215 weak_factory_.InvalidateWeakPtrs(); |
225 } | 216 } |
226 | 217 |
227 // Other methods | 218 // Other methods |
228 void NetworkLocationProvider::RequestPosition() { | 219 void NetworkLocationProvider::RequestPosition() { |
229 DCHECK(CalledOnValidThread()); | 220 DCHECK(CalledOnValidThread()); |
| 221 |
| 222 // TODO(mcasas): consider not using HasWeakPtrs() https://crbug.com/629158. |
| 223 if (weak_factory_.HasWeakPtrs() && !is_wifi_data_complete_) |
| 224 return; |
230 if (!is_new_data_available_) | 225 if (!is_new_data_available_) |
231 return; | 226 return; |
232 | 227 |
233 const Geoposition* cached_position = | 228 const Geoposition* cached_position = |
234 position_cache_->FindPosition(wifi_data_); | 229 position_cache_->FindPosition(wifi_data_); |
235 DCHECK(!wifi_timestamp_.is_null()) | 230 DCHECK(!wifi_timestamp_.is_null()) |
236 << "Timestamp must be set before looking up position"; | 231 << "Timestamp must be set before looking up position"; |
237 if (cached_position) { | 232 if (cached_position) { |
238 DCHECK(cached_position->Validate()); | 233 DCHECK(cached_position->Validate()); |
239 // Record the position and update its timestamp. | 234 // Record the position and update its timestamp. |
240 position_ = *cached_position; | 235 position_ = *cached_position; |
| 236 |
241 // The timestamp of a position fix is determined by the timestamp | 237 // The timestamp of a position fix is determined by the timestamp |
242 // of the source data update. (The value of position_.timestamp from | 238 // of the source data update. (The value of position_.timestamp from |
243 // the cache could be from weeks ago!) | 239 // the cache could be from weeks ago!) |
244 position_.timestamp = wifi_timestamp_; | 240 position_.timestamp = wifi_timestamp_; |
245 is_new_data_available_ = false; | 241 is_new_data_available_ = false; |
| 242 |
246 // Let listeners know that we now have a position available. | 243 // Let listeners know that we now have a position available. |
247 NotifyCallback(position_); | 244 NotifyCallback(position_); |
248 return; | 245 return; |
249 } | 246 } |
250 // Don't send network requests until authorized. http://crbug.com/39171 | 247 // Don't send network requests until authorized. http://crbug.com/39171 |
251 if (!is_permission_granted_) | 248 if (!is_permission_granted_) |
252 return; | 249 return; |
253 | 250 |
254 weak_factory_.InvalidateWeakPtrs(); | 251 weak_factory_.InvalidateWeakPtrs(); |
255 is_new_data_available_ = false; | 252 is_new_data_available_ = false; |
256 | 253 |
257 // TODO(joth): Rather than cancel pending requests, we should create a new | 254 // TODO(joth): Rather than cancel pending requests, we should create a new |
258 // NetworkLocationRequest for each and hold a set of pending requests. | 255 // NetworkLocationRequest for each and hold a set of pending requests. |
259 if (request_->is_request_pending()) { | 256 if (request_->is_request_pending()) { |
260 DVLOG(1) << "NetworkLocationProvider - pre-empting pending network request " | 257 DVLOG(1) << "NetworkLocationProvider - pre-empting pending network request " |
261 "with new data. Wifi APs: " | 258 "with new data. Wifi APs: " |
262 << wifi_data_.access_point_data.size(); | 259 << wifi_data_.access_point_data.size(); |
263 } | 260 } |
264 request_->MakeRequest(access_token_, wifi_data_, wifi_timestamp_); | 261 request_->MakeRequest(access_token_, wifi_data_, wifi_timestamp_); |
265 } | 262 } |
266 | 263 |
267 bool NetworkLocationProvider::IsStarted() const { | 264 bool NetworkLocationProvider::IsStarted() const { |
268 return wifi_data_provider_manager_ != nullptr; | 265 return wifi_data_provider_manager_ != nullptr; |
269 } | 266 } |
270 | 267 |
271 } // namespace device | 268 } // namespace device |
OLD | NEW |