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 // TODO(mcasas): consider not using HasWeakPtrs() https://crbug.com/629158. |
230 if (!is_new_data_available_) | 221 if (!weak_factory_.HasWeakPtrs() || is_wifi_data_complete_) { |
Wez
2016/08/24 23:20:36
Let's use an early-exit for this (like |is_new_dat
CJ
2016/08/24 23:35:28
Done.
| |
231 return; | 222 DCHECK(CalledOnValidThread()); |
Wez
2016/08/24 23:20:36
This DCHECK ensures we're called on the correct th
CJ
2016/08/24 23:35:28
Done.
| |
223 if (!is_new_data_available_) | |
224 return; | |
232 | 225 |
233 const Geoposition* cached_position = | 226 const Geoposition* cached_position = |
234 position_cache_->FindPosition(wifi_data_); | 227 position_cache_->FindPosition(wifi_data_); |
235 DCHECK(!wifi_timestamp_.is_null()) | 228 DCHECK(!wifi_timestamp_.is_null()) |
236 << "Timestamp must be set before looking up position"; | 229 << "Timestamp must be set before looking up position"; |
237 if (cached_position) { | 230 if (cached_position) { |
238 DCHECK(cached_position->Validate()); | 231 DCHECK(cached_position->Validate()); |
239 // Record the position and update its timestamp. | 232 // Record the position and update its timestamp. |
240 position_ = *cached_position; | 233 position_ = *cached_position; |
241 // The timestamp of a position fix is determined by the timestamp | 234 |
242 // of the source data update. (The value of position_.timestamp from | 235 // The timestamp of a position fix is determined by the timestamp |
243 // the cache could be from weeks ago!) | 236 // of the source data update. (The value of position_.timestamp from |
244 position_.timestamp = wifi_timestamp_; | 237 // the cache could be from weeks ago!) |
238 position_.timestamp = wifi_timestamp_; | |
239 is_new_data_available_ = false; | |
240 | |
241 // Let listeners know that we now have a position available. | |
242 NotifyCallback(position_); | |
243 return; | |
244 } | |
245 // Don't send network requests until authorized. http://crbug.com/39171 | |
246 if (!is_permission_granted_) | |
247 return; | |
248 | |
249 weak_factory_.InvalidateWeakPtrs(); | |
245 is_new_data_available_ = false; | 250 is_new_data_available_ = false; |
246 // Let listeners know that we now have a position available. | 251 |
247 NotifyCallback(position_); | 252 // TODO(joth): Rather than cancel pending requests, we should create a new |
248 return; | 253 // // NetworkLocationRequest for each and hold a set of pending requests. |
254 if (request_->is_request_pending()) { | |
255 DVLOG(1) | |
256 << "NetworkLocationProvider - pre-empting pending network request " | |
257 "with new data. Wifi APs: " | |
258 << wifi_data_.access_point_data.size(); | |
259 } | |
260 request_->MakeRequest(access_token_, wifi_data_, wifi_timestamp_); | |
249 } | 261 } |
250 // Don't send network requests until authorized. http://crbug.com/39171 | |
251 if (!is_permission_granted_) | |
252 return; | |
253 | |
254 weak_factory_.InvalidateWeakPtrs(); | |
255 is_new_data_available_ = false; | |
256 | |
257 // TODO(joth): Rather than cancel pending requests, we should create a new | |
258 // NetworkLocationRequest for each and hold a set of pending requests. | |
259 if (request_->is_request_pending()) { | |
260 DVLOG(1) << "NetworkLocationProvider - pre-empting pending network request " | |
261 "with new data. Wifi APs: " | |
262 << wifi_data_.access_point_data.size(); | |
263 } | |
264 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 |