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.
5 #include "content/browser/geolocation/wifi_data_provider_common.h"
8 #include "base/stringprintf.h"
9 #include "base/utf_string_conversions.h"
13 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 ASCIIToUTF16(base::StringPrintf(kMacFormatString
,
27 WifiDataProviderCommon::WifiDataProviderCommon()
28 : Thread("Geolocation_wifi_provider"),
29 is_first_scan_complete_(false),
30 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
33 WifiDataProviderCommon::~WifiDataProviderCommon() {
34 // Thread must be stopped before entering destructor chain to avoid race
35 // conditions; see comment in DeviceDataProvider::Unregister.
36 DCHECK(!IsRunning()); // Must call StopDataProvider before destroying me.
39 bool WifiDataProviderCommon::StartDataProvider() {
40 DCHECK(CalledOnClientThread());
41 DCHECK(!IsRunning()); // StartDataProvider must only be called once.
45 void WifiDataProviderCommon::StopDataProvider() {
46 DCHECK(CalledOnClientThread());
50 bool WifiDataProviderCommon::GetData(WifiData
* data
) {
51 DCHECK(CalledOnClientThread());
53 base::AutoLock
lock(data_mutex_
);
55 // If we've successfully completed a scan, indicate that we have all of the
57 return is_first_scan_complete_
;
60 // Thread implementation
61 void WifiDataProviderCommon::Init() {
62 DCHECK(wlan_api_
== NULL
);
63 wlan_api_
.reset(NewWlanApi());
64 if (wlan_api_
== NULL
) {
65 // Error! Can't do scans, so don't try and schedule one.
66 is_first_scan_complete_
= true;
70 DCHECK(polling_policy_
== NULL
);
71 polling_policy_
.reset(NewPollingPolicy());
72 DCHECK(polling_policy_
!= NULL
);
74 // Perform first scan ASAP regardless of the polling policy. If this scan
75 // fails we'll retry at a rate in line with the polling policy.
79 void WifiDataProviderCommon::CleanUp() {
80 // Destroy these instances in the thread on which they were created.
82 polling_policy_
.reset();
85 void WifiDataProviderCommon::DoWifiScanTask() {
86 bool update_available
= false;
88 if (!wlan_api_
->GetAccessPointData(&new_data
.access_point_data
)) {
89 ScheduleNextScan(polling_policy_
->NoWifiInterval());
92 base::AutoLock
lock(data_mutex_
);
93 update_available
= wifi_data_
.DiffersSignificantly(new_data
);
94 wifi_data_
= new_data
;
96 polling_policy_
->UpdatePollingInterval(update_available
);
97 ScheduleNextScan(polling_policy_
->PollingInterval());
99 if (update_available
|| !is_first_scan_complete_
) {
100 is_first_scan_complete_
= true;
105 void WifiDataProviderCommon::ScheduleNextScan(int interval
) {
106 message_loop()->PostDelayedTask(
108 base::Bind(&WifiDataProviderCommon::DoWifiScanTask
,
109 weak_factory_
.GetWeakPtr()),
110 base::TimeDelta::FromMilliseconds(interval
));
113 } // namespace content