OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "device/bluetooth/bluetooth_audio_sink_bluez.h" | |
6 | |
7 #include <stddef.h> | |
8 #include <stdint.h> | |
9 | |
10 #include <memory> | |
11 #include <vector> | |
12 | |
13 #include "base/bind.h" | |
14 #include "base/logging.h" | |
15 #include "base/memory/ref_counted.h" | |
16 #include "base/message_loop/message_loop.h" | |
17 #include "dbus/object_path.h" | |
18 #include "device/bluetooth/bluetooth_adapter.h" | |
19 #include "device/bluetooth/bluetooth_adapter_factory.h" | |
20 #include "device/bluetooth/bluetooth_audio_sink.h" | |
21 #include "device/bluetooth/dbus/bluetooth_media_client.h" | |
22 #include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h" | |
23 #include "device/bluetooth/dbus/bluetooth_media_transport_client.h" | |
24 #include "device/bluetooth/dbus/bluez_dbus_manager.h" | |
25 #include "device/bluetooth/dbus/fake_bluetooth_media_client.h" | |
26 #include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h
" | |
27 #include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h" | |
28 #include "testing/gtest/include/gtest/gtest.h" | |
29 | |
30 using bluez::FakeBluetoothMediaTransportClient; | |
31 using dbus::ObjectPath; | |
32 using device::BluetoothAdapter; | |
33 using device::BluetoothAdapterFactory; | |
34 using device::BluetoothAudioSink; | |
35 | |
36 namespace bluez { | |
37 | |
38 class TestAudioSinkObserver : public BluetoothAudioSink::Observer { | |
39 public: | |
40 explicit TestAudioSinkObserver(scoped_refptr<BluetoothAudioSink> audio_sink) | |
41 : state_changed_count_(0), | |
42 volume_changed_count_(0), | |
43 total_read_(0), | |
44 state_(audio_sink->GetState()), | |
45 audio_sink_(audio_sink) { | |
46 audio_sink_->AddObserver(this); | |
47 } | |
48 | |
49 ~TestAudioSinkObserver() override { audio_sink_->RemoveObserver(this); } | |
50 | |
51 void BluetoothAudioSinkStateChanged( | |
52 BluetoothAudioSink* audio_sink, | |
53 BluetoothAudioSink::State state) override { | |
54 if (state == BluetoothAudioSink::STATE_IDLE) | |
55 total_read_ = 0; | |
56 | |
57 ++state_changed_count_; | |
58 } | |
59 | |
60 void BluetoothAudioSinkVolumeChanged(BluetoothAudioSink* audio_sink, | |
61 uint16_t volume) override { | |
62 ++volume_changed_count_; | |
63 } | |
64 | |
65 void BluetoothAudioSinkDataAvailable(BluetoothAudioSink* audio_sink, | |
66 char* data, | |
67 size_t size, | |
68 uint16_t read_mtu) override { | |
69 total_read_ += size; | |
70 data_.clear(); | |
71 data_.insert(data_.begin(), data, data + size); | |
72 read_mtu_ = read_mtu; | |
73 } | |
74 | |
75 int state_changed_count_; | |
76 int volume_changed_count_; | |
77 int data_available_count_; | |
78 size_t total_read_; | |
79 std::vector<char> data_; | |
80 uint16_t read_mtu_; | |
81 BluetoothAudioSink::State state_; | |
82 | |
83 private: | |
84 scoped_refptr<BluetoothAudioSink> audio_sink_; | |
85 }; | |
86 | |
87 class BluetoothAudioSinkBlueZTest : public testing::Test { | |
88 public: | |
89 void SetUp() override { | |
90 bluez::BluezDBusManager::Initialize(nullptr /* bus */, | |
91 true /* use_dbus_stub */); | |
92 | |
93 callback_count_ = 0; | |
94 error_callback_count_ = 0; | |
95 | |
96 fake_media_ = static_cast<bluez::FakeBluetoothMediaClient*>( | |
97 bluez::BluezDBusManager::Get()->GetBluetoothMediaClient()); | |
98 fake_transport_ = static_cast<FakeBluetoothMediaTransportClient*>( | |
99 bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient()); | |
100 | |
101 // Initiates Delegate::TransportProperties with default values. | |
102 properties_.device = | |
103 ObjectPath(FakeBluetoothMediaTransportClient::kTransportDevicePath); | |
104 properties_.uuid = bluez::BluetoothMediaClient::kBluetoothAudioSinkUUID; | |
105 properties_.codec = FakeBluetoothMediaTransportClient::kTransportCodec; | |
106 properties_.configuration = std::vector<uint8_t>( | |
107 FakeBluetoothMediaTransportClient::kTransportConfiguration, | |
108 FakeBluetoothMediaTransportClient::kTransportConfiguration + | |
109 FakeBluetoothMediaTransportClient::kTransportConfigurationLength); | |
110 properties_.state = bluez::BluetoothMediaTransportClient::kStateIdle; | |
111 properties_.delay.reset( | |
112 new uint16_t(FakeBluetoothMediaTransportClient::kTransportDelay)); | |
113 properties_.volume.reset( | |
114 new uint16_t(FakeBluetoothMediaTransportClient::kTransportVolume)); | |
115 | |
116 GetAdapter(); | |
117 } | |
118 | |
119 void TearDown() override { | |
120 callback_count_ = 0; | |
121 error_callback_count_ = 0; | |
122 observer_.reset(); | |
123 | |
124 fake_media_->SetVisible(true); | |
125 | |
126 // The adapter should outlive audio sink. | |
127 audio_sink_ = nullptr; | |
128 adapter_ = nullptr; | |
129 bluez::BluezDBusManager::Shutdown(); | |
130 } | |
131 | |
132 // Gets the existing Bluetooth adapter. | |
133 void GetAdapter() { | |
134 BluetoothAdapterFactory::GetAdapter( | |
135 base::Bind(&BluetoothAudioSinkBlueZTest::GetAdapterCallback, | |
136 base::Unretained(this))); | |
137 base::MessageLoop::current()->Run(); | |
138 } | |
139 | |
140 // Called whenever BluetoothAdapter is retrieved successfully. | |
141 void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter) { | |
142 adapter_ = adapter; | |
143 | |
144 ASSERT_NE(adapter_.get(), nullptr); | |
145 ASSERT_TRUE(adapter_->IsInitialized()); | |
146 adapter_->SetPowered(true, | |
147 base::Bind(&BluetoothAudioSinkBlueZTest::Callback, | |
148 base::Unretained(this)), | |
149 base::Bind(&BluetoothAudioSinkBlueZTest::ErrorCallback, | |
150 base::Unretained(this))); | |
151 ASSERT_TRUE(adapter_->IsPresent()); | |
152 ASSERT_TRUE(adapter_->IsPowered()); | |
153 EXPECT_EQ(callback_count_, 1); | |
154 EXPECT_EQ(error_callback_count_, 0); | |
155 | |
156 // Resets callback_count_. | |
157 --callback_count_; | |
158 | |
159 if (base::MessageLoop::current() && | |
160 base::MessageLoop::current()->is_running()) { | |
161 base::MessageLoop::current()->QuitWhenIdle(); | |
162 } | |
163 } | |
164 | |
165 // Registers BluetoothAudioSinkBlueZ with default codec and capabilities. | |
166 // If the audio sink is retrieved successfully, the state changes to | |
167 // STATE_DISCONNECTED. | |
168 void GetAudioSink() { | |
169 // Sets up valid codec and capabilities. | |
170 BluetoothAudioSink::Options options; | |
171 ASSERT_EQ(options.codec, 0x00); | |
172 ASSERT_EQ(options.capabilities, | |
173 std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35})); | |
174 | |
175 // Registers |audio_sink_| with valid codec and capabilities | |
176 adapter_->RegisterAudioSink( | |
177 options, base::Bind(&BluetoothAudioSinkBlueZTest::RegisterCallback, | |
178 base::Unretained(this)), | |
179 base::Bind(&BluetoothAudioSinkBlueZTest::RegisterErrorCallback, | |
180 base::Unretained(this))); | |
181 | |
182 observer_.reset(new TestAudioSinkObserver(audio_sink_)); | |
183 EXPECT_EQ(callback_count_, 1); | |
184 EXPECT_EQ(error_callback_count_, 0); | |
185 EXPECT_EQ(observer_->state_changed_count_, 0); | |
186 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
187 } | |
188 | |
189 void GetFakeMediaEndpoint() { | |
190 BluetoothAudioSinkBlueZ* audio_sink_bluez = | |
191 static_cast<BluetoothAudioSinkBlueZ*>(audio_sink_.get()); | |
192 ASSERT_NE(audio_sink_bluez, nullptr); | |
193 | |
194 media_endpoint_ = | |
195 static_cast<bluez::FakeBluetoothMediaEndpointServiceProvider*>( | |
196 audio_sink_bluez->GetEndpointServiceProvider()); | |
197 } | |
198 | |
199 // Called whenever RegisterAudioSink is completed successfully. | |
200 void RegisterCallback(scoped_refptr<BluetoothAudioSink> audio_sink) { | |
201 ++callback_count_; | |
202 audio_sink_ = audio_sink; | |
203 | |
204 GetFakeMediaEndpoint(); | |
205 ASSERT_NE(media_endpoint_, nullptr); | |
206 fake_media_->SetEndpointRegistered(media_endpoint_, true); | |
207 | |
208 ASSERT_NE(audio_sink_.get(), nullptr); | |
209 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
210 } | |
211 | |
212 // Called whenever RegisterAudioSink failed. | |
213 void RegisterErrorCallback(BluetoothAudioSink::ErrorCode error_code) { | |
214 ++error_callback_count_; | |
215 EXPECT_EQ(error_code, BluetoothAudioSink::ERROR_NOT_REGISTERED); | |
216 } | |
217 | |
218 // Called whenever there capabilities are returned from SelectConfiguration. | |
219 void SelectConfigurationCallback(const std::vector<uint8_t>& capabilities) { | |
220 ++callback_count_; | |
221 | |
222 // |capabilities| should be the same as the capabilities for registering an | |
223 // audio sink in GetAudioSink(). | |
224 EXPECT_EQ(capabilities, std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35})); | |
225 } | |
226 | |
227 void UnregisterErrorCallback(BluetoothAudioSink::ErrorCode error_code) { | |
228 ++error_callback_count_; | |
229 EXPECT_EQ(error_code, BluetoothAudioSink::ERROR_NOT_UNREGISTERED); | |
230 } | |
231 | |
232 // Generic callbacks. | |
233 void Callback() { ++callback_count_; } | |
234 | |
235 void ErrorCallback() { ++error_callback_count_; } | |
236 | |
237 protected: | |
238 int callback_count_; | |
239 int error_callback_count_; | |
240 | |
241 base::MessageLoopForIO message_loop_; | |
242 | |
243 bluez::FakeBluetoothMediaClient* fake_media_; | |
244 FakeBluetoothMediaTransportClient* fake_transport_; | |
245 bluez::FakeBluetoothMediaEndpointServiceProvider* media_endpoint_; | |
246 std::unique_ptr<TestAudioSinkObserver> observer_; | |
247 scoped_refptr<BluetoothAdapter> adapter_; | |
248 scoped_refptr<BluetoothAudioSink> audio_sink_; | |
249 | |
250 // The default property set used while calling SetConfiguration on a media | |
251 // endpoint object. | |
252 bluez::BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties | |
253 properties_; | |
254 }; | |
255 | |
256 TEST_F(BluetoothAudioSinkBlueZTest, RegisterSucceeded) { | |
257 GetAudioSink(); | |
258 } | |
259 | |
260 TEST_F(BluetoothAudioSinkBlueZTest, RegisterFailedWithInvalidOptions) { | |
261 // Sets options with an invalid codec and valid capabilities. | |
262 BluetoothAudioSink::Options options; | |
263 options.codec = 0xff; | |
264 options.capabilities = std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}); | |
265 | |
266 adapter_->RegisterAudioSink( | |
267 options, base::Bind(&BluetoothAudioSinkBlueZTest::RegisterCallback, | |
268 base::Unretained(this)), | |
269 base::Bind(&BluetoothAudioSinkBlueZTest::RegisterErrorCallback, | |
270 base::Unretained(this))); | |
271 | |
272 EXPECT_EQ(callback_count_, 0); | |
273 EXPECT_EQ(error_callback_count_, 1); | |
274 | |
275 // Sets options with a valid codec and invalid capabilities. | |
276 options.codec = 0x00; | |
277 options.capabilities.clear(); | |
278 adapter_->RegisterAudioSink( | |
279 options, base::Bind(&BluetoothAudioSinkBlueZTest::RegisterCallback, | |
280 base::Unretained(this)), | |
281 base::Bind(&BluetoothAudioSinkBlueZTest::RegisterErrorCallback, | |
282 base::Unretained(this))); | |
283 | |
284 EXPECT_EQ(callback_count_, 0); | |
285 EXPECT_EQ(error_callback_count_, 2); | |
286 } | |
287 | |
288 TEST_F(BluetoothAudioSinkBlueZTest, SelectConfiguration) { | |
289 GetAudioSink(); | |
290 | |
291 // Simulates calling SelectConfiguration on the media endpoint object owned by | |
292 // |audio_sink_| with some fake capabilities. | |
293 media_endpoint_->SelectConfiguration( | |
294 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
295 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
296 base::Unretained(this))); | |
297 | |
298 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
299 EXPECT_EQ(callback_count_, 2); | |
300 EXPECT_EQ(error_callback_count_, 0); | |
301 EXPECT_EQ(observer_->state_changed_count_, 0); | |
302 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
303 } | |
304 | |
305 TEST_F(BluetoothAudioSinkBlueZTest, SetConfiguration) { | |
306 GetAudioSink(); | |
307 | |
308 media_endpoint_->SelectConfiguration( | |
309 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
310 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
311 base::Unretained(this))); | |
312 | |
313 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
314 EXPECT_EQ(callback_count_, 2); | |
315 EXPECT_EQ(error_callback_count_, 0); | |
316 EXPECT_EQ(observer_->state_changed_count_, 0); | |
317 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
318 | |
319 // Simulates calling SetConfiguration on the media endpoint object owned by | |
320 // |audio_sink_| with a fake transport path and a | |
321 // Delegate::TransportProperties structure. | |
322 media_endpoint_->SetConfiguration( | |
323 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
324 properties_); | |
325 | |
326 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
327 EXPECT_EQ(callback_count_, 2); | |
328 EXPECT_EQ(error_callback_count_, 0); | |
329 EXPECT_EQ(observer_->state_changed_count_, 1); | |
330 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
331 } | |
332 | |
333 TEST_F(BluetoothAudioSinkBlueZTest, SetConfigurationWithUnexpectedState) { | |
334 GetAudioSink(); | |
335 | |
336 media_endpoint_->SelectConfiguration( | |
337 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
338 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
339 base::Unretained(this))); | |
340 | |
341 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
342 EXPECT_EQ(callback_count_, 2); | |
343 EXPECT_EQ(error_callback_count_, 0); | |
344 EXPECT_EQ(observer_->state_changed_count_, 0); | |
345 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
346 | |
347 // Set state of Delegate::TransportProperties with an unexpected value. | |
348 properties_.state = "pending"; | |
349 | |
350 media_endpoint_->SetConfiguration( | |
351 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
352 properties_); | |
353 | |
354 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
355 EXPECT_EQ(callback_count_, 2); | |
356 EXPECT_EQ(error_callback_count_, 0); | |
357 EXPECT_EQ(observer_->state_changed_count_, 0); | |
358 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
359 } | |
360 | |
361 // Checks if the observer is notified on media-removed event when the state of | |
362 // |audio_sink_| is STATE_DISCONNECTED. Once the media object is removed, the | |
363 // audio sink is no longer valid. | |
364 TEST_F(BluetoothAudioSinkBlueZTest, MediaRemovedDuringDisconnectedState) { | |
365 GetAudioSink(); | |
366 | |
367 // Gets the media object and makes it invisible to see if the state of the | |
368 // audio sink changes accordingly. | |
369 fake_media_->SetVisible(false); | |
370 | |
371 GetFakeMediaEndpoint(); | |
372 | |
373 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID); | |
374 EXPECT_EQ(media_endpoint_, nullptr); | |
375 EXPECT_EQ(observer_->state_changed_count_, 1); | |
376 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
377 } | |
378 | |
379 // Checks if the observer is notified on media-removed event when the state of | |
380 // |audio_sink_| is STATE_IDLE. Once the media object is removed, the audio sink | |
381 // is no longer valid. | |
382 TEST_F(BluetoothAudioSinkBlueZTest, MediaRemovedDuringIdleState) { | |
383 GetAudioSink(); | |
384 | |
385 media_endpoint_->SelectConfiguration( | |
386 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
387 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
388 base::Unretained(this))); | |
389 | |
390 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
391 EXPECT_EQ(callback_count_, 2); | |
392 EXPECT_EQ(error_callback_count_, 0); | |
393 EXPECT_EQ(observer_->state_changed_count_, 0); | |
394 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
395 | |
396 media_endpoint_->SetConfiguration( | |
397 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
398 properties_); | |
399 | |
400 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
401 EXPECT_EQ(callback_count_, 2); | |
402 EXPECT_EQ(error_callback_count_, 0); | |
403 EXPECT_EQ(observer_->state_changed_count_, 1); | |
404 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
405 | |
406 // Gets the media object and makes it invisible to see if the state of the | |
407 // audio sink changes accordingly. | |
408 fake_media_->SetVisible(false); | |
409 | |
410 GetFakeMediaEndpoint(); | |
411 | |
412 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID); | |
413 EXPECT_EQ(media_endpoint_, nullptr); | |
414 | |
415 // The state becomes disconnted and then invalid, since the removal of | |
416 // transport object should happend before media becomes invisible. | |
417 // State: STATE_IDLE -> STATE_DISCONNECTED -> STATE_INVALID | |
418 EXPECT_EQ(observer_->state_changed_count_, 3); | |
419 EXPECT_EQ(observer_->volume_changed_count_, 2); | |
420 } | |
421 | |
422 TEST_F(BluetoothAudioSinkBlueZTest, MediaRemovedDuringActiveState) { | |
423 GetAudioSink(); | |
424 | |
425 media_endpoint_->SelectConfiguration( | |
426 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
427 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
428 base::Unretained(this))); | |
429 | |
430 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
431 EXPECT_EQ(callback_count_, 2); | |
432 EXPECT_EQ(error_callback_count_, 0); | |
433 EXPECT_EQ(observer_->state_changed_count_, 0); | |
434 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
435 | |
436 media_endpoint_->SetConfiguration( | |
437 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
438 properties_); | |
439 | |
440 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
441 EXPECT_EQ(callback_count_, 2); | |
442 EXPECT_EQ(error_callback_count_, 0); | |
443 EXPECT_EQ(observer_->state_changed_count_, 1); | |
444 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
445 | |
446 fake_transport_->SetState(media_endpoint_->object_path(), "pending"); | |
447 | |
448 message_loop_.RunUntilIdle(); | |
449 | |
450 // Acquire is called when the state of |audio_sink_| becomes STATE_PENDING, | |
451 // and Acquire will trigger state change. Therefore, the state will be | |
452 // STATE_ACTIVE right after STATE_PENDING. | |
453 // State: STATE_IDLE -> STATE_PENDING -> STATE_ACTIVE | |
454 EXPECT_EQ(observer_->state_changed_count_, 3); | |
455 | |
456 // Gets the media object and makes it invisible to see if the state of the | |
457 // audio sink changes accordingly. | |
458 fake_media_->SetVisible(false); | |
459 | |
460 GetFakeMediaEndpoint(); | |
461 | |
462 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID); | |
463 EXPECT_EQ(media_endpoint_, nullptr); | |
464 | |
465 // The state becomes disconnted and then invalid, since the removal of | |
466 // transport object should happend before media becomes invisible. | |
467 // State: STATE_ACTIVE -> STATE_DISCONNECTED -> STATE_INVALID | |
468 EXPECT_EQ(observer_->state_changed_count_, 5); | |
469 EXPECT_EQ(observer_->volume_changed_count_, 2); | |
470 } | |
471 | |
472 // Checks if the observer is notified on transport-removed event when the state | |
473 // of |audio_sink_| is STATE_IDEL. Once the media transport object is removed, | |
474 // the audio sink is disconnected. | |
475 TEST_F(BluetoothAudioSinkBlueZTest, TransportRemovedDuringIdleState) { | |
476 GetAudioSink(); | |
477 | |
478 media_endpoint_->SelectConfiguration( | |
479 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
480 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
481 base::Unretained(this))); | |
482 | |
483 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
484 EXPECT_EQ(callback_count_, 2); | |
485 EXPECT_EQ(error_callback_count_, 0); | |
486 EXPECT_EQ(observer_->state_changed_count_, 0); | |
487 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
488 | |
489 media_endpoint_->SetConfiguration( | |
490 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
491 properties_); | |
492 | |
493 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
494 EXPECT_EQ(callback_count_, 2); | |
495 EXPECT_EQ(error_callback_count_, 0); | |
496 EXPECT_EQ(observer_->state_changed_count_, 1); | |
497 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
498 | |
499 // Makes the transport object invalid to see if the state of the audio sink | |
500 // changes accordingly. | |
501 fake_transport_->SetValid(media_endpoint_, false); | |
502 | |
503 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
504 EXPECT_NE(media_endpoint_, nullptr); | |
505 EXPECT_EQ(observer_->state_changed_count_, 2); | |
506 EXPECT_EQ(observer_->volume_changed_count_, 2); | |
507 } | |
508 | |
509 TEST_F(BluetoothAudioSinkBlueZTest, TransportRemovedDuringActiveState) { | |
510 GetAudioSink(); | |
511 | |
512 media_endpoint_->SelectConfiguration( | |
513 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
514 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
515 base::Unretained(this))); | |
516 | |
517 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
518 EXPECT_EQ(callback_count_, 2); | |
519 EXPECT_EQ(error_callback_count_, 0); | |
520 EXPECT_EQ(observer_->state_changed_count_, 0); | |
521 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
522 | |
523 media_endpoint_->SetConfiguration( | |
524 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
525 properties_); | |
526 | |
527 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
528 EXPECT_EQ(callback_count_, 2); | |
529 EXPECT_EQ(error_callback_count_, 0); | |
530 EXPECT_EQ(observer_->state_changed_count_, 1); | |
531 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
532 | |
533 fake_transport_->SetState(media_endpoint_->object_path(), "pending"); | |
534 | |
535 message_loop_.RunUntilIdle(); | |
536 | |
537 // Acquire is called when the state of |audio_sink_| becomes STATE_PENDING, | |
538 // and Acquire will trigger state change. Therefore, the state will be | |
539 // STATE_ACTIVE right after STATE_PENDING. | |
540 // State: STATE_IDLE -> STATE_PENDING -> STATE_ACTIVE | |
541 EXPECT_EQ(observer_->state_changed_count_, 3); | |
542 | |
543 // Makes the transport object invalid to see if the state of the audio sink | |
544 // changes accordingly. | |
545 fake_transport_->SetValid(media_endpoint_, false); | |
546 | |
547 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
548 EXPECT_NE(media_endpoint_, nullptr); | |
549 EXPECT_EQ(observer_->state_changed_count_, 4); | |
550 EXPECT_EQ(observer_->volume_changed_count_, 2); | |
551 } | |
552 | |
553 TEST_F(BluetoothAudioSinkBlueZTest, | |
554 AdapterPoweredChangedDuringDisconnectedState) { | |
555 GetAudioSink(); | |
556 | |
557 adapter_->SetPowered(false, base::Bind(&BluetoothAudioSinkBlueZTest::Callback, | |
558 base::Unretained(this)), | |
559 base::Bind(&BluetoothAudioSinkBlueZTest::ErrorCallback, | |
560 base::Unretained(this))); | |
561 | |
562 EXPECT_TRUE(adapter_->IsPresent()); | |
563 EXPECT_FALSE(adapter_->IsPowered()); | |
564 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
565 EXPECT_EQ(callback_count_, 2); | |
566 EXPECT_EQ(error_callback_count_, 0); | |
567 EXPECT_EQ(observer_->state_changed_count_, 0); | |
568 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
569 | |
570 adapter_->SetPowered(true, base::Bind(&BluetoothAudioSinkBlueZTest::Callback, | |
571 base::Unretained(this)), | |
572 base::Bind(&BluetoothAudioSinkBlueZTest::ErrorCallback, | |
573 base::Unretained(this))); | |
574 | |
575 EXPECT_TRUE(adapter_->IsPresent()); | |
576 EXPECT_TRUE(adapter_->IsPowered()); | |
577 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
578 EXPECT_EQ(callback_count_, 3); | |
579 EXPECT_EQ(error_callback_count_, 0); | |
580 EXPECT_EQ(observer_->state_changed_count_, 0); | |
581 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
582 } | |
583 | |
584 TEST_F(BluetoothAudioSinkBlueZTest, AdapterPoweredChangedDuringIdleState) { | |
585 GetAudioSink(); | |
586 | |
587 media_endpoint_->SelectConfiguration( | |
588 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
589 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
590 base::Unretained(this))); | |
591 | |
592 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
593 EXPECT_EQ(callback_count_, 2); | |
594 EXPECT_EQ(error_callback_count_, 0); | |
595 EXPECT_EQ(observer_->state_changed_count_, 0); | |
596 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
597 | |
598 media_endpoint_->SetConfiguration( | |
599 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
600 properties_); | |
601 | |
602 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
603 EXPECT_EQ(callback_count_, 2); | |
604 EXPECT_EQ(error_callback_count_, 0); | |
605 EXPECT_EQ(observer_->state_changed_count_, 1); | |
606 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
607 | |
608 adapter_->SetPowered(false, base::Bind(&BluetoothAudioSinkBlueZTest::Callback, | |
609 base::Unretained(this)), | |
610 base::Bind(&BluetoothAudioSinkBlueZTest::ErrorCallback, | |
611 base::Unretained(this))); | |
612 GetFakeMediaEndpoint(); | |
613 | |
614 EXPECT_TRUE(adapter_->IsPresent()); | |
615 EXPECT_FALSE(adapter_->IsPowered()); | |
616 EXPECT_NE(media_endpoint_, nullptr); | |
617 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
618 EXPECT_EQ(callback_count_, 3); | |
619 EXPECT_EQ(error_callback_count_, 0); | |
620 EXPECT_EQ(observer_->state_changed_count_, 2); | |
621 EXPECT_EQ(observer_->volume_changed_count_, 2); | |
622 } | |
623 | |
624 TEST_F(BluetoothAudioSinkBlueZTest, | |
625 UnregisterAudioSinkDuringDisconnectedState) { | |
626 GetAudioSink(); | |
627 | |
628 audio_sink_->Unregister( | |
629 base::Bind(&BluetoothAudioSinkBlueZTest::Callback, | |
630 base::Unretained(this)), | |
631 base::Bind(&BluetoothAudioSinkBlueZTest::UnregisterErrorCallback, | |
632 base::Unretained(this))); | |
633 | |
634 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID); | |
635 EXPECT_EQ(callback_count_, 2); | |
636 EXPECT_EQ(error_callback_count_, 0); | |
637 EXPECT_EQ(observer_->state_changed_count_, 1); | |
638 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
639 } | |
640 | |
641 TEST_F(BluetoothAudioSinkBlueZTest, UnregisterAudioSinkDuringIdleState) { | |
642 GetAudioSink(); | |
643 | |
644 media_endpoint_->SelectConfiguration( | |
645 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
646 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
647 base::Unretained(this))); | |
648 | |
649 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
650 EXPECT_EQ(callback_count_, 2); | |
651 EXPECT_EQ(error_callback_count_, 0); | |
652 EXPECT_EQ(observer_->state_changed_count_, 0); | |
653 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
654 | |
655 media_endpoint_->SetConfiguration( | |
656 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
657 properties_); | |
658 | |
659 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
660 EXPECT_EQ(callback_count_, 2); | |
661 EXPECT_EQ(error_callback_count_, 0); | |
662 EXPECT_EQ(observer_->state_changed_count_, 1); | |
663 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
664 | |
665 audio_sink_->Unregister( | |
666 base::Bind(&BluetoothAudioSinkBlueZTest::Callback, | |
667 base::Unretained(this)), | |
668 base::Bind(&BluetoothAudioSinkBlueZTest::UnregisterErrorCallback, | |
669 base::Unretained(this))); | |
670 | |
671 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID); | |
672 EXPECT_EQ(callback_count_, 3); | |
673 EXPECT_EQ(error_callback_count_, 0); | |
674 | |
675 // The state becomes disconnted and then invalid, since the removal of | |
676 // transport object should happend before the unregistration of endpoint. | |
677 // State: STATE_IDLE -> STATE_DISCONNECTED -> STATE_INVALID | |
678 EXPECT_EQ(observer_->state_changed_count_, 3); | |
679 EXPECT_EQ(observer_->volume_changed_count_, 2); | |
680 } | |
681 | |
682 TEST_F(BluetoothAudioSinkBlueZTest, UnregisterAudioSinkDuringActiveState) { | |
683 GetAudioSink(); | |
684 | |
685 media_endpoint_->SelectConfiguration( | |
686 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
687 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
688 base::Unretained(this))); | |
689 | |
690 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
691 EXPECT_EQ(callback_count_, 2); | |
692 EXPECT_EQ(error_callback_count_, 0); | |
693 EXPECT_EQ(observer_->state_changed_count_, 0); | |
694 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
695 | |
696 media_endpoint_->SetConfiguration( | |
697 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
698 properties_); | |
699 | |
700 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
701 EXPECT_EQ(callback_count_, 2); | |
702 EXPECT_EQ(error_callback_count_, 0); | |
703 EXPECT_EQ(observer_->state_changed_count_, 1); | |
704 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
705 | |
706 fake_transport_->SetState(media_endpoint_->object_path(), "pending"); | |
707 | |
708 message_loop_.RunUntilIdle(); | |
709 | |
710 // Acquire is called when the state of |audio_sink_| becomes STATE_PENDING, | |
711 // and Acquire will trigger state change. Therefore, the state will be | |
712 // STATE_ACTIVE right after STATE_PENDING. | |
713 // State: STATE_IDLE -> STATE_PENDING -> STATE_ACTIVE | |
714 EXPECT_EQ(observer_->state_changed_count_, 3); | |
715 | |
716 audio_sink_->Unregister( | |
717 base::Bind(&BluetoothAudioSinkBlueZTest::Callback, | |
718 base::Unretained(this)), | |
719 base::Bind(&BluetoothAudioSinkBlueZTest::UnregisterErrorCallback, | |
720 base::Unretained(this))); | |
721 | |
722 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID); | |
723 EXPECT_EQ(callback_count_, 3); | |
724 EXPECT_EQ(error_callback_count_, 0); | |
725 EXPECT_EQ(observer_->state_changed_count_, 5); | |
726 EXPECT_EQ(observer_->volume_changed_count_, 2); | |
727 } | |
728 | |
729 TEST_F(BluetoothAudioSinkBlueZTest, StateChanged) { | |
730 GetAudioSink(); | |
731 | |
732 media_endpoint_->SelectConfiguration( | |
733 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
734 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
735 base::Unretained(this))); | |
736 | |
737 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
738 EXPECT_EQ(callback_count_, 2); | |
739 EXPECT_EQ(error_callback_count_, 0); | |
740 EXPECT_EQ(observer_->state_changed_count_, 0); | |
741 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
742 | |
743 media_endpoint_->SetConfiguration( | |
744 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
745 properties_); | |
746 | |
747 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
748 EXPECT_EQ(callback_count_, 2); | |
749 EXPECT_EQ(error_callback_count_, 0); | |
750 EXPECT_EQ(observer_->state_changed_count_, 1); | |
751 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
752 | |
753 // Changes the current state of transport to pending. | |
754 fake_transport_->SetState(media_endpoint_->object_path(), "pending"); | |
755 | |
756 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_PENDING); | |
757 EXPECT_EQ(observer_->state_changed_count_, 3); | |
758 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
759 } | |
760 | |
761 TEST_F(BluetoothAudioSinkBlueZTest, VolumeChanged) { | |
762 GetAudioSink(); | |
763 | |
764 media_endpoint_->SelectConfiguration( | |
765 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
766 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
767 base::Unretained(this))); | |
768 | |
769 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
770 EXPECT_EQ(callback_count_, 2); | |
771 EXPECT_EQ(error_callback_count_, 0); | |
772 EXPECT_EQ(observer_->state_changed_count_, 0); | |
773 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
774 | |
775 media_endpoint_->SetConfiguration( | |
776 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
777 properties_); | |
778 | |
779 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
780 EXPECT_EQ(callback_count_, 2); | |
781 EXPECT_EQ(error_callback_count_, 0); | |
782 EXPECT_EQ(observer_->state_changed_count_, 1); | |
783 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
784 | |
785 // |kTransportVolume| is the initial volume of the transport, and this | |
786 // value is propagated to the audio sink via SetConfiguration. | |
787 EXPECT_EQ(audio_sink_->GetVolume(), | |
788 FakeBluetoothMediaTransportClient::kTransportVolume); | |
789 | |
790 // Changes volume to a valid level. | |
791 fake_transport_->SetVolume(media_endpoint_->object_path(), 100); | |
792 | |
793 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
794 EXPECT_EQ(observer_->state_changed_count_, 1); | |
795 EXPECT_EQ(observer_->volume_changed_count_, 2); | |
796 EXPECT_EQ(audio_sink_->GetVolume(), 100); | |
797 | |
798 // Changes volume to an invalid level. | |
799 fake_transport_->SetVolume(media_endpoint_->object_path(), 200); | |
800 | |
801 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
802 EXPECT_EQ(observer_->state_changed_count_, 1); | |
803 EXPECT_EQ(observer_->volume_changed_count_, 3); | |
804 EXPECT_EQ(audio_sink_->GetVolume(), BluetoothAudioSink::kInvalidVolume); | |
805 } | |
806 | |
807 TEST_F(BluetoothAudioSinkBlueZTest, AcquireFD) { | |
808 GetAudioSink(); | |
809 | |
810 media_endpoint_->SelectConfiguration( | |
811 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
812 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
813 base::Unretained(this))); | |
814 | |
815 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
816 EXPECT_EQ(callback_count_, 2); | |
817 EXPECT_EQ(error_callback_count_, 0); | |
818 EXPECT_EQ(observer_->state_changed_count_, 0); | |
819 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
820 | |
821 media_endpoint_->SetConfiguration( | |
822 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
823 properties_); | |
824 | |
825 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
826 EXPECT_EQ(callback_count_, 2); | |
827 EXPECT_EQ(error_callback_count_, 0); | |
828 EXPECT_EQ(observer_->state_changed_count_, 1); | |
829 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
830 | |
831 fake_transport_->SetState(media_endpoint_->object_path(), "pending"); | |
832 | |
833 std::vector<char> data_one(16, 0x12); | |
834 fake_transport_->WriteData(media_endpoint_->object_path(), data_one); | |
835 | |
836 message_loop_.RunUntilIdle(); | |
837 | |
838 // Acquire is called when the state of |audio_sink_| becomes STATE_PENDING, | |
839 // and Acquire will trigger state change. Therefore, the state will be | |
840 // STATE_ACTIVE right after STATE_PENDING. | |
841 // State: STATE_IDLE -> STATE_PENDING -> STATE_ACTIVE | |
842 EXPECT_EQ(observer_->state_changed_count_, 3); | |
843 EXPECT_EQ(observer_->total_read_, data_one.size()); | |
844 EXPECT_EQ(observer_->data_, data_one); | |
845 EXPECT_EQ(observer_->read_mtu_, | |
846 FakeBluetoothMediaTransportClient::kDefaultReadMtu); | |
847 } | |
848 | |
849 // Tests the case where the remote device pauses and resume audio streaming. | |
850 TEST_F(BluetoothAudioSinkBlueZTest, PauseAndResume) { | |
851 GetAudioSink(); | |
852 | |
853 media_endpoint_->SelectConfiguration( | |
854 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
855 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
856 base::Unretained(this))); | |
857 | |
858 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
859 EXPECT_EQ(callback_count_, 2); | |
860 EXPECT_EQ(error_callback_count_, 0); | |
861 EXPECT_EQ(observer_->state_changed_count_, 0); | |
862 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
863 | |
864 media_endpoint_->SetConfiguration( | |
865 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
866 properties_); | |
867 | |
868 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
869 EXPECT_EQ(callback_count_, 2); | |
870 EXPECT_EQ(error_callback_count_, 0); | |
871 EXPECT_EQ(observer_->state_changed_count_, 1); | |
872 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
873 | |
874 fake_transport_->SetState(media_endpoint_->object_path(), "pending"); | |
875 | |
876 std::vector<char> data_one(16, 0x12); | |
877 fake_transport_->WriteData(media_endpoint_->object_path(), data_one); | |
878 | |
879 message_loop_.RunUntilIdle(); | |
880 | |
881 EXPECT_EQ(observer_->data_, data_one); | |
882 EXPECT_EQ(observer_->read_mtu_, | |
883 FakeBluetoothMediaTransportClient::kDefaultReadMtu); | |
884 EXPECT_EQ(observer_->state_changed_count_, 3); | |
885 EXPECT_EQ(observer_->total_read_, data_one.size()); | |
886 | |
887 // Simulates the situation where the remote device pauses and resume audio | |
888 // streaming. | |
889 fake_transport_->SetState(media_endpoint_->object_path(), "idle"); | |
890 | |
891 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
892 EXPECT_EQ(observer_->state_changed_count_, 4); | |
893 | |
894 fake_transport_->SetState(media_endpoint_->object_path(), "pending"); | |
895 | |
896 std::vector<char> data_two(8, 0x10); | |
897 fake_transport_->WriteData(media_endpoint_->object_path(), data_two); | |
898 | |
899 message_loop_.RunUntilIdle(); | |
900 | |
901 EXPECT_EQ(observer_->data_, data_two); | |
902 EXPECT_EQ(observer_->read_mtu_, | |
903 FakeBluetoothMediaTransportClient::kDefaultReadMtu); | |
904 EXPECT_EQ(observer_->state_changed_count_, 6); | |
905 EXPECT_EQ(observer_->total_read_, data_two.size()); | |
906 } | |
907 | |
908 TEST_F(BluetoothAudioSinkBlueZTest, ContinuouslyStreaming) { | |
909 GetAudioSink(); | |
910 | |
911 media_endpoint_->SelectConfiguration( | |
912 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}), | |
913 base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback, | |
914 base::Unretained(this))); | |
915 | |
916 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); | |
917 EXPECT_EQ(callback_count_, 2); | |
918 EXPECT_EQ(error_callback_count_, 0); | |
919 EXPECT_EQ(observer_->state_changed_count_, 0); | |
920 EXPECT_EQ(observer_->volume_changed_count_, 0); | |
921 | |
922 media_endpoint_->SetConfiguration( | |
923 fake_transport_->GetTransportPath(media_endpoint_->object_path()), | |
924 properties_); | |
925 | |
926 EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE); | |
927 EXPECT_EQ(callback_count_, 2); | |
928 EXPECT_EQ(error_callback_count_, 0); | |
929 EXPECT_EQ(observer_->state_changed_count_, 1); | |
930 EXPECT_EQ(observer_->volume_changed_count_, 1); | |
931 | |
932 fake_transport_->SetState(media_endpoint_->object_path(), "pending"); | |
933 | |
934 std::vector<char> data_one(16, 0x12); | |
935 fake_transport_->WriteData(media_endpoint_->object_path(), data_one); | |
936 | |
937 message_loop_.RunUntilIdle(); | |
938 | |
939 EXPECT_EQ(observer_->data_, data_one); | |
940 EXPECT_EQ(observer_->read_mtu_, | |
941 FakeBluetoothMediaTransportClient::kDefaultReadMtu); | |
942 EXPECT_EQ(observer_->state_changed_count_, 3); | |
943 EXPECT_EQ(observer_->total_read_, data_one.size()); | |
944 | |
945 std::vector<char> data_two(8, 0x10); | |
946 fake_transport_->WriteData(media_endpoint_->object_path(), data_two); | |
947 | |
948 message_loop_.RunUntilIdle(); | |
949 | |
950 EXPECT_EQ(observer_->data_, data_two); | |
951 EXPECT_EQ(observer_->read_mtu_, | |
952 FakeBluetoothMediaTransportClient::kDefaultReadMtu); | |
953 EXPECT_EQ(observer_->state_changed_count_, 3); | |
954 EXPECT_EQ(observer_->total_read_, data_one.size() + data_two.size()); | |
955 } | |
956 | |
957 } // namespace bluez | |
OLD | NEW |