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 // Provides wifi scan API binding for chromeos, using proprietary APIs.
7 #include "content/browser/geolocation/wifi_data_provider_chromeos.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chromeos/network/geolocation_handler.h"
12 #include "content/browser/geolocation/wifi_data_provider_manager.h"
13 #include "content/public/browser/browser_thread.h"
19 // The time periods between successive polls of the wifi data.
20 const int kDefaultPollingIntervalMilliseconds
= 10 * 1000; // 10s
21 const int kNoChangePollingIntervalMilliseconds
= 2 * 60 * 1000; // 2 mins
22 const int kTwoNoChangePollingIntervalMilliseconds
= 10 * 60 * 1000; // 10 mins
23 const int kNoWifiPollingIntervalMilliseconds
= 20 * 1000; // 20s
27 WifiDataProviderChromeOs::WifiDataProviderChromeOs() : started_(false) {
30 WifiDataProviderChromeOs::~WifiDataProviderChromeOs() {
33 void WifiDataProviderChromeOs::StartDataProvider() {
34 DCHECK(CalledOnClientThread());
36 DCHECK(polling_policy_
== NULL
);
37 polling_policy_
.reset(
38 new GenericWifiPollingPolicy
<kDefaultPollingIntervalMilliseconds
,
39 kNoChangePollingIntervalMilliseconds
,
40 kTwoNoChangePollingIntervalMilliseconds
,
41 kNoWifiPollingIntervalMilliseconds
>);
46 void WifiDataProviderChromeOs::StopDataProvider() {
47 DCHECK(CalledOnClientThread());
49 polling_policy_
.reset();
53 bool WifiDataProviderChromeOs::GetData(WifiData
* data
) {
54 DCHECK(CalledOnClientThread());
57 return is_first_scan_complete_
;
60 void WifiDataProviderChromeOs::DoStartTaskOnUIThread() {
61 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
62 DoWifiScanTaskOnUIThread();
65 void WifiDataProviderChromeOs::DoWifiScanTaskOnUIThread() {
66 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
68 // This method could be scheduled after a ScheduleStop.
74 if (GetAccessPointData(&new_data
.access_point_data
)) {
75 client_loop()->PostTask(
77 base::Bind(&WifiDataProviderChromeOs::DidWifiScanTask
, this, new_data
));
79 client_loop()->PostTask(
81 base::Bind(&WifiDataProviderChromeOs::DidWifiScanTaskNoResults
, this));
85 void WifiDataProviderChromeOs::DidWifiScanTaskNoResults() {
86 DCHECK(CalledOnClientThread());
87 // Schedule next scan if started (StopDataProvider could have been called
88 // in between DoWifiScanTaskOnUIThread and this method).
90 ScheduleNextScan(polling_policy_
->NoWifiInterval());
93 void WifiDataProviderChromeOs::DidWifiScanTask(const WifiData
& new_data
) {
94 DCHECK(CalledOnClientThread());
95 bool update_available
= wifi_data_
.DiffersSignificantly(new_data
);
96 wifi_data_
= new_data
;
97 // Schedule next scan if started (StopDataProvider could have been called
98 // in between DoWifiScanTaskOnUIThread and this method).
100 polling_policy_
->UpdatePollingInterval(update_available
);
101 ScheduleNextScan(polling_policy_
->PollingInterval());
104 if (update_available
|| !is_first_scan_complete_
) {
105 is_first_scan_complete_
= true;
110 void WifiDataProviderChromeOs::ScheduleNextScan(int interval
) {
111 DCHECK(CalledOnClientThread());
113 BrowserThread::PostDelayedTask(
116 base::Bind(&WifiDataProviderChromeOs::DoWifiScanTaskOnUIThread
, this),
117 base::TimeDelta::FromMilliseconds(interval
));
120 void WifiDataProviderChromeOs::ScheduleStop() {
121 DCHECK(CalledOnClientThread());
126 void WifiDataProviderChromeOs::ScheduleStart() {
127 DCHECK(CalledOnClientThread());
130 // Perform first scan ASAP regardless of the polling policy. If this scan
131 // fails we'll retry at a rate in line with the polling policy.
132 BrowserThread::PostTask(
135 base::Bind(&WifiDataProviderChromeOs::DoStartTaskOnUIThread
, this));
138 bool WifiDataProviderChromeOs::GetAccessPointData(
139 WifiData::AccessPointDataSet
* result
) {
140 // If wifi isn't enabled, we've effectively completed the task.
141 // Return true to indicate an empty access point list.
142 if (!chromeos::NetworkHandler::Get()->geolocation_handler()->wifi_enabled())
145 chromeos::WifiAccessPointVector access_points
;
147 if (!chromeos::NetworkHandler::Get()->geolocation_handler()->
148 GetWifiAccessPoints(&access_points
, &age_ms
)) {
151 for (chromeos::WifiAccessPointVector::const_iterator i
152 = access_points
.begin();
153 i
!= access_points
.end(); ++i
) {
154 AccessPointData ap_data
;
155 ap_data
.mac_address
= base::ASCIIToUTF16(i
->mac_address
);
156 ap_data
.radio_signal_strength
= i
->signal_strength
;
157 ap_data
.channel
= i
->channel
;
158 ap_data
.signal_to_noise
= i
->signal_to_noise
;
159 ap_data
.ssid
= base::UTF8ToUTF16(i
->ssid
);
160 result
->insert(ap_data
);
162 // If the age is significantly longer than our long polling time, assume the
163 // data is stale and return false which will trigger a faster update.
164 if (age_ms
> kTwoNoChangePollingIntervalMilliseconds
* 2)
170 WifiDataProvider
* WifiDataProviderManager::DefaultFactoryFunction() {
171 return new WifiDataProviderChromeOs();
174 } // namespace content