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

Side by Side Diff: media/audio/audio_manager_unittest.cc

Issue 2079843003: Allow AudioManagerCras enumerate audio devices from CRAS not just defaults (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nit: using display_name instead of device_name Created 4 years, 5 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
« no previous file with comments | « media/audio/BUILD.gn ('k') | media/audio/cras/audio_manager_cras.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "media/audio/audio_manager.h" 5 #include "media/audio/audio_manager.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/environment.h" 10 #include "base/environment.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/strings/string_number_conversions.h"
13 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
14 #include "base/test/test_message_loop.h" 15 #include "base/test/test_message_loop.h"
15 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
16 #include "build/build_config.h" 17 #include "build/build_config.h"
17 #include "media/audio/audio_device_description.h" 18 #include "media/audio/audio_device_description.h"
18 #include "media/audio/audio_manager.h" 19 #include "media/audio/audio_manager.h"
19 #include "media/audio/audio_output_proxy.h" 20 #include "media/audio/audio_output_proxy.h"
20 #include "media/audio/audio_unittest_util.h" 21 #include "media/audio/audio_unittest_util.h"
21 #include "media/audio/fake_audio_log_factory.h" 22 #include "media/audio/fake_audio_log_factory.h"
22 #include "media/audio/fake_audio_manager.h" 23 #include "media/audio/fake_audio_manager.h"
23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
24 25
25 #if defined(USE_ALSA) 26 #if defined(USE_ALSA)
26 #include "media/audio/alsa/audio_manager_alsa.h" 27 #include "media/audio/alsa/audio_manager_alsa.h"
27 #endif // defined(USE_ALSA) 28 #endif // defined(USE_ALSA)
28 29
29 #if defined(OS_WIN) 30 #if defined(OS_WIN)
30 #include "base/win/scoped_com_initializer.h" 31 #include "base/win/scoped_com_initializer.h"
31 #include "media/audio/win/audio_manager_win.h" 32 #include "media/audio/win/audio_manager_win.h"
32 #include "media/audio/win/wavein_input_win.h" 33 #include "media/audio/win/wavein_input_win.h"
33 #endif 34 #endif
34 35
35 #if defined(USE_PULSEAUDIO) 36 #if defined(USE_PULSEAUDIO)
36 #include "media/audio/pulse/audio_manager_pulse.h" 37 #include "media/audio/pulse/audio_manager_pulse.h"
37 #endif // defined(USE_PULSEAUDIO) 38 #endif // defined(USE_PULSEAUDIO)
38 39
40 #if defined(USE_CRAS)
41 #include "chromeos/audio/audio_devices_pref_handler_stub.h"
42 #include "chromeos/audio/cras_audio_handler.h"
43 #include "chromeos/dbus/dbus_thread_manager.h"
44 #include "chromeos/dbus/fake_cras_audio_client.h"
45 #include "media/audio/cras/audio_manager_cras.h"
46 #endif // defined(USE_CRAS)
47
39 namespace media { 48 namespace media {
40 49
41 namespace { 50 namespace {
42 template <typename T> 51 template <typename T>
43 struct TestAudioManagerFactory { 52 struct TestAudioManagerFactory {
44 static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) { 53 static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) {
45 return ScopedAudioManagerPtr(new T(base::ThreadTaskRunnerHandle::Get(), 54 return ScopedAudioManagerPtr(new T(base::ThreadTaskRunnerHandle::Get(),
46 base::ThreadTaskRunnerHandle::Get(), 55 base::ThreadTaskRunnerHandle::Get(),
47 audio_log_factory)); 56 audio_log_factory));
48 } 57 }
(...skipping 13 matching lines...) Expand all
62 } 71 }
63 }; 72 };
64 #endif // defined(USE_PULSEAUDIO) 73 #endif // defined(USE_PULSEAUDIO)
65 74
66 template <> 75 template <>
67 struct TestAudioManagerFactory<std::nullptr_t> { 76 struct TestAudioManagerFactory<std::nullptr_t> {
68 static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) { 77 static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) {
69 return AudioManager::CreateForTesting(base::ThreadTaskRunnerHandle::Get()); 78 return AudioManager::CreateForTesting(base::ThreadTaskRunnerHandle::Get());
70 } 79 }
71 }; 80 };
81
82 #if defined(USE_CRAS)
83 using chromeos::AudioNode;
84 using chromeos::AudioNodeList;
85
86 const uint64_t kJabraSpeaker1Id = 30001;
87 const uint64_t kJabraSpeaker1StableDeviceId = 80001;
88 const uint64_t kJabraSpeaker2Id = 30002;
89 const uint64_t kJabraSpeaker2StableDeviceId = 80002;
90 const uint64_t kHDMIOutputId = 30003;
91 const uint64_t kHDMIOutputStabeDevicelId = 80003;
92 const uint64_t kJabraMic1Id = 40001;
93 const uint64_t kJabraMic1StableDeviceId = 90001;
94 const uint64_t kJabraMic2Id = 40002;
95 const uint64_t kJabraMic2StableDeviceId = 90002;
96 const uint64_t kWebcamMicId = 40003;
97 const uint64_t kWebcamMicStableDeviceId = 90003;
98
99 const AudioNode kJabraSpeaker1(false,
100 kJabraSpeaker1Id,
101 kJabraSpeaker1StableDeviceId,
102 "Jabra Speaker",
103 "USB",
104 "Jabra Speaker 1",
105 false,
106 0);
107
108 const AudioNode kJabraSpeaker2(false,
109 kJabraSpeaker2Id,
110 kJabraSpeaker2StableDeviceId,
111 "Jabra Speaker",
112 "USB",
113 "Jabra Speaker 2",
114 false,
115 0);
116
117 const AudioNode kHDMIOutput(false,
118 kHDMIOutputId,
119 kHDMIOutputStabeDevicelId,
120 "HDMI output",
121 "HDMI",
122 "HDA Intel MID",
123 false,
124 0);
125
126 const AudioNode kJabraMic1(true,
127 kJabraMic1Id,
128 kJabraMic1StableDeviceId,
129 "Jabra Mic",
130 "USB",
131 "Jabra Mic 1",
132 false,
133 0);
134
135 const AudioNode kJabraMic2(true,
136 kJabraMic2Id,
137 kJabraMic2StableDeviceId,
138 "Jabra Mic",
139 "USB",
140 "Jabra Mic 2",
141 false,
142 0);
143
144 const AudioNode kUSBCameraMic(true,
145 kWebcamMicId,
146 kWebcamMicStableDeviceId,
147 "Webcam Mic",
148 "USB",
149 "Logitech Webcam",
150 false,
151 0);
152 #endif // defined(USE_CRAS)
153
72 } // namespace 154 } // namespace
73 155
74 // Test fixture which allows us to override the default enumeration API on 156 // Test fixture which allows us to override the default enumeration API on
75 // Windows. 157 // Windows.
76 class AudioManagerTest : public ::testing::Test { 158 class AudioManagerTest : public ::testing::Test {
77 public: 159 public:
78 void HandleDefaultDeviceIDsTest() { 160 void HandleDefaultDeviceIDsTest() {
79 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, 161 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
80 CHANNEL_LAYOUT_STEREO, 48000, 16, 2048); 162 CHANNEL_LAYOUT_STEREO, 48000, 16, 2048);
81 163
(...skipping 26 matching lines...) Expand all
108 void GetDefaultOutputStreamParameters(media::AudioParameters* params) { 190 void GetDefaultOutputStreamParameters(media::AudioParameters* params) {
109 *params = audio_manager_->GetDefaultOutputStreamParameters(); 191 *params = audio_manager_->GetDefaultOutputStreamParameters();
110 } 192 }
111 193
112 void GetAssociatedOutputDeviceID(const std::string& input_device_id, 194 void GetAssociatedOutputDeviceID(const std::string& input_device_id,
113 std::string* output_device_id) { 195 std::string* output_device_id) {
114 *output_device_id = 196 *output_device_id =
115 audio_manager_->GetAssociatedOutputDeviceID(input_device_id); 197 audio_manager_->GetAssociatedOutputDeviceID(input_device_id);
116 } 198 }
117 199
200 #if defined(USE_CRAS)
201 void TearDown() override {
202 chromeos::CrasAudioHandler::Shutdown();
203 audio_pref_handler_ = nullptr;
204 chromeos::DBusThreadManager::Shutdown();
205 }
206
207 void SetUpCrasAudioHandlerWithTestingNodes(const AudioNodeList& audio_nodes) {
208 chromeos::DBusThreadManager::Initialize();
209 audio_client_ = static_cast<chromeos::FakeCrasAudioClient*>(
210 chromeos::DBusThreadManager::Get()->GetCrasAudioClient());
211 audio_client_->SetAudioNodesForTesting(audio_nodes);
212 audio_pref_handler_ = new chromeos::AudioDevicesPrefHandlerStub();
213 chromeos::CrasAudioHandler::Initialize(audio_pref_handler_);
214 cras_audio_handler_ = chromeos::CrasAudioHandler::Get();
215 base::RunLoop().RunUntilIdle();
216 }
217 #endif // defined(USE_CRAS)
218
118 protected: 219 protected:
119 AudioManagerTest() { CreateAudioManagerForTesting(); } 220 AudioManagerTest() { CreateAudioManagerForTesting(); }
120 ~AudioManagerTest() override {} 221 ~AudioManagerTest() override {}
121 222
122 #if defined(OS_WIN) 223 #if defined(OS_WIN)
123 bool SetMMDeviceEnumeration() { 224 bool SetMMDeviceEnumeration() {
124 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get()); 225 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
125 // Windows Wave is used as default if Windows XP was detected => 226 // Windows Wave is used as default if Windows XP was detected =>
126 // return false since MMDevice is not supported on XP. 227 // return false since MMDevice is not supported on XP.
127 if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration) 228 if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 ++it; 279 ++it;
179 } 280 }
180 } else { 281 } else {
181 // Log a warning so we can see the status on the build bots. No need to 282 // Log a warning so we can see the status on the build bots. No need to
182 // break the test though since this does successfully test the code and 283 // break the test though since this does successfully test the code and
183 // some failure cases. 284 // some failure cases.
184 LOG(WARNING) << "No input devices detected"; 285 LOG(WARNING) << "No input devices detected";
185 } 286 }
186 } 287 }
187 288
289 #if defined(USE_CRAS)
290 // Helper method for (USE_CRAS) which verifies that the device list starts
291 // with a valid default record followed by physical device names.
292 static void CheckDeviceNamesCras(
293 const AudioDeviceNames& device_names,
294 const std::map<uint64_t, std::string>& expectation) {
295 DVLOG(2) << "Got " << device_names.size() << " audio devices.";
296 if (!device_names.empty()) {
297 AudioDeviceNames::const_iterator it = device_names.begin();
298
299 // The first device in the list should always be the default device.
300 EXPECT_EQ(AudioDeviceDescription::GetDefaultDeviceName(),
301 it->device_name);
302 EXPECT_EQ(std::string(AudioDeviceDescription::kDefaultDeviceId),
303 it->unique_id);
304
305 // |device_names|'size should be |expectation|'s size plus one because of
306 // default device.
307 EXPECT_EQ(device_names.size(), expectation.size() + 1);
308 ++it;
309 // Check other devices that should have non-empty name and id, and should
310 // be contained in expectation.
311 while (it != device_names.end()) {
312 EXPECT_FALSE(it->device_name.empty());
313 EXPECT_FALSE(it->unique_id.empty());
314 DVLOG(2) << "Device ID(" << it->unique_id
315 << "), label: " << it->device_name;
316 uint64_t key;
317 EXPECT_TRUE(base::StringToUint64(it->unique_id, &key));
318 EXPECT_TRUE(expectation.find(key) != expectation.end());
319 EXPECT_EQ(expectation.find(key)->second, it->device_name);
320 ++it;
321 }
322 } else {
323 // Log a warning so we can see the status on the build bots. No need to
324 // break the test though since this does successfully test the code and
325 // some failure cases.
326 LOG(WARNING) << "No input devices detected";
327 }
328 }
329 #endif // defined(USE_CRAS)
330
188 bool InputDevicesAvailable() { 331 bool InputDevicesAvailable() {
189 return audio_manager_->HasAudioInputDevices(); 332 return audio_manager_->HasAudioInputDevices();
190 } 333 }
191 bool OutputDevicesAvailable() { 334 bool OutputDevicesAvailable() {
192 return audio_manager_->HasAudioOutputDevices(); 335 return audio_manager_->HasAudioOutputDevices();
193 } 336 }
194 337
195 template <typename T = std::nullptr_t> 338 template <typename T = std::nullptr_t>
196 void CreateAudioManagerForTesting() { 339 void CreateAudioManagerForTesting() {
197 // Only one AudioManager may exist at a time, so destroy the one we're 340 // Only one AudioManager may exist at a time, so destroy the one we're
198 // currently holding before creating a new one. 341 // currently holding before creating a new one.
199 // Flush the message loop to run any shutdown tasks posted by AudioManager. 342 // Flush the message loop to run any shutdown tasks posted by AudioManager.
200 audio_manager_.reset(); 343 audio_manager_.reset();
201 base::RunLoop().RunUntilIdle(); 344 base::RunLoop().RunUntilIdle();
202 345
203 audio_manager_ = 346 audio_manager_ =
204 TestAudioManagerFactory<T>::Create(&fake_audio_log_factory_); 347 TestAudioManagerFactory<T>::Create(&fake_audio_log_factory_);
205 // A few AudioManager implementations post initialization tasks to 348 // A few AudioManager implementations post initialization tasks to
206 // audio thread. Flush the thread to ensure that |audio_manager_| is 349 // audio thread. Flush the thread to ensure that |audio_manager_| is
207 // initialized and ready to use before returning from this function. 350 // initialized and ready to use before returning from this function.
208 // TODO(alokp): We should perhaps do this in AudioManager::Create(). 351 // TODO(alokp): We should perhaps do this in AudioManager::Create().
209 base::RunLoop().RunUntilIdle(); 352 base::RunLoop().RunUntilIdle();
210 } 353 }
211 354
212 base::TestMessageLoop message_loop_; 355 base::TestMessageLoop message_loop_;
213 FakeAudioLogFactory fake_audio_log_factory_; 356 FakeAudioLogFactory fake_audio_log_factory_;
214 ScopedAudioManagerPtr audio_manager_; 357 ScopedAudioManagerPtr audio_manager_;
358
359 #if defined(USE_CRAS)
360 chromeos::CrasAudioHandler* cras_audio_handler_ = nullptr; // Not owned.
361 chromeos::FakeCrasAudioClient* audio_client_ = nullptr; // Not owned.
362 scoped_refptr<chromeos::AudioDevicesPrefHandlerStub> audio_pref_handler_;
363 #endif // defined(USE_CRAS)
215 }; 364 };
216 365
366 #if defined(USE_CRAS)
367 TEST_F(AudioManagerTest, EnumerateInputDevicesCras) {
368 // Setup the devices without internal mic, so that it doesn't exist
369 // beamforming capable mic.
370 AudioNodeList audio_nodes;
371 audio_nodes.push_back(kJabraMic1);
372 audio_nodes.push_back(kJabraMic2);
373 audio_nodes.push_back(kUSBCameraMic);
374 audio_nodes.push_back(kHDMIOutput);
375 audio_nodes.push_back(kJabraSpeaker1);
376 SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);
377
378 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
379
380 // Setup expectation with physical devices.
381 std::map<uint64_t, std::string> expectation;
382 expectation[kJabraMic1.id] = kJabraMic1.device_name;
383 expectation[kJabraMic2.id] = kJabraMic2.device_name;
384 expectation[kUSBCameraMic.id] = kUSBCameraMic.device_name;
385
386 DVLOG(2) << "Testing AudioManagerCras.";
387 CreateAudioManagerForTesting<AudioManagerCras>();
388 AudioDeviceNames device_names;
389 audio_manager_->GetAudioInputDeviceNames(&device_names);
390 CheckDeviceNamesCras(device_names, expectation);
391 }
392
393 TEST_F(AudioManagerTest, EnumerateOutputDevicesCras) {
394 // Setup the devices without internal mic, so that it doesn't exist
395 // beamforming capable mic.
396 AudioNodeList audio_nodes;
397 audio_nodes.push_back(kJabraMic1);
398 audio_nodes.push_back(kJabraMic2);
399 audio_nodes.push_back(kUSBCameraMic);
400 audio_nodes.push_back(kHDMIOutput);
401 audio_nodes.push_back(kJabraSpeaker1);
402 SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);
403
404 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
405
406 // Setup expectation with physical devices.
407 std::map<uint64_t, std::string> expectation;
408 expectation[kHDMIOutput.id] = kHDMIOutput.device_name;
409 expectation[kJabraSpeaker1.id] = kJabraSpeaker1.device_name;
410
411 DVLOG(2) << "Testing AudioManagerCras.";
412 CreateAudioManagerForTesting<AudioManagerCras>();
413 AudioDeviceNames device_names;
414 audio_manager_->GetAudioOutputDeviceNames(&device_names);
415 CheckDeviceNamesCras(device_names, expectation);
416 }
417 #else // !defined(USE_CRAS)
418
217 TEST_F(AudioManagerTest, HandleDefaultDeviceIDs) { 419 TEST_F(AudioManagerTest, HandleDefaultDeviceIDs) {
218 // Use a fake manager so we can makeup device ids, this will still use the 420 // Use a fake manager so we can makeup device ids, this will still use the
219 // AudioManagerBase code. 421 // AudioManagerBase code.
220 CreateAudioManagerForTesting<FakeAudioManager>(); 422 CreateAudioManagerForTesting<FakeAudioManager>();
221 HandleDefaultDeviceIDsTest(); 423 HandleDefaultDeviceIDsTest();
222 base::RunLoop().RunUntilIdle(); 424 base::RunLoop().RunUntilIdle();
223 } 425 }
224 426
225 // Test that devices can be enumerated. 427 // Test that devices can be enumerated.
226 TEST_F(AudioManagerTest, EnumerateInputDevices) { 428 TEST_F(AudioManagerTest, EnumerateInputDevices) {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 GetAssociatedOutputDeviceID(it->unique_id, &output_device_id); 626 GetAssociatedOutputDeviceID(it->unique_id, &output_device_id);
425 if (!output_device_id.empty()) { 627 if (!output_device_id.empty()) {
426 DVLOG(2) << it->unique_id << " matches with " << output_device_id; 628 DVLOG(2) << it->unique_id << " matches with " << output_device_id;
427 found_an_associated_device = true; 629 found_an_associated_device = true;
428 } 630 }
429 } 631 }
430 632
431 EXPECT_TRUE(found_an_associated_device); 633 EXPECT_TRUE(found_an_associated_device);
432 #endif // defined(OS_WIN) || defined(OS_MACOSX) 634 #endif // defined(OS_WIN) || defined(OS_MACOSX)
433 } 635 }
636 #endif // defined(USE_CRAS)
434 637
435 } // namespace media 638 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/BUILD.gn ('k') | media/audio/cras/audio_manager_cras.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698