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
3 // found in the LICENSE file.
4
5 #include "media/audio/audio_manager.h"
6
7 #include <map>
8 #include <memory>
9 #include <utility>
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/environment.h"
15 #include "base/logging.h"
16 #include "base/run_loop.h"
17 #include "base/single_thread_task_runner.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_util.h"
20 #include "base/synchronization/waitable_event.h"
21 #include "base/system/sys_info.h"
22 #include "base/test/test_message_loop.h"
23 #include "base/threading/thread_task_runner_handle.h"
24 #include "build/build_config.h"
25 #include "build/chromeos_buildflags.h"
26 #include "media/audio/audio_device_description.h"
27 #include "media/audio/audio_device_info_accessor_for_tests.h"
28 #include "media/audio/audio_device_name.h"
29 #include "media/audio/audio_output_proxy.h"
30 #include "media/audio/audio_unittest_util.h"
31 #include "media/audio/fake_audio_log_factory.h"
32 #include "media/audio/fake_audio_manager.h"
33 #include "media/audio/test_audio_thread.h"
34 #include "media/base/limits.h"
35 #include "media/base/media_switches.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38
39 #if defined(USE_ALSA)
40 #include "media/audio/alsa/audio_manager_alsa.h"
41 #endif // defined(USE_ALSA)
42
43 #if defined(OS_MAC)
44 #include "media/audio/mac/audio_manager_mac.h"
45 #include "media/base/mac/audio_latency_mac.h"
46 #endif
47
48 #if defined(OS_WIN)
49 #include "base/win/scoped_com_initializer.h"
50 #include "media/audio/win/audio_manager_win.h"
51 #endif
52
53 #if defined(USE_PULSEAUDIO)
54 #include "media/audio/pulse/audio_manager_pulse.h"
55 #include "media/audio/pulse/pulse_util.h"
56 #endif // defined(USE_PULSEAUDIO)
57
58 #if defined(USE_CRAS) && BUILDFLAG(IS_ASH)
59 #include "chromeos/audio/audio_devices_pref_handler_stub.h"
60 #include "chromeos/audio/cras_audio_handler.h"
61 #include "chromeos/dbus/audio/fake_cras_audio_client.h"
62 #include "media/audio/cras/audio_manager_chromeos.h"
63 #elif defined(USE_CRAS) && defined(OS_LINUX)
64 #include "media/audio/cras/audio_manager_cras.h"
65 #endif
66
67 namespace media {
68
69 namespace {
70
71 template <typename T>
72 struct TestAudioManagerFactory {
Createmedia::__anon7acea1d40111::TestAudioManagerFactory73 static std::unique_ptr<AudioManager> Create(
74 AudioLogFactory* audio_log_factory) {
75 return std::make_unique<T>(std::make_unique<TestAudioThread>(),
76 audio_log_factory);
77 }
78 };
79
80 #if defined(USE_PULSEAUDIO)
81 template <>
82 struct TestAudioManagerFactory<AudioManagerPulse> {
Createmedia::__anon7acea1d40111::TestAudioManagerFactory83 static std::unique_ptr<AudioManager> Create(
84 AudioLogFactory* audio_log_factory) {
85 pa_threaded_mainloop* pa_mainloop = nullptr;
86 pa_context* pa_context = nullptr;
87 if (!pulse::InitPulse(&pa_mainloop, &pa_context))
88 return nullptr;
89 return std::make_unique<AudioManagerPulse>(
90 std::make_unique<TestAudioThread>(), audio_log_factory, pa_mainloop,
91 pa_context);
92 }
93 };
94 #endif // defined(USE_PULSEAUDIO)
95
96 template <>
97 struct TestAudioManagerFactory<std::nullptr_t> {
Createmedia::__anon7acea1d40111::TestAudioManagerFactory98 static std::unique_ptr<AudioManager> Create(
99 AudioLogFactory* audio_log_factory) {
100 return AudioManager::CreateForTesting(std::make_unique<TestAudioThread>());
101 }
102 };
103
104 #if defined(USE_CRAS) && BUILDFLAG(IS_ASH)
105 using chromeos::AudioNode;
106 using chromeos::AudioNodeList;
107
108 const int kDefaultSampleRate = 48000;
109
110 const uint64_t kInternalSpeakerId = 10001;
111 const uint64_t kInternalSpeakerStableDeviceId = 10001;
112 const uint64_t kInternalMicId = 10002;
113 const uint64_t kInternalMicStableDeviceId = 10002;
114 const uint64_t kJabraSpeaker1Id = 30001;
115 const uint64_t kJabraSpeaker1StableDeviceId = 80001;
116 const uint64_t kJabraSpeaker2Id = 30002;
117 const uint64_t kJabraSpeaker2StableDeviceId = 80002;
118 const uint64_t kHDMIOutputId = 30003;
119 const uint64_t kHDMIOutputStabeDevicelId = 80003;
120 const uint64_t kJabraMic1Id = 40001;
121 const uint64_t kJabraMic1StableDeviceId = 90001;
122 const uint64_t kJabraMic2Id = 40002;
123 const uint64_t kJabraMic2StableDeviceId = 90002;
124 const uint64_t kWebcamMicId = 40003;
125 const uint64_t kWebcamMicStableDeviceId = 90003;
126
127 const AudioNode kInternalSpeaker(false,
128 kInternalSpeakerId,
129 true,
130 kInternalSpeakerStableDeviceId,
131 kInternalSpeakerStableDeviceId ^ 0xFF,
132 "Internal Speaker",
133 "INTERNAL_SPEAKER",
134 "Speaker",
135 false,
136 0,
137 2);
138
139 const AudioNode kInternalMic(true,
140 kInternalMicId,
141 true,
142 kInternalMicStableDeviceId,
143 kInternalMicStableDeviceId ^ 0xFF,
144 "Internal Mic",
145 "INTERNAL_MIC",
146 "Internal Mic",
147 false,
148 0,
149 1);
150
151 const AudioNode kJabraSpeaker1(false,
152 kJabraSpeaker1Id,
153 true,
154 kJabraSpeaker1StableDeviceId,
155 kJabraSpeaker1StableDeviceId ^ 0xFF,
156 "Jabra Speaker",
157 "USB",
158 "Jabra Speaker 1",
159 false,
160 0,
161 2); // expects CHANNEL_LAYOUT_STEREO
162
163 const AudioNode kJabraSpeaker2(false,
164 kJabraSpeaker2Id,
165 true,
166 kJabraSpeaker2StableDeviceId,
167 kJabraSpeaker2StableDeviceId ^ 0xFF,
168 "Jabra Speaker",
169 "USB",
170 "Jabra Speaker 2",
171 false,
172 0,
173 6); // expects CHANNEL_LAYOUT_5_1
174
175 const AudioNode kHDMIOutput(false,
176 kHDMIOutputId,
177 true,
178 kHDMIOutputStabeDevicelId,
179 kHDMIOutputStabeDevicelId ^ 0xFF,
180 "HDMI output",
181 "HDMI",
182 "HDA Intel MID",
183 false,
184 0,
185 8); // expects CHANNEL_LAYOUT_7_1
186
187 const AudioNode kJabraMic1(true,
188 kJabraMic1Id,
189 true,
190 kJabraMic1StableDeviceId,
191 kJabraMic1StableDeviceId ^ 0xFF,
192 "Jabra Mic",
193 "USB",
194 "Jabra Mic 1",
195 false,
196 0,
197 1);
198
199 const AudioNode kJabraMic2(true,
200 kJabraMic2Id,
201 true,
202 kJabraMic2StableDeviceId,
203 kJabraMic2StableDeviceId ^ 0xFF,
204 "Jabra Mic",
205 "USB",
206 "Jabra Mic 2",
207 false,
208 0,
209 1);
210
211 const AudioNode kUSBCameraMic(true,
212 kWebcamMicId,
213 true,
214 kWebcamMicStableDeviceId,
215 kWebcamMicStableDeviceId ^ 0xFF,
216 "Webcam Mic",
217 "USB",
218 "Logitech Webcam",
219 false,
220 0,
221 1);
222 #endif // defined(USE_CRAS)
223
224 const char kRealDefaultInputDeviceID[] = "input2";
225 const char kRealDefaultOutputDeviceID[] = "output3";
226 const char kRealCommunicationsInputDeviceID[] = "input1";
227 const char kRealCommunicationsOutputDeviceID[] = "output1";
228
CheckDescriptionLabels(const AudioDeviceDescriptions & descriptions,const std::string & real_default_id,const std::string & real_communications_id)229 void CheckDescriptionLabels(const AudioDeviceDescriptions& descriptions,
230 const std::string& real_default_id,
231 const std::string& real_communications_id) {
232 std::string real_default_label;
233 std::string real_communications_label;
234 for (const auto& description : descriptions) {
235 if (description.unique_id == real_default_id)
236 real_default_label = description.device_name;
237 else if (description.unique_id == real_communications_id)
238 real_communications_label = description.device_name;
239 }
240
241 for (const auto& description : descriptions) {
242 if (AudioDeviceDescription::IsDefaultDevice(description.unique_id)) {
243 EXPECT_TRUE(base::EndsWith(description.device_name, real_default_label,
244 base::CompareCase::SENSITIVE));
245 } else if (description.unique_id ==
246 AudioDeviceDescription::kCommunicationsDeviceId) {
247 EXPECT_TRUE(base::EndsWith(description.device_name,
248 real_communications_label,
249 base::CompareCase::SENSITIVE));
250 }
251 }
252 }
253
254 } // namespace
255
256 // Test fixture which allows us to override the default enumeration API on
257 // Windows.
258 class AudioManagerTest : public ::testing::Test {
259 public:
HandleDefaultDeviceIDsTest()260 void HandleDefaultDeviceIDsTest() {
261 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
262 CHANNEL_LAYOUT_STEREO, 48000, 2048);
263
264 // Create a stream with the default device id "".
265 AudioOutputStream* stream =
266 audio_manager_->MakeAudioOutputStreamProxy(params, "");
267 ASSERT_TRUE(stream);
268 AudioOutputDispatcher* dispatcher1 =
269 reinterpret_cast<AudioOutputProxy*>(stream)
270 ->get_dispatcher_for_testing();
271
272 // Closing this stream will put it up for reuse.
273 stream->Close();
274 stream = audio_manager_->MakeAudioOutputStreamProxy(
275 params, AudioDeviceDescription::kDefaultDeviceId);
276
277 // Verify both streams are created with the same dispatcher (which is unique
278 // per device).
279 ASSERT_EQ(dispatcher1, reinterpret_cast<AudioOutputProxy*>(stream)
280 ->get_dispatcher_for_testing());
281 stream->Close();
282
283 // Create a non-default device and ensure it gets a different dispatcher.
284 stream = audio_manager_->MakeAudioOutputStreamProxy(params, "123456");
285 ASSERT_NE(dispatcher1, reinterpret_cast<AudioOutputProxy*>(stream)
286 ->get_dispatcher_for_testing());
287 stream->Close();
288 }
289
GetDefaultOutputStreamParameters(media::AudioParameters * params)290 void GetDefaultOutputStreamParameters(media::AudioParameters* params) {
291 *params = device_info_accessor_->GetDefaultOutputStreamParameters();
292 }
293
GetAssociatedOutputDeviceID(const std::string & input_device_id,std::string * output_device_id)294 void GetAssociatedOutputDeviceID(const std::string& input_device_id,
295 std::string* output_device_id) {
296 *output_device_id =
297 device_info_accessor_->GetAssociatedOutputDeviceID(input_device_id);
298 }
299
300 #if defined(USE_CRAS) && BUILDFLAG(IS_ASH)
TearDown()301 void TearDown() override {
302 chromeos::CrasAudioHandler::Shutdown();
303 audio_pref_handler_ = nullptr;
304 chromeos::CrasAudioClient::Shutdown();
305 }
306
SetUpCrasAudioHandlerWithTestingNodes(const AudioNodeList & audio_nodes)307 void SetUpCrasAudioHandlerWithTestingNodes(const AudioNodeList& audio_nodes) {
308 chromeos::CrasAudioClient::InitializeFake();
309 chromeos::FakeCrasAudioClient::Get()->SetAudioNodesForTesting(audio_nodes);
310 audio_pref_handler_ = new chromeos::AudioDevicesPrefHandlerStub();
311 chromeos::CrasAudioHandler::Initialize(
312 /*media_controller_manager*/ mojo::NullRemote(), audio_pref_handler_);
313 cras_audio_handler_ = chromeos::CrasAudioHandler::Get();
314 base::RunLoop().RunUntilIdle();
315 }
316
SetActiveOutputNode(uint64_t node_id)317 void SetActiveOutputNode(uint64_t node_id) {
318 cras_audio_handler_->SwitchToDevice(
319 *cras_audio_handler_->GetDeviceFromId(node_id), true /* notify */,
320 chromeos::CrasAudioHandler::ACTIVATE_BY_USER /* activate_by */);
321 }
322
GetPreferredOutputStreamParameters(ChannelLayout channel_layout,int32_t user_buffer_size=0)323 AudioParameters GetPreferredOutputStreamParameters(
324 ChannelLayout channel_layout, int32_t user_buffer_size = 0) {
325 // Generated AudioParameters should follow the same rule as in
326 // AudioManagerCras::GetPreferredOutputStreamParameters().
327 int sample_rate = kDefaultSampleRate;
328 int32_t buffer_size = user_buffer_size;
329 if (buffer_size == 0) // Not user-provided.
330 cras_audio_handler_->GetDefaultOutputBufferSize(&buffer_size);
331 return AudioParameters(
332 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, sample_rate,
333 buffer_size,
334 AudioParameters::HardwareCapabilities(limits::kMinAudioBufferSize,
335 limits::kMaxAudioBufferSize));
336 }
337 #endif // defined(USE_CRAS) && BUILDFLAG(IS_ASH)
338
339 protected:
AudioManagerTest()340 AudioManagerTest() {
341 CreateAudioManagerForTesting();
342 }
~AudioManagerTest()343 ~AudioManagerTest() override { audio_manager_->Shutdown(); }
344
345 // Helper method which verifies that the device list starts with a valid
346 // default record followed by non-default device names.
CheckDeviceDescriptions(const AudioDeviceDescriptions & device_descriptions)347 static void CheckDeviceDescriptions(
348 const AudioDeviceDescriptions& device_descriptions) {
349 DVLOG(2) << "Got " << device_descriptions.size() << " audio devices.";
350 if (!device_descriptions.empty()) {
351 auto it = device_descriptions.begin();
352
353 // The first device in the list should always be the default device.
354 EXPECT_EQ(std::string(AudioDeviceDescription::kDefaultDeviceId),
355 it->unique_id);
356 ++it;
357
358 // Other devices should have non-empty name and id and should not contain
359 // default name or id.
360 while (it != device_descriptions.end()) {
361 EXPECT_FALSE(it->device_name.empty());
362 EXPECT_FALSE(it->unique_id.empty());
363 EXPECT_FALSE(it->group_id.empty());
364 DVLOG(2) << "Device ID(" << it->unique_id
365 << "), label: " << it->device_name
366 << "group: " << it->group_id;
367 EXPECT_NE(AudioDeviceDescription::GetDefaultDeviceName(),
368 it->device_name);
369 EXPECT_NE(std::string(AudioDeviceDescription::kDefaultDeviceId),
370 it->unique_id);
371 ++it;
372 }
373 } else {
374 // Log a warning so we can see the status on the build bots. No need to
375 // break the test though since this does successfully test the code and
376 // some failure cases.
377 LOG(WARNING) << "No input devices detected";
378 }
379 }
380
381 #if defined(USE_CRAS) && BUILDFLAG(IS_ASH)
382 // Helper method for (USE_CRAS) which verifies that the device list starts
383 // with a valid default record followed by physical device names.
CheckDeviceDescriptionsCras(const AudioDeviceDescriptions & device_descriptions,const std::map<uint64_t,std::string> & expectation)384 static void CheckDeviceDescriptionsCras(
385 const AudioDeviceDescriptions& device_descriptions,
386 const std::map<uint64_t, std::string>& expectation) {
387 DVLOG(2) << "Got " << device_descriptions.size() << " audio devices.";
388 if (!device_descriptions.empty()) {
389 AudioDeviceDescriptions::const_iterator it = device_descriptions.begin();
390
391 // The first device in the list should always be the default device.
392 EXPECT_EQ(AudioDeviceDescription::GetDefaultDeviceName(),
393 it->device_name);
394 EXPECT_EQ(std::string(AudioDeviceDescription::kDefaultDeviceId),
395 it->unique_id);
396
397 // |device_descriptions|'size should be |expectation|'s size plus one
398 // because of
399 // default device.
400 EXPECT_EQ(device_descriptions.size(), expectation.size() + 1);
401 ++it;
402 // Check other devices that should have non-empty name and id, and should
403 // be contained in expectation.
404 while (it != device_descriptions.end()) {
405 EXPECT_FALSE(it->device_name.empty());
406 EXPECT_FALSE(it->unique_id.empty());
407 EXPECT_FALSE(it->group_id.empty());
408 DVLOG(2) << "Device ID(" << it->unique_id
409 << "), label: " << it->device_name
410 << "group: " << it->group_id;
411 uint64_t key;
412 EXPECT_TRUE(base::StringToUint64(it->unique_id, &key));
413 EXPECT_TRUE(expectation.find(key) != expectation.end());
414 EXPECT_EQ(expectation.find(key)->second, it->device_name);
415 ++it;
416 }
417 } else {
418 // Log a warning so we can see the status on the build bots. No need to
419 // break the test though since this does successfully test the code and
420 // some failure cases.
421 LOG(WARNING) << "No input devices detected";
422 }
423 }
424
425 // Helper method for (USE_CRAS) which returns |group_id| from |device_id|.
getGroupID(const AudioDeviceDescriptions & device_descriptions,const std::string device_id)426 std::string getGroupID(const AudioDeviceDescriptions& device_descriptions,
427 const std::string device_id) {
428 AudioDeviceDescriptions::const_iterator it =
429 std::find_if(device_descriptions.begin(), device_descriptions.end(),
430 [&device_id](const auto& audio_device_desc) {
431 return audio_device_desc.unique_id == device_id;
432 });
433
434 EXPECT_NE(it, device_descriptions.end());
435 return it->group_id;
436 }
437 #endif // defined(USE_CRAS) && BUILDFLAG(IS_ASH)
438
InputDevicesAvailable()439 bool InputDevicesAvailable() {
440 #if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
441 // TODO(crbug.com/1128458): macOS on ARM64 says it has devices, but won't
442 // let any of them be opened or listed.
443 return false;
444 #else
445 return device_info_accessor_->HasAudioInputDevices();
446 #endif
447 }
OutputDevicesAvailable()448 bool OutputDevicesAvailable() {
449 return device_info_accessor_->HasAudioOutputDevices();
450 }
451
452 template <typename T = std::nullptr_t>
CreateAudioManagerForTesting()453 void CreateAudioManagerForTesting() {
454 // Only one AudioManager may exist at a time, so destroy the one we're
455 // currently holding before creating a new one.
456 // Flush the message loop to run any shutdown tasks posted by AudioManager.
457 if (audio_manager_) {
458 audio_manager_->Shutdown();
459 audio_manager_.reset();
460 }
461
462 audio_manager_ =
463 TestAudioManagerFactory<T>::Create(&fake_audio_log_factory_);
464 // A few AudioManager implementations post initialization tasks to
465 // audio thread. Flush the thread to ensure that |audio_manager_| is
466 // initialized and ready to use before returning from this function.
467 // TODO(alokp): We should perhaps do this in AudioManager::Create().
468 base::RunLoop().RunUntilIdle();
469 device_info_accessor_ =
470 std::make_unique<AudioDeviceInfoAccessorForTests>(audio_manager_.get());
471 }
472
473 base::TestMessageLoop message_loop_;
474 FakeAudioLogFactory fake_audio_log_factory_;
475 std::unique_ptr<AudioManager> audio_manager_;
476 std::unique_ptr<AudioDeviceInfoAccessorForTests> device_info_accessor_;
477
478 #if defined(USE_CRAS) && BUILDFLAG(IS_ASH)
479 chromeos::CrasAudioHandler* cras_audio_handler_ = nullptr; // Not owned.
480 scoped_refptr<chromeos::AudioDevicesPrefHandlerStub> audio_pref_handler_;
481 #endif // defined(USE_CRAS) && BUILDFLAG(IS_ASH)
482 };
483
484 #if defined(USE_CRAS) && BUILDFLAG(IS_ASH)
TEST_F(AudioManagerTest,EnumerateInputDevicesCras)485 TEST_F(AudioManagerTest, EnumerateInputDevicesCras) {
486 // Setup the devices without internal mic, so that it doesn't exist
487 // beamforming capable mic.
488 AudioNodeList audio_nodes;
489 audio_nodes.push_back(kJabraMic1);
490 audio_nodes.push_back(kJabraMic2);
491 audio_nodes.push_back(kUSBCameraMic);
492 audio_nodes.push_back(kHDMIOutput);
493 audio_nodes.push_back(kJabraSpeaker1);
494 SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);
495
496 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
497
498 // Setup expectation with physical devices.
499 std::map<uint64_t, std::string> expectation;
500 expectation[kJabraMic1.id] =
501 cras_audio_handler_->GetDeviceFromId(kJabraMic1.id)->display_name;
502 expectation[kJabraMic2.id] =
503 cras_audio_handler_->GetDeviceFromId(kJabraMic2.id)->display_name;
504 expectation[kUSBCameraMic.id] =
505 cras_audio_handler_->GetDeviceFromId(kUSBCameraMic.id)->display_name;
506
507 DVLOG(2) << "Testing AudioManagerCras.";
508 CreateAudioManagerForTesting<AudioManagerChromeOS>();
509 AudioDeviceDescriptions device_descriptions;
510 device_info_accessor_->GetAudioInputDeviceDescriptions(&device_descriptions);
511 CheckDeviceDescriptionsCras(device_descriptions, expectation);
512 }
513
TEST_F(AudioManagerTest,EnumerateOutputDevicesCras)514 TEST_F(AudioManagerTest, EnumerateOutputDevicesCras) {
515 // Setup the devices without internal mic, so that it doesn't exist
516 // beamforming capable mic.
517 AudioNodeList audio_nodes;
518 audio_nodes.push_back(kJabraMic1);
519 audio_nodes.push_back(kJabraMic2);
520 audio_nodes.push_back(kUSBCameraMic);
521 audio_nodes.push_back(kHDMIOutput);
522 audio_nodes.push_back(kJabraSpeaker1);
523 SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);
524
525 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
526
527 // Setup expectation with physical devices.
528 std::map<uint64_t, std::string> expectation;
529 expectation[kHDMIOutput.id] =
530 cras_audio_handler_->GetDeviceFromId(kHDMIOutput.id)->display_name;
531 expectation[kJabraSpeaker1.id] =
532 cras_audio_handler_->GetDeviceFromId(kJabraSpeaker1.id)->display_name;
533
534 DVLOG(2) << "Testing AudioManagerCras.";
535 CreateAudioManagerForTesting<AudioManagerChromeOS>();
536 AudioDeviceDescriptions device_descriptions;
537 device_info_accessor_->GetAudioOutputDeviceDescriptions(&device_descriptions);
538 CheckDeviceDescriptionsCras(device_descriptions, expectation);
539 }
540
TEST_F(AudioManagerTest,CheckOutputStreamParametersCras)541 TEST_F(AudioManagerTest, CheckOutputStreamParametersCras) {
542 // Setup the devices without internal mic, so that it doesn't exist
543 // beamforming capable mic.
544 AudioNodeList audio_nodes;
545 audio_nodes.push_back(kJabraMic1);
546 audio_nodes.push_back(kJabraMic2);
547 audio_nodes.push_back(kUSBCameraMic);
548 audio_nodes.push_back(kHDMIOutput);
549 audio_nodes.push_back(kJabraSpeaker1);
550 audio_nodes.push_back(kJabraSpeaker2);
551
552 SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);
553
554 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
555
556 DVLOG(2) << "Testing AudioManagerCras.";
557 CreateAudioManagerForTesting<AudioManagerChromeOS>();
558 AudioParameters params, golden_params;
559
560 // channel_layout:
561 // JabraSpeaker1 (2-channel): CHANNEL_LAYOUT_STEREO
562 // JabraSpeaker2 (6-channel): CHANNEL_LAYOUT_5_1
563 // HDMIOutput (8-channel): CHANNEL_LAYOUT_7_1
564
565 // Check GetOutputStreamParameters() with device ID. The returned parameters
566 // should be reflected to the specific output device.
567 params = device_info_accessor_->GetOutputStreamParameters(
568 base::NumberToString(kJabraSpeaker1Id));
569 golden_params = GetPreferredOutputStreamParameters(
570 ChannelLayout::CHANNEL_LAYOUT_STEREO);
571 EXPECT_TRUE(params.Equals(golden_params));
572 params = device_info_accessor_->GetOutputStreamParameters(
573 base::NumberToString(kJabraSpeaker2Id));
574 golden_params = GetPreferredOutputStreamParameters(
575 ChannelLayout::CHANNEL_LAYOUT_5_1);
576 EXPECT_TRUE(params.Equals(golden_params));
577 params = device_info_accessor_->GetOutputStreamParameters(
578 base::NumberToString(kHDMIOutputId));
579 golden_params = GetPreferredOutputStreamParameters(
580 ChannelLayout::CHANNEL_LAYOUT_7_1);
581 EXPECT_TRUE(params.Equals(golden_params));
582
583 // Set user-provided audio buffer size by command line, then check the buffer
584 // size in stream parameters is equal to the user-provided one.
585 int argc = 2;
586 char const *argv0 = "dummy";
587 char const *argv1 = "--audio-buffer-size=2048";
588 const char* argv[] = {argv0, argv1, 0};
589 base::CommandLine::Reset();
590 EXPECT_TRUE(base::CommandLine::Init(argc, argv));
591
592 // Check GetOutputStreamParameters() with default ID. The returned parameters
593 // should reflect the currently active output device.
594 SetActiveOutputNode(kJabraSpeaker1Id);
595 params = device_info_accessor_->GetOutputStreamParameters(
596 AudioDeviceDescription::kDefaultDeviceId);
597 golden_params = GetPreferredOutputStreamParameters(
598 ChannelLayout::CHANNEL_LAYOUT_STEREO, 2048);
599 EXPECT_TRUE(params.Equals(golden_params));
600 SetActiveOutputNode(kJabraSpeaker2Id);
601 params = device_info_accessor_->GetOutputStreamParameters(
602 AudioDeviceDescription::kDefaultDeviceId);
603 golden_params = GetPreferredOutputStreamParameters(
604 ChannelLayout::CHANNEL_LAYOUT_5_1, 2048);
605 EXPECT_TRUE(params.Equals(golden_params));
606 SetActiveOutputNode(kHDMIOutputId);
607 params = device_info_accessor_->GetOutputStreamParameters(
608 AudioDeviceDescription::kDefaultDeviceId);
609 golden_params = GetPreferredOutputStreamParameters(
610 ChannelLayout::CHANNEL_LAYOUT_7_1, 2048);
611 EXPECT_TRUE(params.Equals(golden_params));
612
613 // Check non-default device again.
614 params = device_info_accessor_->GetOutputStreamParameters(
615 base::NumberToString(kJabraSpeaker1Id));
616 golden_params = GetPreferredOutputStreamParameters(
617 ChannelLayout::CHANNEL_LAYOUT_STEREO, 2048);
618 EXPECT_TRUE(params.Equals(golden_params));
619 }
620
TEST_F(AudioManagerTest,LookupDefaultInputDeviceWithProperGroupId)621 TEST_F(AudioManagerTest, LookupDefaultInputDeviceWithProperGroupId) {
622 // Setup devices with external microphone as active device.
623 // Switch active device to the internal microphone.
624 // Check if default device has the same group id as internal microphone.
625 AudioNodeList audio_nodes;
626 audio_nodes.push_back(kInternalMic);
627 audio_nodes.push_back(kJabraMic1);
628 SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);
629
630 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
631
632 // Setup expectation with physical devices.
633 std::map<uint64_t, std::string> expectation;
634 expectation[kInternalMic.id] =
635 cras_audio_handler_->GetDeviceFromId(kInternalMic.id)->display_name;
636 expectation[kJabraMic1.id] =
637 cras_audio_handler_->GetDeviceFromId(kJabraMic1.id)->display_name;
638
639 CreateAudioManagerForTesting<AudioManagerChromeOS>();
640 auto previous_default_device_id =
641 device_info_accessor_->GetDefaultInputDeviceID();
642 EXPECT_EQ(base::NumberToString(kJabraMic1.id), previous_default_device_id);
643 AudioDeviceDescriptions device_descriptions;
644 device_info_accessor_->GetAudioInputDeviceDescriptions(&device_descriptions);
645
646 CheckDeviceDescriptions(device_descriptions);
647
648 // Set internal microphone as active.
649 chromeos::AudioDevice internal_microphone(kInternalMic);
650 cras_audio_handler_->SwitchToDevice(
651 internal_microphone, true, chromeos::CrasAudioHandler::ACTIVATE_BY_USER);
652 auto new_default_device_id = device_info_accessor_->GetDefaultInputDeviceID();
653 EXPECT_NE(previous_default_device_id, new_default_device_id);
654
655 auto default_device_group_id =
656 getGroupID(device_descriptions, new_default_device_id);
657 auto mic_group_id =
658 getGroupID(device_descriptions, base::NumberToString(kInternalMic.id));
659
660 EXPECT_EQ(default_device_group_id, mic_group_id);
661 EXPECT_EQ(base::NumberToString(kInternalMic.id), new_default_device_id);
662 }
663
TEST_F(AudioManagerTest,LookupDefaultOutputDeviceWithProperGroupId)664 TEST_F(AudioManagerTest, LookupDefaultOutputDeviceWithProperGroupId) {
665 // Setup devices with external speaker as active device.
666 // Switch active device to the internal speaker.
667 // Check if default device has the same group id as internal speaker.
668 AudioNodeList audio_nodes;
669 audio_nodes.push_back(kInternalSpeaker);
670 audio_nodes.push_back(kJabraSpeaker1);
671
672 SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);
673
674 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
675
676 // Setup expectation with physical devices.
677 std::map<uint64_t, std::string> expectation;
678 expectation[kInternalSpeaker.id] =
679 cras_audio_handler_->GetDeviceFromId(kInternalSpeaker.id)->display_name;
680 expectation[kJabraSpeaker1.id] =
681 cras_audio_handler_->GetDeviceFromId(kJabraSpeaker1.id)->display_name;
682
683 CreateAudioManagerForTesting<AudioManagerChromeOS>();
684 auto previous_default_device_id =
685 device_info_accessor_->GetDefaultOutputDeviceID();
686 EXPECT_EQ(base::NumberToString(kJabraSpeaker1.id),
687 previous_default_device_id);
688 AudioDeviceDescriptions device_descriptions;
689 device_info_accessor_->GetAudioOutputDeviceDescriptions(&device_descriptions);
690
691 CheckDeviceDescriptions(device_descriptions);
692
693 // Set internal speaker as active.
694 chromeos::AudioDevice internal_speaker(kInternalSpeaker);
695 cras_audio_handler_->SwitchToDevice(
696 internal_speaker, true, chromeos::CrasAudioHandler::ACTIVATE_BY_USER);
697 auto new_default_device_id =
698 device_info_accessor_->GetDefaultOutputDeviceID();
699 EXPECT_NE(previous_default_device_id, new_default_device_id);
700
701 auto default_device_group_id =
702 getGroupID(device_descriptions, new_default_device_id);
703 auto speaker_group_id = getGroupID(device_descriptions,
704 base::NumberToString(kInternalSpeaker.id));
705
706 EXPECT_EQ(default_device_group_id, speaker_group_id);
707 EXPECT_EQ(base::NumberToString(kInternalSpeaker.id), new_default_device_id);
708 }
709 #else // !(defined(USE_CRAS) && BUILDFLAG(IS_ASH))
710
TEST_F(AudioManagerTest,HandleDefaultDeviceIDs)711 TEST_F(AudioManagerTest, HandleDefaultDeviceIDs) {
712 // Use a fake manager so we can makeup device ids, this will still use the
713 // AudioManagerBase code.
714 CreateAudioManagerForTesting<FakeAudioManager>();
715 HandleDefaultDeviceIDsTest();
716 base::RunLoop().RunUntilIdle();
717 }
718
719 // Test that devices can be enumerated.
TEST_F(AudioManagerTest,EnumerateInputDevices)720 TEST_F(AudioManagerTest, EnumerateInputDevices) {
721 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
722
723 AudioDeviceDescriptions device_descriptions;
724 device_info_accessor_->GetAudioInputDeviceDescriptions(&device_descriptions);
725 CheckDeviceDescriptions(device_descriptions);
726 }
727
728 // Test that devices can be enumerated.
TEST_F(AudioManagerTest,EnumerateOutputDevices)729 TEST_F(AudioManagerTest, EnumerateOutputDevices) {
730 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
731
732 AudioDeviceDescriptions device_descriptions;
733 device_info_accessor_->GetAudioOutputDeviceDescriptions(&device_descriptions);
734 CheckDeviceDescriptions(device_descriptions);
735 }
736
737 // Run additional tests for Windows since enumeration can be done using
738 // two different APIs. MMDevice is default for Vista and higher and Wave
739 // is default for XP and lower.
740 #if defined(OS_WIN)
741
742 // Override default enumeration API and force usage of Windows MMDevice.
743 // This test will only run on Windows Vista and higher.
TEST_F(AudioManagerTest,EnumerateInputDevicesWinMMDevice)744 TEST_F(AudioManagerTest, EnumerateInputDevicesWinMMDevice) {
745 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
746
747 AudioDeviceDescriptions device_descriptions;
748 device_info_accessor_->GetAudioInputDeviceDescriptions(&device_descriptions);
749 CheckDeviceDescriptions(device_descriptions);
750 }
751
TEST_F(AudioManagerTest,EnumerateOutputDevicesWinMMDevice)752 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinMMDevice) {
753 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
754
755 AudioDeviceDescriptions device_descriptions;
756 device_info_accessor_->GetAudioOutputDeviceDescriptions(&device_descriptions);
757 CheckDeviceDescriptions(device_descriptions);
758 }
759 #endif // defined(OS_WIN)
760
761 #if defined(USE_PULSEAUDIO)
762 // On Linux, there are two implementations available and both can
763 // sometimes be tested on a single system. These tests specifically
764 // test Pulseaudio.
765
TEST_F(AudioManagerTest,EnumerateInputDevicesPulseaudio)766 TEST_F(AudioManagerTest, EnumerateInputDevicesPulseaudio) {
767 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
768
769 CreateAudioManagerForTesting<AudioManagerPulse>();
770 if (audio_manager_.get()) {
771 AudioDeviceDescriptions device_descriptions;
772 device_info_accessor_->GetAudioInputDeviceDescriptions(
773 &device_descriptions);
774 CheckDeviceDescriptions(device_descriptions);
775 } else {
776 LOG(WARNING) << "No pulseaudio on this system.";
777 }
778 }
779
TEST_F(AudioManagerTest,EnumerateOutputDevicesPulseaudio)780 TEST_F(AudioManagerTest, EnumerateOutputDevicesPulseaudio) {
781 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
782
783 CreateAudioManagerForTesting<AudioManagerPulse>();
784 if (audio_manager_.get()) {
785 AudioDeviceDescriptions device_descriptions;
786 device_info_accessor_->GetAudioOutputDeviceDescriptions(
787 &device_descriptions);
788 CheckDeviceDescriptions(device_descriptions);
789 } else {
790 LOG(WARNING) << "No pulseaudio on this system.";
791 }
792 }
793 #endif // defined(USE_PULSEAUDIO)
794
795 #if defined(USE_ALSA)
796 // On Linux, there are two implementations available and both can
797 // sometimes be tested on a single system. These tests specifically
798 // test Alsa.
799
TEST_F(AudioManagerTest,EnumerateInputDevicesAlsa)800 TEST_F(AudioManagerTest, EnumerateInputDevicesAlsa) {
801 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
802
803 DVLOG(2) << "Testing AudioManagerAlsa.";
804 CreateAudioManagerForTesting<AudioManagerAlsa>();
805 AudioDeviceDescriptions device_descriptions;
806 device_info_accessor_->GetAudioInputDeviceDescriptions(&device_descriptions);
807 CheckDeviceDescriptions(device_descriptions);
808 }
809
TEST_F(AudioManagerTest,EnumerateOutputDevicesAlsa)810 TEST_F(AudioManagerTest, EnumerateOutputDevicesAlsa) {
811 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
812
813 DVLOG(2) << "Testing AudioManagerAlsa.";
814 CreateAudioManagerForTesting<AudioManagerAlsa>();
815 AudioDeviceDescriptions device_descriptions;
816 device_info_accessor_->GetAudioOutputDeviceDescriptions(&device_descriptions);
817 CheckDeviceDescriptions(device_descriptions);
818 }
819 #endif // defined(USE_ALSA)
820
TEST_F(AudioManagerTest,GetDefaultOutputStreamParameters)821 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) {
822 #if defined(OS_WIN) || defined(OS_MAC)
823 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
824
825 AudioParameters params;
826 GetDefaultOutputStreamParameters(¶ms);
827 EXPECT_TRUE(params.IsValid());
828 #endif // defined(OS_WIN) || defined(OS_MAC)
829 }
830
TEST_F(AudioManagerTest,GetAssociatedOutputDeviceID)831 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) {
832 #if defined(OS_WIN) || defined(OS_MAC)
833 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable() && OutputDevicesAvailable());
834
835 AudioDeviceDescriptions device_descriptions;
836 device_info_accessor_->GetAudioInputDeviceDescriptions(&device_descriptions);
837 bool found_an_associated_device = false;
838 for (const auto& description : device_descriptions) {
839 EXPECT_FALSE(description.unique_id.empty());
840 EXPECT_FALSE(description.device_name.empty());
841 EXPECT_FALSE(description.group_id.empty());
842 std::string output_device_id;
843 GetAssociatedOutputDeviceID(description.unique_id, &output_device_id);
844 if (!output_device_id.empty()) {
845 DVLOG(2) << description.unique_id << " matches with " << output_device_id;
846 found_an_associated_device = true;
847 }
848 }
849
850 EXPECT_TRUE(found_an_associated_device);
851 #endif // defined(OS_WIN) || defined(OS_MAC)
852 }
853 #endif // defined(USE_CRAS) && BUILDFLAG(IS_ASH)
854
855 class TestAudioManager : public FakeAudioManager {
856 // For testing the default implementation of GetGroupId(Input|Output)
857 // input$i is associated to output$i, if both exist.
858 // Default input is input1.
859 // Default output is output2.
860 public:
TestAudioManager(std::unique_ptr<AudioThread> audio_thread,AudioLogFactory * audio_log_factory)861 TestAudioManager(std::unique_ptr<AudioThread> audio_thread,
862 AudioLogFactory* audio_log_factory)
863 : FakeAudioManager(std::move(audio_thread), audio_log_factory) {}
864
GetDefaultInputDeviceID()865 std::string GetDefaultInputDeviceID() override {
866 return kRealDefaultInputDeviceID;
867 }
GetDefaultOutputDeviceID()868 std::string GetDefaultOutputDeviceID() override {
869 return kRealDefaultOutputDeviceID;
870 }
GetCommunicationsInputDeviceID()871 std::string GetCommunicationsInputDeviceID() override {
872 return kRealCommunicationsInputDeviceID;
873 }
GetCommunicationsOutputDeviceID()874 std::string GetCommunicationsOutputDeviceID() override {
875 return kRealCommunicationsOutputDeviceID;
876 }
877
GetAssociatedOutputDeviceID(const std::string & input_id)878 std::string GetAssociatedOutputDeviceID(
879 const std::string& input_id) override {
880 if (input_id == "input1")
881 return "output1";
882 DCHECK_EQ(std::string(kRealDefaultInputDeviceID), "input2");
883 if (input_id == AudioDeviceDescription::kDefaultDeviceId ||
884 input_id == kRealDefaultInputDeviceID)
885 return "output2";
886 return std::string();
887 }
888
889 private:
GetAudioInputDeviceNames(AudioDeviceNames * device_names)890 void GetAudioInputDeviceNames(AudioDeviceNames* device_names) override {
891 DCHECK(device_names->empty());
892 device_names->emplace_back(AudioDeviceName::CreateDefault());
893 device_names->emplace_back("Input 1", "input1");
894 device_names->emplace_back("Input 2", "input2");
895 device_names->emplace_back("Input 3", "input3");
896 }
897
GetAudioOutputDeviceNames(AudioDeviceNames * device_names)898 void GetAudioOutputDeviceNames(AudioDeviceNames* device_names) override {
899 DCHECK(device_names->empty());
900 device_names->emplace_back(AudioDeviceName::CreateDefault());
901 device_names->emplace_back("Output 1", "output1");
902 device_names->emplace_back("Output 2", "output2");
903 device_names->emplace_back("Output 3", "output3");
904 }
905 };
906
TEST_F(AudioManagerTest,GroupId)907 TEST_F(AudioManagerTest, GroupId) {
908 CreateAudioManagerForTesting<TestAudioManager>();
909 // Groups:
910 // input1, output1
911 // input2, output2, default input
912 // input3
913 // output3, default output
914 AudioDeviceDescriptions inputs;
915 device_info_accessor_->GetAudioInputDeviceDescriptions(&inputs);
916 AudioDeviceDescriptions outputs;
917 device_info_accessor_->GetAudioOutputDeviceDescriptions(&outputs);
918 // default input
919 EXPECT_EQ(inputs[0].group_id, outputs[2].group_id);
920 // default input and default output are not associated
921 EXPECT_NE(inputs[0].group_id, outputs[0].group_id);
922
923 // default output
924 EXPECT_EQ(outputs[0].group_id, outputs[3].group_id);
925
926 // real inputs and outputs that are associated
927 EXPECT_EQ(inputs[1].group_id, outputs[1].group_id);
928 EXPECT_EQ(inputs[2].group_id, outputs[2].group_id);
929
930 // real inputs and outputs that are not associated
931 EXPECT_NE(inputs[3].group_id, outputs[3].group_id);
932
933 // group IDs of different devices should differ.
934 EXPECT_NE(inputs[1].group_id, inputs[2].group_id);
935 EXPECT_NE(inputs[1].group_id, inputs[3].group_id);
936 EXPECT_NE(inputs[2].group_id, inputs[3].group_id);
937 EXPECT_NE(outputs[1].group_id, outputs[2].group_id);
938 EXPECT_NE(outputs[1].group_id, outputs[3].group_id);
939 EXPECT_NE(outputs[2].group_id, outputs[3].group_id);
940 }
941
TEST_F(AudioManagerTest,DefaultCommunicationsLabelsContainRealLabels)942 TEST_F(AudioManagerTest, DefaultCommunicationsLabelsContainRealLabels) {
943 CreateAudioManagerForTesting<TestAudioManager>();
944 std::string default_input_id =
945 device_info_accessor_->GetDefaultInputDeviceID();
946 EXPECT_EQ(default_input_id, kRealDefaultInputDeviceID);
947 std::string default_output_id =
948 device_info_accessor_->GetDefaultOutputDeviceID();
949 EXPECT_EQ(default_output_id, kRealDefaultOutputDeviceID);
950 std::string communications_input_id =
951 device_info_accessor_->GetCommunicationsInputDeviceID();
952 EXPECT_EQ(communications_input_id, kRealCommunicationsInputDeviceID);
953 std::string communications_output_id =
954 device_info_accessor_->GetCommunicationsOutputDeviceID();
955 EXPECT_EQ(communications_output_id, kRealCommunicationsOutputDeviceID);
956 AudioDeviceDescriptions inputs;
957 device_info_accessor_->GetAudioInputDeviceDescriptions(&inputs);
958 CheckDescriptionLabels(inputs, default_input_id, communications_input_id);
959
960 AudioDeviceDescriptions outputs;
961 device_info_accessor_->GetAudioOutputDeviceDescriptions(&outputs);
962 CheckDescriptionLabels(outputs, default_output_id, communications_output_id);
963 }
964
965 // GetPreferredOutputStreamParameters() can make changes to its input_params,
966 // ensure that creating a stream with the default parameters always works.
TEST_F(AudioManagerTest,CheckMakeOutputStreamWithPreferredParameters)967 TEST_F(AudioManagerTest, CheckMakeOutputStreamWithPreferredParameters) {
968 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
969
970 AudioParameters params;
971 GetDefaultOutputStreamParameters(¶ms);
972 ASSERT_TRUE(params.IsValid());
973
974 AudioOutputStream* stream =
975 audio_manager_->MakeAudioOutputStreamProxy(params, "");
976 ASSERT_TRUE(stream);
977
978 stream->Close();
979 }
980
981 #if defined(OS_MAC) || defined(USE_CRAS)
982 class TestAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
983 public:
TestAudioSourceCallback(int expected_frames_per_buffer,base::WaitableEvent * event)984 TestAudioSourceCallback(int expected_frames_per_buffer,
985 base::WaitableEvent* event)
986 : expected_frames_per_buffer_(expected_frames_per_buffer),
987 event_(event) {}
988
~TestAudioSourceCallback()989 ~TestAudioSourceCallback() override {}
990
OnMoreData(base::TimeDelta,base::TimeTicks,int,AudioBus * dest)991 int OnMoreData(base::TimeDelta,
992 base::TimeTicks,
993 int,
994 AudioBus* dest) override {
995 EXPECT_EQ(dest->frames(), expected_frames_per_buffer_);
996 event_->Signal();
997 return 0;
998 }
999
OnError(ErrorType type)1000 void OnError(ErrorType type) override { FAIL(); }
1001
1002 private:
1003 const int expected_frames_per_buffer_;
1004 base::WaitableEvent* event_;
1005
1006 DISALLOW_COPY_AND_ASSIGN(TestAudioSourceCallback);
1007 };
1008
1009 // Test that we can create an AudioOutputStream with kMinAudioBufferSize and
1010 // kMaxAudioBufferSize and that the callback AudioBus is the expected size.
TEST_F(AudioManagerTest,CheckMinMaxAudioBufferSizeCallbacks)1011 TEST_F(AudioManagerTest, CheckMinMaxAudioBufferSizeCallbacks) {
1012 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
1013
1014 #if defined(OS_MAC)
1015 CreateAudioManagerForTesting<AudioManagerMac>();
1016 #elif defined(USE_CRAS) && BUILDFLAG(IS_ASH)
1017 CreateAudioManagerForTesting<AudioManagerChromeOS>();
1018 #endif
1019
1020 DCHECK(audio_manager_);
1021
1022 AudioParameters default_params;
1023 GetDefaultOutputStreamParameters(&default_params);
1024 ASSERT_LT(default_params.frames_per_buffer(),
1025 media::limits::kMaxAudioBufferSize);
1026
1027 #if defined(OS_MAC)
1028 // On OSX the preferred output buffer size is higher than the minimum
1029 // but users may request the minimum size explicitly.
1030 ASSERT_GT(default_params.frames_per_buffer(),
1031 GetMinAudioBufferSizeMacOS(media::limits::kMinAudioBufferSize,
1032 default_params.sample_rate()));
1033 #elif defined(USE_CRAS)
1034 // On CRAS the preferred output buffer size varies per board and may be as low
1035 // as the minimum for some boards.
1036 ASSERT_GE(default_params.frames_per_buffer(),
1037 media::limits::kMinAudioBufferSize);
1038 #else
1039 NOTREACHED();
1040 #endif
1041
1042 AudioOutputStream* stream;
1043 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1044 base::WaitableEvent::InitialState::NOT_SIGNALED);
1045
1046 // Create an output stream with the minimum buffer size parameters and ensure
1047 // that no errors are returned.
1048 AudioParameters min_params = default_params;
1049 min_params.set_frames_per_buffer(media::limits::kMinAudioBufferSize);
1050 stream = audio_manager_->MakeAudioOutputStreamProxy(min_params, "");
1051 ASSERT_TRUE(stream);
1052 EXPECT_TRUE(stream->Open());
1053 event.Reset();
1054 TestAudioSourceCallback min_source(min_params.frames_per_buffer(), &event);
1055 stream->Start(&min_source);
1056 event.Wait();
1057 stream->Stop();
1058 stream->Close();
1059
1060 // Verify the same for the maximum buffer size.
1061 AudioParameters max_params = default_params;
1062 max_params.set_frames_per_buffer(media::limits::kMaxAudioBufferSize);
1063 stream = audio_manager_->MakeAudioOutputStreamProxy(max_params, "");
1064 ASSERT_TRUE(stream);
1065 EXPECT_TRUE(stream->Open());
1066 event.Reset();
1067 TestAudioSourceCallback max_source(max_params.frames_per_buffer(), &event);
1068 stream->Start(&max_source);
1069 event.Wait();
1070 stream->Stop();
1071 stream->Close();
1072 }
1073 #endif
1074
1075 } // namespace media
1076