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

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: Removed SetVisible from FakeBluetoothMediaEndpointServiceProvider and fixed nits. 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);
111 } 154 }
112 155
113 // Called whenever RegisterAudioSink failed. 156 // Called whenever RegisterAudioSink failed.
114 void RegisterErrorCallback(BluetoothAudioSink::ErrorCode error_code) { 157 void RegisterErrorCallback(BluetoothAudioSink::ErrorCode error_code) {
115 ++error_callback_count_; 158 ++error_callback_count_;
116 ASSERT_EQ(error_code, BluetoothAudioSink::ERROR_NOT_REGISTERED); 159 ASSERT_EQ(error_code, BluetoothAudioSink::ERROR_NOT_REGISTERED);
117 } 160 }
118 161
162 // Called whenever there capabilities are returned from SelectConfiguration.
163 void SelectConfigurationCallback(const std::vector<uint8_t>& capabilities) {
164 ++callback_count_;
165
166 // |capabilities| should be the same as the capabilities for registering an
167 // audio sink in GetAudioSink().
168 ASSERT_EQ(capabilities, std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}));
169 }
170
119 // Generic callbacks. 171 // Generic callbacks.
120 void Callback() { 172 void Callback() {
121 ++callback_count_; 173 ++callback_count_;
122 } 174 }
123 175
124 void ErrorCallback() { 176 void ErrorCallback() {
125 ++error_callback_count_; 177 ++error_callback_count_;
126 } 178 }
127 179
128 protected: 180 protected:
129 int callback_count_; 181 int callback_count_;
130 int error_callback_count_; 182 int error_callback_count_;
183
131 base::MessageLoop message_loop_; 184 base::MessageLoop message_loop_;
185
132 scoped_refptr<BluetoothAdapter> adapter_; 186 scoped_refptr<BluetoothAdapter> adapter_;
133 scoped_refptr<BluetoothAudioSink> audio_sink_; 187 scoped_refptr<BluetoothAudioSink> audio_sink_;
188
189 // The default property set used while calling SetConfiguration on a media
190 // endpoint object.
191 BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties
192 properties_;
134 }; 193 };
135 194
136 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterSucceeded) { 195 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterSucceeded) {
137 // Sets up valid codec and capabilities. 196 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 197
149 // Adds observer for the audio sink. 198 // Adds an observer for |audio_sink_|.
150 TestAudioSinkObserver observer(audio_sink_); 199 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); 200 ASSERT_EQ(observer.state_changed_count_, 0);
155 ASSERT_EQ(observer.volume_changed_count_, 0); 201 ASSERT_EQ(observer.volume_changed_count_, 0);
156 } 202 }
157 203
158 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterFailedWithInvalidOptions) { 204 TEST_F(BluetoothAudioSinkChromeOSTest, RegisterFailedWithInvalidOptions) {
159 // Sets options with an invalid codec and valid capabilities. 205 // Sets options with an invalid codec and valid capabilities.
160 BluetoothAudioSink::Options options; 206 BluetoothAudioSink::Options options;
161 options.codec = 0xff; 207 options.codec = 0xff;
162 options.capabilities = std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35}); 208 options.capabilities = std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35});
163 209
(...skipping 10 matching lines...) Expand all
174 // Sets options with a valid codec and invalid capabilities. 220 // Sets options with a valid codec and invalid capabilities.
175 options.codec = 0x00; 221 options.codec = 0x00;
176 options.capabilities.clear(); 222 options.capabilities.clear();
177 adapter_->RegisterAudioSink( 223 adapter_->RegisterAudioSink(
178 options, 224 options,
179 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback, 225 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
180 base::Unretained(this)), 226 base::Unretained(this)),
181 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback, 227 base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
182 base::Unretained(this))); 228 base::Unretained(this)));
183 229
230
184 ASSERT_EQ(callback_count_, 0); 231 ASSERT_EQ(callback_count_, 0);
185 ASSERT_EQ(error_callback_count_, 2); 232 ASSERT_EQ(error_callback_count_, 2);
186 } 233 }
187 234
235 TEST_F(BluetoothAudioSinkChromeOSTest, SelectConfiguration) {
236 GetAudioSink();
237
238 // Adds an observer for |audio_sink_|.
239 TestAudioSinkObserver observer(audio_sink_);
240 ASSERT_EQ(observer.state_changed_count_, 0);
241 ASSERT_EQ(observer.volume_changed_count_, 0);
242
243 // Simulates calling SelectConfiguration on the media endpoint object owned by
244 // |audio_sink_| with some fake capabilities.
245 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
246 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
247 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
248 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
249 audio_sink_chromeos->GetEndpointServiceProvider());
250 ASSERT_NE(media_endpoint, nullptr);
251
252 media_endpoint->SelectConfiguration(
253 std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
254 base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
255 base::Unretained(this)));
256
257 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
258 ASSERT_EQ(callback_count_, 2);
259 ASSERT_EQ(error_callback_count_, 0);
260 ASSERT_EQ(observer.state_changed_count_, 0);
261 ASSERT_EQ(observer.volume_changed_count_, 0);
262 }
263
264 TEST_F(BluetoothAudioSinkChromeOSTest, SetConfiguration) {
265 GetAudioSink();
266
267 // Adds an observer for |audio_sink_|.
268 TestAudioSinkObserver observer(audio_sink_);
269 ASSERT_EQ(observer.state_changed_count_, 0);
270 ASSERT_EQ(observer.volume_changed_count_, 0);
271
272 // Simulates calling SetConfiguration on the media endpoint object owned by
273 // |audio_sink_| with a fake transport path and a
274 // Delegate::TransportProperties structure.
275 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
276 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
277 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
278 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
279 audio_sink_chromeos->GetEndpointServiceProvider());
280 ASSERT_NE(media_endpoint, nullptr);
281
282 media_endpoint->SetConfiguration(
283 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
284 properties_);
285
286 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE);
287 ASSERT_EQ(callback_count_, 1);
288 ASSERT_EQ(error_callback_count_, 0);
289 ASSERT_EQ(observer.state_changed_count_, 1);
290 ASSERT_EQ(observer.volume_changed_count_, 1);
291 }
292
293 TEST_F(BluetoothAudioSinkChromeOSTest, SetConfigurationWithUnexpectedState) {
294 GetAudioSink();
295
296 // Adds an observer for |audio_sink_|.
297 TestAudioSinkObserver observer(audio_sink_);
298 ASSERT_EQ(observer.state_changed_count_, 0);
299 ASSERT_EQ(observer.volume_changed_count_, 0);
300
301 // Simulates calling SetConfiguration on the media endpoint object owned by
302 // |audio_sink_| with a fake transport path and a
303 // Delegate::TransportProperties structure.
304 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
305 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
306 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
307 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
308 audio_sink_chromeos->GetEndpointServiceProvider());
309 ASSERT_NE(media_endpoint, nullptr);
310
311 // Set state of Delegate::TransportProperties with an unexpected value.
312 properties_.state = "active";
313
314 media_endpoint->SetConfiguration(
315 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
316 properties_);
317
318 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
319 ASSERT_EQ(callback_count_, 1);
320 ASSERT_EQ(error_callback_count_, 0);
321 ASSERT_EQ(observer.state_changed_count_, 0);
322 ASSERT_EQ(observer.volume_changed_count_, 0);
323 }
324
325 // Checks if the observer is notified while the media object is
326 // removed(invisible). Once the media object is removed, the audio sink is no
327 // longer valid.
328 TEST_F(BluetoothAudioSinkChromeOSTest, ObserverNotifiedWhenMediaRemoved) {
329 GetAudioSink();
330
331 // Adds an observer for |audio_sink_|.
332 TestAudioSinkObserver observer(audio_sink_);
333 ASSERT_EQ(observer.state_changed_count_, 0);
334 ASSERT_EQ(observer.volume_changed_count_, 0);
335
336 // Gets the media object and makes it invisible to see if the state of the
337 // audio sink changes accordingly.
338 FakeBluetoothMediaClient* media = static_cast<FakeBluetoothMediaClient*>(
339 DBusThreadManager::Get()->GetBluetoothMediaClient());
340 media->SetVisible(false);
341
342 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
343 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
344 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
345 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
346 audio_sink_chromeos->GetEndpointServiceProvider());
347
348 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID);
349 ASSERT_EQ(media_endpoint, nullptr);
350 }
351
352 // Checks if the observer is notified while the media transport is
353 // removed(invisible). Once the media transport object is removed, the audio
354 // sink is disconnected.
355 TEST_F(BluetoothAudioSinkChromeOSTest, ObserverNotifiedWhenTransportRemoved) {
356 GetAudioSink();
357
358 // Adds an observer for |audio_sink_|.
359 TestAudioSinkObserver observer(audio_sink_);
360 ASSERT_EQ(observer.state_changed_count_, 0);
361 ASSERT_EQ(observer.volume_changed_count_, 0);
362
363 // Simulates calling SetConfiguration on the media endpoint object owned by
364 // |audio_sink_| with a fake transport path and a
365 // Delegate::TransportProperties structure.
366 BluetoothAudioSinkChromeOS* audio_sink_chromeos =
367 static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
368 FakeBluetoothMediaEndpointServiceProvider* media_endpoint =
369 static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
370 audio_sink_chromeos->GetEndpointServiceProvider());
371 ASSERT_NE(media_endpoint, nullptr);
372
373 media_endpoint->SetConfiguration(
374 ObjectPath(FakeBluetoothMediaTransportClient::kTransportPath),
375 properties_);
376
377 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_IDLE);
378 ASSERT_EQ(callback_count_, 1);
379 ASSERT_EQ(error_callback_count_, 0);
380 ASSERT_EQ(observer.state_changed_count_, 1);
381 ASSERT_EQ(observer.volume_changed_count_, 1);
382
383 // Gets the media transport object and makes it invalid to see if the state
384 // of the audio sink changes accordingly.
385 FakeBluetoothMediaTransportClient* transport =
386 static_cast<FakeBluetoothMediaTransportClient*>(
387 DBusThreadManager::Get()->GetBluetoothMediaTransportClient());
388
389 transport->SetValid(media_endpoint->object_path(), false);
390 ASSERT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
391 ASSERT_NE(media_endpoint, nullptr);
392 }
393
188 } // namespace chromeos 394 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698