Index: device/bluetooth/bluetooth_experimental_chromeos_unittest.cc |
diff --git a/device/bluetooth/bluetooth_experimental_chromeos_unittest.cc b/device/bluetooth/bluetooth_experimental_chromeos_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6e5122cdcff19877f2e28616d3f4b005f9f74fb2 |
--- /dev/null |
+++ b/device/bluetooth/bluetooth_experimental_chromeos_unittest.cc |
@@ -0,0 +1,1887 @@ |
+// Copyright (c) 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/command_line.h" |
+#include "base/message_loop.h" |
+#include "base/utf_string_conversions.h" |
+#include "chromeos/chromeos_switches.h" |
+#include "chromeos/dbus/fake_bluetooth_adapter_client.h" |
+#include "chromeos/dbus/fake_bluetooth_device_client.h" |
+#include "chromeos/dbus/mock_dbus_thread_manager_without_gmock.h" |
+#include "dbus/object_path.h" |
+#include "device/bluetooth/bluetooth_adapter.h" |
+#include "device/bluetooth/bluetooth_adapter_experimental_chromeos.h" |
+#include "device/bluetooth/bluetooth_adapter_factory.h" |
+#include "device/bluetooth/bluetooth_device.h" |
+#include "device/bluetooth/bluetooth_device_experimental_chromeos.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using device::BluetoothAdapter; |
+using device::BluetoothAdapterFactory; |
+using device::BluetoothDevice; |
+ |
+namespace chromeos { |
+ |
+class TestObserver : public BluetoothAdapter::Observer { |
+ public: |
+ TestObserver(scoped_refptr<BluetoothAdapter> adapter) |
+ : present_changed_count_(0), |
+ powered_changed_count_(0), |
+ discovering_changed_count_(0), |
+ last_present_(false), |
+ last_powered_(false), |
+ last_discovering_(false), |
+ device_added_count_(0), |
+ device_changed_count_(0), |
+ device_removed_count_(0), |
+ last_device_(NULL), |
+ adapter_(adapter) { |
+ } |
+ virtual ~TestObserver() {} |
+ |
+ virtual void AdapterPresentChanged(BluetoothAdapter* adapter, |
+ bool present) OVERRIDE { |
+ EXPECT_EQ(adapter_, adapter); |
+ |
+ ++present_changed_count_; |
+ last_present_ = present; |
+ } |
+ |
+ virtual void AdapterPoweredChanged(BluetoothAdapter* adapter, |
+ bool powered) OVERRIDE { |
+ EXPECT_EQ(adapter_, adapter); |
+ |
+ ++powered_changed_count_; |
+ last_powered_ = powered; |
+ } |
+ |
+ virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter, |
+ bool discovering) OVERRIDE { |
+ EXPECT_EQ(adapter_, adapter); |
+ |
+ ++discovering_changed_count_; |
+ last_discovering_ = discovering; |
+ |
+ QuitMessageLoop(); |
youngki
2013/04/17 16:23:45
Why does AdapterDiscoveringChanged break out of lo
keybuk
2013/04/17 17:46:31
mistake: deleted
|
+ } |
+ |
+ virtual void DeviceAdded(BluetoothAdapter* adapter, |
+ BluetoothDevice* device) OVERRIDE { |
+ EXPECT_EQ(adapter_, adapter); |
+ |
+ ++device_added_count_; |
+ last_device_ = device; |
+ last_device_address_ = device->GetAddress(); |
+ |
+ QuitMessageLoop(); |
+ } |
+ |
+ virtual void DeviceChanged(BluetoothAdapter* adapter, |
+ BluetoothDevice* device) OVERRIDE { |
+ EXPECT_EQ(adapter_, adapter); |
+ |
+ ++device_changed_count_; |
+ last_device_ = device; |
+ last_device_address_ = device->GetAddress(); |
+ |
+ QuitMessageLoop(); |
+ } |
+ |
+ virtual void DeviceRemoved(BluetoothAdapter* adapter, |
+ BluetoothDevice* device) OVERRIDE { |
+ EXPECT_EQ(adapter_, adapter); |
+ |
+ ++device_removed_count_; |
+ // Can't save device, it may be freed |
+ last_device_address_ = device->GetAddress(); |
+ |
+ QuitMessageLoop(); |
+ } |
+ |
+ int present_changed_count_; |
+ int powered_changed_count_; |
+ int discovering_changed_count_; |
+ bool last_present_; |
+ bool last_powered_; |
+ bool last_discovering_; |
+ int device_added_count_; |
+ int device_changed_count_; |
+ int device_removed_count_; |
+ BluetoothDevice* last_device_; |
+ std::string last_device_address_; |
+ |
+ private: |
+ // Some tests use a message loop since background processing is simulated; |
+ // break out of those loops. |
+ void QuitMessageLoop() { |
+ if (MessageLoop::current() && MessageLoop::current()->is_running()) |
+ MessageLoop::current()->Quit(); |
+ } |
+ |
+ scoped_refptr<BluetoothAdapter> adapter_; |
+}; |
+ |
+class TestPairingDelegate : public BluetoothDevice::PairingDelegate { |
+ public: |
+ TestPairingDelegate() |
+ : call_count_(0), |
+ request_pincode_count_(0), |
+ request_passkey_count_(0), |
+ display_pincode_count_(0), |
+ display_passkey_count_(0), |
+ confirm_passkey_count_(0), |
+ dismiss_count_(0) {} |
+ virtual ~TestPairingDelegate() {} |
+ |
+ void RequestPinCode(BluetoothDevice* device) OVERRIDE { |
+ ++call_count_; |
+ ++request_pincode_count_; |
+ QuitMessageLoop(); |
+ } |
+ |
+ void RequestPasskey(BluetoothDevice* device) OVERRIDE { |
+ ++call_count_; |
+ ++request_passkey_count_; |
+ QuitMessageLoop(); |
+ } |
+ |
+ void DisplayPinCode(BluetoothDevice* device, |
+ const std::string& pincode) OVERRIDE { |
+ ++call_count_; |
+ ++display_pincode_count_; |
+ last_pincode_ = pincode; |
+ QuitMessageLoop(); |
+ } |
+ |
+ void DisplayPasskey(BluetoothDevice* device, |
+ uint32 passkey) OVERRIDE { |
+ ++call_count_; |
+ ++display_passkey_count_; |
+ last_passkey_ = passkey; |
+ QuitMessageLoop(); |
+ } |
+ |
+ void ConfirmPasskey(BluetoothDevice* device, |
+ uint32 passkey) OVERRIDE { |
+ ++call_count_; |
+ ++confirm_passkey_count_; |
+ last_passkey_ = passkey; |
+ QuitMessageLoop(); |
+ } |
+ |
+ void DismissDisplayOrConfirm() OVERRIDE { |
+ ++call_count_; |
+ ++dismiss_count_; |
+ QuitMessageLoop(); |
+ } |
+ |
+ int call_count_; |
+ int request_pincode_count_; |
+ int request_passkey_count_; |
+ int display_pincode_count_; |
+ int display_passkey_count_; |
+ int confirm_passkey_count_; |
+ int dismiss_count_; |
+ uint32 last_passkey_; |
+ std::string last_pincode_; |
+ |
+ private: |
+ // Some tests use a message loop since background processing is simulated; |
+ // break out of those loops. |
+ void QuitMessageLoop() { |
+ if (MessageLoop::current() && MessageLoop::current()->is_running()) |
+ MessageLoop::current()->Quit(); |
+ } |
+}; |
+ |
+class BluetoothExperimentalChromeOSTest : public testing::Test { |
+ public: |
+ virtual void SetUp() { |
+ if (!CommandLine::ForCurrentProcess()->HasSwitch( |
+ chromeos::switches::kEnableExperimentalBluetooth)) |
+ CommandLine::ForCurrentProcess()->AppendSwitch( |
+ chromeos::switches::kEnableExperimentalBluetooth); |
+ |
+ mock_dbus_thread_manager_ = |
+ new MockDBusThreadManagerWithoutGMock(); |
+ DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager_); |
+ |
+ fake_bluetooth_adapter_client_ = |
+ mock_dbus_thread_manager_->fake_bluetooth_adapter_client(); |
+ fake_bluetooth_device_client_ = |
+ mock_dbus_thread_manager_->fake_bluetooth_device_client(); |
+ |
+ callback_count_ = 0; |
+ error_callback_count_ = 0; |
+ last_connect_error_ = BluetoothDevice::ERROR_UNKNOWN; |
+ } |
+ |
+ virtual void TearDown() { |
+ adapter_ = NULL; |
+ DBusThreadManager::Shutdown(); |
+ } |
+ |
+ // Generic callbacks |
+ void Callback() { |
+ ++callback_count_; |
+ } |
+ |
+ void ErrorCallback() { |
+ ++error_callback_count_; |
+ } |
+ |
+ void ConnectErrorCallback(enum BluetoothDevice::ConnectErrorCode error) { |
+ ++error_callback_count_; |
+ last_connect_error_ = error; |
+ } |
+ |
+ // Call to fill the adapter_ member with a BluetoothAdapter instance. |
+ void GetAdapter() { |
+ BluetoothAdapterFactory::GetAdapter( |
youngki
2013/04/17 16:23:45
Why don't you just create adapter directly by new
keybuk
2013/04/17 17:46:31
Done.
|
+ base::Bind(&BluetoothExperimentalChromeOSTest::SetAdapter, |
+ base::Unretained(this))); |
+ ASSERT_TRUE(adapter_ != NULL); |
+ ASSERT_TRUE(adapter_->IsInitialized()); |
+ } |
+ |
+ void SetAdapter(scoped_refptr<BluetoothAdapter> adapter) { |
+ adapter_ = adapter; |
+ } |
+ |
+ // Run a discovery phase until the named device is detected. |
+ void DiscoverDevice(const std::string& address) { |
+ ASSERT_TRUE(adapter_ != NULL); |
youngki
2013/04/17 16:23:45
Can we take out all the ASSERT* and EXPECT* and pu
keybuk
2013/04/17 17:46:31
There already is a separate testing case for these
|
+ |
+ if (MessageLoop::current() == NULL) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ DiscoverDevices(); |
+ return; |
+ } |
+ |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ adapter_->SetPowered( |
+ true, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ adapter_->StartDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(2, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ ASSERT_TRUE(adapter_->IsPowered()); |
+ ASSERT_TRUE(adapter_->IsDiscovering()); |
+ |
+ while (!observer.device_removed_count_ && |
+ observer.last_device_address_ != address) |
+ MessageLoop::current()->Run(); |
+ |
+ adapter_->StopDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ ASSERT_FALSE(adapter_->IsDiscovering()); |
+ |
+ adapter_->RemoveObserver(&observer); |
+ } |
+ |
+ // Run a discovery phase so we have devices that can be paired with. |
+ void DiscoverDevices() { |
+ DiscoverDevice("does not exist"); |
youngki
2013/04/17 16:23:45
why do we pass "does not exist"? And how does this
keybuk
2013/04/17 17:46:31
will add comment
|
+ } |
+ |
+ protected: |
+ FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_; |
+ FakeBluetoothDeviceClient* fake_bluetooth_device_client_; |
+ MockDBusThreadManagerWithoutGMock* mock_dbus_thread_manager_; |
+ scoped_refptr<BluetoothAdapter> adapter_; |
+ |
+ int callback_count_; |
+ int error_callback_count_; |
+ enum BluetoothDevice::ConnectErrorCode last_connect_error_; |
+}; |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, AlreadyPresent) { |
+ GetAdapter(); |
+ |
+ // This verifies that the class gets the list of adapters when created; |
+ // and initializes with an existing adapter if there is one. |
+ EXPECT_TRUE(adapter_->IsPresent()); |
+ EXPECT_FALSE(adapter_->IsPowered()); |
+ EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress, |
+ adapter_->GetAddress()); |
+ EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterName, adapter_->GetName()); |
+ EXPECT_FALSE(adapter_->IsDiscovering()); |
+ |
+ // There should be a device |
+ BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
+ EXPECT_EQ(1U, devices.size()); |
+ EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ devices[0]->GetAddress()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, BecomePresent) { |
+ fake_bluetooth_adapter_client_->SetVisible(false); |
+ GetAdapter(); |
+ ASSERT_FALSE(adapter_->IsPresent()); |
+ |
+ // Install an observer; expect the AdapterPresentChanged to be called |
+ // with true, and IsPresent() to return true. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ fake_bluetooth_adapter_client_->SetVisible(true); |
+ |
+ EXPECT_EQ(1, observer.present_changed_count_); |
+ EXPECT_TRUE(observer.last_present_); |
+ |
+ EXPECT_TRUE(adapter_->IsPresent()); |
+ |
+ // We should have had a device announced. |
+ EXPECT_EQ(1, observer.device_added_count_); |
+ EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ observer.last_device_address_); |
+ |
+ // Other callbacks shouldn't be called if the values are false. |
+ EXPECT_EQ(0, observer.powered_changed_count_); |
+ EXPECT_EQ(0, observer.discovering_changed_count_); |
+ EXPECT_FALSE(adapter_->IsPowered()); |
+ EXPECT_FALSE(adapter_->IsDiscovering()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, BecomeNotPresent) { |
+ GetAdapter(); |
+ ASSERT_TRUE(adapter_->IsPresent()); |
+ |
+ // Install an observer; expect the AdapterPresentChanged to be called |
+ // with false, and IsPresent() to return false. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ fake_bluetooth_adapter_client_->SetVisible(false); |
+ |
+ EXPECT_EQ(1, observer.present_changed_count_); |
+ EXPECT_FALSE(observer.last_present_); |
+ |
+ EXPECT_FALSE(adapter_->IsPresent()); |
+ |
+ // We should have had a device removed. |
+ EXPECT_EQ(1, observer.device_removed_count_); |
+ EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ observer.last_device_address_); |
+ |
+ // Other callbacks shouldn't be called since the values are false. |
+ EXPECT_EQ(0, observer.powered_changed_count_); |
+ EXPECT_EQ(0, observer.discovering_changed_count_); |
+ EXPECT_FALSE(adapter_->IsPowered()); |
+ EXPECT_FALSE(adapter_->IsDiscovering()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, SecondAdapter) { |
+ GetAdapter(); |
+ ASSERT_TRUE(adapter_->IsPresent()); |
+ |
+ // Install an observer, then add a second adapter. Nothing should change, |
+ // we ignore the second adapter. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ fake_bluetooth_adapter_client_->SetSecondVisible(true); |
+ |
+ EXPECT_EQ(0, observer.present_changed_count_); |
+ |
+ EXPECT_TRUE(adapter_->IsPresent()); |
+ EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress, |
+ adapter_->GetAddress()); |
+ |
+ // Try removing the first adapter, we should now act as if the adapter |
+ // is no longer present rather than fall back to the second. |
+ fake_bluetooth_adapter_client_->SetVisible(false); |
+ |
+ EXPECT_EQ(1, observer.present_changed_count_); |
+ EXPECT_FALSE(observer.last_present_); |
+ |
+ EXPECT_FALSE(adapter_->IsPresent()); |
+ |
+ // We should have had a device removed. |
+ EXPECT_EQ(1, observer.device_removed_count_); |
+ EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ observer.last_device_address_); |
+ |
+ // Other callbacks shouldn't be called since the values are false. |
+ EXPECT_EQ(0, observer.powered_changed_count_); |
+ EXPECT_EQ(0, observer.discovering_changed_count_); |
+ EXPECT_FALSE(adapter_->IsPowered()); |
+ EXPECT_FALSE(adapter_->IsDiscovering()); |
+ |
+ observer.device_removed_count_ = 0; |
+ |
+ // Removing the second adapter shouldn't set anything either. |
+ fake_bluetooth_adapter_client_->SetSecondVisible(false); |
+ |
+ EXPECT_EQ(0, observer.device_removed_count_); |
+ EXPECT_EQ(0, observer.powered_changed_count_); |
+ EXPECT_EQ(0, observer.discovering_changed_count_); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, BecomePowered) { |
+ GetAdapter(); |
+ ASSERT_FALSE(adapter_->IsPowered()); |
+ |
+ // Install an observer; expect the AdapterPoweredChanged to be called |
+ // with true, and IsPowered() to return true. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ adapter_->SetPowered( |
+ true, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(1, observer.powered_changed_count_); |
+ EXPECT_TRUE(observer.last_powered_); |
+ |
+ EXPECT_TRUE(adapter_->IsPowered()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, BecomeNotPowered) { |
+ GetAdapter(); |
+ adapter_->SetPowered( |
+ true, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ ASSERT_TRUE(adapter_->IsPowered()); |
+ |
+ // Install an observer; expect the AdapterPoweredChanged to be called |
+ // with false, and IsPowered() to return false. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ adapter_->SetPowered( |
+ false, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(1, observer.powered_changed_count_); |
+ EXPECT_FALSE(observer.last_powered_); |
+ |
+ EXPECT_FALSE(adapter_->IsPowered()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, StopDiscovery) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ |
+ GetAdapter(); |
+ |
+ adapter_->SetPowered( |
+ true, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ adapter_->StartDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(2, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ ASSERT_TRUE(adapter_->IsPowered()); |
+ ASSERT_TRUE(adapter_->IsDiscovering()); |
+ |
+ // Install an observer; aside from the callback, expect the |
+ // AdapterDiscoveringChanged method to be called and no longer to be |
+ // discovering, |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ adapter_->StopDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(1, observer.discovering_changed_count_); |
+ EXPECT_FALSE(observer.last_discovering_); |
+ |
+ EXPECT_FALSE(adapter_->IsDiscovering()); |
+ |
+ message_loop.RunUntilIdle(); |
youngki
2013/04/17 16:23:45
This method has been deprecated: https://code.goog
keybuk
2013/04/17 17:46:31
Not needed anymore with the current test code - dr
|
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, StopDiscoveryAfterTwoStarts) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ |
+ GetAdapter(); |
+ |
+ adapter_->SetPowered( |
+ true, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ adapter_->StartDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(2, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ ASSERT_TRUE(adapter_->IsPowered()); |
+ ASSERT_TRUE(adapter_->IsDiscovering()); |
+ |
+ // Install an observer and start discovering again; only the callback |
+ // should be called since we were already discovering to begin with. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ adapter_->StartDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ EXPECT_EQ(0, observer.discovering_changed_count_); |
+ |
+ // Stop discovering; only the callback should be called since we're still |
+ // discovering. The adapter should be still discovering. |
+ adapter_->StopDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ EXPECT_EQ(0, observer.discovering_changed_count_); |
+ |
+ EXPECT_TRUE(adapter_->IsDiscovering()); |
+ |
+ // Stop discovering one more time; aside from the callback, expect the |
+ // AdapterDiscoveringChanged method to be called and no longer to be |
+ // discovering, |
+ adapter_->StopDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(1, observer.discovering_changed_count_); |
+ EXPECT_FALSE(observer.last_discovering_); |
+ |
+ EXPECT_FALSE(adapter_->IsDiscovering()); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, Discovery) { |
+ // Test a simulated discovery session. |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ GetAdapter(); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ adapter_->SetPowered( |
+ true, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ adapter_->StartDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(2, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ ASSERT_TRUE(adapter_->IsPowered()); |
+ ASSERT_TRUE(adapter_->IsDiscovering()); |
+ |
+ // First device to appear should be an Apple Mouse. |
+ 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(); |
+ 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(); |
+ |
+ EXPECT_EQ(1, observer.device_removed_count_); |
+ EXPECT_EQ(FakeBluetoothDeviceClient::kVanishingDeviceAddress, |
+ observer.last_device_address_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PoweredAndDiscovering) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ |
+ GetAdapter(); |
+ adapter_->SetPowered( |
+ true, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ adapter_->StartDiscovering( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(2, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ // Stop the timers that the simulation uses |
+ fake_bluetooth_device_client_->EndDiscoverySimulation( |
+ dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); |
+ message_loop.RunUntilIdle(); |
+ |
+ ASSERT_TRUE(adapter_->IsPowered()); |
+ ASSERT_TRUE(adapter_->IsDiscovering()); |
+ |
+ fake_bluetooth_adapter_client_->SetVisible(false); |
+ ASSERT_FALSE(adapter_->IsPresent()); |
+ |
+ // Install an observer; expect the AdapterPresentChanged, |
+ // AdapterPoweredChanged and AdapterDiscoveringChanged methods to be called |
+ // with true, and IsPresent(), IsPowered() and IsDiscovering() to all |
+ // return true. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ fake_bluetooth_adapter_client_->SetVisible(true); |
+ |
+ EXPECT_EQ(1, observer.present_changed_count_); |
+ EXPECT_TRUE(observer.last_present_); |
+ EXPECT_TRUE(adapter_->IsPresent()); |
+ |
+ EXPECT_EQ(1, observer.powered_changed_count_); |
+ EXPECT_TRUE(observer.last_powered_); |
+ EXPECT_TRUE(adapter_->IsPowered()); |
+ |
+ EXPECT_EQ(1, observer.discovering_changed_count_); |
+ EXPECT_TRUE(observer.last_discovering_); |
+ EXPECT_TRUE(adapter_->IsDiscovering()); |
+ |
+ observer.present_changed_count_ = 0; |
+ observer.powered_changed_count_ = 0; |
+ observer.discovering_changed_count_ = 0; |
+ |
+ // Now mark the adapter not present again. Expect the methods to be called |
+ // again, to reset the properties back to false |
+ fake_bluetooth_adapter_client_->SetVisible(false); |
+ |
+ EXPECT_EQ(1, observer.present_changed_count_); |
+ EXPECT_FALSE(observer.last_present_); |
+ EXPECT_FALSE(adapter_->IsPresent()); |
+ |
+ EXPECT_EQ(1, observer.powered_changed_count_); |
+ EXPECT_FALSE(observer.last_powered_); |
+ EXPECT_FALSE(adapter_->IsPowered()); |
+ |
+ EXPECT_EQ(1, observer.discovering_changed_count_); |
+ EXPECT_FALSE(observer.last_discovering_); |
+ EXPECT_FALSE(adapter_->IsDiscovering()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, DeviceProperties) { |
+ GetAdapter(); |
+ |
+ BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
+ ASSERT_EQ(1U, devices.size()); |
+ ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ devices[0]->GetAddress()); |
+ |
+ // Verify the other device properties. |
+ EXPECT_EQ(UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName), |
+ devices[0]->GetName()); |
+ EXPECT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[0]->GetDeviceType()); |
+ EXPECT_TRUE(devices[0]->IsPaired()); |
+ EXPECT_FALSE(devices[0]->IsConnected()); |
+ EXPECT_FALSE(devices[0]->IsConnectable()); |
+ EXPECT_FALSE(devices[0]->IsConnecting()); |
+ |
+ BluetoothDevice::ServiceList uuids = devices[0]->GetServices(); |
+ ASSERT_EQ(2U, uuids.size()); |
+ EXPECT_EQ(uuids[0], "00001800-0000-1000-8000-00805f9b34fb"); |
+ EXPECT_EQ(uuids[1], "00001801-0000-1000-8000-00805f9b34fb"); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, DeviceClassChanged) { |
+ // Simulate a change of class of a device, as sometimes occurs |
+ // during discovery. |
+ GetAdapter(); |
+ |
+ BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
+ ASSERT_EQ(1U, devices.size()); |
+ ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ devices[0]->GetAddress()); |
+ ASSERT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[0]->GetDeviceType()); |
+ |
+ // Install an observer; expect the DeviceChanged method to be called when |
+ // we change the class of the device. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); |
+ |
+ properties->bluetooth_class.ReplaceValue(0x002580); |
+ properties->NotifyPropertyChanged(properties->bluetooth_class.name()); |
+ |
+ EXPECT_EQ(1, observer.device_changed_count_); |
+ EXPECT_EQ(devices[0], observer.last_device_); |
+ |
+ EXPECT_EQ(BluetoothDevice::DEVICE_MOUSE, devices[0]->GetDeviceType()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, DeviceNameChanged) { |
+ // Simulate a change of name of a device. |
+ GetAdapter(); |
+ |
+ BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
+ ASSERT_EQ(1U, devices.size()); |
+ ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ devices[0]->GetAddress()); |
+ ASSERT_EQ(UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName), |
+ devices[0]->GetName()); |
+ |
+ // Install an observer; expect the DeviceChanged method to be called when |
+ // we change the alias of the device. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); |
+ |
+ static const std::string new_name("New Device Name"); |
+ properties->alias.ReplaceValue(new_name); |
+ properties->NotifyPropertyChanged(properties->alias.name()); |
+ |
+ EXPECT_EQ(1, observer.device_changed_count_); |
+ EXPECT_EQ(devices[0], observer.last_device_); |
+ |
+ EXPECT_EQ(UTF8ToUTF16(new_name), devices[0]->GetName()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, DeviceUuidsChanged) { |
+ // Simulate a change of advertised services of a device. |
+ GetAdapter(); |
+ |
+ BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
+ ASSERT_EQ(1U, devices.size()); |
+ ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ devices[0]->GetAddress()); |
+ |
+ BluetoothDevice::ServiceList uuids = devices[0]->GetServices(); |
+ ASSERT_EQ(2U, uuids.size()); |
+ ASSERT_EQ(uuids[0], "00001800-0000-1000-8000-00805f9b34fb"); |
+ ASSERT_EQ(uuids[1], "00001801-0000-1000-8000-00805f9b34fb"); |
+ |
+ // Install an observer; expect the DeviceChanged method to be called when |
+ // we change the class of the device. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); |
+ |
+ uuids.push_back("0000110c-0000-1000-8000-00805f9b34fb"); |
+ uuids.push_back("0000110e-0000-1000-8000-00805f9b34fb"); |
+ uuids.push_back("0000110a-0000-1000-8000-00805f9b34fb"); |
+ |
+ properties->uuids.ReplaceValue(uuids); |
+ properties->NotifyPropertyChanged(properties->uuids.name()); |
+ |
+ EXPECT_EQ(1, observer.device_changed_count_); |
+ EXPECT_EQ(devices[0], observer.last_device_); |
+ |
+ // Fetching the value should give the new one. |
+ uuids = devices[0]->GetServices(); |
+ ASSERT_EQ(5U, uuids.size()); |
+ EXPECT_EQ(uuids[0], "00001800-0000-1000-8000-00805f9b34fb"); |
+ EXPECT_EQ(uuids[1], "00001801-0000-1000-8000-00805f9b34fb"); |
+ EXPECT_EQ(uuids[2], "0000110c-0000-1000-8000-00805f9b34fb"); |
+ EXPECT_EQ(uuids[3], "0000110e-0000-1000-8000-00805f9b34fb"); |
+ EXPECT_EQ(uuids[4], "0000110a-0000-1000-8000-00805f9b34fb"); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, ForgetDevice) { |
+ GetAdapter(); |
+ |
+ BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
+ ASSERT_EQ(1U, devices.size()); |
+ ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, |
+ devices[0]->GetAddress()); |
+ |
+ std::string address = devices[0]->GetAddress(); |
+ |
+ // Install an observer; expect the DeviceRemoved method to be called |
+ // with the device we remove. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ devices[0]->Forget( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(1, observer.device_removed_count_); |
+ EXPECT_EQ(address, observer.last_device_address_); |
+ |
+ // GetDevices shouldn't return the device either. |
+ devices = adapter_->GetDevices(); |
+ ASSERT_EQ(0U, devices.size()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, ConnectPairedDevice) { |
+ GetAdapter(); |
+ |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kPairedDeviceAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_TRUE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ // Connect without a pairing delegate; since the device is already Paired |
+ // this should succeed and the device should become connected. |
+ device->Connect( |
+ NULL, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(1, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, ConnectUnpairableDevice) { |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kMicrosoftMouseAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ // Connect without a pairing delegate; since the device does not require |
+ // pairing, this should succeed and the device should become connected. |
+ device->Connect( |
+ NULL, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(1, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, ConnectConnectedDevice) { |
+ GetAdapter(); |
+ |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kPairedDeviceAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_TRUE(device->IsPaired()); |
+ |
+ device->Connect( |
+ NULL, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ ASSERT_EQ(1, callback_count_); |
+ ASSERT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ ASSERT_TRUE(device->IsConnected()); |
+ |
+ // Connect again; since the device is already Connected, this shouldn't do |
+ // anything, not even the observer method should be called. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ device->Connect( |
+ NULL, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, ConnectDeviceFails) { |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kAppleMouseAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ // Connect without a pairing delegate; since the device requires pairing, |
+ // this should fail with an error. |
+ device->Connect( |
+ NULL, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_); |
+ |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, DisconnectDevice) { |
+ GetAdapter(); |
+ |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kPairedDeviceAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_TRUE(device->IsPaired()); |
+ |
+ device->Connect( |
+ NULL, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ ASSERT_EQ(1, callback_count_); |
+ ASSERT_EQ(0, error_callback_count_); |
+ callback_count_ = 0; |
+ |
+ ASSERT_TRUE(device->IsConnected()); |
+ ASSERT_FALSE(device->IsConnecting()); |
+ |
+ // Disconnect the device, we should see the observer method fire and the |
+ // device get dropped. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ device->Disconnect( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ EXPECT_EQ(1, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_FALSE(device->IsConnected()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, DisconnectUnconnectedDevice) { |
+ GetAdapter(); |
+ |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kPairedDeviceAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_TRUE(device->IsPaired()); |
+ ASSERT_FALSE(device->IsConnected()); |
+ |
+ // Disconnect the device, we should see the observer method fire and the |
+ // device get dropped. |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ device->Disconnect( |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ |
+ EXPECT_FALSE(device->IsConnected()); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairAppleMouse) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // The Apple Mouse requires no PIN or Passkey to pair; this is equivalent |
+ // to Simple Secure Pairing or a device with a fixed 0000 PIN. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kAppleMouseAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(0, pairing_delegate.call_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ // One change for connected, and one for paired. |
+ EXPECT_EQ(2, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ |
+ EXPECT_TRUE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ // Make sure the trusted property has been set to true. |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kAppleMousePath)); |
+ EXPECT_TRUE(properties->trusted.value()); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairAppleKeyboard) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // The Apple Keyboard requires that we display a randomly generated |
+ // PIN on the screen. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kAppleKeyboardAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.display_pincode_count_); |
+ EXPECT_EQ("123456", pairing_delegate.last_pincode_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ // One change for connected, and one for paired. |
+ EXPECT_EQ(2, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ |
+ EXPECT_TRUE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ // Make sure the trusted property has been set to true. |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kAppleKeyboardPath)); |
+ EXPECT_TRUE(properties->trusted.value()); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairMotorolaKeyboard) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // The Motorola Keyboard requires that we display a randomly generated |
+ // Passkey on the screen, and notifies us as it's typed in. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kMotorolaKeyboardAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.display_passkey_count_); |
+ EXPECT_EQ(123456U, pairing_delegate.last_passkey_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // TODO(keybuk): verify we get typing notifications |
+ |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ // One change for connected, and one for paired. |
+ EXPECT_EQ(2, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ |
+ EXPECT_TRUE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ // Make sure the trusted property has been set to true. |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kMotorolaKeyboardPath)); |
+ EXPECT_TRUE(properties->trusted.value()); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairSonyHeadphones) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // The Sony Headphones fake requires that the user enters a PIN for them. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kSonyHeadphonesAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.request_pincode_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Set the PIN. |
+ device->SetPinCode("1234"); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ // One change for connected, and one for paired. |
+ EXPECT_EQ(2, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ |
+ EXPECT_TRUE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ // Make sure the trusted property has been set to true. |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kSonyHeadphonesPath)); |
+ EXPECT_TRUE(properties->trusted.value()); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairPhone) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // The fake phone requests that we confirm a displayed passkey. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kPhoneAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_); |
+ EXPECT_EQ(123456U, pairing_delegate.last_passkey_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Confirm the passkey. |
+ device->ConfirmPairing(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ // One change for connected, and one for paired. |
+ EXPECT_EQ(2, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ |
+ EXPECT_TRUE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ // Make sure the trusted property has been set to true. |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kPhonePath)); |
+ EXPECT_TRUE(properties->trusted.value()); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairWeirdDevice) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Use the "weird device" fake that requires that the user enters a Passkey, |
+ // this would be some kind of device that has a display, but doesn't use |
+ // "just works" - maybe a car? |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kWeirdDeviceAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.request_passkey_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Set the Passkey. |
+ device->SetPasskey(1234); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(1, callback_count_); |
+ EXPECT_EQ(0, error_callback_count_); |
+ |
+ // One change for connected, and one for paired. |
+ EXPECT_EQ(2, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_TRUE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ |
+ EXPECT_TRUE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ // Make sure the trusted property has been set to true. |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kWeirdDevicePath)); |
+ EXPECT_TRUE(properties->trusted.value()); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingFails) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevice(FakeBluetoothDeviceClient::kVanishingDeviceAddress); |
+ |
+ // The vanishing device times out during pairing |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kVanishingDeviceAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(0, pairing_delegate.call_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Run the loop to get the error.. |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ |
+ EXPECT_EQ(BluetoothDevice::ERROR_AUTH_TIMEOUT, last_connect_error_); |
+ |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ EXPECT_FALSE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingFailsAtConnection) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Everything seems to go according to plan with the Microsoft Mouse, it |
+ // pairs with 0000, but then you can't make connections to it after. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kMicrosoftMouseAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(0, pairing_delegate.call_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_); |
+ |
+ // Just one change for paired, the device should not be connected. |
+ EXPECT_EQ(1, observer.device_changed_count_); |
+ EXPECT_EQ(device, observer.last_device_); |
+ |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ |
+ EXPECT_TRUE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ // Make sure the trusted property has been set to true still (since pairing |
+ // worked). |
+ FakeBluetoothDeviceClient::Properties* properties = |
+ fake_bluetooth_device_client_->GetProperties( |
+ dbus::ObjectPath(FakeBluetoothDeviceClient::kMicrosoftMousePath)); |
+ EXPECT_TRUE(properties->trusted.value()); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingRejectedAtPinCode) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Reject the pairing after we receive a request for the PIN code. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kSonyHeadphonesAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.request_pincode_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Reject the pairing. |
+ device->RejectPairing(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_); |
+ |
+ // Should be no changes. |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ EXPECT_FALSE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingCancelledAtPinCode) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Cancel the pairing after we receive a request for the PIN code. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kSonyHeadphonesAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.request_pincode_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Cancel the pairing. |
+ device->CancelPairing(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_); |
+ |
+ // Should be no changes. |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ EXPECT_FALSE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingRejectedAtPasskey) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Reject the pairing after we receive a request for the passkey. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kWeirdDeviceAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.request_passkey_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Reject the pairing. |
+ device->RejectPairing(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_); |
+ |
+ // Should be no changes. |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ EXPECT_FALSE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingCancelledAtPasskey) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Cancel the pairing after we receive a request for the passkey. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kWeirdDeviceAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.request_passkey_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Cancel the pairing. |
+ device->CancelPairing(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_); |
+ |
+ // Should be no changes. |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ EXPECT_FALSE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingRejectedAtConfirmation) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Reject the pairing after we receive a request for passkey confirmation. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kPhoneAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Reject the pairing. |
+ device->RejectPairing(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_); |
+ |
+ // Should be no changes. |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ EXPECT_FALSE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingCancelledAtConfirmation) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Cancel the pairing after we receive a request for the passkey. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kPhoneAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Cancel the pairing. |
+ device->CancelPairing(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_); |
+ |
+ // Should be no changes. |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ EXPECT_FALSE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(2, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+TEST_F(BluetoothExperimentalChromeOSTest, PairingCancelledInFlight) { |
+ base::MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
+ fake_bluetooth_device_client_->SetSimulationIntervalMs(10); |
+ |
+ GetAdapter(); |
+ DiscoverDevices(); |
+ |
+ // Cancel the pairing while we're waiting for the remote host. |
+ BluetoothDevice* device = adapter_->GetDevice( |
+ FakeBluetoothDeviceClient::kAppleMouseAddress); |
+ ASSERT_TRUE(device != NULL); |
+ ASSERT_FALSE(device->IsPaired()); |
+ |
+ TestObserver observer(adapter_); |
+ adapter_->AddObserver(&observer); |
+ |
+ TestPairingDelegate pairing_delegate; |
+ device->Connect( |
+ &pairing_delegate, |
+ base::Bind(&BluetoothExperimentalChromeOSTest::Callback, |
+ base::Unretained(this)), |
+ base::Bind(&BluetoothExperimentalChromeOSTest::ConnectErrorCallback, |
+ base::Unretained(this))); |
+ |
+ EXPECT_EQ(0, pairing_delegate.call_count_); |
+ EXPECT_TRUE(device->IsConnecting()); |
+ |
+ // Cancel the pairing. |
+ device->CancelPairing(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, callback_count_); |
+ EXPECT_EQ(1, error_callback_count_); |
+ EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_); |
+ |
+ // Should be no changes. |
+ EXPECT_EQ(0, observer.device_changed_count_); |
+ EXPECT_FALSE(device->IsConnected()); |
+ EXPECT_FALSE(device->IsConnecting()); |
+ EXPECT_FALSE(device->IsPaired()); |
+ |
+ // Pairing dialog should be dismissed |
+ EXPECT_EQ(1, pairing_delegate.call_count_); |
+ EXPECT_EQ(1, pairing_delegate.dismiss_count_); |
+ |
+ message_loop.RunUntilIdle(); |
+} |
+ |
+} // namespace chromeos |