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 "content/browser/geolocation/network_location_provider.h" | 5 #include "content/browser/geolocation/network_location_provider.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/public/browser/access_token_store.h" | 10 #include "content/public/browser/access_token_store.h" |
11 | 11 |
12 namespace content { | 12 namespace content { |
13 namespace { | 13 namespace { |
14 // The maximum period of time we'll wait for a complete set of wifi data | 14 // The maximum period of time we'll wait for a complete set of wifi data |
15 // before sending the request. | 15 // before sending the request. |
16 const int kDataCompleteWaitSeconds = 2; | 16 const int kDataCompleteWaitSeconds = 2; |
17 } // namespace | 17 } // namespace |
18 | 18 |
19 // static | 19 // static |
20 const size_t NetworkLocationProvider::PositionCache::kMaximumSize = 10; | 20 const size_t NetworkLocationProvider::PositionCache::kMaximumSize = 10; |
21 | 21 |
22 NetworkLocationProvider::PositionCache::PositionCache() {} | 22 NetworkLocationProvider::PositionCache::PositionCache() {} |
23 | 23 |
24 NetworkLocationProvider::PositionCache::~PositionCache() {} | 24 NetworkLocationProvider::PositionCache::~PositionCache() {} |
25 | 25 |
26 bool NetworkLocationProvider::PositionCache::CachePosition( | 26 bool NetworkLocationProvider::PositionCache::CachePosition( |
27 const WifiData& wifi_data, | 27 const WifiData& wifi_data, |
28 const Geoposition& position) { | 28 const Geoposition& position) { |
29 // Check that we can generate a valid key for the wifi data. | 29 // Check that we can generate a valid key for the wifi data. |
30 string16 key; | 30 base::string16 key; |
31 if (!MakeKey(wifi_data, &key)) { | 31 if (!MakeKey(wifi_data, &key)) { |
32 return false; | 32 return false; |
33 } | 33 } |
34 // If the cache is full, remove the oldest entry. | 34 // If the cache is full, remove the oldest entry. |
35 if (cache_.size() == kMaximumSize) { | 35 if (cache_.size() == kMaximumSize) { |
36 DCHECK(cache_age_list_.size() == kMaximumSize); | 36 DCHECK(cache_age_list_.size() == kMaximumSize); |
37 CacheAgeList::iterator oldest_entry = cache_age_list_.begin(); | 37 CacheAgeList::iterator oldest_entry = cache_age_list_.begin(); |
38 DCHECK(oldest_entry != cache_age_list_.end()); | 38 DCHECK(oldest_entry != cache_age_list_.end()); |
39 cache_.erase(*oldest_entry); | 39 cache_.erase(*oldest_entry); |
40 cache_age_list_.erase(oldest_entry); | 40 cache_age_list_.erase(oldest_entry); |
41 } | 41 } |
42 DCHECK_LT(cache_.size(), kMaximumSize); | 42 DCHECK_LT(cache_.size(), kMaximumSize); |
43 // Insert the position into the cache. | 43 // Insert the position into the cache. |
44 std::pair<CacheMap::iterator, bool> result = | 44 std::pair<CacheMap::iterator, bool> result = |
45 cache_.insert(std::make_pair(key, position)); | 45 cache_.insert(std::make_pair(key, position)); |
46 if (!result.second) { | 46 if (!result.second) { |
47 NOTREACHED(); // We never try to add the same key twice. | 47 NOTREACHED(); // We never try to add the same key twice. |
48 CHECK_EQ(cache_.size(), cache_age_list_.size()); | 48 CHECK_EQ(cache_.size(), cache_age_list_.size()); |
49 return false; | 49 return false; |
50 } | 50 } |
51 cache_age_list_.push_back(result.first); | 51 cache_age_list_.push_back(result.first); |
52 DCHECK_EQ(cache_.size(), cache_age_list_.size()); | 52 DCHECK_EQ(cache_.size(), cache_age_list_.size()); |
53 return true; | 53 return true; |
54 } | 54 } |
55 | 55 |
56 // Searches for a cached position response for the current WiFi data. Returns | 56 // Searches for a cached position response for the current WiFi data. Returns |
57 // the cached position if available, NULL otherwise. | 57 // the cached position if available, NULL otherwise. |
58 const Geoposition* NetworkLocationProvider::PositionCache::FindPosition( | 58 const Geoposition* NetworkLocationProvider::PositionCache::FindPosition( |
59 const WifiData& wifi_data) { | 59 const WifiData& wifi_data) { |
60 string16 key; | 60 base::string16 key; |
61 if (!MakeKey(wifi_data, &key)) { | 61 if (!MakeKey(wifi_data, &key)) { |
62 return NULL; | 62 return NULL; |
63 } | 63 } |
64 CacheMap::const_iterator iter = cache_.find(key); | 64 CacheMap::const_iterator iter = cache_.find(key); |
65 return iter == cache_.end() ? NULL : &iter->second; | 65 return iter == cache_.end() ? NULL : &iter->second; |
66 } | 66 } |
67 | 67 |
68 // Makes the key for the map of cached positions, using the available data. | 68 // Makes the key for the map of cached positions, using the available data. |
69 // Returns true if a good key was generated, false otherwise. | 69 // Returns true if a good key was generated, false otherwise. |
70 // | 70 // |
71 // static | 71 // static |
72 bool NetworkLocationProvider::PositionCache::MakeKey( | 72 bool NetworkLocationProvider::PositionCache::MakeKey( |
73 const WifiData& wifi_data, | 73 const WifiData& wifi_data, |
74 string16* key) { | 74 base::string16* key) { |
75 // Currently we use only WiFi data and base the key only on the MAC addresses. | 75 // Currently we use only WiFi data and base the key only on the MAC addresses. |
76 DCHECK(key); | 76 DCHECK(key); |
77 key->clear(); | 77 key->clear(); |
78 const size_t kCharsPerMacAddress = 6 * 3 + 1; // e.g. "11:22:33:44:55:66|" | 78 const size_t kCharsPerMacAddress = 6 * 3 + 1; // e.g. "11:22:33:44:55:66|" |
79 key->reserve(wifi_data.access_point_data.size() * kCharsPerMacAddress); | 79 key->reserve(wifi_data.access_point_data.size() * kCharsPerMacAddress); |
80 const string16 separator(ASCIIToUTF16("|")); | 80 const base::string16 separator(ASCIIToUTF16("|")); |
81 for (WifiData::AccessPointDataSet::const_iterator iter = | 81 for (WifiData::AccessPointDataSet::const_iterator iter = |
82 wifi_data.access_point_data.begin(); | 82 wifi_data.access_point_data.begin(); |
83 iter != wifi_data.access_point_data.end(); | 83 iter != wifi_data.access_point_data.end(); |
84 iter++) { | 84 iter++) { |
85 *key += separator; | 85 *key += separator; |
86 *key += iter->mac_address; | 86 *key += iter->mac_address; |
87 *key += separator; | 87 *key += separator; |
88 } | 88 } |
89 // If the key is the empty string, return false, as we don't want to cache a | 89 // If the key is the empty string, return false, as we don't want to cache a |
90 // position for such data. | 90 // position for such data. |
91 return !key->empty(); | 91 return !key->empty(); |
92 } | 92 } |
93 | 93 |
94 // NetworkLocationProvider factory function | 94 // NetworkLocationProvider factory function |
95 LocationProviderBase* NewNetworkLocationProvider( | 95 LocationProviderBase* NewNetworkLocationProvider( |
96 AccessTokenStore* access_token_store, | 96 AccessTokenStore* access_token_store, |
97 net::URLRequestContextGetter* context, | 97 net::URLRequestContextGetter* context, |
98 const GURL& url, | 98 const GURL& url, |
99 const string16& access_token) { | 99 const base::string16& access_token) { |
100 return new NetworkLocationProvider( | 100 return new NetworkLocationProvider( |
101 access_token_store, context, url, access_token); | 101 access_token_store, context, url, access_token); |
102 } | 102 } |
103 | 103 |
104 // NetworkLocationProvider | 104 // NetworkLocationProvider |
105 NetworkLocationProvider::NetworkLocationProvider( | 105 NetworkLocationProvider::NetworkLocationProvider( |
106 AccessTokenStore* access_token_store, | 106 AccessTokenStore* access_token_store, |
107 net::URLRequestContextGetter* url_context_getter, | 107 net::URLRequestContextGetter* url_context_getter, |
108 const GURL& url, | 108 const GURL& url, |
109 const string16& access_token) | 109 const base::string16& access_token) |
110 : access_token_store_(access_token_store), | 110 : access_token_store_(access_token_store), |
111 wifi_data_provider_(NULL), | 111 wifi_data_provider_(NULL), |
112 wifi_data_update_callback_( | 112 wifi_data_update_callback_( |
113 base::Bind(&NetworkLocationProvider::WifiDataUpdateAvailable, | 113 base::Bind(&NetworkLocationProvider::WifiDataUpdateAvailable, |
114 base::Unretained(this))), | 114 base::Unretained(this))), |
115 is_wifi_data_complete_(false), | 115 is_wifi_data_complete_(false), |
116 access_token_(access_token), | 116 access_token_(access_token), |
117 is_permission_granted_(false), | 117 is_permission_granted_(false), |
118 is_new_data_available_(false), | 118 is_new_data_available_(false), |
119 weak_factory_(this) { | 119 weak_factory_(this) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 void NetworkLocationProvider::WifiDataUpdateAvailable( | 156 void NetworkLocationProvider::WifiDataUpdateAvailable( |
157 WifiDataProvider* provider) { | 157 WifiDataProvider* provider) { |
158 DCHECK(provider == wifi_data_provider_); | 158 DCHECK(provider == wifi_data_provider_); |
159 is_wifi_data_complete_ = wifi_data_provider_->GetData(&wifi_data_); | 159 is_wifi_data_complete_ = wifi_data_provider_->GetData(&wifi_data_); |
160 OnWifiDataUpdated(); | 160 OnWifiDataUpdated(); |
161 } | 161 } |
162 | 162 |
163 void NetworkLocationProvider::LocationResponseAvailable( | 163 void NetworkLocationProvider::LocationResponseAvailable( |
164 const Geoposition& position, | 164 const Geoposition& position, |
165 bool server_error, | 165 bool server_error, |
166 const string16& access_token, | 166 const base::string16& access_token, |
167 const WifiData& wifi_data) { | 167 const WifiData& wifi_data) { |
168 DCHECK(CalledOnValidThread()); | 168 DCHECK(CalledOnValidThread()); |
169 // Record the position and update our cache. | 169 // Record the position and update our cache. |
170 position_ = position; | 170 position_ = position; |
171 if (position.Validate()) { | 171 if (position.Validate()) { |
172 position_cache_->CachePosition(wifi_data, position); | 172 position_cache_->CachePosition(wifi_data, position); |
173 } | 173 } |
174 | 174 |
175 // Record access_token if it's set. | 175 // Record access_token if it's set. |
176 if (!access_token.empty() && access_token_ != access_token) { | 176 if (!access_token.empty() && access_token_ != access_token) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 } | 266 } |
267 request_->MakeRequest(access_token_, wifi_data_, | 267 request_->MakeRequest(access_token_, wifi_data_, |
268 wifi_data_updated_timestamp_); | 268 wifi_data_updated_timestamp_); |
269 } | 269 } |
270 | 270 |
271 bool NetworkLocationProvider::IsStarted() const { | 271 bool NetworkLocationProvider::IsStarted() const { |
272 return wifi_data_provider_ != NULL; | 272 return wifi_data_provider_ != NULL; |
273 } | 273 } |
274 | 274 |
275 } // namespace content | 275 } // namespace content |
OLD | NEW |