Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / geolocation / wifi_data_provider_chromeos.cc
blob18d84bad10904de93ce1c8f21d7b2aa8e5444b4e
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"
9 #include "base/bind.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"
15 namespace content {
17 namespace {
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
25 } // namespace
27 WifiDataProviderChromeOs::WifiDataProviderChromeOs()
28 : started_(false), is_first_scan_complete_(false) {
31 WifiDataProviderChromeOs::~WifiDataProviderChromeOs() {
34 void WifiDataProviderChromeOs::StartDataProvider() {
35 DCHECK(CalledOnClientThread());
37 DCHECK(polling_policy_ == NULL);
38 polling_policy_.reset(
39 new GenericWifiPollingPolicy<kDefaultPollingIntervalMilliseconds,
40 kNoChangePollingIntervalMilliseconds,
41 kTwoNoChangePollingIntervalMilliseconds,
42 kNoWifiPollingIntervalMilliseconds>);
44 ScheduleStart();
47 void WifiDataProviderChromeOs::StopDataProvider() {
48 DCHECK(CalledOnClientThread());
50 polling_policy_.reset();
51 ScheduleStop();
54 bool WifiDataProviderChromeOs::GetData(WifiData* data) {
55 DCHECK(CalledOnClientThread());
56 DCHECK(data);
57 *data = wifi_data_;
58 return is_first_scan_complete_;
61 void WifiDataProviderChromeOs::DoStartTaskOnUIThread() {
62 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63 DoWifiScanTaskOnUIThread();
66 void WifiDataProviderChromeOs::DoWifiScanTaskOnUIThread() {
67 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
69 // This method could be scheduled after a ScheduleStop.
70 if (!started_)
71 return;
73 WifiData new_data;
75 if (GetAccessPointData(&new_data.access_point_data)) {
76 client_loop()->PostTask(
77 FROM_HERE,
78 base::Bind(&WifiDataProviderChromeOs::DidWifiScanTask, this, new_data));
79 } else {
80 client_loop()->PostTask(
81 FROM_HERE,
82 base::Bind(&WifiDataProviderChromeOs::DidWifiScanTaskNoResults, this));
86 void WifiDataProviderChromeOs::DidWifiScanTaskNoResults() {
87 DCHECK(CalledOnClientThread());
88 // Schedule next scan if started (StopDataProvider could have been called
89 // in between DoWifiScanTaskOnUIThread and this method).
90 if (started_)
91 ScheduleNextScan(polling_policy_->NoWifiInterval());
94 void WifiDataProviderChromeOs::DidWifiScanTask(const WifiData& new_data) {
95 DCHECK(CalledOnClientThread());
96 bool update_available = wifi_data_.DiffersSignificantly(new_data);
97 wifi_data_ = new_data;
98 // Schedule next scan if started (StopDataProvider could have been called
99 // in between DoWifiScanTaskOnUIThread and this method).
100 if (started_) {
101 polling_policy_->UpdatePollingInterval(update_available);
102 ScheduleNextScan(polling_policy_->PollingInterval());
105 if (update_available || !is_first_scan_complete_) {
106 is_first_scan_complete_ = true;
107 RunCallbacks();
111 void WifiDataProviderChromeOs::ScheduleNextScan(int interval) {
112 DCHECK(CalledOnClientThread());
113 DCHECK(started_);
114 BrowserThread::PostDelayedTask(
115 BrowserThread::UI,
116 FROM_HERE,
117 base::Bind(&WifiDataProviderChromeOs::DoWifiScanTaskOnUIThread, this),
118 base::TimeDelta::FromMilliseconds(interval));
121 void WifiDataProviderChromeOs::ScheduleStop() {
122 DCHECK(CalledOnClientThread());
123 DCHECK(started_);
124 started_ = false;
127 void WifiDataProviderChromeOs::ScheduleStart() {
128 DCHECK(CalledOnClientThread());
129 DCHECK(!started_);
130 started_ = true;
131 // Perform first scan ASAP regardless of the polling policy. If this scan
132 // fails we'll retry at a rate in line with the polling policy.
133 BrowserThread::PostTask(
134 BrowserThread::UI,
135 FROM_HERE,
136 base::Bind(&WifiDataProviderChromeOs::DoStartTaskOnUIThread, this));
139 bool WifiDataProviderChromeOs::GetAccessPointData(
140 WifiData::AccessPointDataSet* result) {
141 // If wifi isn't enabled, we've effectively completed the task.
142 // Return true to indicate an empty access point list.
143 if (!chromeos::NetworkHandler::Get()->geolocation_handler()->wifi_enabled())
144 return true;
146 chromeos::WifiAccessPointVector access_points;
147 int64 age_ms = 0;
148 if (!chromeos::NetworkHandler::Get()->geolocation_handler()->
149 GetWifiAccessPoints(&access_points, &age_ms)) {
150 return false;
152 for (chromeos::WifiAccessPointVector::const_iterator i
153 = access_points.begin();
154 i != access_points.end(); ++i) {
155 AccessPointData ap_data;
156 ap_data.mac_address = base::ASCIIToUTF16(i->mac_address);
157 ap_data.radio_signal_strength = i->signal_strength;
158 ap_data.channel = i->channel;
159 ap_data.signal_to_noise = i->signal_to_noise;
160 ap_data.ssid = base::UTF8ToUTF16(i->ssid);
161 result->insert(ap_data);
163 // If the age is significantly longer than our long polling time, assume the
164 // data is stale and return false which will trigger a faster update.
165 if (age_ms > kTwoNoChangePollingIntervalMilliseconds * 2)
166 return false;
167 return true;
170 // static
171 WifiDataProvider* WifiDataProviderManager::DefaultFactoryFunction() {
172 return new WifiDataProviderChromeOs();
175 } // namespace content