2b5c218c24b1b0ef257d575b90ca0b951a8445b4
[platform/framework/web/crosswalk.git] / src / content / browser / geolocation / wifi_data_provider_chromeos.cc
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 // Provides wifi scan API binding for chromeos, using proprietary APIs.
6
7 #include "content/browser/geolocation/wifi_data_provider_chromeos.h"
8
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"
14
15 namespace content {
16
17 namespace {
18
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
24
25 }  // namespace
26
27 WifiDataProviderChromeOs::WifiDataProviderChromeOs() : started_(false) {
28 }
29
30 WifiDataProviderChromeOs::~WifiDataProviderChromeOs() {
31 }
32
33 void WifiDataProviderChromeOs::StartDataProvider() {
34   DCHECK(CalledOnClientThread());
35
36   DCHECK(polling_policy_ == NULL);
37   polling_policy_.reset(
38       new GenericWifiPollingPolicy<kDefaultPollingIntervalMilliseconds,
39                                    kNoChangePollingIntervalMilliseconds,
40                                    kTwoNoChangePollingIntervalMilliseconds,
41                                    kNoWifiPollingIntervalMilliseconds>);
42
43   ScheduleStart();
44 }
45
46 void WifiDataProviderChromeOs::StopDataProvider() {
47   DCHECK(CalledOnClientThread());
48
49   polling_policy_.reset();
50   ScheduleStop();
51 }
52
53 bool WifiDataProviderChromeOs::GetData(WifiData* data) {
54   DCHECK(CalledOnClientThread());
55   DCHECK(data);
56   *data = wifi_data_;
57   return is_first_scan_complete_;
58 }
59
60 void WifiDataProviderChromeOs::DoStartTaskOnUIThread() {
61   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62   DoWifiScanTaskOnUIThread();
63 }
64
65 void WifiDataProviderChromeOs::DoWifiScanTaskOnUIThread() {
66   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
67
68   // This method could be scheduled after a ScheduleStop.
69   if (!started_)
70     return;
71
72   WifiData new_data;
73
74   if (GetAccessPointData(&new_data.access_point_data)) {
75     client_loop()->PostTask(
76         FROM_HERE,
77         base::Bind(&WifiDataProviderChromeOs::DidWifiScanTask, this, new_data));
78   } else {
79     client_loop()->PostTask(
80         FROM_HERE,
81         base::Bind(&WifiDataProviderChromeOs::DidWifiScanTaskNoResults, this));
82   }
83 }
84
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).
89   if (started_)
90     ScheduleNextScan(polling_policy_->NoWifiInterval());
91 }
92
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).
99   if (started_) {
100     polling_policy_->UpdatePollingInterval(update_available);
101     ScheduleNextScan(polling_policy_->PollingInterval());
102   }
103
104   if (update_available || !is_first_scan_complete_) {
105     is_first_scan_complete_ = true;
106     RunCallbacks();
107   }
108 }
109
110 void WifiDataProviderChromeOs::ScheduleNextScan(int interval) {
111   DCHECK(CalledOnClientThread());
112   DCHECK(started_);
113   BrowserThread::PostDelayedTask(
114       BrowserThread::UI,
115       FROM_HERE,
116       base::Bind(&WifiDataProviderChromeOs::DoWifiScanTaskOnUIThread, this),
117       base::TimeDelta::FromMilliseconds(interval));
118 }
119
120 void WifiDataProviderChromeOs::ScheduleStop() {
121   DCHECK(CalledOnClientThread());
122   DCHECK(started_);
123   started_ = false;
124 }
125
126 void WifiDataProviderChromeOs::ScheduleStart() {
127   DCHECK(CalledOnClientThread());
128   DCHECK(!started_);
129   started_ = true;
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(
133       BrowserThread::UI,
134       FROM_HERE,
135       base::Bind(&WifiDataProviderChromeOs::DoStartTaskOnUIThread, this));
136 }
137
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())
143     return true;
144
145   chromeos::WifiAccessPointVector access_points;
146   int64 age_ms = 0;
147   if (!chromeos::NetworkHandler::Get()->geolocation_handler()->
148       GetWifiAccessPoints(&access_points, &age_ms)) {
149     return false;
150   }
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);
161   }
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)
165     return false;
166   return true;
167 }
168
169 // static
170 WifiDataProvider* WifiDataProviderManager::DefaultFactoryFunction() {
171   return new WifiDataProviderChromeOs();
172 }
173
174 }  // namespace content