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 "content/browser/geolocation/wifi_data_provider_common.h" 6 7 #include "base/bind.h" 8 #include "base/strings/stringprintf.h" 9 #include "base/strings/utf_string_conversions.h" 10 11 namespace content { 12 13 base::string16 MacAddressAsString16(const uint8 mac_as_int[6]) { 14 // mac_as_int is big-endian. Write in byte chunks. 15 // Format is XX-XX-XX-XX-XX-XX. 16 static const char* const kMacFormatString = 17 "%02x-%02x-%02x-%02x-%02x-%02x"; 18 return base::ASCIIToUTF16(base::StringPrintf(kMacFormatString, 19 mac_as_int[0], 20 mac_as_int[1], 21 mac_as_int[2], 22 mac_as_int[3], 23 mac_as_int[4], 24 mac_as_int[5])); 25 } 26 27 WifiDataProviderCommon::WifiDataProviderCommon() 28 : is_first_scan_complete_(false), 29 weak_factory_(this) { 30 } 31 32 WifiDataProviderCommon::~WifiDataProviderCommon() { 33 } 34 35 void WifiDataProviderCommon::StartDataProvider() { 36 DCHECK(wlan_api_ == NULL); 37 wlan_api_.reset(NewWlanApi()); 38 if (wlan_api_ == NULL) { 39 // Error! Can't do scans, so don't try and schedule one. 40 is_first_scan_complete_ = true; 41 return; 42 } 43 44 DCHECK(polling_policy_ == NULL); 45 polling_policy_.reset(NewPollingPolicy()); 46 DCHECK(polling_policy_ != NULL); 47 48 // Perform first scan ASAP regardless of the polling policy. If this scan 49 // fails we'll retry at a rate in line with the polling policy. 50 ScheduleNextScan(0); 51 } 52 53 void WifiDataProviderCommon::StopDataProvider() { 54 wlan_api_.reset(); 55 polling_policy_.reset(); 56 } 57 58 bool WifiDataProviderCommon::GetData(WifiData* data) { 59 *data = wifi_data_; 60 // If we've successfully completed a scan, indicate that we have all of the 61 // data we can get. 62 return is_first_scan_complete_; 63 } 64 65 void WifiDataProviderCommon::DoWifiScanTask() { 66 bool update_available = false; 67 WifiData new_data; 68 if (!wlan_api_->GetAccessPointData(&new_data.access_point_data)) { 69 ScheduleNextScan(polling_policy_->NoWifiInterval()); 70 } else { 71 update_available = wifi_data_.DiffersSignificantly(new_data); 72 wifi_data_ = new_data; 73 polling_policy_->UpdatePollingInterval(update_available); 74 ScheduleNextScan(polling_policy_->PollingInterval()); 75 } 76 if (update_available || !is_first_scan_complete_) { 77 is_first_scan_complete_ = true; 78 RunCallbacks(); 79 } 80 } 81 82 void WifiDataProviderCommon::ScheduleNextScan(int interval) { 83 client_loop()->PostDelayedTask( 84 FROM_HERE, 85 base::Bind(&WifiDataProviderCommon::DoWifiScanTask, 86 weak_factory_.GetWeakPtr()), 87 base::TimeDelta::FromMilliseconds(interval)); 88 } 89 90 } // namespace content 91