Enable multiline RTL alignment in RTHB on mac
[chromium-blink-merge.git] / device / bluetooth / bluetooth_audio_sink_chromeos_unittest.cc
blob9aa727f08b4c862a8e40bf8df65961c8bb2c5b6e
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <vector>
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop/message_loop.h"
11 #include "chromeos/dbus/bluetooth_media_client.h"
12 #include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h"
13 #include "chromeos/dbus/bluetooth_media_transport_client.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "chromeos/dbus/fake_bluetooth_media_client.h"
16 #include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h"
17 #include "chromeos/dbus/fake_bluetooth_media_transport_client.h"
18 #include "dbus/object_path.h"
19 #include "device/bluetooth/bluetooth_adapter.h"
20 #include "device/bluetooth/bluetooth_adapter_factory.h"
21 #include "device/bluetooth/bluetooth_audio_sink.h"
22 #include "device/bluetooth/bluetooth_audio_sink_chromeos.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 using dbus::ObjectPath;
26 using device::BluetoothAdapter;
27 using device::BluetoothAdapterFactory;
28 using device::BluetoothAudioSink;
30 namespace chromeos {
32 class TestAudioSinkObserver : public BluetoothAudioSink::Observer {
33 public:
34 explicit TestAudioSinkObserver(scoped_refptr<BluetoothAudioSink> audio_sink)
35 : state_changed_count_(0),
36 volume_changed_count_(0),
37 state_(audio_sink->GetState()),
38 audio_sink_(audio_sink) {
39 audio_sink_->AddObserver(this);
42 ~TestAudioSinkObserver() override { audio_sink_->RemoveObserver(this); }
44 void BluetoothAudioSinkStateChanged(
45 BluetoothAudioSink* audio_sink,
46 BluetoothAudioSink::State state) override {
47 ++state_changed_count_;
50 void BluetoothAudioSinkVolumeChanged(BluetoothAudioSink* audio_sink,
51 uint16_t volume) override {
52 ++volume_changed_count_;
55 int state_changed_count_;
56 int volume_changed_count_;
57 BluetoothAudioSink::State state_;
59 private:
60 scoped_refptr<BluetoothAudioSink> audio_sink_;
63 class BluetoothAudioSinkChromeOSTest : public testing::Test {
64 public:
65 void SetUp() override {
66 DBusThreadManager::Initialize();
68 callback_count_ = 0;
69 error_callback_count_ = 0;
71 // Initiates Delegate::TransportProperties with default values.
72 properties_.device =
73 ObjectPath(FakeBluetoothMediaTransportClient::kTransportDevicePath);
74 properties_.uuid = BluetoothMediaClient::kBluetoothAudioSinkUUID;
75 properties_.codec = FakeBluetoothMediaTransportClient::kTransportCodec;
76 properties_.configuration =
77 FakeBluetoothMediaTransportClient::kTransportConfiguration;
78 properties_.state = BluetoothMediaTransportClient::kStateIdle;
79 properties_.delay.reset(
80 new uint16_t(FakeBluetoothMediaTransportClient::kTransportDelay));
81 properties_.volume.reset(
82 new uint16_t(FakeBluetoothMediaTransportClient::kTransportVolume));
84 GetAdapter();
87 void TearDown() override {
88 callback_count_ = 0;
89 error_callback_count_ = 0;
91 // The adapter should outlive audio sink.
92 audio_sink_ = nullptr;
93 adapter_ = nullptr;
94 DBusThreadManager::Shutdown();
97 // Gets the existing Bluetooth adapter.
98 void GetAdapter() {
99 BluetoothAdapterFactory::GetAdapter(
100 base::Bind(&BluetoothAudioSinkChromeOSTest::GetAdapterCallback,
101 base::Unretained(this)));
104 // Called whenever BluetoothAdapter is retrieved successfully.
105 void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
106 adapter_ = adapter;
108 ASSERT_NE(adapter_.get(), nullptr);
109 ASSERT_TRUE(adapter_->IsInitialized());
110 adapter_->SetPowered(
111 true,
112 base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
113 base::Unretained(this)),
114 base::Bind(&BluetoothAudioSinkChromeOSTest::ErrorCallback,
115 base::Unretained(this)));
116 ASSERT_TRUE(adapter_->IsPresent());
117 ASSERT_TRUE(adapter_->IsPowered());
118 EXPECT_EQ(callback_count_, 1);
119 EXPECT_EQ(error_callback_count_, 0);
121 // Resets callback_count_.
122 --callback_count_;
125 // Registers BluetoothAudioSinkChromeOS with default codec and capabilities.
126 void GetAudioSink() {
127 // Sets up valid codec and capabilities.
128 BluetoothAudioSink::Options options;
129 ASSERT_EQ(options.codec, 0x00);
130 ASSERT_EQ(options.capabilities,
131 std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}));
133 // Registers |audio_sink_| with valid codec and capabilities
134 adapter_->RegisterAudioSink(
135 options,
136 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
137 base::Unretained(this)),
138 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
139 base::Unretained(this)));
141 EXPECT_EQ(callback_count_, 1);
142 EXPECT_EQ(error_callback_count_, 0);
145 // Called whenever RegisterAudioSink is completed successfully.
146 void RegisterCallback(
147 scoped_refptr<BluetoothAudioSink> audio_sink) {
148 ++callback_count_;
149 audio_sink_ = audio_sink;
150 ASSERT_NE(audio_sink_.get(), nullptr);
151 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
154 // Called whenever RegisterAudioSink failed.
155 void RegisterErrorCallback(BluetoothAudioSink::ErrorCode error_code) {
156 ++error_callback_count_;
157 EXPECT_EQ(error_code, BluetoothAudioSink::ERROR_NOT_REGISTERED);
160 // Called whenever there capabilities are returned from SelectConfiguration.
161 void SelectConfigurationCallback(const std::vector<uint8_t>& capabilities) {
162 ++callback_count_;
164 // |capabilities| should be the same as the capabilities for registering an
165 // audio sink in GetAudioSink().
166 EXPECT_EQ(capabilities, std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}));
169 // Generic callbacks.
170 void Callback() {
171 ++callback_count_;
174 void ErrorCallback() {
175 ++error_callback_count_;
178 protected:
179 int callback_count_;
180 int error_callback_count_;
182 base::MessageLoop message_loop_;
184 scoped_refptr<BluetoothAdapter> adapter_;
185 scoped_refptr<BluetoothAudioSink> audio_sink_;
187 // The default property set used while calling SetConfiguration on a media
188 // endpoint object.
189 BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties
190 properties_;
193 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterSucceeded) {
194 GetAudioSink();
196 // Adds an observer for |audio_sink_|.
197 TestAudioSinkObserver observer(audio_sink_);
198 EXPECT_EQ(observer.state_changed_count_, 0);
199 EXPECT_EQ(observer.volume_changed_count_, 0);
202 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterFailedWithInvalidOptions) {
203 // Sets options with an invalid codec and valid capabilities.
204 BluetoothAudioSink::Options options;
205 options.codec = 0xff;
206 options.capabilities = std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35});
208 adapter_->RegisterAudioSink(
209 options,
210 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
211 base::Unretained(this)),
212 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
213 base::Unretained(this)));
215 EXPECT_EQ(callback_count_, 0);
216 EXPECT_EQ(error_callback_count_, 1);
218 // Sets options with a valid codec and invalid capabilities.
219 options.codec = 0x00;
220 options.capabilities.clear();
221 adapter_->RegisterAudioSink(
222 options,
223 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
224 base::Unretained(this)),
225 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
226 base::Unretained(this)));
228 EXPECT_EQ(callback_count_, 0);
229 EXPECT_EQ(error_callback_count_, 2);
232 TEST_F(BluetoothAudioSinkChromeOSTest, SelectConfiguration) {
233 GetAudioSink();
235 // Adds an observer for |audio_sink_|.
236 TestAudioSinkObserver observer(audio_sink_);
237 EXPECT_EQ(observer.state_changed_count_, 0);
238 EXPECT_EQ(observer.volume_changed_count_, 0);
240 // Simulates calling SelectConfiguration on the media endpoint object owned by
241 // |audio_sink_| with some fake capabilities.
242 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
243 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
244 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
245 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
246 audio_sink_chromeos->GetEndpointServiceProvider());
247 ASSERT_NE(media_endpoint, nullptr);
249 media_endpoint->SelectConfiguration(
250 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
251 base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
252 base::Unretained(this)));
254 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
255 EXPECT_EQ(callback_count_, 2);
256 EXPECT_EQ(error_callback_count_, 0);
257 EXPECT_EQ(observer.state_changed_count_, 0);
258 EXPECT_EQ(observer.volume_changed_count_, 0);
261 TEST_F(BluetoothAudioSinkChromeOSTest, SetConfiguration) {
262 GetAudioSink();
264 // Adds an observer for |audio_sink_|.
265 TestAudioSinkObserver observer(audio_sink_);
266 EXPECT_EQ(observer.state_changed_count_, 0);
267 EXPECT_EQ(observer.volume_changed_count_, 0);
269 // Simulates calling SetConfiguration on the media endpoint object owned by
270 // |audio_sink_| with a fake transport path and a
271 // Delegate::TransportProperties structure.
272 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
273 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
274 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
275 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
276 audio_sink_chromeos->GetEndpointServiceProvider());
277 ASSERT_NE(media_endpoint, nullptr);
279 media_endpoint->SetConfiguration(
280 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
281 properties_);
283 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE);
284 EXPECT_EQ(callback_count_, 1);
285 EXPECT_EQ(error_callback_count_, 0);
286 EXPECT_EQ(observer.state_changed_count_, 1);
287 EXPECT_EQ(observer.volume_changed_count_, 1);
290 TEST_F(BluetoothAudioSinkChromeOSTest, SetConfigurationWithUnexpectedState) {
291 GetAudioSink();
293 // Adds an observer for |audio_sink_|.
294 TestAudioSinkObserver observer(audio_sink_);
295 EXPECT_EQ(observer.state_changed_count_, 0);
296 EXPECT_EQ(observer.volume_changed_count_, 0);
298 // Simulates calling SetConfiguration on the media endpoint object owned by
299 // |audio_sink_| with a fake transport path and a
300 // Delegate::TransportProperties structure.
301 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
302 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
303 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
304 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
305 audio_sink_chromeos->GetEndpointServiceProvider());
306 ASSERT_NE(media_endpoint, nullptr);
308 // Set state of Delegate::TransportProperties with an unexpected value.
309 properties_.state = "active";
311 media_endpoint->SetConfiguration(
312 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
313 properties_);
315 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
316 EXPECT_EQ(callback_count_, 1);
317 EXPECT_EQ(error_callback_count_, 0);
318 EXPECT_EQ(observer.state_changed_count_, 0);
319 EXPECT_EQ(observer.volume_changed_count_, 0);
322 // Checks if the observer is notified while the media object is
323 // removed(invisible). Once the media object is removed, the audio sink is no
324 // longer valid.
325 TEST_F(BluetoothAudioSinkChromeOSTest, ObserverNotifiedWhenMediaRemoved) {
326 GetAudioSink();
328 // Adds an observer for |audio_sink_|.
329 TestAudioSinkObserver observer(audio_sink_);
330 EXPECT_EQ(observer.state_changed_count_, 0);
331 EXPECT_EQ(observer.volume_changed_count_, 0);
333 // Gets the media object and makes it invisible to see if the state of the
334 // audio sink changes accordingly.
335 FakeBluetoothMediaClient* media = static_cast<FakeBluetoothMediaClient*>(
336 DBusThreadManager::Get()->GetBluetoothMediaClient());
337 media->SetVisible(false);
339 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
340 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
341 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
342 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
343 audio_sink_chromeos->GetEndpointServiceProvider());
345 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID);
346 EXPECT_EQ(media_endpoint, nullptr);
349 // Checks if the observer is notified while the media transport is
350 // removed(invisible). Once the media transport object is removed, the audio
351 // sink is disconnected.
352 TEST_F(BluetoothAudioSinkChromeOSTest, ObserverNotifiedWhenTransportRemoved) {
353 GetAudioSink();
355 // Adds an observer for |audio_sink_|.
356 TestAudioSinkObserver observer(audio_sink_);
357 EXPECT_EQ(observer.state_changed_count_, 0);
358 EXPECT_EQ(observer.volume_changed_count_, 0);
360 // Simulates calling SetConfiguration on the media endpoint object owned by
361 // |audio_sink_| with a fake transport path and a
362 // Delegate::TransportProperties structure.
363 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
364 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
365 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
366 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
367 audio_sink_chromeos->GetEndpointServiceProvider());
368 ASSERT_NE(media_endpoint, nullptr);
370 media_endpoint->SetConfiguration(
371 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
372 properties_);
374 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE);
375 EXPECT_EQ(callback_count_, 1);
376 EXPECT_EQ(error_callback_count_, 0);
377 EXPECT_EQ(observer.state_changed_count_, 1);
378 EXPECT_EQ(observer.volume_changed_count_, 1);
380 // Gets the media transport object and makes it invalid to see if the state
381 // of the audio sink changes accordingly.
382 FakeBluetoothMediaTransportClient* transport =
383 static_cast<FakeBluetoothMediaTransportClient*>(
384 DBusThreadManager::Get()->GetBluetoothMediaTransportClient());
386 transport->SetValid(media_endpoint->object_path(), false);
387 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
388 EXPECT_NE(media_endpoint, nullptr);
391 } // namespace chromeos