By moving the call to Load() up in SearchProvider::Start(), we are giving a chance...
[chromium-blink-merge.git] / content / browser / geolocation / wifi_data_provider_common.cc
blobfd5667a8339f8a00b5dc04c77479f6228bd0540a
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"
7 #include "base/bind.h"
8 #include "base/stringprintf.h"
9 #include "base/utf_string_conversions.h"
11 namespace content {
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,
19 mac_as_int[0],
20 mac_as_int[1],
21 mac_as_int[2],
22 mac_as_int[3],
23 mac_as_int[4],
24 mac_as_int[5]));
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.
42 return Start();
45 void WifiDataProviderCommon::StopDataProvider() {
46 DCHECK(CalledOnClientThread());
47 Stop();
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_;
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;
67 return;
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.
76 ScheduleNextScan(0);
79 void WifiDataProviderCommon::CleanUp() {
80 // Destroy these instances in the thread on which they were created.
81 wlan_api_.reset();
82 polling_policy_.reset();
85 void WifiDataProviderCommon::DoWifiScanTask() {
86 bool update_available = false;
87 WifiData new_data;
88 if (!wlan_api_->GetAccessPointData(&new_data.access_point_data)) {
89 ScheduleNextScan(polling_policy_->NoWifiInterval());
90 } else {
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;
101 NotifyListeners();
105 void WifiDataProviderCommon::ScheduleNextScan(int interval) {
106 message_loop()->PostDelayedTask(
107 FROM_HERE,
108 base::Bind(&WifiDataProviderCommon::DoWifiScanTask,
109 weak_factory_.GetWeakPtr()),
110 base::TimeDelta::FromMilliseconds(interval));
113 } // namespace content