diff options
author | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-04 19:27:43 +0000 |
---|---|---|
committer | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-04 19:27:43 +0000 |
commit | 1073598a0433e59683f43b9098c1d86110646a2b (patch) | |
tree | 89d99a1eaa4708550c67e64333f0909b7066f2a9 /device | |
parent | 95795dd9bf0371dff6e9ef737b2dcca107300dea (diff) | |
download | chromium_src-1073598a0433e59683f43b9098c1d86110646a2b.zip chromium_src-1073598a0433e59683f43b9098c1d86110646a2b.tar.gz chromium_src-1073598a0433e59683f43b9098c1d86110646a2b.tar.bz2 |
Implemented AdapterState.
I had to use polling to update the adapter since IOBluetoothHostController is not KVO compliant (i.e. we cannot put callbacks or notifiers to listen to the adapter state changes).
But fortunately we do not have to create a separate thread since all the Bluetooth System APIs in MACOSX are asynchronous.
BUG=135472
Review URL: https://chromiumcodereview.appspot.com/12379054
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185943 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device')
-rw-r--r-- | device/bluetooth/bluetooth_adapter_mac.h | 21 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_adapter_mac.mm | 83 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_adapter_mac_unittest.mm | 37 | ||||
-rw-r--r-- | device/device.gyp | 1 |
4 files changed, 139 insertions, 3 deletions
diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h index 25ba8df..30857c7 100644 --- a/device/bluetooth/bluetooth_adapter_mac.h +++ b/device/bluetooth/bluetooth_adapter_mac.h @@ -7,11 +7,21 @@ #include <string> +#include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "device/bluetooth/bluetooth_adapter.h" +namespace base { + +class SequencedTaskRunner; + +} // namespace base + namespace device { +class BluetoothAdapterMacTest; + class BluetoothAdapterMac : public BluetoothAdapter { public: // BluetoothAdapter override @@ -39,11 +49,22 @@ class BluetoothAdapterMac : public BluetoothAdapter { private: friend class BluetoothAdapterFactory; + friend class BluetoothAdapterMacTest; BluetoothAdapterMac(); virtual ~BluetoothAdapterMac(); void TrackDefaultAdapter(); + void TrackTestAdapter( + scoped_refptr<base::SequencedTaskRunner> ui_task_runner); + void PollAdapter(); + + bool powered_; + + scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; + + // List of observers interested in event notifications from us. + ObserverList<BluetoothAdapter::Observer> observers_; base::WeakPtrFactory<BluetoothAdapterMac> weak_ptr_factory_; diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm index 8b4091767..5d964cc 100644 --- a/device/bluetooth/bluetooth_adapter_mac.mm +++ b/device/bluetooth/bluetooth_adapter_mac.mm @@ -2,13 +2,43 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/compiler_specific.h" #include "device/bluetooth/bluetooth_adapter_mac.h" +#include <IOBluetooth/objc/IOBluetoothHostController.h> + +#include <string> + +#include "base/bind.h" +#include "base/compiler_specific.h" +#include "base/location.h" +#include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "base/time.h" +#include "base/strings/sys_string_conversions.h" + +// Replicate specific 10.7 SDK declarations for building with prior SDKs. +#if !defined(MAC_OS_X_VERSION_10_7) || \ +MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface IOBluetoothHostController (LionSDKDeclarations) +- (NSString *)nameAsString; +- (BluetoothHCIPowerState)powerState; +@end + +#endif // MAC_OS_X_VERSION_10_7 + +namespace { + +const int kPollIntervalMs = 500; + +} // namespace + namespace device { BluetoothAdapterMac::BluetoothAdapterMac() : BluetoothAdapter(), + powered_(false), ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { } @@ -16,9 +46,13 @@ BluetoothAdapterMac::~BluetoothAdapterMac() { } void BluetoothAdapterMac::AddObserver(BluetoothAdapter::Observer* observer) { + DCHECK(observer); + observers_.AddObserver(observer); } void BluetoothAdapterMac::RemoveObserver(BluetoothAdapter::Observer* observer) { + DCHECK(observer); + observers_.RemoveObserver(observer); } bool BluetoothAdapterMac::IsInitialized() const { @@ -26,11 +60,11 @@ bool BluetoothAdapterMac::IsInitialized() const { } bool BluetoothAdapterMac::IsPresent() const { - return false; + return !address_.empty(); } bool BluetoothAdapterMac::IsPowered() const { - return false; + return powered_; } void BluetoothAdapterMac::SetPowered(bool powered, @@ -61,6 +95,49 @@ void BluetoothAdapterMac::ReadLocalOutOfBandPairingData( } void BluetoothAdapterMac::TrackDefaultAdapter() { + ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); + PollAdapter(); +} + +void BluetoothAdapterMac::TrackTestAdapter( + scoped_refptr<base::SequencedTaskRunner> ui_task_runner) { + ui_task_runner_ = ui_task_runner; + PollAdapter(); +} + +void BluetoothAdapterMac::PollAdapter() { + bool was_present = IsPresent(); + std::string name = ""; + std::string address = ""; + bool powered = false; + IOBluetoothHostController* controller = + [IOBluetoothHostController defaultController]; + + if (controller != nil) { + name = base::SysNSStringToUTF8([controller nameAsString]); + address = base::SysNSStringToUTF8([controller addressAsString]); + powered = ([controller powerState] == kBluetoothHCIPowerStateON); + } + + bool is_present = !address.empty(); + name_ = name; + address_ = address; + + if (was_present != is_present) { + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + AdapterPresentChanged(this, is_present)); + } + if (powered_ != powered) { + powered_ = powered; + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + AdapterPoweredChanged(this, powered_)); + } + + ui_task_runner_->PostDelayedTask( + FROM_HERE, + base::Bind(&BluetoothAdapterMac::PollAdapter, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(kPollIntervalMs)); } } // namespace device diff --git a/device/bluetooth/bluetooth_adapter_mac_unittest.mm b/device/bluetooth/bluetooth_adapter_mac_unittest.mm new file mode 100644 index 0000000..9067820 --- /dev/null +++ b/device/bluetooth/bluetooth_adapter_mac_unittest.mm @@ -0,0 +1,37 @@ +// Copyright 2013 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 "base/memory/ref_counted.h" +#include "base/test/test_simple_task_runner.h" +#include "device/bluetooth/bluetooth_adapter_mac.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace device { + +class BluetoothAdapterMacTest : public testing::Test { + public: + BluetoothAdapterMacTest() + : ui_task_runner_(new base::TestSimpleTaskRunner()), + adapter_(new BluetoothAdapterMac()), + adapter_mac_(static_cast<BluetoothAdapterMac*>(adapter_.get())) { + adapter_mac_->TrackTestAdapter(ui_task_runner_); + } + + virtual void SetUp() OVERRIDE { + } + + virtual void TearDown() OVERRIDE { + } + + protected: + scoped_refptr<base::TestSimpleTaskRunner> ui_task_runner_; + scoped_refptr<BluetoothAdapter> adapter_; + BluetoothAdapterMac* adapter_mac_; +}; + +TEST_F(BluetoothAdapterMacTest, Poll) { + EXPECT_FALSE(ui_task_runner_->GetPendingTasks().empty()); +} + +} // namespace device diff --git a/device/device.gyp b/device/device.gyp index 14cd65a9..e5335f8 100644 --- a/device/device.gyp +++ b/device/device.gyp @@ -151,6 +151,7 @@ 'sources': [ 'bluetooth/bluetooth_adapter_chromeos_unittest.cc', 'bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc', + 'bluetooth/bluetooth_adapter_mac_unittest.mm', 'bluetooth/bluetooth_adapter_win_unittest.cc', 'bluetooth/bluetooth_device_win_unittest.cc', 'bluetooth/bluetooth_service_record_chromeos_unittest.cc', |