diff options
Diffstat (limited to 'chrome/browser')
6 files changed, 322 insertions, 280 deletions
diff --git a/chrome/browser/geolocation/wifi_data_provider_common.cc b/chrome/browser/geolocation/wifi_data_provider_common.cc index 07724d5..2091e38 100644 --- a/chrome/browser/geolocation/wifi_data_provider_common.cc +++ b/chrome/browser/geolocation/wifi_data_provider_common.cc @@ -15,3 +15,80 @@ string16 MacAddressAsString16(const uint8 mac_as_int[6]) { mac_as_int[0], mac_as_int[1], mac_as_int[2], mac_as_int[3], mac_as_int[4], mac_as_int[5])); } + +WifiDataProviderCommon::WifiDataProviderCommon() + : Thread(__FILE__), + is_first_scan_complete_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { +} + +WifiDataProviderCommon::~WifiDataProviderCommon() { + // Thread must be stopped before entering destructor chain to avoid race + // conditions; see comment in DeviceDataProvider::Unregister. + DCHECK(!IsRunning()) << "Must call StopDataProvider before destroying me"; +} + +bool WifiDataProviderCommon::StartDataProvider() { + DCHECK(CalledOnClientThread()); + return Start(); +} + +void WifiDataProviderCommon::StopDataProvider() { + DCHECK(CalledOnClientThread()); + Stop(); +} + +bool WifiDataProviderCommon::GetData(WifiData *data) { + DCHECK(CalledOnClientThread()); + DCHECK(data); + AutoLock lock(data_mutex_); + *data = wifi_data_; + // If we've successfully completed a scan, indicate that we have all of the + // data we can get. + return is_first_scan_complete_; +} + +// Thread implementation +void WifiDataProviderCommon::Init() { + DCHECK(wlan_api_ == NULL); + wlan_api_.reset(NewWlanApi()); + if (wlan_api_ == NULL) { + // Error! Can't do scans, so don't try and schedule one. + is_first_scan_complete_ = true; + return; + } + + DCHECK(polling_policy_ == NULL); + polling_policy_.reset(NewPolicyPolicy()); + DCHECK(polling_policy_ != NULL); + + ScheduleNextScan(); +} + +void WifiDataProviderCommon::CleanUp() { + // Destroy these instances in the thread on which they were created. + wlan_api_.reset(); + polling_policy_.reset(); +} + +void WifiDataProviderCommon::DoWifiScanTask() { + WifiData new_data; + if (wlan_api_->GetAccessPointData(&new_data.access_point_data)) { + data_mutex_.Acquire(); + bool update_available = wifi_data_.DiffersSignificantly(new_data); + wifi_data_ = new_data; + data_mutex_.Release(); + polling_policy_->UpdatePollingInterval(update_available); + if (update_available || !is_first_scan_complete_) { + is_first_scan_complete_ = true; + NotifyListeners(); + } + } + ScheduleNextScan(); +} + +void WifiDataProviderCommon::ScheduleNextScan() { + message_loop()->PostDelayedTask(FROM_HERE, + task_factory_.NewRunnableMethod(&WifiDataProviderCommon::DoWifiScanTask), + polling_policy_->PollingInterval()); +} diff --git a/chrome/browser/geolocation/wifi_data_provider_common.h b/chrome/browser/geolocation/wifi_data_provider_common.h index 9836b42..9d428f3 100644 --- a/chrome/browser/geolocation/wifi_data_provider_common.h +++ b/chrome/browser/geolocation/wifi_data_provider_common.h @@ -9,7 +9,9 @@ #include "base/logging.h" #include "base/string16.h" -#include "base/basictypes.h" +#include "base/task.h" +#include "base/thread.h" +#include "chrome/browser/geolocation/device_data_provider.h" // Converts a MAC address stored as an array of uint8 to a string. string16 MacAddressAsString16(const uint8 mac_as_int[6]); @@ -50,4 +52,71 @@ class GenericPollingPolicy : public PollingPolicyInterface { int polling_interval_; }; +// Base class to promote code sharing between platform specific wifi data +// providers. It's optional for specific platforms to derive this, but if they +// do threading and polling is taken care of by this base class, and all the +// platform need do is provide the underlying WLAN access API and policy policy, +// both of which will be create & accessed in the worker thread (only). +// Also designed this way to promotes ease of testing the cross-platform +// behavior w.r.t. polling & threading. +class WifiDataProviderCommon + : public WifiDataProviderImplBase, + private base::Thread { + public: + // Interface to abstract the low level data OS library call, and to allow + // mocking (hence public). + class WlanApiInterface { + public: + virtual ~WlanApiInterface() {} + // Gets wifi data for all visible access points. + virtual bool GetAccessPointData(WifiData::AccessPointDataSet* data) = 0; + }; + + WifiDataProviderCommon(); + + // WifiDataProviderImplBase implementation + virtual bool StartDataProvider(); + virtual void StopDataProvider(); + virtual bool GetData(WifiData *data); + + protected: + virtual ~WifiDataProviderCommon(); + + // Returns ownership. Will be called from the worker thread. + virtual WlanApiInterface* NewWlanApi() = 0; + + // Returns ownership. Will be called from the worker thread. + virtual PollingPolicyInterface* NewPolicyPolicy() = 0; + + private: + // Thread implementation + virtual void Init(); + virtual void CleanUp(); + + // Task which run in the child thread. + void DoWifiScanTask(); + + // Will schedule a scan; i.e. enqueue DoWifiScanTask deferred task. + void ScheduleNextScan(); + + WifiData wifi_data_; + Lock data_mutex_; + + // Whether we've successfully completed a scan for WiFi data (or the polling + // thread has terminated early). + bool is_first_scan_complete_; + + // Underlying OS wifi API. + scoped_ptr<WlanApiInterface> wlan_api_; + + // Controls the polling update interval. + scoped_ptr<PollingPolicyInterface> polling_policy_; + + // Holder for the tasks which run on the thread; takes care of cleanup. + ScopedRunnableMethodFactory<WifiDataProviderCommon> task_factory_; + + DISALLOW_COPY_AND_ASSIGN(WifiDataProviderCommon); +}; + + #endif // CHROME_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_COMMON_H_ diff --git a/chrome/browser/geolocation/wifi_data_provider_common_unittest.cc b/chrome/browser/geolocation/wifi_data_provider_common_unittest.cc new file mode 100644 index 0000000..1abf220 --- /dev/null +++ b/chrome/browser/geolocation/wifi_data_provider_common_unittest.cc @@ -0,0 +1,147 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/geolocation/wifi_data_provider_common.h" + +#include <vector> + +#include "base/scoped_ptr.h" +#include "base/string_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +class MockWlanApi : public WifiDataProviderCommon::WlanApiInterface { + public: + MockWlanApi() : calls_(0), bool_return_(true) { + } + virtual bool GetAccessPointData(WifiData::AccessPointDataSet* data) { + ++calls_; + *data = data_out_; + return bool_return_; + } + int calls_; + bool bool_return_; + WifiData::AccessPointDataSet data_out_; +}; + +// Stops the specified (nested) message loop when the listener is called back. +class MessageLoopQuitListener + : public WifiDataProviderCommon::ListenerInterface { + public: + explicit MessageLoopQuitListener(MessageLoop* message_loop) + : message_loop_to_quit_(message_loop) { + CHECK(message_loop_to_quit_ != NULL); + } + // ListenerInterface + virtual void DeviceDataUpdateAvailable( + DeviceDataProvider<WifiData>* provider) { + // Provider should call back on client's thread. + EXPECT_EQ(MessageLoop::current(), message_loop_to_quit_); + provider_ = provider; + message_loop_to_quit_->Quit(); + } + MessageLoop* message_loop_to_quit_; + DeviceDataProvider<WifiData>* provider_; +}; + +class WifiDataProviderCommonWithMock : public WifiDataProviderCommon { + public: + WifiDataProviderCommonWithMock() + : new_wlan_api_(new MockWlanApi) {} + + // WifiDataProviderCommon + virtual WlanApiInterface* NewWlanApi() { + CHECK(new_wlan_api_ != NULL); + return new_wlan_api_.release(); + } + virtual PollingPolicyInterface* NewPolicyPolicy() { + return new GenericPollingPolicy<1, 2, 3>; + } + + scoped_ptr<MockWlanApi> new_wlan_api_; + + DISALLOW_COPY_AND_ASSIGN(WifiDataProviderCommonWithMock); +}; + + +WifiDataProviderImplBase* CreateWifiDataProviderCommonWithMock() { + return new WifiDataProviderCommonWithMock; +} + +// Main test fixture +class GeolocationWifiDataProviderCommonTest : public testing::Test { + public: + virtual void SetUp() { + provider_ = new WifiDataProviderCommonWithMock; + wlan_api_ = provider_->new_wlan_api_.get(); + } + virtual void TearDown() { + provider_->StopDataProvider(); + provider_ = NULL; + } + + protected: + MessageLoop main_message_loop_; + scoped_refptr<WifiDataProviderCommonWithMock> provider_; + MockWlanApi* wlan_api_; +}; + +TEST_F(GeolocationWifiDataProviderCommonTest, CreateDestroy) { + // Test fixture members were SetUp correctly. + EXPECT_EQ(&main_message_loop_, MessageLoop::current()); + EXPECT_TRUE(NULL != provider_.get()); + EXPECT_TRUE(NULL != wlan_api_); +} + +TEST_F(GeolocationWifiDataProviderCommonTest, StartThread) { + EXPECT_TRUE(provider_->StartDataProvider()); + provider_->StopDataProvider(); + SUCCEED(); +} + +TEST_F(GeolocationWifiDataProviderCommonTest, DoAnEmptyScan) { + MessageLoopQuitListener quit_listener(&main_message_loop_); + provider_->AddListener(&quit_listener); + EXPECT_TRUE(provider_->StartDataProvider()); + main_message_loop_.Run(); + // Check we had at least one call. The worker thread may have raced ahead + // and made multiple calls. + EXPECT_GT(wlan_api_->calls_, 0); + WifiData data; + EXPECT_TRUE(provider_->GetData(&data)); + EXPECT_EQ(0, static_cast<int>(data.access_point_data.size())); + provider_->RemoveListener(&quit_listener); +} + +TEST_F(GeolocationWifiDataProviderCommonTest, DoScanWithResults) { + MessageLoopQuitListener quit_listener(&main_message_loop_); + provider_->AddListener(&quit_listener); + AccessPointData single_access_point; + single_access_point.age = 1; + single_access_point.channel = 2; + single_access_point.mac_address = 3; + single_access_point.radio_signal_strength = 4; + single_access_point.signal_to_noise = 5; + single_access_point.ssid = ASCIIToUTF16("foossid"); + wlan_api_->data_out_.insert(single_access_point); + + EXPECT_TRUE(provider_->StartDataProvider()); + main_message_loop_.Run(); + EXPECT_GT(wlan_api_->calls_, 0); + WifiData data; + EXPECT_TRUE(provider_->GetData(&data)); + EXPECT_EQ(1, static_cast<int>(data.access_point_data.size())); + EXPECT_EQ(single_access_point.age, data.access_point_data.begin()->age); + EXPECT_EQ(single_access_point.ssid, data.access_point_data.begin()->ssid); + provider_->RemoveListener(&quit_listener); +} + +TEST_F(GeolocationWifiDataProviderCommonTest, + StartThreadViaDeviceDataProvider) { + MessageLoopQuitListener quit_listener(&main_message_loop_); + WifiDataProvider::SetFactory(CreateWifiDataProviderCommonWithMock); + DeviceDataProvider<WifiData>::Register(&quit_listener); + main_message_loop_.Run(); + DeviceDataProvider<WifiData>::Unregister(&quit_listener); + DeviceDataProvider<WifiData>::ResetFactory(); +} diff --git a/chrome/browser/geolocation/wifi_data_provider_unittest_win.cc b/chrome/browser/geolocation/wifi_data_provider_unittest_win.cc index 90a7e36..e2dd891 100644 --- a/chrome/browser/geolocation/wifi_data_provider_unittest_win.cc +++ b/chrome/browser/geolocation/wifi_data_provider_unittest_win.cc @@ -2,145 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/geolocation/wifi_data_provider_win.h" +// Most logic for the platform wifi provider is now factored into +// WifiDataProviderCommon and covered by it's unit tests. -#include <vector> +#include "chrome/browser/geolocation/wifi_data_provider_win.h" -#include "base/scoped_ptr.h" -#include "base/string_util.h" -#include "chrome/browser/geolocation/wifi_data_provider_common.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { -class MockWlanApi : public Win32WifiDataProvider::WlanApiInterface { - public: - MockWlanApi() : calls_(0), bool_return_(true) { - } - virtual bool GetAccessPointData(WifiData::AccessPointDataSet* data) { - ++calls_; - *data = data_out_; - return bool_return_; - } - int calls_; - bool bool_return_; - WifiData::AccessPointDataSet data_out_; -}; - -class MockPollingPolicy : public PollingPolicyInterface { - public: - virtual void UpdatePollingInterval(bool scan_results_differ) { - results_differed_.push_back(scan_results_differ); - } - virtual int PollingInterval() { return 1; } - std::vector<bool> results_differed_; -}; - -// Stops the specified (nested) message loop when the listener is called back. -class MessageLoopQuitListener - : public Win32WifiDataProvider::ListenerInterface { - public: - explicit MessageLoopQuitListener(MessageLoop* message_loop) - : message_loop_to_quit_(message_loop) { - CHECK(message_loop_to_quit_ != NULL); - } - // ListenerInterface - virtual void DeviceDataUpdateAvailable( - DeviceDataProvider<WifiData>* provider) { - // Provider should call back on client's thread. - EXPECT_EQ(MessageLoop::current(), message_loop_to_quit_); - provider_ = provider; - message_loop_to_quit_->Quit(); - } - MessageLoop* message_loop_to_quit_; - DeviceDataProvider<WifiData>* provider_; -}; - -Win32WifiDataProvider* CreateWin32WifiDataProvider(MockWlanApi** wlan_api_out) { - Win32WifiDataProvider* provider = new Win32WifiDataProvider; - *wlan_api_out = new MockWlanApi; - provider->inject_mock_wlan_api(*wlan_api_out); // Takes ownership. - provider->inject_mock_polling_policy(new MockPollingPolicy); // ditto - return provider; -} - -WifiDataProviderImplBase* CreateWin32WifiDataProvider() { - MockWlanApi* wlan_api; - return CreateWin32WifiDataProvider(&wlan_api); -} -} // namespace - -// Main test fixture -class GeolocationWin32WifiDataProviderTest : public testing::Test { - public: - virtual void SetUp() { - provider_ = CreateWin32WifiDataProvider(&wlan_api_); - } - virtual void TearDown() { - provider_->StopDataProvider(); - provider_ = NULL; - } - - protected: - MessageLoop main_message_loop_; - scoped_refptr<Win32WifiDataProvider> provider_; - MockWlanApi* wlan_api_; -}; - -TEST_F(GeolocationWin32WifiDataProviderTest, CreateDestroy) { - // Test fixture members were SetUp correctly. - EXPECT_EQ(&main_message_loop_, MessageLoop::current()); - EXPECT_TRUE(NULL != provider_.get()); - EXPECT_TRUE(NULL != wlan_api_); -} - -TEST_F(GeolocationWin32WifiDataProviderTest, StartThread) { - EXPECT_TRUE(provider_->StartDataProvider()); - provider_->StopDataProvider(); +TEST(GeolocationWin32WifiDataProviderTest, CreateDestroy) { + // WifiDataProviderCommon requires the client to have a message loop. + MessageLoop dummy_loop; + scoped_refptr<Win32WifiDataProvider> instance(new Win32WifiDataProvider); + instance = NULL; SUCCEED(); -} - -TEST_F(GeolocationWin32WifiDataProviderTest, DoAnEmptyScan) { - MessageLoopQuitListener quit_listener(&main_message_loop_); - provider_->AddListener(&quit_listener); - EXPECT_TRUE(provider_->StartDataProvider()); - main_message_loop_.Run(); - // Check we had at least one call. The worker thread may have raced ahead - // and made multiple calls. - EXPECT_GT(wlan_api_->calls_, 0); - WifiData data; - EXPECT_TRUE(provider_->GetData(&data)); - EXPECT_EQ(0, data.access_point_data.size()); - provider_->RemoveListener(&quit_listener); -} - -TEST_F(GeolocationWin32WifiDataProviderTest, DoScanWithResults) { - MessageLoopQuitListener quit_listener(&main_message_loop_); - provider_->AddListener(&quit_listener); - AccessPointData single_access_point; - single_access_point.age = 1; - single_access_point.channel = 2; - single_access_point.mac_address = 3; - single_access_point.radio_signal_strength = 4; - single_access_point.signal_to_noise = 5; - single_access_point.ssid = L"foossid"; - wlan_api_->data_out_.insert(single_access_point); - - EXPECT_TRUE(provider_->StartDataProvider()); - main_message_loop_.Run(); - EXPECT_GT(wlan_api_->calls_, 0); - WifiData data; - EXPECT_TRUE(provider_->GetData(&data)); - EXPECT_EQ(1, data.access_point_data.size()); - EXPECT_EQ(single_access_point.age, data.access_point_data.begin()->age); - EXPECT_EQ(single_access_point.ssid, data.access_point_data.begin()->ssid); - provider_->RemoveListener(&quit_listener); -} - -TEST_F(GeolocationWin32WifiDataProviderTest, StartThreadViaDeviceDataProvider) { - MessageLoopQuitListener quit_listener(&main_message_loop_); - WifiDataProvider::SetFactory(CreateWin32WifiDataProvider); - DeviceDataProvider<WifiData>::Register(&quit_listener); - main_message_loop_.Run(); - DeviceDataProvider<WifiData>::Unregister(&quit_listener); - DeviceDataProvider<WifiData>::ResetFactory(); + // Can't actually call start provider on the Win32WifiDataProvider without + // it accessing hardware and so risking making the test flaky. } diff --git a/chrome/browser/geolocation/wifi_data_provider_win.cc b/chrome/browser/geolocation/wifi_data_provider_win.cc index f103036..3453f05 100644 --- a/chrome/browser/geolocation/wifi_data_provider_win.cc +++ b/chrome/browser/geolocation/wifi_data_provider_win.cc @@ -79,7 +79,7 @@ typedef DWORD (WINAPI *WlanCloseHandleFunction)(HANDLE hClientHandle, // Local classes and functions -class WindowsWlanApi : public Win32WifiDataProvider::WlanApiInterface { +class WindowsWlanApi : public WifiDataProviderCommon::WlanApiInterface { public: ~WindowsWlanApi(); // Factory function. Will return NULL if this API is unavailable. @@ -109,7 +109,7 @@ class WindowsWlanApi : public Win32WifiDataProvider::WlanApiInterface { WlanCloseHandleFunction WlanCloseHandle_function_; }; -class WindowsNdisApi : public Win32WifiDataProvider::WlanApiInterface { +class WindowsNdisApi : public WifiDataProviderCommon::WlanApiInterface { public: ~WindowsNdisApi(); static WindowsNdisApi* Create(); @@ -159,105 +159,26 @@ WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() { return new Win32WifiDataProvider(); } -Win32WifiDataProvider::Win32WifiDataProvider() - : Thread(__FILE__), - is_first_scan_complete_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { +Win32WifiDataProvider::Win32WifiDataProvider() { } Win32WifiDataProvider::~Win32WifiDataProvider() { - // Thread must be stopped before entering destructor chain to avoid race - // conditions; see comment in DeviceDataProvider::Unregister. - DCHECK(!IsRunning()) << "Must call StopDataProvider before destroying me"; } -void Win32WifiDataProvider::inject_mock_wlan_api(WlanApiInterface* wlan_api) { - DCHECK(wlan_api_ == NULL); - DCHECK(wlan_api); - wlan_api_.reset(wlan_api); -} - -void Win32WifiDataProvider::inject_mock_polling_policy( - PollingPolicyInterface* policy) { - DCHECK(polling_policy_ == NULL); - DCHECK(policy); - polling_policy_.reset(policy); -} - -bool Win32WifiDataProvider::StartDataProvider() { - DCHECK(CalledOnClientThread()); - return Start(); -} - -void Win32WifiDataProvider::StopDataProvider() { - DCHECK(CalledOnClientThread()); - Stop(); -} - -bool Win32WifiDataProvider::GetData(WifiData *data) { - DCHECK(CalledOnClientThread()); - DCHECK(data); - AutoLock lock(data_mutex_); - *data = wifi_data_; - // If we've successfully completed a scan, indicate that we have all of the - // data we can get. - return is_first_scan_complete_; -} - -// Thread implementation -void Win32WifiDataProvider::Init() { +WifiDataProviderCommon::WlanApiInterface* Win32WifiDataProvider::NewWlanApi() { // Use the WLAN interface if we're on Vista and if it's available. Otherwise, // use NDIS. - if (wlan_api_ == NULL) { - wlan_api_.reset(WindowsWlanApi::Create()); - } - if (wlan_api_ == NULL) { - wlan_api_.reset(WindowsNdisApi::Create()); - } - if (wlan_api_ == NULL) { - // Error! Can't do scans, so don't try and schedule one. - is_first_scan_complete_ = true; - return; - } - - if (polling_policy_ == NULL) { - polling_policy_.reset( - new GenericPollingPolicy<kDefaultPollingInterval, - kNoChangePollingInterval, - kTwoNoChangePollingInterval>); - } - DCHECK(polling_policy_ != NULL); - - ScheduleNextScan(); -} - -void Win32WifiDataProvider::CleanUp() { - // Destroy the wlan api instance in the thread in which it was created. - wlan_api_.reset(); -} - -void Win32WifiDataProvider::DoWifiScanTask() { - // TODO(joth): Almost all of this is shareable across platforms. - WifiData new_data; - if (wlan_api_->GetAccessPointData(&new_data.access_point_data)) { - bool update_available; - data_mutex_.Acquire(); - update_available = wifi_data_.DiffersSignificantly(new_data); - wifi_data_ = new_data; - data_mutex_.Release(); - polling_policy_->UpdatePollingInterval(update_available); - if (update_available || !is_first_scan_complete_) { - is_first_scan_complete_ = true; - NotifyListeners(); - } + WlanApiInterface* api = WindowsWlanApi::Create(); + if (api) { + return api; } - ScheduleNextScan(); + return WindowsNdisApi::Create(); } -void Win32WifiDataProvider::ScheduleNextScan() { - message_loop()->PostDelayedTask(FROM_HERE, - task_factory_.NewRunnableMethod(&Win32WifiDataProvider::DoWifiScanTask), - polling_policy_->PollingInterval()); +PollingPolicyInterface* Win32WifiDataProvider::NewPolicyPolicy() { + return new GenericPollingPolicy<kDefaultPollingInterval, + kNoChangePollingInterval, + kTwoNoChangePollingInterval>; } // Local classes and functions @@ -639,7 +560,7 @@ int PerformQuery(HANDLE adapter_handle, } bool ResizeBuffer(int requested_size, scoped_ptr_malloc<BYTE>* buffer) { - DCHECK(requested_size > 0); + DCHECK_GT(requested_size, 0); DCHECK(buffer); if (requested_size > kMaximumBufferSize) { buffer->reset(); diff --git a/chrome/browser/geolocation/wifi_data_provider_win.h b/chrome/browser/geolocation/wifi_data_provider_win.h index 62d0766..3a1e727 100644 --- a/chrome/browser/geolocation/wifi_data_provider_win.h +++ b/chrome/browser/geolocation/wifi_data_provider_win.h @@ -5,66 +5,20 @@ #ifndef CHROME_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_WIN_H_ #define CHROME_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_WIN_H_ -#include "base/task.h" -#include "base/thread.h" -#include "chrome/browser/geolocation/device_data_provider.h" +#include "chrome/browser/geolocation/wifi_data_provider_common.h" class PollingPolicyInterface; -class Win32WifiDataProvider - : public WifiDataProviderImplBase, - private base::Thread { +class Win32WifiDataProvider : public WifiDataProviderCommon { public: - // Interface to abstract the low level data OS library call, and to allow - // mocking (hence public). - class WlanApiInterface { - public: - virtual ~WlanApiInterface() {} - // Gets wifi data for all visible access points. - virtual bool GetAccessPointData(WifiData::AccessPointDataSet *data) = 0; - }; - Win32WifiDataProvider(); - // Takes ownership of wlan_api. Must be called before Start(). - void inject_mock_wlan_api(WlanApiInterface* wlan_api); - - // Takes ownership of polic. Must be called before Start(). - void inject_mock_polling_policy(PollingPolicyInterface* policy); - - // WifiDataProviderImplBase implementation - virtual bool StartDataProvider(); - virtual void StopDataProvider(); - virtual bool GetData(WifiData *data); - private: virtual ~Win32WifiDataProvider(); - // Thread implementation - virtual void Init(); - virtual void CleanUp(); - - // Task which run in the child thread. - void DoWifiScanTask(); - - // Will schedule a scan; i.e. enqueue DoWifiScanTask deferred task. - void ScheduleNextScan(); - - WifiData wifi_data_; - Lock data_mutex_; - - // Whether we've successfully completed a scan for WiFi data (or the polling - // thread has terminated early). - bool is_first_scan_complete_; - - // Underlying OS wifi API. - scoped_ptr<WlanApiInterface> wlan_api_; - - // Controls the polling update interval. - scoped_ptr<PollingPolicyInterface> polling_policy_; - - // Holder for the tasks which run on the thread; takes care of cleanup. - ScopedRunnableMethodFactory<Win32WifiDataProvider> task_factory_; + // WifiDataProviderCommon + virtual WlanApiInterface* NewWlanApi(); + virtual PollingPolicyInterface* NewPolicyPolicy(); DISALLOW_COPY_AND_ASSIGN(Win32WifiDataProvider); }; |