Chromium Code Reviews| Index: device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc |
| diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc b/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc |
| index 5fcccfb8b8b78c4d1fe52016fe4414e99e68e681..e4739f4e4a9cecc3684ffd64a330549d4217ddb7 100644 |
| --- a/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc |
| +++ b/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc |
| @@ -8,7 +8,13 @@ |
| #include "base/logging.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/message_loop/message_loop.h" |
| +#include "chromeos/dbus/bluetooth_media_client.h" |
| +#include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h" |
| +#include "chromeos/dbus/bluetooth_media_transport_client.h" |
| #include "chromeos/dbus/dbus_thread_manager.h" |
| +#include "chromeos/dbus/fake_bluetooth_media_client.h" |
| +#include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h" |
| +#include "chromeos/dbus/fake_bluetooth_media_transport_client.h" |
| #include "dbus/object_path.h" |
| #include "device/bluetooth/bluetooth_adapter.h" |
| #include "device/bluetooth/bluetooth_adapter_factory.h" |
| @@ -16,6 +22,7 @@ |
| #include "device/bluetooth/bluetooth_audio_sink_chromeos.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| +using dbus::ObjectPath; |
| using device::BluetoothAdapter; |
| using device::BluetoothAdapterFactory; |
| using device::BluetoothAudioSink; |
| @@ -56,12 +63,23 @@ class TestAudioSinkObserver : public BluetoothAudioSink::Observer { |
| class BluetoothAudioSinkChromeOSTest : public testing::Test { |
| public: |
| void SetUp() override { |
| - chromeos::DBusThreadManager::Initialize(); |
| + DBusThreadManager::Initialize(); |
| callback_count_ = 0; |
| error_callback_count_ = 0; |
| - audio_sink_ = nullptr; |
| - adapter_ = nullptr; |
| + |
| + // Initiates Delegate::TransportProperties with default values. |
| + properties_.device = |
| + ObjectPath(FakeBluetoothMediaTransportClient::kTransportDevicePath); |
| + properties_.uuid = BluetoothMediaClient::kBluetoothAudioSinkUUID; |
| + properties_.codec = FakeBluetoothMediaTransportClient::kTransportCodec; |
| + properties_.configuration = |
| + FakeBluetoothMediaTransportClient::kTransportConfiguration; |
| + properties_.state = BluetoothMediaTransportClient::kStateIdle; |
| + properties_.delay.reset( |
| + new uint16_t(FakeBluetoothMediaTransportClient::kTransportDelay)); |
| + properties_.volume.reset( |
| + new uint16_t(FakeBluetoothMediaTransportClient::kTransportVolume)); |
| GetAdapter(); |
| } |
| @@ -76,13 +94,14 @@ class BluetoothAudioSinkChromeOSTest : public testing::Test { |
| DBusThreadManager::Shutdown(); |
| } |
| - // Get the existing Bluetooth adapter. |
| + // Gets the existing Bluetooth adapter. |
| void GetAdapter() { |
| BluetoothAdapterFactory::GetAdapter( |
| base::Bind(&BluetoothAudioSinkChromeOSTest::GetAdapterCallback, |
| base::Unretained(this))); |
| } |
| + // Called whenever BluetoothAdapter is retrieved successfully. |
| void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter) { |
| adapter_ = adapter; |
| @@ -98,9 +117,31 @@ class BluetoothAudioSinkChromeOSTest : public testing::Test { |
| ASSERT_TRUE(adapter_->IsPowered()); |
| ASSERT_EQ(callback_count_, 1); |
| ASSERT_EQ(error_callback_count_, 0); |
| + |
| + // Resets callback_count_. |
| --callback_count_; |
| } |
| + // Registers BluetoothAudioSinkChromeOS with default codec and capabilities. |
| + void GetAudioSink() { |
| + // Sets up valid codec and capabilities. |
| + BluetoothAudioSink::Options options; |
| + ASSERT_EQ(options.codec, 0x00); |
| + ASSERT_EQ(options.capabilities, |
| + std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35})); |
| + |
| + // Registers |audio_sink_| with valid codec and capabilities |
| + adapter_->RegisterAudioSink( |
| + options, |
| + base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback, |
| + base::Unretained(this)), |
| + base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback, |
| + base::Unretained(this))); |
| + |
| + ASSERT_EQ(callback_count_, 1); |
|
Miao
2015/02/12 19:08:03
Changed some ASSERT to EXPECT according to the con
|
| + ASSERT_EQ(error_callback_count_, 0); |
| + } |
| + |
| // Called whenever RegisterAudioSink is completed successfully. |
| void RegisterCallback( |
| scoped_refptr<BluetoothAudioSink> audio_sink) { |
| @@ -116,6 +157,15 @@ class BluetoothAudioSinkChromeOSTest : public testing::Test { |
| ASSERT_EQ(error_code, BluetoothAudioSink::ERROR_NOT_REGISTERED); |
| } |
| + // Called whenever there capabilities are returned from SelectConfiguration. |
| + void SelectConfigurationCallback(const std::vector<uint8_t>& capabilities) { |
| + ++callback_count_; |
| + |
| + // |capabilities| should be the same as the capabilities for registering an |
| + // audio sink in GetAudioSink(). |
| + ASSERT_EQ(capabilities, std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35})); |
| + } |
| + |
| // Generic callbacks. |
| void Callback() { |
| ++callback_count_; |
| @@ -128,29 +178,23 @@ class BluetoothAudioSinkChromeOSTest : public testing::Test { |
| protected: |
| int callback_count_; |
| int error_callback_count_; |
| + |
| base::MessageLoop message_loop_; |
| + |
| scoped_refptr<BluetoothAdapter> adapter_; |
| scoped_refptr<BluetoothAudioSink> audio_sink_; |
| + |
| + // The default property set used while calling SetConfiguration on a media |
| + // endpoint object. |
| + BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties |
| + properties_; |
| }; |
| TEST_F(BluetoothAudioSinkChromeOSTest, RegisterSucceeded) { |
| - // Sets up valid codec and capabilities. |
| - BluetoothAudioSink::Options options; |
| - ASSERT_EQ(options.codec, 0x00); |
| - ASSERT_EQ(options.capabilities, |
| - std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35})); |
| - adapter_->RegisterAudioSink( |
| - options, |
| - base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback, |
| - base::Unretained(this)), |
| - base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback, |
| - base::Unretained(this))); |
| + GetAudioSink(); |
| - // Adds observer for the audio sink. |
| + // Adds an observer for |audio_sink_|. |
| TestAudioSinkObserver observer(audio_sink_); |
| - |
| - ASSERT_EQ(callback_count_, 1); |
| - ASSERT_EQ(error_callback_count_, 0); |
| ASSERT_EQ(observer.state_changed_count_, 0); |
| ASSERT_EQ(observer.volume_changed_count_, 0); |
| } |
| @@ -181,8 +225,168 @@ TEST_F(BluetoothAudioSinkChromeOSTest, RegisterFailedWithInvalidOptions) { |
| base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback, |
| base::Unretained(this))); |
| + |
| ASSERT_EQ(callback_count_, 0); |
| ASSERT_EQ(error_callback_count_, 2); |
| } |
| +TEST_F(BluetoothAudioSinkChromeOSTest, SelectConfiguration) { |
| + GetAudioSink(); |
| + |
| + // Adds an observer for |audio_sink_|. |
| + TestAudioSinkObserver observer(audio_sink_); |
| + ASSERT_EQ(observer.state_changed_count_, 0); |
| + ASSERT_EQ(observer.volume_changed_count_, 0); |
| + |
| + // Simulates calling SelectConfiguration on the media endpoint object owned by |
| + // |audio_sink_| with some fake capabilities. |
| + BluetoothAudioSinkChromeOS* audio_sink_chromeos = |
| + static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get()); |
| + FakeBluetoothMediaEndpointServiceProvider* media_endpoint = |
| + static_cast<FakeBluetoothMediaEndpointServiceProvider*>( |
| + audio_sink_chromeos->GetEndpointServiceProvider()); |
| + ASSERT_NE(media_endpoint, nullptr); |
| + |
| + media_endpoint->SelectConfiguration( |
| + std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), |
| + base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback, |
| + base::Unretained(this))); |
| + |
| + ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); |
| + ASSERT_EQ(callback_count_, 2); |
| + ASSERT_EQ(error_callback_count_, 0); |
| + ASSERT_EQ(observer.state_changed_count_, 0); |
| + ASSERT_EQ(observer.volume_changed_count_, 0); |
| +} |
| + |
| +TEST_F(BluetoothAudioSinkChromeOSTest, SetConfiguration) { |
| + GetAudioSink(); |
| + |
| + // Adds an observer for |audio_sink_|. |
| + TestAudioSinkObserver observer(audio_sink_); |
| + ASSERT_EQ(observer.state_changed_count_, 0); |
| + ASSERT_EQ(observer.volume_changed_count_, 0); |
| + |
| + // Simulates calling SetConfiguration on the media endpoint object owned by |
| + // |audio_sink_| with a fake transport path and a |
| + // Delegate::TransportProperties structure. |
| + BluetoothAudioSinkChromeOS* audio_sink_chromeos = |
| + static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get()); |
| + FakeBluetoothMediaEndpointServiceProvider* media_endpoint = |
| + static_cast<FakeBluetoothMediaEndpointServiceProvider*>( |
| + audio_sink_chromeos->GetEndpointServiceProvider()); |
| + ASSERT_NE(media_endpoint, nullptr); |
| + |
| + media_endpoint->SetConfiguration( |
| + ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath), |
| + properties_); |
| + |
| + ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); |
| + ASSERT_EQ(callback_count_, 1); |
| + ASSERT_EQ(error_callback_count_, 0); |
| + ASSERT_EQ(observer.state_changed_count_, 1); |
| + ASSERT_EQ(observer.volume_changed_count_, 1); |
| +} |
| + |
| +TEST_F(BluetoothAudioSinkChromeOSTest, SetConfigurationWithUnexpectedState) { |
| + GetAudioSink(); |
| + |
| + // Adds an observer for |audio_sink_|. |
| + TestAudioSinkObserver observer(audio_sink_); |
| + ASSERT_EQ(observer.state_changed_count_, 0); |
| + ASSERT_EQ(observer.volume_changed_count_, 0); |
| + |
| + // Simulates calling SetConfiguration on the media endpoint object owned by |
| + // |audio_sink_| with a fake transport path and a |
| + // Delegate::TransportProperties structure. |
| + BluetoothAudioSinkChromeOS* audio_sink_chromeos = |
| + static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get()); |
| + FakeBluetoothMediaEndpointServiceProvider* media_endpoint = |
| + static_cast<FakeBluetoothMediaEndpointServiceProvider*>( |
| + audio_sink_chromeos->GetEndpointServiceProvider()); |
| + ASSERT_NE(media_endpoint, nullptr); |
| + |
| + // Set state of Delegate::TransportProperties with an unexpected value. |
| + properties_.state = "active"; |
| + |
| + media_endpoint->SetConfiguration( |
| + ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath), |
| + properties_); |
| + |
| + ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); |
| + ASSERT_EQ(callback_count_, 1); |
| + ASSERT_EQ(error_callback_count_, 0); |
| + ASSERT_EQ(observer.state_changed_count_, 0); |
| + ASSERT_EQ(observer.volume_changed_count_, 0); |
| +} |
| + |
| +// Checks if the observer is notified while the media object is |
| +// removed(invisible). Once the media object is removed, the audio sink is no |
| +// longer valid. |
| +TEST_F(BluetoothAudioSinkChromeOSTest, ObserverNotifiedWhenMediaRemoved) { |
| + GetAudioSink(); |
| + |
| + // Adds an observer for |audio_sink_|. |
| + TestAudioSinkObserver observer(audio_sink_); |
| + ASSERT_EQ(observer.state_changed_count_, 0); |
| + ASSERT_EQ(observer.volume_changed_count_, 0); |
| + |
| + // Gets the media object and makes it invisible to see if the state of the |
| + // audio sink changes accordingly. |
| + FakeBluetoothMediaClient* media = static_cast<FakeBluetoothMediaClient*>( |
| + DBusThreadManager::Get()->GetBluetoothMediaClient()); |
| + media->SetVisible(false); |
| + |
| + BluetoothAudioSinkChromeOS* audio_sink_chromeos = |
| + static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get()); |
| + FakeBluetoothMediaEndpointServiceProvider* media_endpoint = |
| + static_cast<FakeBluetoothMediaEndpointServiceProvider*>( |
| + audio_sink_chromeos->GetEndpointServiceProvider()); |
| + |
| + ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID); |
| + ASSERT_EQ(media_endpoint, nullptr); |
| +} |
| + |
| +// Checks if the observer is notified while the media transport is |
| +// removed(invisible). Once the media transport object is removed, the audio |
| +// sink is disconnected. |
| +TEST_F(BluetoothAudioSinkChromeOSTest, ObserverNotifiedWhenTransportRemoved) { |
| + GetAudioSink(); |
| + |
| + // Adds an observer for |audio_sink_|. |
| + TestAudioSinkObserver observer(audio_sink_); |
| + ASSERT_EQ(observer.state_changed_count_, 0); |
| + ASSERT_EQ(observer.volume_changed_count_, 0); |
| + |
| + // Simulates calling SetConfiguration on the media endpoint object owned by |
| + // |audio_sink_| with a fake transport path and a |
| + // Delegate::TransportProperties structure. |
| + BluetoothAudioSinkChromeOS* audio_sink_chromeos = |
| + static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get()); |
| + FakeBluetoothMediaEndpointServiceProvider* media_endpoint = |
| + static_cast<FakeBluetoothMediaEndpointServiceProvider*>( |
| + audio_sink_chromeos->GetEndpointServiceProvider()); |
| + ASSERT_NE(media_endpoint, nullptr); |
| + |
| + media_endpoint->SetConfiguration( |
| + ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath), |
| + properties_); |
| + |
| + ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); |
| + ASSERT_EQ(callback_count_, 1); |
| + ASSERT_EQ(error_callback_count_, 0); |
| + ASSERT_EQ(observer.state_changed_count_, 1); |
| + ASSERT_EQ(observer.volume_changed_count_, 1); |
| + |
| + // Gets the media transport object and makes it invalid to see if the state |
| + // of the audio sink changes accordingly. |
| + FakeBluetoothMediaTransportClient* transport = |
| + static_cast<FakeBluetoothMediaTransportClient*>( |
| + DBusThreadManager::Get()->GetBluetoothMediaTransportClient()); |
| + |
| + transport->SetValid(media_endpoint->object_path(), false); |
| + ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); |
| + ASSERT_NE(media_endpoint, nullptr); |
| +} |
| + |
| } // namespace chromeos |