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