diff options
author | armansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 20:25:27 +0000 |
---|---|---|
committer | armansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 20:25:27 +0000 |
commit | f1a63b48b69d58583505aa6edab6b160c34c5bec (patch) | |
tree | f699921291d675e98395aa1fc0801db3d67ab5e3 /device | |
parent | f694ffab2a7d56bcf2a5996735eadbdba801537f (diff) | |
download | chromium_src-f1a63b48b69d58583505aa6edab6b160c34c5bec.zip chromium_src-f1a63b48b69d58583505aa6edab6b160c34c5bec.tar.gz chromium_src-f1a63b48b69d58583505aa6edab6b160c34c5bec.tar.bz2 |
device/bluetooth: Add BluetoothAdapter::DiscoverySession.
Added the new BluetoothAdapter::DiscoverySession class and
BluetoothAdapter::StartDiscoverySession. This CL implements this
API in a platform independent fashion and marks
BluetoothAdapter::StartDiscovering and BluetoothAdapter::StopDiscovering
as deprecated.
BUG=345008,344995
TEST=device_unittests
Review URL: https://codereview.chromium.org/180783004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254206 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device')
-rw-r--r-- | device/bluetooth/bluetooth.gyp | 2 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_adapter.cc | 37 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_adapter.h | 42 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_adapter_chromeos.cc | 13 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_adapter_chromeos.h | 12 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_chromeos_unittest.cc | 274 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_discovery_session.cc | 48 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_discovery_session.h | 87 |
8 files changed, 396 insertions, 119 deletions
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp index 1f13ef3..5693fdc 100644 --- a/device/bluetooth/bluetooth.gyp +++ b/device/bluetooth/bluetooth.gyp @@ -39,6 +39,8 @@ 'bluetooth_device_mac.mm', 'bluetooth_device_win.cc', 'bluetooth_device_win.h', + 'bluetooth_discovery_session.cc', + 'bluetooth_discovery_session.h', 'bluetooth_gatt_characteristic.cc', 'bluetooth_gatt_characteristic.h', 'bluetooth_gatt_descriptor.cc', diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc index 1462f49..ce63bdd 100644 --- a/device/bluetooth/bluetooth_adapter.cc +++ b/device/bluetooth/bluetooth_adapter.cc @@ -4,18 +4,31 @@ #include "device/bluetooth/bluetooth_adapter.h" +#include "base/bind.h" #include "base/stl_util.h" #include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/bluetooth_discovery_session.h" namespace device { -BluetoothAdapter::BluetoothAdapter() { +BluetoothAdapter::BluetoothAdapter() + : weak_ptr_factory_(this) { } BluetoothAdapter::~BluetoothAdapter() { STLDeleteValues(&devices_); } +void BluetoothAdapter::StartDiscoverySession( + const DiscoverySessionCallback& callback, + const ErrorCallback& error_callback) { + AddDiscoverySession( + base::Bind(&BluetoothAdapter::OnStartDiscoverySession, + weak_ptr_factory_.GetWeakPtr(), + callback), + error_callback); +} + void BluetoothAdapter::StartDiscovering(const base::Closure& callback, const ErrorCallback& error_callback) { AddDiscoverySession(callback, error_callback); @@ -96,4 +109,26 @@ BluetoothDevice::PairingDelegate* BluetoothAdapter::DefaultPairingDelegate() { return pairing_delegates_.front().first; } +void BluetoothAdapter::OnStartDiscoverySession( + const DiscoverySessionCallback& callback) { + VLOG(1) << "Discovery session started!"; + scoped_ptr<BluetoothDiscoverySession> discovery_session( + new BluetoothDiscoverySession(this)); + discovery_sessions_.insert(discovery_session.get()); + callback.Run(discovery_session.Pass()); +} + +void BluetoothAdapter::MarkDiscoverySessionsAsInactive() { + for (std::set<BluetoothDiscoverySession*>::iterator + iter = discovery_sessions_.begin(); + iter != discovery_sessions_.end(); ++iter) { + (*iter)->MarkAsInactive(); + } +} + +void BluetoothAdapter::DiscoverySessionDestroyed( + BluetoothDiscoverySession* discovery_session) { + discovery_sessions_.erase(discovery_session); +} + } // namespace device diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h index cec53e0..badcccd 100644 --- a/device/bluetooth/bluetooth_adapter.h +++ b/device/bluetooth/bluetooth_adapter.h @@ -7,15 +7,19 @@ #include <list> #include <map> +#include <set> #include <string> #include <utility> #include "base/callback.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "device/bluetooth/bluetooth_device.h" namespace device { +class BluetoothDiscoverySession; + struct BluetoothOutOfBandPairingData; // BluetoothAdapter represents a local Bluetooth adapter which may be used to @@ -76,7 +80,7 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { // The ErrorCallback is used for methods that can fail in which case it // is called, in the success case the callback is simply not called. - typedef base::Callback<void()> ErrorCallback; + typedef base::Closure ErrorCallback; // The BluetoothOutOfBandPairingDataCallback is used to return // BluetoothOutOfBandPairingData to the caller. @@ -135,6 +139,18 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { // Indicates whether the adapter is currently discovering new devices. virtual bool IsDiscovering() const = 0; + // Requests the adapter to start a new discovery session. On success, a new + // instance of BluetoothDiscoverySession will be returned to the caller via + // |callback| and the adapter will be discovering nearby Bluetooth devices. + // The returned BluetoothDiscoverySession is owned by the caller and it's the + // owner's responsibility to properly clean it up and stop the session when + // device discovery is no longer needed. + typedef base::Callback<void(scoped_ptr<BluetoothDiscoverySession>)> + DiscoverySessionCallback; + virtual void StartDiscoverySession(const DiscoverySessionCallback& callback, + const ErrorCallback& error_callback); + + // DEPRECATED: Use StartDiscoverySession instead. // Requests that the adapter begin discovering new devices, code must // always call this method if they require the adapter be in discovery // and should not make it conditional on the value of IsDiscovering() @@ -148,6 +164,7 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { virtual void StartDiscovering(const base::Closure& callback, const ErrorCallback& error_callback); + // DEPRECATED: Use BluetoothDiscoverySession::Stop instead. // Requests that an earlier call to StartDiscovering() be cancelled; the // adapter may not actually cease discovering devices if other callers // have called StartDiscovering() and not yet called this method. On @@ -204,6 +221,7 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { protected: friend class base::RefCounted<BluetoothAdapter>; + friend class BluetoothDiscoverySession; BluetoothAdapter(); virtual ~BluetoothAdapter(); @@ -248,6 +266,23 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { virtual void RemovePairingDelegateInternal( BluetoothDevice::PairingDelegate* pairing_delegate) = 0; + // Success callback passed to AddDiscoverySession by StartDiscoverySession. + void OnStartDiscoverySession(const DiscoverySessionCallback& callback); + + // Marks all known DiscoverySession instances as inactive. Called by + // BluetoothAdapter in the event that the adapter unexpectedly stops + // discovering. This should be called by all platform implementations. + void MarkDiscoverySessionsAsInactive(); + + // Removes |discovery_session| from |discovery_sessions_|, if its in there. + // Called by DiscoverySession when an instance is destroyed. + void DiscoverySessionDestroyed(BluetoothDiscoverySession* discovery_session); + + // List of all DiscoverySession objects. We keep raw pointers, with the + // assumption that a DiscoverySession will remove itself from this list when + // it gets destroyed. + std::set<BluetoothDiscoverySession*> discovery_sessions_; + // Devices paired with, connected to, discovered by, or visible to the // adapter. The key is the Bluetooth address of the device and the value // is the BluetoothDevice object whose lifetime is managed by the @@ -259,6 +294,11 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { typedef std::pair<BluetoothDevice::PairingDelegate*, PairingDelegatePriority> PairingDelegatePair; std::list<PairingDelegatePair> pairing_delegates_; + + private: + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAdapter> weak_ptr_factory_; }; } // namespace device diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc index f5a8ad7..50232f7 100644 --- a/device/bluetooth/bluetooth_adapter_chromeos.cc +++ b/device/bluetooth/bluetooth_adapter_chromeos.cc @@ -628,11 +628,7 @@ void BluetoothAdapterChromeOS::DiscoveringChanged( if (!discovering && !discovery_request_pending_ && num_discovery_sessions_ > 0) { num_discovery_sessions_ = 0; - // TODO(armansito): When we implement the DiscoverySession API, all - // active DiscoverySession instances need to be notified to update - // themselves. We want to do this before we notify the other observers - // so that any DiscoverySession objects that those observers might own - // have been marked as inactive. + MarkDiscoverySessionsAsInactive(); } FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, AdapterDiscoveringChanged(this, discovering)); @@ -732,11 +728,6 @@ void BluetoothAdapterChromeOS::RemoveDiscoverySession( if (discovery_request_pending_) { VLOG(1) << "Pending request to initiate device discovery. Queueing request " << "to stop discovery session."; - // TODO(armansito): We should never hit this case once we have the - // DiscoverySession API, as there would be no active DiscoverySession - // objects to allow calling this method while a call is pending to either - // return the first active or deactivate the last active DiscoverySession - // object in the first place. For now, report error. error_callback.Run(); return; } @@ -745,7 +736,7 @@ void BluetoothAdapterChromeOS::RemoveDiscoverySession( if (num_discovery_sessions_ == 0) { // TODO(armansito): This should never happen once we have the // DiscoverySession API. Replace this case with an assert once it's - // implemented. (See crbug.com/3445008). + // the deprecated methods have been removed. (See crbug.com/3445008). VLOG(1) << "No active discovery sessions. Returning error."; error_callback.Run(); return; diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h index c8b5ea6..fccf740 100644 --- a/device/bluetooth/bluetooth_adapter_chromeos.h +++ b/device/bluetooth/bluetooth_adapter_chromeos.h @@ -225,18 +225,6 @@ class BluetoothAdapterChromeOS // requested discovery, dropping our count to 0 won't necessarily result in // the controller actually stopping discovery if, for example, an application // other than Chrome, such as bt_console, was also used to start discovery. - // - // TODO(armansito): With the new API, it will not be possible to have requests - // to remove a discovery session while a call is pending. If the pending - // request is to start discovery, |num_discovery_sessions_| is 0. Since no - // active instance of DiscoverySession exists, clients can only make calls to - // request new sessions. Likewise, if the pending request is to stop - // discovery, |num_discovery_sessions_| is 1 and we're currently processing - // the request to stop the last active DiscoverySession. We should make sure - // that this invariant holds via asserts once we implement DiscoverySession - // and have fully removed the deprecated methods. For now, just return an - // error in the removal case to support the deprecated methods. (See - // crbug.com/3445008). DiscoveryCallbackQueue discovery_request_queue_; // Object path of the adapter we track. diff --git a/device/bluetooth/bluetooth_chromeos_unittest.cc b/device/bluetooth/bluetooth_chromeos_unittest.cc index 0d10dd0..4b51bbe 100644 --- a/device/bluetooth/bluetooth_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_chromeos_unittest.cc @@ -15,6 +15,7 @@ #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_device_chromeos.h" +#include "device/bluetooth/bluetooth_discovery_session.h" #include "device/bluetooth/bluetooth_pairing_chromeos.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -22,6 +23,7 @@ using device::BluetoothAdapter; using device::BluetoothAdapterFactory; using device::BluetoothDevice; +using device::BluetoothDiscoverySession; namespace chromeos { @@ -244,6 +246,17 @@ class BluetoothChromeOSTest : public testing::Test { } virtual void TearDown() { + if (last_discovery_session_.get() && last_discovery_session_->active()) { + callback_count_ = 0; + last_discovery_session_->Stop( + base::Bind(&BluetoothChromeOSTest::Callback, + base::Unretained(this)), + base::Bind(&BluetoothChromeOSTest::ErrorCallback, + base::Unretained(this))); + message_loop_.Run(); + ASSERT_EQ(1, callback_count_); + } + last_discovery_session_.reset(); adapter_ = NULL; DBusThreadManager::Shutdown(); } @@ -254,6 +267,13 @@ class BluetoothChromeOSTest : public testing::Test { QuitMessageLoop(); } + void DiscoverySessionCallback( + scoped_ptr<BluetoothDiscoverySession> discovery_session) { + ++callback_count_; + last_discovery_session_ = discovery_session.Pass(); + QuitMessageLoop(); + } + void ErrorCallback() { ++error_callback_count_; QuitMessageLoop(); @@ -285,13 +305,7 @@ class BluetoothChromeOSTest : public testing::Test { // without using this function. void DiscoverDevice(const std::string& address) { ASSERT_TRUE(adapter_.get() != NULL); - - if (base::MessageLoop::current() == NULL) { - base::MessageLoop message_loop; - DiscoverDevices(); - return; - } - + ASSERT_TRUE(base::MessageLoop::current() != NULL); fake_bluetooth_device_client_->SetSimulationIntervalMs(10); TestObserver observer(adapter_); @@ -343,6 +357,7 @@ class BluetoothChromeOSTest : public testing::Test { } protected: + base::MessageLoop message_loop_; FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_; FakeBluetoothDeviceClient* fake_bluetooth_device_client_; scoped_refptr<BluetoothAdapter> adapter_; @@ -351,6 +366,7 @@ class BluetoothChromeOSTest : public testing::Test { int error_callback_count_; enum BluetoothDevice::ConnectErrorCode last_connect_error_; std::string last_client_error_; + scoped_ptr<BluetoothDiscoverySession> last_discovery_session_; private: // Some tests use a message loop since background processing is simulated; @@ -616,8 +632,6 @@ TEST_F(BluetoothChromeOSTest, BecomeNotDiscoverable) { } TEST_F(BluetoothChromeOSTest, StopDiscovery) { - base::MessageLoop message_loop; - GetAdapter(); adapter_->SetPowered( @@ -631,7 +645,7 @@ TEST_F(BluetoothChromeOSTest, StopDiscovery) { base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(2, callback_count_); EXPECT_EQ(0, error_callback_count_); callback_count_ = 0; @@ -650,7 +664,7 @@ TEST_F(BluetoothChromeOSTest, StopDiscovery) { base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -661,8 +675,6 @@ TEST_F(BluetoothChromeOSTest, StopDiscovery) { } TEST_F(BluetoothChromeOSTest, StopDiscoveryAfterTwoStarts) { - base::MessageLoop message_loop; - GetAdapter(); adapter_->SetPowered( @@ -676,7 +688,7 @@ TEST_F(BluetoothChromeOSTest, StopDiscoveryAfterTwoStarts) { base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(2, callback_count_); EXPECT_EQ(0, error_callback_count_); callback_count_ = 0; @@ -694,7 +706,7 @@ TEST_F(BluetoothChromeOSTest, StopDiscoveryAfterTwoStarts) { base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); callback_count_ = 0; @@ -708,7 +720,7 @@ TEST_F(BluetoothChromeOSTest, StopDiscoveryAfterTwoStarts) { base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); callback_count_ = 0; @@ -725,7 +737,7 @@ TEST_F(BluetoothChromeOSTest, StopDiscoveryAfterTwoStarts) { base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -737,8 +749,6 @@ TEST_F(BluetoothChromeOSTest, StopDiscoveryAfterTwoStarts) { TEST_F(BluetoothChromeOSTest, Discovery) { // Test a simulated discovery session. - base::MessageLoop message_loop; - fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -756,7 +766,7 @@ TEST_F(BluetoothChromeOSTest, Discovery) { base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(2, callback_count_); EXPECT_EQ(0, error_callback_count_); callback_count_ = 0; @@ -765,19 +775,19 @@ TEST_F(BluetoothChromeOSTest, Discovery) { ASSERT_TRUE(adapter_->IsDiscovering()); // First device to appear should be an Apple Mouse. - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, observer.device_added_count_); EXPECT_EQ(FakeBluetoothDeviceClient::kAppleMouseAddress, observer.last_device_address_); // Next we should get another two devices... - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(3, observer.device_added_count_); // Okay, let's run forward until a device is actually removed... while (!observer.device_removed_count_) - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, observer.device_removed_count_); EXPECT_EQ(FakeBluetoothDeviceClient::kVanishingDeviceAddress, @@ -785,8 +795,6 @@ TEST_F(BluetoothChromeOSTest, Discovery) { } TEST_F(BluetoothChromeOSTest, PoweredAndDiscovering) { - base::MessageLoop message_loop; - GetAdapter(); adapter_->SetPowered( true, @@ -799,7 +807,7 @@ TEST_F(BluetoothChromeOSTest, PoweredAndDiscovering) { base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(2, callback_count_); EXPECT_EQ(0, error_callback_count_); callback_count_ = 0; @@ -859,7 +867,6 @@ TEST_F(BluetoothChromeOSTest, PoweredAndDiscovering) { // This unit test asserts that the basic reference counting logic works // correctly for discovery requests done via the BluetoothAdapter. TEST_F(BluetoothChromeOSTest, MultipleDiscoverySessions) { - base::MessageLoop message_loop; GetAdapter(); adapter_->SetPowered( true, @@ -888,7 +895,7 @@ TEST_F(BluetoothChromeOSTest, MultipleDiscoverySessions) { base::Unretained(this))); } // Run only once, as there should have been one D-Bus call. - message_loop.Run(); + message_loop_.Run(); // The observer should have received the discovering changed event exactly // once, the success callback should have been called 3 times and the adapter @@ -944,7 +951,7 @@ TEST_F(BluetoothChromeOSTest, MultipleDiscoverySessions) { base::Unretained(this))); } // Run only once, as there should have been one D-Bus call. - message_loop.Run(); + message_loop_.Run(); // The observer should have received the discovering changed event exactly // once, the success callback should have been called 4 times and the adapter @@ -975,7 +982,6 @@ TEST_F(BluetoothChromeOSTest, MultipleDiscoverySessions) { // the BluetoothAdapter. TEST_F(BluetoothChromeOSTest, UnexpectedChangesDuringMultipleDiscoverySessions) { - base::MessageLoop message_loop; GetAdapter(); adapter_->SetPowered( true, @@ -1004,7 +1010,7 @@ TEST_F(BluetoothChromeOSTest, base::Unretained(this))); } // Run only once, as there should have been one D-Bus call. - message_loop.Run(); + message_loop_.Run(); // The observer should have received the discovering changed event exactly // once, the success callback should have been called 3 times and the adapter @@ -1034,7 +1040,7 @@ TEST_F(BluetoothChromeOSTest, base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(2, observer.discovering_changed_count_); EXPECT_EQ(4, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1050,7 +1056,7 @@ TEST_F(BluetoothChromeOSTest, base::Unretained(this))); } // Run only once, as there should have been one D-Bus call. - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(3, observer.discovering_changed_count_); EXPECT_EQ(6, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1088,7 +1094,7 @@ TEST_F(BluetoothChromeOSTest, base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); // Run the loop, as there should have been a D-Bus call. + message_loop_.Run(); // Run the loop, as there should have been a D-Bus call. EXPECT_EQ(5, observer.discovering_changed_count_); EXPECT_EQ(7, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1100,7 +1106,7 @@ TEST_F(BluetoothChromeOSTest, base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); // Run the loop, as there should have been a D-Bus call. + message_loop_.Run(); // Run the loop, as there should have been a D-Bus call. EXPECT_EQ(5, observer.discovering_changed_count_); EXPECT_EQ(8, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1113,7 +1119,7 @@ TEST_F(BluetoothChromeOSTest, base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); // Run the loop, as there should have been a D-Bus call. + message_loop_.Run(); // Run the loop, as there should have been a D-Bus call. EXPECT_EQ(5, observer.discovering_changed_count_); EXPECT_EQ(9, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1129,7 +1135,7 @@ TEST_F(BluetoothChromeOSTest, base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(5, observer.discovering_changed_count_); EXPECT_EQ(10, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1143,7 +1149,7 @@ TEST_F(BluetoothChromeOSTest, base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(6, observer.discovering_changed_count_); EXPECT_EQ(11, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1152,7 +1158,6 @@ TEST_F(BluetoothChromeOSTest, } TEST_F(BluetoothChromeOSTest, QueuedDiscoveryRequests) { - base::MessageLoop message_loop; GetAdapter(); adapter_->SetPowered( @@ -1219,7 +1224,7 @@ TEST_F(BluetoothChromeOSTest, QueuedDiscoveryRequests) { // Process the pending call. The queued calls should execute and the discovery // session reference count should increase. - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(3, callback_count_); EXPECT_EQ(1, error_callback_count_); EXPECT_EQ(1, observer.discovering_changed_count_); @@ -1266,7 +1271,7 @@ TEST_F(BluetoothChromeOSTest, QueuedDiscoveryRequests) { EXPECT_FALSE(adapter_->IsDiscovering()); // Run the pending request. - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(6, callback_count_); EXPECT_EQ(2, error_callback_count_); EXPECT_EQ(3, observer.discovering_changed_count_); @@ -1275,7 +1280,7 @@ TEST_F(BluetoothChromeOSTest, QueuedDiscoveryRequests) { // The queued request to start discovery should have been issued but is still // pending. Run the loop and verify. - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(7, callback_count_); EXPECT_EQ(2, error_callback_count_); EXPECT_EQ(3, observer.discovering_changed_count_); @@ -1283,6 +1288,113 @@ TEST_F(BluetoothChromeOSTest, QueuedDiscoveryRequests) { EXPECT_TRUE(adapter_->IsDiscovering()); } +TEST_F(BluetoothChromeOSTest, StartDiscoverySession) { + GetAdapter(); + + adapter_->SetPowered( + true, + base::Bind(&BluetoothChromeOSTest::Callback, + base::Unretained(this)), + base::Bind(&BluetoothChromeOSTest::ErrorCallback, + base::Unretained(this))); + EXPECT_EQ(1, callback_count_); + EXPECT_EQ(0, error_callback_count_); + EXPECT_TRUE(adapter_->IsPowered()); + callback_count_ = 0; + + TestObserver observer(adapter_); + adapter_->AddObserver(&observer); + + EXPECT_EQ(0, observer.discovering_changed_count_); + EXPECT_FALSE(observer.last_discovering_); + EXPECT_FALSE(adapter_->IsDiscovering()); + EXPECT_FALSE(last_discovery_session_.get()); + + // Request a new discovery session. + adapter_->StartDiscoverySession( + base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback, + base::Unretained(this)), + base::Bind(&BluetoothChromeOSTest::ErrorCallback, + base::Unretained(this))); + message_loop_.Run(); + EXPECT_EQ(1, observer.discovering_changed_count_); + EXPECT_EQ(1, callback_count_); + EXPECT_EQ(0, error_callback_count_); + EXPECT_TRUE(observer.last_discovering_); + EXPECT_TRUE(adapter_->IsDiscovering()); + EXPECT_TRUE(last_discovery_session_.get()); + EXPECT_TRUE(last_discovery_session_->active()); + + // Start another session. A new one should be returned in the callback, which + // in turn will destroy the previous session. Adapter should still be + // discovering and the reference count should be 1. + adapter_->StartDiscoverySession( + base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback, + base::Unretained(this)), + base::Bind(&BluetoothChromeOSTest::ErrorCallback, + base::Unretained(this))); + message_loop_.Run(); + EXPECT_EQ(1, observer.discovering_changed_count_); + EXPECT_EQ(2, callback_count_); + EXPECT_EQ(0, error_callback_count_); + EXPECT_TRUE(observer.last_discovering_); + EXPECT_TRUE(adapter_->IsDiscovering()); + EXPECT_TRUE(last_discovery_session_.get()); + EXPECT_TRUE(last_discovery_session_->active()); + + // Hold on to the current discovery session to prevent it from getting + // destroyed during the next call to StartDiscoverySession. + scoped_ptr<BluetoothDiscoverySession> discovery_session = + last_discovery_session_.Pass(); + + // Request a new session. + adapter_->StartDiscoverySession( + base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback, + base::Unretained(this)), + base::Bind(&BluetoothChromeOSTest::ErrorCallback, + base::Unretained(this))); + message_loop_.Run(); + EXPECT_EQ(1, observer.discovering_changed_count_); + EXPECT_EQ(3, callback_count_); + EXPECT_EQ(0, error_callback_count_); + EXPECT_TRUE(observer.last_discovering_); + EXPECT_TRUE(adapter_->IsDiscovering()); + EXPECT_TRUE(last_discovery_session_.get()); + EXPECT_TRUE(last_discovery_session_->active()); + EXPECT_NE(last_discovery_session_.get(), discovery_session); + + // Stop the previous discovery session. The session should end but discovery + // should continue. + discovery_session->Stop( + base::Bind(&BluetoothChromeOSTest::Callback, + base::Unretained(this)), + base::Bind(&BluetoothChromeOSTest::ErrorCallback, + base::Unretained(this))); + message_loop_.Run(); + EXPECT_EQ(1, observer.discovering_changed_count_); + EXPECT_EQ(4, callback_count_); + EXPECT_EQ(0, error_callback_count_); + EXPECT_TRUE(observer.last_discovering_); + EXPECT_TRUE(adapter_->IsDiscovering()); + EXPECT_TRUE(last_discovery_session_.get()); + EXPECT_TRUE(last_discovery_session_->active()); + EXPECT_FALSE(discovery_session->active()); + + // Delete the current active session. Discovery should eventually stop. + last_discovery_session_.reset(); + while (observer.last_discovering_) { + message_loop_.RunUntilIdle(); + } + EXPECT_EQ(2, observer.discovering_changed_count_); + EXPECT_EQ(4, callback_count_); + EXPECT_EQ(0, error_callback_count_); + EXPECT_FALSE(observer.last_discovering_); + EXPECT_FALSE(adapter_->IsDiscovering()); + EXPECT_FALSE(last_discovery_session_.get()); + + adapter_->RemoveObserver(&observer); +} + TEST_F(BluetoothChromeOSTest, DeviceProperties) { GetAdapter(); @@ -1712,7 +1824,6 @@ TEST_F(BluetoothChromeOSTest, DisconnectUnconnectedDevice) { } TEST_F(BluetoothChromeOSTest, PairAppleMouse) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -1739,7 +1850,7 @@ TEST_F(BluetoothChromeOSTest, PairAppleMouse) { EXPECT_EQ(0, pairing_delegate.call_count_); EXPECT_TRUE(device->IsConnecting()); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1769,7 +1880,6 @@ TEST_F(BluetoothChromeOSTest, PairAppleMouse) { } TEST_F(BluetoothChromeOSTest, PairAppleKeyboard) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -1798,7 +1908,7 @@ TEST_F(BluetoothChromeOSTest, PairAppleKeyboard) { EXPECT_EQ("123456", pairing_delegate.last_pincode_); EXPECT_TRUE(device->IsConnecting()); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1828,7 +1938,6 @@ TEST_F(BluetoothChromeOSTest, PairAppleKeyboard) { } TEST_F(BluetoothChromeOSTest, PairMotorolaKeyboard) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -1863,14 +1972,14 @@ TEST_F(BluetoothChromeOSTest, PairMotorolaKeyboard) { // One call to KeysEntered() for each key, including [enter]. for(int i = 1; i <= 7; ++i) { - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(2 + i, pairing_delegate.call_count_); EXPECT_EQ(1 + i, pairing_delegate.keys_entered_count_); EXPECT_EQ(static_cast<uint32_t>(i), pairing_delegate.last_entered_); } - message_loop.Run(); + message_loop_.Run(); // 8 KeysEntered notifications (0 to 7, inclusive) and one aditional call for // DisplayPasskey(). @@ -1908,7 +2017,6 @@ TEST_F(BluetoothChromeOSTest, PairMotorolaKeyboard) { } TEST_F(BluetoothChromeOSTest, PairSonyHeadphones) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -1937,7 +2045,7 @@ TEST_F(BluetoothChromeOSTest, PairSonyHeadphones) { // Set the PIN. device->SetPinCode("1234"); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -1967,7 +2075,6 @@ TEST_F(BluetoothChromeOSTest, PairSonyHeadphones) { } TEST_F(BluetoothChromeOSTest, PairPhone) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -1997,7 +2104,7 @@ TEST_F(BluetoothChromeOSTest, PairPhone) { // Confirm the passkey. device->ConfirmPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -2023,7 +2130,6 @@ TEST_F(BluetoothChromeOSTest, PairPhone) { } TEST_F(BluetoothChromeOSTest, PairWeirdDevice) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2054,7 +2160,7 @@ TEST_F(BluetoothChromeOSTest, PairWeirdDevice) { // Set the Passkey. device->SetPasskey(1234); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -2080,7 +2186,6 @@ TEST_F(BluetoothChromeOSTest, PairWeirdDevice) { } TEST_F(BluetoothChromeOSTest, PairBoseSpeakers) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2106,7 +2211,7 @@ TEST_F(BluetoothChromeOSTest, PairBoseSpeakers) { EXPECT_EQ(0, pairing_delegate.call_count_); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -2132,7 +2237,6 @@ TEST_F(BluetoothChromeOSTest, PairBoseSpeakers) { } TEST_F(BluetoothChromeOSTest, PairUnpairableDeviceFails) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2158,7 +2262,7 @@ TEST_F(BluetoothChromeOSTest, PairUnpairableDeviceFails) { EXPECT_TRUE(device->IsConnecting()); // Run the loop to get the error.. - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2171,7 +2275,6 @@ TEST_F(BluetoothChromeOSTest, PairUnpairableDeviceFails) { } TEST_F(BluetoothChromeOSTest, PairingFails) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2198,7 +2301,7 @@ TEST_F(BluetoothChromeOSTest, PairingFails) { EXPECT_TRUE(device->IsConnecting()); // Run the loop to get the error.. - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2211,7 +2314,6 @@ TEST_F(BluetoothChromeOSTest, PairingFails) { } TEST_F(BluetoothChromeOSTest, PairingFailsAtConnection) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2238,7 +2340,7 @@ TEST_F(BluetoothChromeOSTest, PairingFailsAtConnection) { EXPECT_EQ(0, pairing_delegate.call_count_); EXPECT_TRUE(device->IsConnecting()); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2264,7 +2366,6 @@ TEST_F(BluetoothChromeOSTest, PairingFailsAtConnection) { } TEST_F(BluetoothChromeOSTest, PairingRejectedAtPinCode) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2293,7 +2394,7 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtPinCode) { // Reject the pairing. device->RejectPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2307,7 +2408,6 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtPinCode) { } TEST_F(BluetoothChromeOSTest, PairingCancelledAtPinCode) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2336,7 +2436,7 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtPinCode) { // Cancel the pairing. device->CancelPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2350,7 +2450,6 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtPinCode) { } TEST_F(BluetoothChromeOSTest, PairingRejectedAtPasskey) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2379,7 +2478,7 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtPasskey) { // Reject the pairing. device->RejectPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2393,7 +2492,6 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtPasskey) { } TEST_F(BluetoothChromeOSTest, PairingCancelledAtPasskey) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2422,7 +2520,7 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtPasskey) { // Cancel the pairing. device->CancelPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2436,7 +2534,6 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtPasskey) { } TEST_F(BluetoothChromeOSTest, PairingRejectedAtConfirmation) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2465,7 +2562,7 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtConfirmation) { // Reject the pairing. device->RejectPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2479,7 +2576,6 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtConfirmation) { } TEST_F(BluetoothChromeOSTest, PairingCancelledAtConfirmation) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2508,7 +2604,7 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtConfirmation) { // Cancel the pairing. device->CancelPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2522,7 +2618,6 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtConfirmation) { } TEST_F(BluetoothChromeOSTest, PairingCancelledInFlight) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2550,7 +2645,7 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledInFlight) { // Cancel the pairing. device->CancelPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2564,7 +2659,6 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledInFlight) { } TEST_F(BluetoothChromeOSTest, IncomingPairSonyHeadphones) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2599,7 +2693,7 @@ TEST_F(BluetoothChromeOSTest, IncomingPairSonyHeadphones) { // Set the PIN. device->SetPinCode("1234"); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -2617,7 +2711,6 @@ TEST_F(BluetoothChromeOSTest, IncomingPairSonyHeadphones) { } TEST_F(BluetoothChromeOSTest, IncomingPairPhone) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2653,7 +2746,7 @@ TEST_F(BluetoothChromeOSTest, IncomingPairPhone) { // Confirm the passkey. device->ConfirmPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -2671,7 +2764,6 @@ TEST_F(BluetoothChromeOSTest, IncomingPairPhone) { } TEST_F(BluetoothChromeOSTest, IncomingPairWeirdDevice) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2706,7 +2798,7 @@ TEST_F(BluetoothChromeOSTest, IncomingPairWeirdDevice) { // Set the Passkey. device->SetPasskey(1234); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -2724,7 +2816,6 @@ TEST_F(BluetoothChromeOSTest, IncomingPairWeirdDevice) { } TEST_F(BluetoothChromeOSTest, IncomingPairBoseSpeakers) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2760,7 +2851,7 @@ TEST_F(BluetoothChromeOSTest, IncomingPairBoseSpeakers) { // Confirm the pairing. device->ConfirmPairing(); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(1, callback_count_); EXPECT_EQ(0, error_callback_count_); @@ -2778,7 +2869,6 @@ TEST_F(BluetoothChromeOSTest, IncomingPairBoseSpeakers) { } TEST_F(BluetoothChromeOSTest, IncomingPairSonyHeadphonesWithoutDelegate) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2804,7 +2894,7 @@ TEST_F(BluetoothChromeOSTest, IncomingPairSonyHeadphonesWithoutDelegate) { base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2822,7 +2912,6 @@ TEST_F(BluetoothChromeOSTest, IncomingPairSonyHeadphonesWithoutDelegate) { } TEST_F(BluetoothChromeOSTest, IncomingPairPhoneWithoutDelegate) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2848,7 +2937,7 @@ TEST_F(BluetoothChromeOSTest, IncomingPairPhoneWithoutDelegate) { base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2866,7 +2955,6 @@ TEST_F(BluetoothChromeOSTest, IncomingPairPhoneWithoutDelegate) { } TEST_F(BluetoothChromeOSTest, IncomingPairWeirdDeviceWithoutDelegate) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2892,7 +2980,7 @@ TEST_F(BluetoothChromeOSTest, IncomingPairWeirdDeviceWithoutDelegate) { base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2910,7 +2998,6 @@ TEST_F(BluetoothChromeOSTest, IncomingPairWeirdDeviceWithoutDelegate) { } TEST_F(BluetoothChromeOSTest, IncomingPairBoseSpeakersWithoutDelegate) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); @@ -2936,7 +3023,7 @@ TEST_F(BluetoothChromeOSTest, IncomingPairBoseSpeakersWithoutDelegate) { base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, base::Unretained(this))); - message_loop.Run(); + message_loop_.Run(); EXPECT_EQ(0, callback_count_); EXPECT_EQ(1, error_callback_count_); @@ -2954,7 +3041,6 @@ TEST_F(BluetoothChromeOSTest, IncomingPairBoseSpeakersWithoutDelegate) { } TEST_F(BluetoothChromeOSTest, RemovePairingDelegateDuringPairing) { - base::MessageLoop message_loop; fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); diff --git a/device/bluetooth/bluetooth_discovery_session.cc b/device/bluetooth/bluetooth_discovery_session.cc new file mode 100644 index 0000000..afeacff --- /dev/null +++ b/device/bluetooth/bluetooth_discovery_session.cc @@ -0,0 +1,48 @@ +// Copyright 2014 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 "device/bluetooth/bluetooth_discovery_session.h" + +#include "base/bind.h" +#include "device/bluetooth/bluetooth_adapter.h" + +namespace device { + +BluetoothDiscoverySession::BluetoothDiscoverySession(BluetoothAdapter* adapter) + : active_(true), + adapter_(adapter), + weak_ptr_factory_(this) { +} + +BluetoothDiscoverySession::~BluetoothDiscoverySession() { + Stop(base::Bind(&base::DoNothing), base::Bind(&base::DoNothing)); + adapter_->DiscoverySessionDestroyed(this); +} + +void BluetoothDiscoverySession::Stop( + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (!active_) { + LOG(ERROR) << "Discovery session not active. Cannot stop."; + error_callback.Run(); + return; + } + VLOG(1) << "Stopping device discovery session."; + adapter_->RemoveDiscoverySession( + base::Bind(&BluetoothDiscoverySession::OnStop, + weak_ptr_factory_.GetWeakPtr(), + callback), + error_callback); +} + +void BluetoothDiscoverySession::OnStop(const base::Closure& callback) { + active_ = false; + callback.Run(); +} + +void BluetoothDiscoverySession::MarkAsInactive() { + active_ = false; +} + +} // namespace device diff --git a/device/bluetooth/bluetooth_discovery_session.h b/device/bluetooth/bluetooth_discovery_session.h new file mode 100644 index 0000000..72bdb30 --- /dev/null +++ b/device/bluetooth/bluetooth_discovery_session.h @@ -0,0 +1,87 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_BLUETOOTH_DISCOVERY_SESSION_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_DISCOVERY_SESSION_H_ + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" + +namespace device { + +class BluetoothAdapter; + +// BluetoothDiscoverySession represents a current active or inactive device +// discovery session. Instances of this class are obtained by calling +// BluetoothAdapter::StartDiscoverySession. The Bluetooth adapter will be +// constantly searching for nearby devices, as long as at least one instance +// of an active BluetoothDiscoverySession exists. A BluetoothDiscoverySession is +// considered active, as long as the adapter is discovering AND the owner of the +// instance has not called BluetoothDiscoverySession::Stop. A +// BluetoothDiscoverySession might unexpectedly become inactive, if the adapter +// unexpectedly stops discovery. Users can implement the +// AdapterDiscoveringChanged method of the BluetoothAdapter::Observer interface +// to be notified of such a change and promptly request a new +// BluetoothDiscoverySession if their existing sessions have become inactive. +class BluetoothDiscoverySession { + public: + // The ErrorCallback is used by methods to asynchronously report errors. + typedef base::Closure ErrorCallback; + + // Destructor automatically terminates the discovery session. If this + // results in a call to the underlying system to stop device discovery + // (i.e. this instance represents the last active discovery session), + // the call may not always succeed. To be notified of such failures, + // users are highly encouraged to call BluetoothDiscoverySession::Stop, + // instead of relying on the destructor. + ~BluetoothDiscoverySession(); + + // Returns true if the session is active, false otherwise. If false, the + // adapter might still be discovering as there might still be other active + // sessions; this just means that this instance no longer has a say in + // whether or not discovery should continue. In this case, the application + // should request a new BluetoothDiscoverySession to make sure that device + // discovery continues. + bool active() const { return active_; } + + // Requests this discovery session instance to stop. If this instance is + // active, the session will stop. On success, |callback| is called and + // on error |error_callback| is called. After a successful invocation, the + // adapter may or may not stop device discovery, depending on whether or not + // other active discovery sessions are present. Users are highly encouraged + // to call this method to end a discovery session, instead of relying on the + // destructor, so that they can be notified of the result via the callback + // arguments. + void Stop(const base::Closure& callback, + const ErrorCallback& error_callback); + + private: + friend class BluetoothAdapter; + explicit BluetoothDiscoverySession(BluetoothAdapter* adapter); + + // Internal callback invoked when a call to Stop has succeeded. + void OnStop(const base::Closure& callback); + + // Marks this instance as inactive. Called by BluetoothAdapter to mark a + // session as inactive in the case of an unexpected change to the adapter + // discovery state. + void MarkAsInactive(); + + // Whether or not this instance represents an active discovery session. + bool active_; + + // The adapter that created this instance. + scoped_refptr<BluetoothAdapter> adapter_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothDiscoverySession> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoverySession); +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_DISCOVERY_SESSION_H_ |