Loading media/libaudiohal/impl/Hal2AidlMapper.cpp +25 −10 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ using aidl::android::media::audio::common::AudioDeviceDescription; using aidl::android::media::audio::common::AudioDeviceType; using aidl::android::media::audio::common::AudioFormatDescription; using aidl::android::media::audio::common::AudioFormatType; using aidl::android::media::audio::common::AudioGainConfig; using aidl::android::media::audio::common::AudioInputFlags; using aidl::android::media::audio::common::AudioIoFlags; using aidl::android::media::audio::common::AudioOutputFlags; Loading Loading @@ -325,8 +326,8 @@ status_t Hal2AidlMapper::findOrCreatePatch( } status_t Hal2AidlMapper::findOrCreateDevicePortConfig( const AudioDevice& device, const AudioConfig* config, AudioPortConfig* portConfig, bool* created) { const AudioDevice& device, const AudioConfig* config, const AudioGainConfig* gainConfig, AudioPortConfig* portConfig, bool* created) { if (auto portConfigIt = findPortConfig(device); portConfigIt == mPortConfigs.end()) { auto portsIt = findPort(device); if (portsIt == mPorts.end()) { Loading @@ -339,12 +340,18 @@ status_t Hal2AidlMapper::findOrCreateDevicePortConfig( if (config != nullptr) { setPortConfigFromConfig(&requestedPortConfig, *config); } if (gainConfig != nullptr) { requestedPortConfig.gain = *gainConfig; } return createOrUpdatePortConfigRetry(requestedPortConfig, portConfig, created); } else { AudioPortConfig requestedPortConfig = portConfigIt->second; if (config != nullptr) { setPortConfigFromConfig(&requestedPortConfig, *config); } if (gainConfig != nullptr) { requestedPortConfig.gain = *gainConfig; } if (requestedPortConfig != portConfigIt->second) { return createOrUpdatePortConfigRetry(requestedPortConfig, portConfig, created); Loading Loading @@ -447,18 +454,26 @@ status_t Hal2AidlMapper::findOrCreatePortConfig( requestedPortConfig.ext.get<Tag::mix>().handle, source, destinationPortIds, portConfig, created); } else if (requestedPortConfig.ext.getTag() == Tag::device) { if (const auto& p = requestedPortConfig; p.sampleRate.has_value() && p.channelMask.has_value() && p.format.has_value()) { AudioConfig config; const auto& p = requestedPortConfig; const bool hasAudioConfig = p.sampleRate.has_value() && p.channelMask.has_value() && p.format.has_value(); const bool hasGainConfig = p.gain.has_value(); if (hasAudioConfig || hasGainConfig) { AudioConfig config, *configPtr = nullptr; if (hasAudioConfig) { setConfigFromPortConfig(&config, requestedPortConfig); configPtr = &config; } const AudioGainConfig* gainConfigPtr = nullptr; if (hasGainConfig) gainConfigPtr = &(*(p.gain)); return findOrCreateDevicePortConfig( requestedPortConfig.ext.get<Tag::device>().device, &config, requestedPortConfig.ext.get<Tag::device>().device, configPtr, gainConfigPtr, portConfig, created); } else { ALOGD("%s: device port config does not have audio or gain config specified", __func__); return findOrCreateDevicePortConfig( requestedPortConfig.ext.get<Tag::device>().device, nullptr /*config*/, portConfig, created); nullptr /*gainConfig*/, portConfig, created); } } ALOGW("%s: unsupported audio port config: %s", Loading Loading @@ -769,7 +784,7 @@ status_t Hal2AidlMapper::prepareToOpenStream( // then find / create a patch between them, and open a stream on the mix port. AudioPortConfig devicePortConfig; bool created = false; RETURN_STATUS_IF_ERROR(findOrCreateDevicePortConfig(device, config, RETURN_STATUS_IF_ERROR(findOrCreateDevicePortConfig(device, config, nullptr /*gainConfig*/, &devicePortConfig, &created)); LOG_ALWAYS_FATAL_IF(devicePortConfig.id == 0); if (created) { Loading media/libaudiohal/impl/Hal2AidlMapper.h +1 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ class Hal2AidlMapper { status_t findOrCreateDevicePortConfig( const ::aidl::android::media::audio::common::AudioDevice& device, const ::aidl::android::media::audio::common::AudioConfig* config, const ::aidl::android::media::audio::common::AudioGainConfig* gainConfig, ::aidl::android::media::audio::common::AudioPortConfig* portConfig, bool* created); // If the resulting 'portConfig->id' is 0, that means the config was not created, Loading media/libaudiohal/tests/CoreAudioHalAidl_test.cpp +80 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <aidl/android/hardware/audio/core/BnModule.h> #include <aidl/android/hardware/audio/core/BnStreamCommon.h> #include <aidl/android/media/audio/BnHalAdapterVendorExtension.h> #include <aidl/android/media/audio/common/AudioGainMode.h> #include <aidl/android/media/audio/common/Int.h> #include <utils/Log.h> Loading @@ -44,6 +45,8 @@ using ::aidl::android::media::audio::common::AudioDeviceDescription; using ::aidl::android::media::audio::common::AudioDeviceType; using ::aidl::android::media::audio::common::AudioFormatDescription; using ::aidl::android::media::audio::common::AudioFormatType; using ::aidl::android::media::audio::common::AudioGainConfig; using ::aidl::android::media::audio::common::AudioGainMode; using ::aidl::android::media::audio::common::AudioIoFlags; using ::aidl::android::media::audio::common::AudioPort; using ::aidl::android::media::audio::common::AudioPortConfig; Loading Loading @@ -179,6 +182,11 @@ Configuration getTestConfiguration() { primaryInMix.profiles = standardPcmAudioProfiles; c.ports.push_back(primaryInMix); AudioPort speakerOutDevice = createPort(c.nextPortId++, "Speaker", 0, false, createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)); speakerOutDevice.profiles = standardPcmAudioProfiles; c.ports.push_back(speakerOutDevice); AudioPort btOutDevice = createPort(c.nextPortId++, "BT A2DP Out", 0, false, createPortDeviceExt(AudioDeviceType::OUT_DEVICE, 0, Loading Loading @@ -209,6 +217,13 @@ class ModuleMock : public ::aidl::android::hardware::audio::core::BnModule, getAudioPatches(&result); return result; } std::optional<AudioPortConfig> getPortConfig(int32_t id) { auto iter = findById<AudioPortConfig>(mConfig.portConfigs, id); if (iter != mConfig.portConfigs.end()) { return *iter; } return std::nullopt; } private: ndk::ScopedAStatus setModuleDebug( Loading Loading @@ -646,6 +661,19 @@ std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, } } // namespace aidl::android::hardware::audio::core namespace aidl::android::media::audio::common { template <typename P> std::enable_if_t<std::is_function_v<typename mf_traits<decltype(&P::toString)>::member_type>, std::ostream&> operator<<(std::ostream& os, const P& p) { return os << p.toString(); } template <typename E> std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, const E& e) { return os << toString(e); } } // namespace aidl::android::media::audio::common using namespace android; namespace { Loading Loading @@ -1214,3 +1242,55 @@ TEST_F(Hal2AidlMapperTest, ChangeTransientPatchDevice) { EXPECT_EQ(std::vector<int32_t>{backMicPortConfig.id}, patchIt->sourcePortConfigIds); EXPECT_EQ(std::vector<int32_t>{mixPortConfig.id}, patchIt->sinkPortConfigIds); } TEST_F(Hal2AidlMapperTest, SetAudioPortConfigGainChangeExistingPortConfig) { // First set config, then update gain. AudioPortConfig speakerPortConfig; speakerPortConfig.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0); speakerPortConfig.channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>( AudioChannelLayout::LAYOUT_STEREO); speakerPortConfig.format = AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = PcmType::INT_16_BIT}; speakerPortConfig.sampleRate = ::aidl::android::media::audio::common::Int(48000); AudioPortConfig resultingPortConfig; ASSERT_EQ(OK, mMapper->setPortConfig(speakerPortConfig, std::set<int32_t>(), &resultingPortConfig)); EXPECT_NE(0, resultingPortConfig.id); EXPECT_NE(0, resultingPortConfig.portId); AudioPortConfig gainUpdate; gainUpdate.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0); AudioGainConfig gainConfig{.index = -1, .mode = 1 << static_cast<int>(AudioGainMode::JOINT), .channelMask = AudioChannelLayout{}, .values = std::vector<int32_t>{-3200}, .rampDurationMs = 0}; gainUpdate.gain = gainConfig; AudioPortConfig resultingGainUpdate; ASSERT_EQ(OK, mMapper->setPortConfig(gainUpdate, std::set<int32_t>(), &resultingGainUpdate)); EXPECT_EQ(resultingPortConfig.id, resultingGainUpdate.id); auto updatedPortConfig = mModule->getPortConfig(resultingGainUpdate.id); ASSERT_TRUE(updatedPortConfig.has_value()); ASSERT_TRUE(updatedPortConfig->gain.has_value()); EXPECT_EQ(gainConfig, updatedPortConfig->gain); } TEST_F(Hal2AidlMapperTest, SetAudioPortConfigGainChangeFromScratch) { // Set gain as the first operation, the HAL should suggest the rest of the configuration. AudioPortConfig gainSet; gainSet.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0); AudioGainConfig gainConfig{.index = -1, .mode = 1 << static_cast<int>(AudioGainMode::JOINT), .channelMask = AudioChannelLayout{}, .values = std::vector<int32_t>{-3200}, .rampDurationMs = 0}; gainSet.gain = gainConfig; AudioPortConfig resultingPortConfig; ASSERT_EQ(OK, mMapper->setPortConfig(gainSet, std::set<int32_t>(), &resultingPortConfig)); EXPECT_NE(0, resultingPortConfig.id); EXPECT_NE(0, resultingPortConfig.portId); auto portConfig = mModule->getPortConfig(resultingPortConfig.id); ASSERT_TRUE(portConfig.has_value()); ASSERT_TRUE(portConfig->gain.has_value()); EXPECT_EQ(gainConfig, portConfig->gain); } Loading
media/libaudiohal/impl/Hal2AidlMapper.cpp +25 −10 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ using aidl::android::media::audio::common::AudioDeviceDescription; using aidl::android::media::audio::common::AudioDeviceType; using aidl::android::media::audio::common::AudioFormatDescription; using aidl::android::media::audio::common::AudioFormatType; using aidl::android::media::audio::common::AudioGainConfig; using aidl::android::media::audio::common::AudioInputFlags; using aidl::android::media::audio::common::AudioIoFlags; using aidl::android::media::audio::common::AudioOutputFlags; Loading Loading @@ -325,8 +326,8 @@ status_t Hal2AidlMapper::findOrCreatePatch( } status_t Hal2AidlMapper::findOrCreateDevicePortConfig( const AudioDevice& device, const AudioConfig* config, AudioPortConfig* portConfig, bool* created) { const AudioDevice& device, const AudioConfig* config, const AudioGainConfig* gainConfig, AudioPortConfig* portConfig, bool* created) { if (auto portConfigIt = findPortConfig(device); portConfigIt == mPortConfigs.end()) { auto portsIt = findPort(device); if (portsIt == mPorts.end()) { Loading @@ -339,12 +340,18 @@ status_t Hal2AidlMapper::findOrCreateDevicePortConfig( if (config != nullptr) { setPortConfigFromConfig(&requestedPortConfig, *config); } if (gainConfig != nullptr) { requestedPortConfig.gain = *gainConfig; } return createOrUpdatePortConfigRetry(requestedPortConfig, portConfig, created); } else { AudioPortConfig requestedPortConfig = portConfigIt->second; if (config != nullptr) { setPortConfigFromConfig(&requestedPortConfig, *config); } if (gainConfig != nullptr) { requestedPortConfig.gain = *gainConfig; } if (requestedPortConfig != portConfigIt->second) { return createOrUpdatePortConfigRetry(requestedPortConfig, portConfig, created); Loading Loading @@ -447,18 +454,26 @@ status_t Hal2AidlMapper::findOrCreatePortConfig( requestedPortConfig.ext.get<Tag::mix>().handle, source, destinationPortIds, portConfig, created); } else if (requestedPortConfig.ext.getTag() == Tag::device) { if (const auto& p = requestedPortConfig; p.sampleRate.has_value() && p.channelMask.has_value() && p.format.has_value()) { AudioConfig config; const auto& p = requestedPortConfig; const bool hasAudioConfig = p.sampleRate.has_value() && p.channelMask.has_value() && p.format.has_value(); const bool hasGainConfig = p.gain.has_value(); if (hasAudioConfig || hasGainConfig) { AudioConfig config, *configPtr = nullptr; if (hasAudioConfig) { setConfigFromPortConfig(&config, requestedPortConfig); configPtr = &config; } const AudioGainConfig* gainConfigPtr = nullptr; if (hasGainConfig) gainConfigPtr = &(*(p.gain)); return findOrCreateDevicePortConfig( requestedPortConfig.ext.get<Tag::device>().device, &config, requestedPortConfig.ext.get<Tag::device>().device, configPtr, gainConfigPtr, portConfig, created); } else { ALOGD("%s: device port config does not have audio or gain config specified", __func__); return findOrCreateDevicePortConfig( requestedPortConfig.ext.get<Tag::device>().device, nullptr /*config*/, portConfig, created); nullptr /*gainConfig*/, portConfig, created); } } ALOGW("%s: unsupported audio port config: %s", Loading Loading @@ -769,7 +784,7 @@ status_t Hal2AidlMapper::prepareToOpenStream( // then find / create a patch between them, and open a stream on the mix port. AudioPortConfig devicePortConfig; bool created = false; RETURN_STATUS_IF_ERROR(findOrCreateDevicePortConfig(device, config, RETURN_STATUS_IF_ERROR(findOrCreateDevicePortConfig(device, config, nullptr /*gainConfig*/, &devicePortConfig, &created)); LOG_ALWAYS_FATAL_IF(devicePortConfig.id == 0); if (created) { Loading
media/libaudiohal/impl/Hal2AidlMapper.h +1 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ class Hal2AidlMapper { status_t findOrCreateDevicePortConfig( const ::aidl::android::media::audio::common::AudioDevice& device, const ::aidl::android::media::audio::common::AudioConfig* config, const ::aidl::android::media::audio::common::AudioGainConfig* gainConfig, ::aidl::android::media::audio::common::AudioPortConfig* portConfig, bool* created); // If the resulting 'portConfig->id' is 0, that means the config was not created, Loading
media/libaudiohal/tests/CoreAudioHalAidl_test.cpp +80 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <aidl/android/hardware/audio/core/BnModule.h> #include <aidl/android/hardware/audio/core/BnStreamCommon.h> #include <aidl/android/media/audio/BnHalAdapterVendorExtension.h> #include <aidl/android/media/audio/common/AudioGainMode.h> #include <aidl/android/media/audio/common/Int.h> #include <utils/Log.h> Loading @@ -44,6 +45,8 @@ using ::aidl::android::media::audio::common::AudioDeviceDescription; using ::aidl::android::media::audio::common::AudioDeviceType; using ::aidl::android::media::audio::common::AudioFormatDescription; using ::aidl::android::media::audio::common::AudioFormatType; using ::aidl::android::media::audio::common::AudioGainConfig; using ::aidl::android::media::audio::common::AudioGainMode; using ::aidl::android::media::audio::common::AudioIoFlags; using ::aidl::android::media::audio::common::AudioPort; using ::aidl::android::media::audio::common::AudioPortConfig; Loading Loading @@ -179,6 +182,11 @@ Configuration getTestConfiguration() { primaryInMix.profiles = standardPcmAudioProfiles; c.ports.push_back(primaryInMix); AudioPort speakerOutDevice = createPort(c.nextPortId++, "Speaker", 0, false, createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)); speakerOutDevice.profiles = standardPcmAudioProfiles; c.ports.push_back(speakerOutDevice); AudioPort btOutDevice = createPort(c.nextPortId++, "BT A2DP Out", 0, false, createPortDeviceExt(AudioDeviceType::OUT_DEVICE, 0, Loading Loading @@ -209,6 +217,13 @@ class ModuleMock : public ::aidl::android::hardware::audio::core::BnModule, getAudioPatches(&result); return result; } std::optional<AudioPortConfig> getPortConfig(int32_t id) { auto iter = findById<AudioPortConfig>(mConfig.portConfigs, id); if (iter != mConfig.portConfigs.end()) { return *iter; } return std::nullopt; } private: ndk::ScopedAStatus setModuleDebug( Loading Loading @@ -646,6 +661,19 @@ std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, } } // namespace aidl::android::hardware::audio::core namespace aidl::android::media::audio::common { template <typename P> std::enable_if_t<std::is_function_v<typename mf_traits<decltype(&P::toString)>::member_type>, std::ostream&> operator<<(std::ostream& os, const P& p) { return os << p.toString(); } template <typename E> std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, const E& e) { return os << toString(e); } } // namespace aidl::android::media::audio::common using namespace android; namespace { Loading Loading @@ -1214,3 +1242,55 @@ TEST_F(Hal2AidlMapperTest, ChangeTransientPatchDevice) { EXPECT_EQ(std::vector<int32_t>{backMicPortConfig.id}, patchIt->sourcePortConfigIds); EXPECT_EQ(std::vector<int32_t>{mixPortConfig.id}, patchIt->sinkPortConfigIds); } TEST_F(Hal2AidlMapperTest, SetAudioPortConfigGainChangeExistingPortConfig) { // First set config, then update gain. AudioPortConfig speakerPortConfig; speakerPortConfig.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0); speakerPortConfig.channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>( AudioChannelLayout::LAYOUT_STEREO); speakerPortConfig.format = AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = PcmType::INT_16_BIT}; speakerPortConfig.sampleRate = ::aidl::android::media::audio::common::Int(48000); AudioPortConfig resultingPortConfig; ASSERT_EQ(OK, mMapper->setPortConfig(speakerPortConfig, std::set<int32_t>(), &resultingPortConfig)); EXPECT_NE(0, resultingPortConfig.id); EXPECT_NE(0, resultingPortConfig.portId); AudioPortConfig gainUpdate; gainUpdate.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0); AudioGainConfig gainConfig{.index = -1, .mode = 1 << static_cast<int>(AudioGainMode::JOINT), .channelMask = AudioChannelLayout{}, .values = std::vector<int32_t>{-3200}, .rampDurationMs = 0}; gainUpdate.gain = gainConfig; AudioPortConfig resultingGainUpdate; ASSERT_EQ(OK, mMapper->setPortConfig(gainUpdate, std::set<int32_t>(), &resultingGainUpdate)); EXPECT_EQ(resultingPortConfig.id, resultingGainUpdate.id); auto updatedPortConfig = mModule->getPortConfig(resultingGainUpdate.id); ASSERT_TRUE(updatedPortConfig.has_value()); ASSERT_TRUE(updatedPortConfig->gain.has_value()); EXPECT_EQ(gainConfig, updatedPortConfig->gain); } TEST_F(Hal2AidlMapperTest, SetAudioPortConfigGainChangeFromScratch) { // Set gain as the first operation, the HAL should suggest the rest of the configuration. AudioPortConfig gainSet; gainSet.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0); AudioGainConfig gainConfig{.index = -1, .mode = 1 << static_cast<int>(AudioGainMode::JOINT), .channelMask = AudioChannelLayout{}, .values = std::vector<int32_t>{-3200}, .rampDurationMs = 0}; gainSet.gain = gainConfig; AudioPortConfig resultingPortConfig; ASSERT_EQ(OK, mMapper->setPortConfig(gainSet, std::set<int32_t>(), &resultingPortConfig)); EXPECT_NE(0, resultingPortConfig.id); EXPECT_NE(0, resultingPortConfig.portId); auto portConfig = mModule->getPortConfig(resultingPortConfig.id); ASSERT_TRUE(portConfig.has_value()); ASSERT_TRUE(portConfig->gain.has_value()); EXPECT_EQ(gainConfig, portConfig->gain); }