Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(445)

Side by Side Diff: device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc

Issue 910023002: device/bluetooth:Implement BluetoothMediaEndpointServiceProvider delegate and media-related overrid… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <vector> 5 #include <vector>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop/message_loop.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"
11 #include "chromeos/dbus/dbus_thread_manager.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"
12 #include "dbus/object_path.h" 18 #include "dbus/object_path.h"
13 #include "device/bluetooth/bluetooth_adapter.h" 19 #include "device/bluetooth/bluetooth_adapter.h"
14 #include "device/bluetooth/bluetooth_adapter_factory.h" 20 #include "device/bluetooth/bluetooth_adapter_factory.h"
15 #include "device/bluetooth/bluetooth_audio_sink.h" 21 #include "device/bluetooth/bluetooth_audio_sink.h"
16 #include "device/bluetooth/bluetooth_audio_sink_chromeos.h" 22 #include "device/bluetooth/bluetooth_audio_sink_chromeos.h"
17 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
18 24
25 using dbus::ObjectPath;
19 using device::BluetoothAdapter; 26 using device::BluetoothAdapter;
20 using device::BluetoothAdapterFactory; 27 using device::BluetoothAdapterFactory;
21 using device::BluetoothAudioSink; 28 using device::BluetoothAudioSink;
22 29
23 namespace chromeos { 30 namespace chromeos {
24 31
25 class TestAudioSinkObserver : public BluetoothAudioSink::Observer { 32 class TestAudioSinkObserver : public BluetoothAudioSink::Observer {
26 public: 33 public:
27 explicit TestAudioSinkObserver(scoped_refptr<BluetoothAudioSink> audio_sink) 34 explicit TestAudioSinkObserver(scoped_refptr<BluetoothAudioSink> audio_sink)
28 : state_changed_count_(0), 35 : state_changed_count_(0),
(...skipping 20 matching lines...) Expand all
49 int volume_changed_count_; 56 int volume_changed_count_;
50 BluetoothAudioSink::State state_; 57 BluetoothAudioSink::State state_;
51 58
52 private: 59 private:
53 scoped_refptr<BluetoothAudioSink> audio_sink_; 60 scoped_refptr<BluetoothAudioSink> audio_sink_;
54 }; 61 };
55 62
56 class BluetoothAudioSinkChromeOSTest : public testing::Test { 63 class BluetoothAudioSinkChromeOSTest : public testing::Test {
57 public: 64 public:
58 void SetUp() override { 65 void SetUp() override {
59 chromeos::DBusThreadManager::Initialize(); 66 DBusThreadManager::Initialize();
60 67
61 callback_count_ = 0; 68 callback_count_ = 0;
62 error_callback_count_ = 0; 69 error_callback_count_ = 0;
63 audio_sink_ = nullptr; 70 audio_sink_ = nullptr;
64 adapter_ = nullptr; 71 adapter_ = nullptr;
65 72
73 // Initiates Delegate::TransportProperties with default values.
74 properties_.device =
75 ObjectPath(FakeBluetoothMediaTransportClient::kTransportDevicePath);
76 properties_.uuid = BluetoothMediaClient::kBluetoothAudioSinkUUID;
77 properties_.codec = FakeBluetoothMediaTransportClient::kTransportCodec;
78 properties_.configuration =
79 FakeBluetoothMediaTransportClient::kTransportConfiguration;
80 properties_.state = BluetoothMediaTransportClient::kStateIdle;
81 properties_.delay.reset(
82 new uint16_t(FakeBluetoothMediaTransportClient::kTransportDelay));
83 properties_.volume.reset(
84 new uint16_t(FakeBluetoothMediaTransportClient::kTransportVolume));
85
66 GetAdapter(); 86 GetAdapter();
67 } 87 }
68 88
69 void TearDown() override { 89 void TearDown() override {
70 callback_count_ = 0; 90 callback_count_ = 0;
71 error_callback_count_ = 0; 91 error_callback_count_ = 0;
72 92
73 // The adapter should outlive audio sink. 93 // The adapter should outlive audio sink.
74 audio_sink_ = nullptr; 94 audio_sink_ = nullptr;
75 adapter_ = nullptr; 95 adapter_ = nullptr;
76 DBusThreadManager::Shutdown(); 96 DBusThreadManager::Shutdown();
77 } 97 }
78 98
79 // Get the existing Bluetooth adapter. 99 // Gets the existing Bluetooth adapter.
80 void GetAdapter() { 100 void GetAdapter() {
81 BluetoothAdapterFactory::GetAdapter( 101 BluetoothAdapterFactory::GetAdapter(
82 base::Bind(&BluetoothAudioSinkChromeOSTest::GetAdapterCallback, 102 base::Bind(&BluetoothAudioSinkChromeOSTest::GetAdapterCallback,
83 base::Unretained(this))); 103 base::Unretained(this)));
84 } 104 }
85 105
106 // Called whenever BluetoothAdapter is retrieved successfully.
86 void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter) { 107 void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
87 adapter_ = adapter; 108 adapter_ = adapter;
88 109
89 ASSERT_NE(adapter_.get(), nullptr); 110 ASSERT_NE(adapter_.get(), nullptr);
90 ASSERT_TRUE(adapter_->IsInitialized()); 111 ASSERT_TRUE(adapter_->IsInitialized());
91 adapter_->SetPowered( 112 adapter_->SetPowered(
92 true, 113 true,
93 base::Bind(&BluetoothAudioSinkChromeOSTest::Callback, 114 base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
94 base::Unretained(this)), 115 base::Unretained(this)),
95 base::Bind(&BluetoothAudioSinkChromeOSTest::ErrorCallback, 116 base::Bind(&BluetoothAudioSinkChromeOSTest::ErrorCallback,
96 base::Unretained(this))); 117 base::Unretained(this)));
97 ASSERT_TRUE(adapter_->IsPresent()); 118 ASSERT_TRUE(adapter_->IsPresent());
98 ASSERT_TRUE(adapter_->IsPowered()); 119 ASSERT_TRUE(adapter_->IsPowered());
99 ASSERT_EQ(callback_count_, 1); 120 ASSERT_EQ(callback_count_, 1);
100 ASSERT_EQ(error_callback_count_, 0); 121 ASSERT_EQ(error_callback_count_, 0);
122
123 // Resets callback_count_.
101 --callback_count_; 124 --callback_count_;
102 } 125 }
103 126
127 // Registers BluetoothAudioSinkChromeOS with default codec and capabilities.
128 void GetAudioSink() {
129 // Sets up valid codec and capabilities.
130 BluetoothAudioSink::Options options;
131 ASSERT_EQ(options.codec, 0x00);
132 ASSERT_EQ(options.capabilities,
133 std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}));
134
135 // Registers |audio_sink_| with valid codec and capabilities
136 adapter_->RegisterAudioSink(
137 options,
138 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
139 base::Unretained(this)),
140 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
141 base::Unretained(this)));
142
143 ASSERT_EQ(callback_count_, 1);
144 ASSERT_EQ(error_callback_count_, 0);
145 }
146
104 // Called whenever RegisterAudioSink is completed successfully. 147 // Called whenever RegisterAudioSink is completed successfully.
105 void RegisterCallback( 148 void RegisterCallback(
106 scoped_refptr<BluetoothAudioSink> audio_sink) { 149 scoped_refptr<BluetoothAudioSink> audio_sink) {
107 ++callback_count_; 150 ++callback_count_;
108 audio_sink_ = audio_sink; 151 audio_sink_ = audio_sink;
109 ASSERT_NE(audio_sink_.get(), nullptr); 152 ASSERT_NE(audio_sink_.get(), nullptr);
110 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED); 153 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
154
155 // Updates visible of a registered media endpoint.
156 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
157 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
158 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
159 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
160 audio_sink_chromeos->GetEndpointServiceProvider());
161 media_endpoint->SetVisible(true);
111 } 162 }
112 163
113 // Called whenever RegisterAudioSink failed. 164 // Called whenever RegisterAudioSink failed.
114 void RegisterErrorCallback(BluetoothAudioSink::ErrorCode error_code) { 165 void RegisterErrorCallback(BluetoothAudioSink::ErrorCode error_code) {
115 ++error_callback_count_; 166 ++error_callback_count_;
116 ASSERT_EQ(error_code, BluetoothAudioSink::ERROR_NOT_REGISTERED); 167 ASSERT_EQ(error_code, BluetoothAudioSink::ERROR_NOT_REGISTERED);
117 } 168 }
118 169
170 // Called whenever there capabilities are returned from SelectConfiguration.
171 void SelectConfigurationCallback(const std::vector<uint8_t>& capabilities) {
172 ++callback_count_;
173
174 // |capabilities| should be the same as the capabilities for registering an
175 // audio sink in GetAudioSink().
176 ASSERT_EQ(capabilities, std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}));
177 }
178
119 // Generic callbacks. 179 // Generic callbacks.
120 void Callback() { 180 void Callback() {
121 ++callback_count_; 181 ++callback_count_;
122 } 182 }
123 183
124 void ErrorCallback() { 184 void ErrorCallback() {
125 ++error_callback_count_; 185 ++error_callback_count_;
126 } 186 }
127 187
128 protected: 188 protected:
129 int callback_count_; 189 int callback_count_;
130 int error_callback_count_; 190 int error_callback_count_;
191
131 base::MessageLoop message_loop_; 192 base::MessageLoop message_loop_;
193
132 scoped_refptr<BluetoothAdapter> adapter_; 194 scoped_refptr<BluetoothAdapter> adapter_;
133 scoped_refptr<BluetoothAudioSink> audio_sink_; 195 scoped_refptr<BluetoothAudioSink> audio_sink_;
196
197 // The default property set used while calling SetConfiguration on a media
198 // endpoint object.
199 BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties
200 properties_;
134 }; 201 };
135 202
136 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterSucceeded) { 203 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterSucceeded) {
137 // Sets up valid codec and capabilities. 204 GetAudioSink();
138 BluetoothAudioSink::Options options;
139 ASSERT_EQ(options.codec, 0x00);
140 ASSERT_EQ(options.capabilities,
141 std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}));
142 adapter_->RegisterAudioSink(
143 options,
144 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
145 base::Unretained(this)),
146 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
147 base::Unretained(this)));
148 205
149 // Adds observer for the audio sink. 206 // Adds an observer for |audio_sink_|.
150 TestAudioSinkObserver observer(audio_sink_); 207 TestAudioSinkObserver observer(audio_sink_);
151
152 ASSERT_EQ(callback_count_, 1);
153 ASSERT_EQ(error_callback_count_, 0);
154 ASSERT_EQ(observer.state_changed_count_, 0); 208 ASSERT_EQ(observer.state_changed_count_, 0);
155 ASSERT_EQ(observer.volume_changed_count_, 0); 209 ASSERT_EQ(observer.volume_changed_count_, 0);
156 } 210 }
157 211
158 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterFailedWithInvalidOptions) { 212 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterFailedWithInvalidOptions) {
159 // Sets options with an invalid codec and valid capabilities. 213 // Sets options with an invalid codec and valid capabilities.
160 BluetoothAudioSink::Options options; 214 BluetoothAudioSink::Options options;
161 options.codec = 0xff; 215 options.codec = 0xff;
162 options.capabilities = std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}); 216 options.capabilities = std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35});
163 217
(...skipping 10 matching lines...) Expand all
174 // Sets options with a valid codec and invalid capabilities. 228 // Sets options with a valid codec and invalid capabilities.
175 options.codec = 0x00; 229 options.codec = 0x00;
176 options.capabilities.clear(); 230 options.capabilities.clear();
177 adapter_->RegisterAudioSink( 231 adapter_->RegisterAudioSink(
178 options, 232 options,
179 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback, 233 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
180 base::Unretained(this)), 234 base::Unretained(this)),
181 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback, 235 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
182 base::Unretained(this))); 236 base::Unretained(this)));
183 237
238
184 ASSERT_EQ(callback_count_, 0); 239 ASSERT_EQ(callback_count_, 0);
185 ASSERT_EQ(error_callback_count_, 2); 240 ASSERT_EQ(error_callback_count_, 2);
186 } 241 }
187 242
243 TEST_F(BluetoothAudioSinkChromeOSTest, SelectConfiguration) {
244 GetAudioSink();
245
246 // Adds an observer for |audio_sink_|.
247 TestAudioSinkObserver observer(audio_sink_);
248 ASSERT_EQ(observer.state_changed_count_, 0);
249 ASSERT_EQ(observer.volume_changed_count_, 0);
250
251 // Simulates calling SelectConfiguration on the media endpoint object owned by
252 // |audio_sink_| with some fake capabilities.
253 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
254 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
255 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
256 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
257 audio_sink_chromeos->GetEndpointServiceProvider());
258 ASSERT_NE(media_endpoint, nullptr);
259
260 media_endpoint->SelectConfiguration(
261 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
262 base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
263 base::Unretained(this)));
264
265 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
266 ASSERT_EQ(callback_count_, 2);
267 ASSERT_EQ(error_callback_count_, 0);
268 ASSERT_EQ(observer.state_changed_count_, 0);
269 ASSERT_EQ(observer.volume_changed_count_, 0);
270 }
271
272 TEST_F(BluetoothAudioSinkChromeOSTest, SetConfiguration) {
273 GetAudioSink();
274
275 // Adds an observer for |audio_sink_|.
276 TestAudioSinkObserver observer(audio_sink_);
277 ASSERT_EQ(observer.state_changed_count_, 0);
278 ASSERT_EQ(observer.volume_changed_count_, 0);
279
280 // Simulates calling SetConfiguration on the media endpoint object owned by
281 // |audio_sink_| with a fake transport path and a
282 // Delegate::TransportProperties structure.
283 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
284 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
285 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
286 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
287 audio_sink_chromeos->GetEndpointServiceProvider());
288 ASSERT_NE(media_endpoint, nullptr);
289
290 media_endpoint->SetConfiguration(
291 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
292 properties_);
293
294 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE);
295 ASSERT_EQ(callback_count_, 1);
296 ASSERT_EQ(error_callback_count_, 0);
297 ASSERT_EQ(observer.state_changed_count_, 1);
298 ASSERT_EQ(observer.volume_changed_count_, 1);
299 }
300
301 TEST_F(BluetoothAudioSinkChromeOSTest, SetConfigurationWithUnexpectedState) {
302 GetAudioSink();
303
304 // Adds an observer for |audio_sink_|.
305 TestAudioSinkObserver observer(audio_sink_);
306 ASSERT_EQ(observer.state_changed_count_, 0);
307 ASSERT_EQ(observer.volume_changed_count_, 0);
308
309 // Simulates calling SetConfiguration on the media endpoint object owned by
310 // |audio_sink_| with a fake transport path and a
311 // Delegate::TransportProperties structure.
312 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
313 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
314 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
315 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
316 audio_sink_chromeos->GetEndpointServiceProvider());
317 ASSERT_NE(media_endpoint, nullptr);
318
319 // Set state of Delegate::TransportProperties with an unexpected value.
320 properties_.state = "active";
321
322 media_endpoint->SetConfiguration(
323 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
324 properties_);
325
326 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
327 ASSERT_EQ(callback_count_, 1);
328 ASSERT_EQ(error_callback_count_, 0);
329 ASSERT_EQ(observer.state_changed_count_, 0);
330 ASSERT_EQ(observer.volume_changed_count_, 0);
331 }
332
333 // Checks if the observer is notified while the media object is
334 // removed(invisible). Once the media object is removed, the audio sink is no
335 // longer valid.
336 TEST_F(BluetoothAudioSinkChromeOSTest, ObserverNotifiedWhenMediaRemoved) {
337 GetAudioSink();
338
339 // Adds an observer for |audio_sink_|.
340 TestAudioSinkObserver observer(audio_sink_);
341 ASSERT_EQ(observer.state_changed_count_, 0);
342 ASSERT_EQ(observer.volume_changed_count_, 0);
343
344 // Gets the media object and makes it invisible to see if the state of the
345 // audio sink changes accordingly.
346 FakeBluetoothMediaClient* media = static_cast<FakeBluetoothMediaClient*>(
347 DBusThreadManager::Get()->GetBluetoothMediaClient());
348 media->SetVisible(false);
349
350 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
351 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
352 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
353 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
354 audio_sink_chromeos->GetEndpointServiceProvider());
355
356 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID);
357 ASSERT_EQ(media_endpoint, nullptr);
358 }
359
360 // Checks if the observer is notified while the media transport is
361 // removed(invisible). Once the media transport object is removed, the audio
362 // sink is disconnected.
363 TEST_F(BluetoothAudioSinkChromeOSTest, ObserverNotifiedWhenTransportRemoved) {
364 GetAudioSink();
365
366 // Adds an observer for |audio_sink_|.
367 TestAudioSinkObserver observer(audio_sink_);
368 ASSERT_EQ(observer.state_changed_count_, 0);
369 ASSERT_EQ(observer.volume_changed_count_, 0);
370
371 // Simulates calling SetConfiguration on the media endpoint object owned by
372 // |audio_sink_| with a fake transport path and a
373 // Delegate::TransportProperties structure.
374 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
375 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
376 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
377 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
378 audio_sink_chromeos->GetEndpointServiceProvider());
379 ASSERT_NE(media_endpoint, nullptr);
380
381 media_endpoint->SetConfiguration(
382 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
383 properties_);
384
385 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE);
386 ASSERT_EQ(callback_count_, 1);
387 ASSERT_EQ(error_callback_count_, 0);
388 ASSERT_EQ(observer.state_changed_count_, 1);
389 ASSERT_EQ(observer.volume_changed_count_, 1);
390
391 // Gets the media transport object and makes it invisible to see if the state
392 // of the audio sink changes accordingly.
393 FakeBluetoothMediaTransportClient* transport =
394 static_cast<FakeBluetoothMediaTransportClient*>(
395 DBusThreadManager::Get()->GetBluetoothMediaTransportClient());
396
397 transport->SetVisible(media_endpoint->object_path(), false);
398 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
399 ASSERT_NE(media_endpoint, nullptr);
400 }
401
188 } // namespace chromeos 402 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698