diff options
Diffstat (limited to 'chromium/media/audio/audio_manager_unittest.cc')
-rw-r--r-- | chromium/media/audio/audio_manager_unittest.cc | 251 |
1 files changed, 245 insertions, 6 deletions
diff --git a/chromium/media/audio/audio_manager_unittest.cc b/chromium/media/audio/audio_manager_unittest.cc index 65948647255..f9db1276a2b 100644 --- a/chromium/media/audio/audio_manager_unittest.cc +++ b/chromium/media/audio/audio_manager_unittest.cc @@ -102,6 +102,12 @@ struct TestAudioManagerFactory<std::nullptr_t> { using chromeos::AudioNode; using chromeos::AudioNodeList; +const int kDefaultSampleRate = 48000; + +const uint64_t kInternalSpeakerId = 10001; +const uint64_t kInternalSpeakerStableDeviceId = 10001; +const uint64_t kInternalMicId = 10002; +const uint64_t kInternalMicStableDeviceId = 10002; const uint64_t kJabraSpeaker1Id = 30001; const uint64_t kJabraSpeaker1StableDeviceId = 80001; const uint64_t kJabraSpeaker2Id = 30002; @@ -115,6 +121,30 @@ const uint64_t kJabraMic2StableDeviceId = 90002; const uint64_t kWebcamMicId = 40003; const uint64_t kWebcamMicStableDeviceId = 90003; +const AudioNode kInternalSpeaker(false, + kInternalSpeakerId, + true, + kInternalSpeakerStableDeviceId, + kInternalSpeakerStableDeviceId ^ 0xFF, + "Internal Speaker", + "INTERNAL_SPEAKER", + "Speaker", + false, + 0, + 2); + +const AudioNode kInternalMic(true, + kInternalMicId, + true, + kInternalMicStableDeviceId, + kInternalMicStableDeviceId ^ 0xFF, + "Internal Mic", + "INTERNAL_MIC", + "Internal Mic", + false, + 0, + 1); + const AudioNode kJabraSpeaker1(false, kJabraSpeaker1Id, true, @@ -124,7 +154,8 @@ const AudioNode kJabraSpeaker1(false, "USB", "Jabra Speaker 1", false, - 0); + 0, + 2); // expects CHANNEL_LAYOUT_STEREO const AudioNode kJabraSpeaker2(false, kJabraSpeaker2Id, @@ -135,7 +166,8 @@ const AudioNode kJabraSpeaker2(false, "USB", "Jabra Speaker 2", false, - 0); + 0, + 6); // expects CHANNEL_LAYOUT_5_1 const AudioNode kHDMIOutput(false, kHDMIOutputId, @@ -146,7 +178,8 @@ const AudioNode kHDMIOutput(false, "HDMI", "HDA Intel MID", false, - 0); + 0, + 8); // expects CHANNEL_LAYOUT_7_1 const AudioNode kJabraMic1(true, kJabraMic1Id, @@ -157,7 +190,8 @@ const AudioNode kJabraMic1(true, "USB", "Jabra Mic 1", false, - 0); + 0, + 1); const AudioNode kJabraMic2(true, kJabraMic2Id, @@ -168,7 +202,8 @@ const AudioNode kJabraMic2(true, "USB", "Jabra Mic 2", false, - 0); + 0, + 1); const AudioNode kUSBCameraMic(true, kWebcamMicId, @@ -179,7 +214,8 @@ const AudioNode kUSBCameraMic(true, "USB", "Logitech Webcam", false, - 0); + 0, + 1); #endif // defined(USE_CRAS) const char kRealDefaultInputDeviceID[] = "input2"; @@ -274,6 +310,27 @@ class AudioManagerTest : public ::testing::Test { cras_audio_handler_ = chromeos::CrasAudioHandler::Get(); base::RunLoop().RunUntilIdle(); } + + void SetActiveOutputNode(uint64_t node_id) { + cras_audio_handler_->SwitchToDevice( + *cras_audio_handler_->GetDeviceFromId(node_id), true /* notify */, + chromeos::CrasAudioHandler::ACTIVATE_BY_USER /* activate_by */); + } + + AudioParameters GetPreferredOutputStreamParameters( + ChannelLayout channel_layout, int32_t user_buffer_size = 0) { + // Generated AudioParameters should follow the same rule as in + // AudioManagerCras::GetPreferredOutputStreamParameters(). + int sample_rate = kDefaultSampleRate; + int32_t buffer_size = user_buffer_size; + if (buffer_size == 0) // Not user-provided. + cras_audio_handler_->GetDefaultOutputBufferSize(&buffer_size); + return AudioParameters( + AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, sample_rate, + buffer_size, + AudioParameters::HardwareCapabilities(limits::kMinAudioBufferSize, + limits::kMaxAudioBufferSize)); + } #endif // defined(USE_CRAS) protected: @@ -367,6 +424,19 @@ class AudioManagerTest : public ::testing::Test { LOG(WARNING) << "No input devices detected"; } } + + // Helper method for (USE_CRAS) which returns |group_id| from |device_id|. + std::string getGroupID(const AudioDeviceDescriptions& device_descriptions, + const std::string device_id) { + AudioDeviceDescriptions::const_iterator it = + std::find_if(device_descriptions.begin(), device_descriptions.end(), + [&device_id](const auto& audio_device_desc) { + return audio_device_desc.unique_id == device_id; + }); + + EXPECT_NE(it, device_descriptions.end()); + return it->group_id; + } #endif // defined(USE_CRAS) bool InputDevicesAvailable() { @@ -464,6 +534,175 @@ TEST_F(AudioManagerTest, EnumerateOutputDevicesCras) { device_info_accessor_->GetAudioOutputDeviceDescriptions(&device_descriptions); CheckDeviceDescriptionsCras(device_descriptions, expectation); } + +TEST_F(AudioManagerTest, CheckOutputStreamParametersCras) { + // Setup the devices without internal mic, so that it doesn't exist + // beamforming capable mic. + AudioNodeList audio_nodes; + audio_nodes.push_back(kJabraMic1); + audio_nodes.push_back(kJabraMic2); + audio_nodes.push_back(kUSBCameraMic); + audio_nodes.push_back(kHDMIOutput); + audio_nodes.push_back(kJabraSpeaker1); + audio_nodes.push_back(kJabraSpeaker2); + + SetUpCrasAudioHandlerWithTestingNodes(audio_nodes); + + ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable()); + + DVLOG(2) << "Testing AudioManagerCras."; + CreateAudioManagerForTesting<AudioManagerCras>(); + AudioParameters params, golden_params; + + // channel_layout: + // JabraSpeaker1 (2-channel): CHANNEL_LAYOUT_STEREO + // JabraSpeaker2 (6-channel): CHANNEL_LAYOUT_5_1 + // HDMIOutput (8-channel): CHANNEL_LAYOUT_7_1 + + // Check GetOutputStreamParameters() with device ID. The returned parameters + // should be reflected to the specific output device. + params = device_info_accessor_->GetOutputStreamParameters( + base::NumberToString(kJabraSpeaker1Id)); + golden_params = GetPreferredOutputStreamParameters( + ChannelLayout::CHANNEL_LAYOUT_STEREO); + EXPECT_TRUE(params.Equals(golden_params)); + params = device_info_accessor_->GetOutputStreamParameters( + base::NumberToString(kJabraSpeaker2Id)); + golden_params = GetPreferredOutputStreamParameters( + ChannelLayout::CHANNEL_LAYOUT_5_1); + EXPECT_TRUE(params.Equals(golden_params)); + params = device_info_accessor_->GetOutputStreamParameters( + base::NumberToString(kHDMIOutputId)); + golden_params = GetPreferredOutputStreamParameters( + ChannelLayout::CHANNEL_LAYOUT_7_1); + EXPECT_TRUE(params.Equals(golden_params)); + + // Set user-provided audio buffer size by command line, then check the buffer + // size in stream parameters is equal to the user-provided one. + int argc = 2; + char const *argv0 = "dummy"; + char const *argv1 = "--audio-buffer-size=2048"; + const char* argv[] = {argv0, argv1, 0}; + base::CommandLine::Reset(); + EXPECT_TRUE(base::CommandLine::Init(argc, argv)); + + // Check GetOutputStreamParameters() with default ID. The returned parameters + // should reflect the currently active output device. + SetActiveOutputNode(kJabraSpeaker1Id); + params = device_info_accessor_->GetOutputStreamParameters( + AudioDeviceDescription::kDefaultDeviceId); + golden_params = GetPreferredOutputStreamParameters( + ChannelLayout::CHANNEL_LAYOUT_STEREO, 2048); + EXPECT_TRUE(params.Equals(golden_params)); + SetActiveOutputNode(kJabraSpeaker2Id); + params = device_info_accessor_->GetOutputStreamParameters( + AudioDeviceDescription::kDefaultDeviceId); + golden_params = GetPreferredOutputStreamParameters( + ChannelLayout::CHANNEL_LAYOUT_5_1, 2048); + EXPECT_TRUE(params.Equals(golden_params)); + SetActiveOutputNode(kHDMIOutputId); + params = device_info_accessor_->GetOutputStreamParameters( + AudioDeviceDescription::kDefaultDeviceId); + golden_params = GetPreferredOutputStreamParameters( + ChannelLayout::CHANNEL_LAYOUT_7_1, 2048); + EXPECT_TRUE(params.Equals(golden_params)); + + // Check non-default device again. + params = device_info_accessor_->GetOutputStreamParameters( + base::NumberToString(kJabraSpeaker1Id)); + golden_params = GetPreferredOutputStreamParameters( + ChannelLayout::CHANNEL_LAYOUT_STEREO, 2048); + EXPECT_TRUE(params.Equals(golden_params)); +} + +TEST_F(AudioManagerTest, LookupDefaultInputDeviceWithProperGroupId) { + // Setup devices with external microphone as active device. + // Switch active device to the internal microphone. + // Check if default device has the same group id as internal microphone. + AudioNodeList audio_nodes; + audio_nodes.push_back(kInternalMic); + audio_nodes.push_back(kJabraMic1); + SetUpCrasAudioHandlerWithTestingNodes(audio_nodes); + + ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable()); + + // Setup expectation with physical devices. + std::map<uint64_t, std::string> expectation; + expectation[kInternalMic.id] = + cras_audio_handler_->GetDeviceFromId(kInternalMic.id)->display_name; + expectation[kJabraMic1.id] = + cras_audio_handler_->GetDeviceFromId(kJabraMic1.id)->display_name; + + CreateAudioManagerForTesting<AudioManagerCras>(); + auto previous_default_device_id = + device_info_accessor_->GetDefaultInputDeviceID(); + EXPECT_EQ(base::NumberToString(kJabraMic1.id), previous_default_device_id); + AudioDeviceDescriptions device_descriptions; + device_info_accessor_->GetAudioInputDeviceDescriptions(&device_descriptions); + + CheckDeviceDescriptions(device_descriptions); + + // Set internal microphone as active. + chromeos::AudioDevice internal_microphone(kInternalMic); + cras_audio_handler_->SwitchToDevice( + internal_microphone, true, chromeos::CrasAudioHandler::ACTIVATE_BY_USER); + auto new_default_device_id = device_info_accessor_->GetDefaultInputDeviceID(); + EXPECT_NE(previous_default_device_id, new_default_device_id); + + auto default_device_group_id = + getGroupID(device_descriptions, new_default_device_id); + auto mic_group_id = + getGroupID(device_descriptions, base::NumberToString(kInternalMic.id)); + + EXPECT_EQ(default_device_group_id, mic_group_id); + EXPECT_EQ(base::NumberToString(kInternalMic.id), new_default_device_id); +} + +TEST_F(AudioManagerTest, LookupDefaultOutputDeviceWithProperGroupId) { + // Setup devices with external speaker as active device. + // Switch active device to the internal speaker. + // Check if default device has the same group id as internal speaker. + AudioNodeList audio_nodes; + audio_nodes.push_back(kInternalSpeaker); + audio_nodes.push_back(kJabraSpeaker1); + + SetUpCrasAudioHandlerWithTestingNodes(audio_nodes); + + ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable()); + + // Setup expectation with physical devices. + std::map<uint64_t, std::string> expectation; + expectation[kInternalSpeaker.id] = + cras_audio_handler_->GetDeviceFromId(kInternalSpeaker.id)->display_name; + expectation[kJabraSpeaker1.id] = + cras_audio_handler_->GetDeviceFromId(kJabraSpeaker1.id)->display_name; + + CreateAudioManagerForTesting<AudioManagerCras>(); + auto previous_default_device_id = + device_info_accessor_->GetDefaultOutputDeviceID(); + EXPECT_EQ(base::NumberToString(kJabraSpeaker1.id), + previous_default_device_id); + AudioDeviceDescriptions device_descriptions; + device_info_accessor_->GetAudioOutputDeviceDescriptions(&device_descriptions); + + CheckDeviceDescriptions(device_descriptions); + + // Set internal speaker as active. + chromeos::AudioDevice internal_speaker(kInternalSpeaker); + cras_audio_handler_->SwitchToDevice( + internal_speaker, true, chromeos::CrasAudioHandler::ACTIVATE_BY_USER); + auto new_default_device_id = + device_info_accessor_->GetDefaultOutputDeviceID(); + EXPECT_NE(previous_default_device_id, new_default_device_id); + + auto default_device_group_id = + getGroupID(device_descriptions, new_default_device_id); + auto speaker_group_id = getGroupID(device_descriptions, + base::NumberToString(kInternalSpeaker.id)); + + EXPECT_EQ(default_device_group_id, speaker_group_id); + EXPECT_EQ(base::NumberToString(kInternalSpeaker.id), new_default_device_id); +} #else // !defined(USE_CRAS) TEST_F(AudioManagerTest, HandleDefaultDeviceIDs) { |