| 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/location.h" |    8 #include "base/location.h" | 
|    9 #include "base/single_thread_task_runner.h" |    9 #include "base/single_thread_task_runner.h" | 
|   10 #include "base/strings/utf_string_conversions.h" |   10 #include "base/strings/utf_string_conversions.h" | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   50     NOTREACHED();  // We never try to add the same key twice. |   50     NOTREACHED();  // We never try to add the same key twice. | 
|   51     CHECK_EQ(cache_.size(), cache_age_list_.size()); |   51     CHECK_EQ(cache_.size(), cache_age_list_.size()); | 
|   52     return false; |   52     return false; | 
|   53   } |   53   } | 
|   54   cache_age_list_.push_back(result.first); |   54   cache_age_list_.push_back(result.first); | 
|   55   DCHECK_EQ(cache_.size(), cache_age_list_.size()); |   55   DCHECK_EQ(cache_.size(), cache_age_list_.size()); | 
|   56   return true; |   56   return true; | 
|   57 } |   57 } | 
|   58  |   58  | 
|   59 // Searches for a cached position response for the current WiFi data. Returns |   59 // Searches for a cached position response for the current WiFi data. Returns | 
|   60 // the cached position if available, NULL otherwise. |   60 // the cached position if available, nullptr otherwise. | 
|   61 const Geoposition* NetworkLocationProvider::PositionCache::FindPosition( |   61 const Geoposition* NetworkLocationProvider::PositionCache::FindPosition( | 
|   62     const WifiData& wifi_data) { |   62     const WifiData& wifi_data) { | 
|   63   base::string16 key; |   63   base::string16 key; | 
|   64   if (!MakeKey(wifi_data, &key)) { |   64   if (!MakeKey(wifi_data, &key)) { | 
|   65     return NULL; |   65     return nullptr; | 
|   66   } |   66   } | 
|   67   CacheMap::const_iterator iter = cache_.find(key); |   67   CacheMap::const_iterator iter = cache_.find(key); | 
|   68   return iter == cache_.end() ? NULL : &iter->second; |   68   return iter == cache_.end() ? nullptr : &iter->second; | 
|   69 } |   69 } | 
|   70  |   70  | 
|   71 // Makes the key for the map of cached positions, using the available data. |   71 // Makes the key for the map of cached positions, using the available data. | 
|   72 // Returns true if a good key was generated, false otherwise. |   72 // Returns true if a good key was generated, false otherwise. | 
|   73 // |   73 // | 
|   74 // static |   74 // static | 
|   75 bool NetworkLocationProvider::PositionCache::MakeKey( |   75 bool NetworkLocationProvider::PositionCache::MakeKey( | 
|   76     const WifiData& wifi_data, |   76     const WifiData& wifi_data, | 
|   77     base::string16* key) { |   77     base::string16* key) { | 
|   78   // Currently we use only WiFi data and base the key only on the MAC addresses. |   78   // Currently we use only WiFi data and base the key only on the MAC addresses. | 
|   79   DCHECK(key); |   79   DCHECK(key); | 
|   80   key->clear(); |   80   key->clear(); | 
|   81   const size_t kCharsPerMacAddress = 6 * 3 + 1;  // e.g. "11:22:33:44:55:66|" |   81   const size_t kCharsPerMacAddress = 6 * 3 + 1;  // e.g. "11:22:33:44:55:66|" | 
|   82   key->reserve(wifi_data.access_point_data.size() * kCharsPerMacAddress); |   82   key->reserve(wifi_data.access_point_data.size() * kCharsPerMacAddress); | 
|   83   const base::string16 separator(base::ASCIIToUTF16("|")); |   83   const base::string16 separator(base::ASCIIToUTF16("|")); | 
|   84   for (const auto& access_point_data : wifi_data.access_point_data) { |   84   for (const auto& access_point_data : wifi_data.access_point_data) { | 
|   85     *key += separator; |   85     *key += separator; | 
|   86     *key += access_point_data.mac_address; |   86     *key += access_point_data.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     const scoped_refptr<AccessTokenStore>& access_token_store, | 
|   97     net::URLRequestContextGetter* context, |   97     const scoped_refptr<net::URLRequestContextGetter>& context, | 
|   98     const GURL& url, |   98     const GURL& url, | 
|   99     const base::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     const scoped_refptr<AccessTokenStore>& access_token_store, | 
|  107     net::URLRequestContextGetter* url_context_getter, |  107     const scoped_refptr<net::URLRequestContextGetter>& url_context_getter, | 
|  108     const GURL& url, |  108     const GURL& url, | 
|  109     const base::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_manager_(NULL), |  111       wifi_data_provider_manager_(nullptr), | 
|  112       wifi_data_update_callback_( |  112       wifi_data_update_callback_( | 
|  113           base::Bind(&NetworkLocationProvider::OnWifiDataUpdate, |  113           base::Bind(&NetworkLocationProvider::OnWifiDataUpdate, | 
|  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       position_cache_(new PositionCache), | 
|  119       weak_factory_(this) { |  120       weak_factory_(this) { | 
|  120   // Create the position cache. |  | 
|  121   position_cache_.reset(new PositionCache()); |  | 
|  122  |  | 
|  123   request_.reset(new NetworkLocationRequest( |  121   request_.reset(new NetworkLocationRequest( | 
|  124       url_context_getter, |  122       url_context_getter, | 
|  125       url, |  123       url, | 
|  126       base::Bind(&NetworkLocationProvider::OnLocationResponse, |  124       base::Bind(&NetworkLocationProvider::OnLocationResponse, | 
|  127                  base::Unretained(this)))); |  125                  base::Unretained(this)))); | 
|  128 } |  126 } | 
|  129  |  127  | 
|  130 NetworkLocationProvider::~NetworkLocationProvider() { |  128 NetworkLocationProvider::~NetworkLocationProvider() { | 
|  131   StopProvider(); |  129   StopProvider(); | 
|  132 } |  130 } | 
|  133  |  131  | 
|  134 // LocationProvider implementation |  132 // LocationProvider implementation | 
|  135 void NetworkLocationProvider::GetPosition(Geoposition* position) { |  133 void NetworkLocationProvider::GetPosition(Geoposition* position) { | 
|  136   DCHECK(position); |  134   DCHECK(position); | 
|  137   *position = position_; |  135   *position = position_; | 
|  138 } |  136 } | 
|  139  |  137  | 
|  140 void NetworkLocationProvider::RequestRefresh() { |  138 void NetworkLocationProvider::RequestRefresh() { | 
|  141   // TODO(joth): When called via the public (base class) interface, this should |  139   // TODO(joth): When called via the public (base class) interface, this should | 
|  142   // poke each data provider to get them to expedite their next scan. |  140   // poke each data provider to get them to expedite their next scan. | 
|  143   // Whilst in the delayed start, only send request if all data is ready. |  141   // Whilst in the delayed start, only send request if all data is ready. | 
 |  142   // TODO(mcasas): consider not using HasWeakPtrs() https://crbug.com/629158. | 
|  144   if (!weak_factory_.HasWeakPtrs() || is_wifi_data_complete_) { |  143   if (!weak_factory_.HasWeakPtrs() || is_wifi_data_complete_) { | 
|  145     RequestPosition(); |  144     RequestPosition(); | 
|  146   } |  145   } | 
|  147 } |  146 } | 
|  148  |  147  | 
|  149 void NetworkLocationProvider::OnPermissionGranted() { |  148 void NetworkLocationProvider::OnPermissionGranted() { | 
|  150   const bool was_permission_granted = is_permission_granted_; |  149   const bool was_permission_granted = is_permission_granted_; | 
|  151   is_permission_granted_ = true; |  150   is_permission_granted_ = true; | 
|  152   if (!was_permission_granted && IsStarted()) { |  151   if (!was_permission_granted && IsStarted()) { | 
|  153     RequestRefresh(); |  152     RequestRefresh(); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  179   } |  178   } | 
|  180  |  179  | 
|  181   // Let listeners know that we now have a position available. |  180   // Let listeners know that we now have a position available. | 
|  182   NotifyCallback(position_); |  181   NotifyCallback(position_); | 
|  183 } |  182 } | 
|  184  |  183  | 
|  185 bool NetworkLocationProvider::StartProvider(bool high_accuracy) { |  184 bool NetworkLocationProvider::StartProvider(bool high_accuracy) { | 
|  186   DCHECK(CalledOnValidThread()); |  185   DCHECK(CalledOnValidThread()); | 
|  187   if (IsStarted()) |  186   if (IsStarted()) | 
|  188     return true; |  187     return true; | 
|  189   DCHECK(wifi_data_provider_manager_ == NULL); |  188   DCHECK(!wifi_data_provider_manager_); | 
|  190   if (!request_->url().is_valid()) { |  189   if (!request_->url().is_valid()) { | 
|  191     LOG(WARNING) << "StartProvider() : Failed, Bad URL: " |  190     LOG(WARNING) << "StartProvider() : Failed, Bad URL: " | 
|  192                  << request_->url().possibly_invalid_spec(); |  191                  << request_->url().possibly_invalid_spec(); | 
|  193     return false; |  192     return false; | 
|  194   } |  193   } | 
|  195  |  194  | 
|  196   // Registers a callback with the data provider. The first call to Register |  195   // Registers a callback with the data provider. The first call to Register | 
|  197   // will create a singleton data provider and it will be deleted when the last |  196   // will create a singleton data provider and it will be deleted when the last | 
|  198   // callback is removed with Unregister. |  197   // callback is removed with Unregister. | 
|  199   wifi_data_provider_manager_ = |  198   wifi_data_provider_manager_ = | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  216  |  215  | 
|  217   is_new_data_available_ = is_wifi_data_complete_; |  216   is_new_data_available_ = is_wifi_data_complete_; | 
|  218   RequestRefresh(); |  217   RequestRefresh(); | 
|  219 } |  218 } | 
|  220  |  219  | 
|  221 void NetworkLocationProvider::StopProvider() { |  220 void NetworkLocationProvider::StopProvider() { | 
|  222   DCHECK(CalledOnValidThread()); |  221   DCHECK(CalledOnValidThread()); | 
|  223   if (IsStarted()) { |  222   if (IsStarted()) { | 
|  224     wifi_data_provider_manager_->Unregister(&wifi_data_update_callback_); |  223     wifi_data_provider_manager_->Unregister(&wifi_data_update_callback_); | 
|  225   } |  224   } | 
|  226   wifi_data_provider_manager_ = NULL; |  225   wifi_data_provider_manager_ = nullptr; | 
|  227   weak_factory_.InvalidateWeakPtrs(); |  226   weak_factory_.InvalidateWeakPtrs(); | 
|  228 } |  227 } | 
|  229  |  228  | 
|  230 // Other methods |  229 // Other methods | 
|  231 void NetworkLocationProvider::RequestPosition() { |  230 void NetworkLocationProvider::RequestPosition() { | 
|  232   DCHECK(CalledOnValidThread()); |  231   DCHECK(CalledOnValidThread()); | 
|  233   if (!is_new_data_available_) |  232   if (!is_new_data_available_) | 
|  234     return; |  233     return; | 
|  235  |  234  | 
|  236   const Geoposition* cached_position = |  235   const Geoposition* cached_position = | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|  261   // NetworkLocationRequest for each and hold a set of pending requests. |  260   // NetworkLocationRequest for each and hold a set of pending requests. | 
|  262   if (request_->is_request_pending()) { |  261   if (request_->is_request_pending()) { | 
|  263     DVLOG(1) << "NetworkLocationProvider - pre-empting pending network request " |  262     DVLOG(1) << "NetworkLocationProvider - pre-empting pending network request " | 
|  264                 "with new data. Wifi APs: " |  263                 "with new data. Wifi APs: " | 
|  265              << wifi_data_.access_point_data.size(); |  264              << wifi_data_.access_point_data.size(); | 
|  266   } |  265   } | 
|  267   request_->MakeRequest(access_token_, wifi_data_, wifi_timestamp_); |  266   request_->MakeRequest(access_token_, wifi_data_, wifi_timestamp_); | 
|  268 } |  267 } | 
|  269  |  268  | 
|  270 bool NetworkLocationProvider::IsStarted() const { |  269 bool NetworkLocationProvider::IsStarted() const { | 
|  271   return wifi_data_provider_manager_ != NULL; |  270   return wifi_data_provider_manager_ != nullptr; | 
|  272 } |  271 } | 
|  273  |  272  | 
|  274 }  // namespace content |  273 }  // namespace content | 
| OLD | NEW |