Loading services/audioflinger/MelReporter.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -38,24 +38,21 @@ bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::strin ndk::SpAIBinder soundDoseBinder; if (device->getSoundDoseInterface(module, &soundDoseBinder) != OK) { ALOGW("%s: HAL cannot provide sound dose interface for module %s, use internal MEL", ALOGW("%s: HAL cannot provide sound dose interface for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } if (soundDoseBinder == nullptr) { ALOGW("%s: HAL doesn't implement a sound dose interface for module %s, use internal MEL", ALOGW("%s: HAL doesn't implement a sound dose interface for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } std::shared_ptr<ISoundDose> soundDoseInterface = ISoundDose::fromBinder(soundDoseBinder); if (!mSoundDoseManager->setHalSoundDoseInterface(soundDoseInterface)) { if (!mSoundDoseManager->setHalSoundDoseInterface(module, soundDoseInterface)) { ALOGW("%s: cannot activate HAL MEL reporting for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } Loading @@ -73,7 +70,8 @@ void AudioFlinger::MelReporter::activateInternalSoundDoseComputation() { mUseHalSoundDoseInterface = false; } mSoundDoseManager->setHalSoundDoseInterface(nullptr); // reset the HAL interfaces and use internal MELs mSoundDoseManager->resetHalSoundDoseInterfaces(); } void AudioFlinger::MelReporter::onFirstRef() { Loading Loading @@ -251,6 +249,9 @@ sp<media::ISoundDose> AudioFlinger::MelReporter::getSoundDoseInterface( void AudioFlinger::MelReporter::stopInternalMelComputation() { ALOGV("%s", __func__); std::lock_guard _l(mLock); if (mUseHalSoundDoseInterface) { return; } mActiveMelPatches.clear(); mUseHalSoundDoseInterface = true; } Loading services/audioflinger/sounddose/SoundDoseManager.cpp +50 −33 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ sp<audio_utils::MelProcessor> SoundDoseManager::getOrCreateProcessorForDevice( size_t channelCount, audio_format_t format) { std::lock_guard _l(mLock); if (mHalSoundDose != nullptr && mEnabledCsd) { if (mHalSoundDose.size() > 0 && mEnabledCsd) { ALOGD("%s: using HAL MEL computation, no MelProcessor needed.", __func__); return nullptr; } Loading Loading @@ -83,19 +83,27 @@ sp<audio_utils::MelProcessor> SoundDoseManager::getOrCreateProcessorForDevice( return melProcessor; } bool SoundDoseManager::setHalSoundDoseInterface(const std::shared_ptr<ISoundDose>& halSoundDose) { bool SoundDoseManager::setHalSoundDoseInterface(const std::string &module, const std::shared_ptr<ISoundDose> &halSoundDose) { ALOGV("%s", __func__); if (halSoundDose == nullptr) { ALOGI("%s: passed ISoundDose object is null", __func__); return false; } std::shared_ptr<HalSoundDoseCallback> halSoundDoseCallback; { std::lock_guard _l(mLock); mHalSoundDose = halSoundDose; if (halSoundDose == nullptr) { ALOGI("%s: passed ISoundDose object is null, switching to internal CSD", __func__); if (mHalSoundDose.find(module) != mHalSoundDose.end()) { ALOGW("%s: Module %s already has a sound dose HAL assigned, skipping", __func__, module.c_str()); return false; } mHalSoundDose[module] = halSoundDose; if (!mHalSoundDose->setOutputRs2UpperBound(mRs2UpperBound).isOk()) { if (!halSoundDose->setOutputRs2UpperBound(mRs2UpperBound).isOk()) { ALOGW("%s: Cannot set RS2 value for momentary exposure %f", __func__, mRs2UpperBound); Loading @@ -119,16 +127,26 @@ bool SoundDoseManager::setHalSoundDoseInterface(const std::shared_ptr<ISoundDose return true; } void SoundDoseManager::resetHalSoundDoseInterfaces() { ALOGV("%s", __func__); const std::lock_guard _l(mLock); mHalSoundDose.clear(); } void SoundDoseManager::setOutputRs2UpperBound(float rs2Value) { ALOGV("%s", __func__); std::lock_guard _l(mLock); if (mHalSoundDose != nullptr) { if (mHalSoundDose.size() > 0) { for (auto& halSoundDose : mHalSoundDose) { // using the HAL sound dose interface if (!mHalSoundDose->setOutputRs2UpperBound(rs2Value).isOk()) { if (!halSoundDose.second->setOutputRs2UpperBound(rs2Value).isOk()) { ALOGE("%s: Cannot set RS2 value for momentary exposure %f", __func__, rs2Value); return; continue; } } mRs2UpperBound = rs2Value; return; } Loading Loading @@ -200,14 +218,16 @@ void SoundDoseManager::clearMapDeviceIdEntries(audio_port_handle_t deviceId) { ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWarning( float in_currentDbA, const AudioDevice& in_audioDevice) { auto soundDoseManager = mSoundDoseManager.promote(); sp<SoundDoseManager> soundDoseManager; { const std::lock_guard _l(mCbLock); soundDoseManager = mSoundDoseManager.promote(); if (soundDoseManager == nullptr) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } } std::shared_ptr<ISoundDose> halSoundDose; soundDoseManager->getHalSoundDose(&halSoundDose); if(halSoundDose == nullptr) { if (!soundDoseManager->useHalSoundDose()) { ALOGW("%s: HAL sound dose interface deactivated. Ignoring", __func__); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } Loading @@ -227,14 +247,16 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWa ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onNewMelValues( const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord, const AudioDevice& in_audioDevice) { auto soundDoseManager = mSoundDoseManager.promote(); sp<SoundDoseManager> soundDoseManager; { const std::lock_guard _l(mCbLock); soundDoseManager = mSoundDoseManager.promote(); if (soundDoseManager == nullptr) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } } std::shared_ptr<ISoundDose> halSoundDose; soundDoseManager->getHalSoundDose(&halSoundDose); if(halSoundDose == nullptr) { if (!soundDoseManager->useHalSoundDose()) { ALOGW("%s: HAL sound dose interface deactivated. Ignoring", __func__); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } Loading Loading @@ -508,7 +530,7 @@ bool SoundDoseManager::shouldComputeCsdForDeviceWithAddress(const audio_devices_ void SoundDoseManager::setUseFrameworkMel(bool useFrameworkMel) { // invalidate any HAL sound dose interface used setHalSoundDoseInterface(nullptr); resetHalSoundDoseInterfaces(); std::lock_guard _l(mLock); mUseFrameworkMel = useFrameworkMel; Loading @@ -534,17 +556,12 @@ bool SoundDoseManager::isSoundDoseHalSupported() const { return false; } std::shared_ptr<ISoundDose> halSoundDose; getHalSoundDose(&halSoundDose); if (mHalSoundDose == nullptr) { return false; } return true; return useHalSoundDose(); } void SoundDoseManager::getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const { std::lock_guard _l(mLock); *halSoundDose = mHalSoundDose; bool SoundDoseManager::useHalSoundDose() const { const std::lock_guard _l(mLock); return mHalSoundDose.size() > 0; } void SoundDoseManager::resetSoundDose() { Loading services/audioflinger/sounddose/SoundDoseManager.h +13 −6 Original line number Diff line number Diff line Loading @@ -94,12 +94,15 @@ public: sp<media::ISoundDose> getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback); /** * Sets the HAL sound dose interface to use for the MEL computation. Use nullptr * for using the internal MEL computation. * Sets the HAL sound dose interface for a specific module to use for the MEL computation. * * @return true if setting the HAL sound dose value was successful, false otherwise. */ bool setHalSoundDoseInterface(const std::shared_ptr<ISoundDose>& halSoundDose); bool setHalSoundDoseInterface(const std::string &module, const std::shared_ptr<ISoundDose> &halSoundDose); /** Reset all the stored HAL sound dose interface. */ void resetHalSoundDoseInterfaces(); /** Returns the cached audio port id from the active devices. */ audio_port_handle_t getIdForAudioDevice( Loading Loading @@ -193,6 +196,7 @@ private: const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override; wp<SoundDoseManager> mSoundDoseManager; std::mutex mCbLock; }; void resetSoundDose(); Loading @@ -206,8 +210,11 @@ private: void setUseFrameworkMel(bool useFrameworkMel); void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices); bool isSoundDoseHalSupported() const; /** Returns the HAL sound dose interface or null if internal MEL computation is used. */ void getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const; /** * Returns true if there is one active HAL sound dose interface or null if internal MEL * computation is used. **/ bool useHalSoundDose() const; mutable std::mutex mLock; Loading Loading @@ -241,7 +248,7 @@ private: sp<SoundDose> mSoundDose GUARDED_BY(mLock); std::shared_ptr<ISoundDose> mHalSoundDose GUARDED_BY(mLock); std::unordered_map<std::string, std::shared_ptr<ISoundDose>> mHalSoundDose GUARDED_BY(mLock); std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock); bool mUseFrameworkMel GUARDED_BY(mLock) = false; Loading services/audioflinger/sounddose/tests/sounddosemanager_tests.cpp +25 −7 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ public: MOCK_METHOD(void, stopMelComputationForDeviceId, (audio_port_handle_t), (override)); }; constexpr char kPrimaryModule[] = "primary"; constexpr char kSecondaryModule[] = "secondary"; class SoundDoseManagerTest : public ::testing::Test { protected: Loading @@ -52,17 +54,24 @@ protected: mMelReporterCallback = sp<MelReporterCallback>::make(); mSoundDoseManager = sp<SoundDoseManager>::make(mMelReporterCallback); mHalSoundDose = ndk::SharedRefBase::make<HalSoundDoseMock>(); mSecondaryHalSoundDose = ndk::SharedRefBase::make<HalSoundDoseMock>(); ON_CALL(*mHalSoundDose.get(), setOutputRs2UpperBound) .WillByDefault([] (float rs2) { EXPECT_EQ(rs2, ISoundDose::DEFAULT_MAX_RS2); return ndk::ScopedAStatus::ok(); }); ON_CALL(*mSecondaryHalSoundDose.get(), setOutputRs2UpperBound) .WillByDefault([] (float rs2) { EXPECT_EQ(rs2, ISoundDose::DEFAULT_MAX_RS2); return ndk::ScopedAStatus::ok(); }); } sp<MelReporterCallback> mMelReporterCallback; sp<SoundDoseManager> mSoundDoseManager; std::shared_ptr<HalSoundDoseMock> mHalSoundDose; std::shared_ptr<HalSoundDoseMock> mSecondaryHalSoundDose; }; TEST_F(SoundDoseManagerTest, GetProcessorForExistingStream) { Loading Loading @@ -110,7 +119,7 @@ TEST_F(SoundDoseManagerTest, NewMelValuesCacheNewRecord) { } TEST_F(SoundDoseManagerTest, InvalidHalInterfaceIsNotSet) { EXPECT_FALSE(mSoundDoseManager->setHalSoundDoseInterface(nullptr)); EXPECT_FALSE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, nullptr)); } TEST_F(SoundDoseManagerTest, SetHalSoundDoseDisablesNewMelProcessorCallbacks) { Loading @@ -122,7 +131,7 @@ TEST_F(SoundDoseManagerTest, SetHalSoundDoseDisablesNewMelProcessorCallbacks) { return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_EQ(nullptr, mSoundDoseManager->getOrCreateProcessorForDevice(/*deviceId=*/2, /*streamHandle=*/1, Loading @@ -139,8 +148,17 @@ TEST_F(SoundDoseManagerTest, SetHalSoundDoseRegistersHalCallbacks) { EXPECT_NE(nullptr, callback); return ndk::ScopedAStatus::ok(); }); EXPECT_CALL(*mSecondaryHalSoundDose.get(), setOutputRs2UpperBound).Times(1); EXPECT_CALL(*mSecondaryHalSoundDose.get(), registerSoundDoseCallback) .Times(1) .WillOnce([&] (const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& callback) { EXPECT_NE(nullptr, callback); return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kSecondaryModule, mSecondaryHalSoundDose)); } TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalWithNoAddressIllegalArgument) { Loading @@ -154,7 +172,7 @@ TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalWithNoAddressIllegalArgumen return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_NE(nullptr, halCallback); AudioDevice audioDevice = {}; Loading @@ -175,9 +193,9 @@ TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalAfterInternalSelectedReturn return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_NE(nullptr, halCallback); EXPECT_FALSE(mSoundDoseManager->setHalSoundDoseInterface(nullptr)); mSoundDoseManager->resetHalSoundDoseInterfaces(); AudioDevice audioDevice = {}; audioDevice.address.set<AudioDeviceAddress::id>("test"); Loading @@ -197,7 +215,7 @@ TEST_F(SoundDoseManagerTest, OnNewMelValuesFromHalWithNoAddressIllegalArgument) return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_NE(nullptr, halCallback); AudioDevice audioDevice = {}; Loading Loading
services/audioflinger/MelReporter.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -38,24 +38,21 @@ bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::strin ndk::SpAIBinder soundDoseBinder; if (device->getSoundDoseInterface(module, &soundDoseBinder) != OK) { ALOGW("%s: HAL cannot provide sound dose interface for module %s, use internal MEL", ALOGW("%s: HAL cannot provide sound dose interface for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } if (soundDoseBinder == nullptr) { ALOGW("%s: HAL doesn't implement a sound dose interface for module %s, use internal MEL", ALOGW("%s: HAL doesn't implement a sound dose interface for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } std::shared_ptr<ISoundDose> soundDoseInterface = ISoundDose::fromBinder(soundDoseBinder); if (!mSoundDoseManager->setHalSoundDoseInterface(soundDoseInterface)) { if (!mSoundDoseManager->setHalSoundDoseInterface(module, soundDoseInterface)) { ALOGW("%s: cannot activate HAL MEL reporting for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } Loading @@ -73,7 +70,8 @@ void AudioFlinger::MelReporter::activateInternalSoundDoseComputation() { mUseHalSoundDoseInterface = false; } mSoundDoseManager->setHalSoundDoseInterface(nullptr); // reset the HAL interfaces and use internal MELs mSoundDoseManager->resetHalSoundDoseInterfaces(); } void AudioFlinger::MelReporter::onFirstRef() { Loading Loading @@ -251,6 +249,9 @@ sp<media::ISoundDose> AudioFlinger::MelReporter::getSoundDoseInterface( void AudioFlinger::MelReporter::stopInternalMelComputation() { ALOGV("%s", __func__); std::lock_guard _l(mLock); if (mUseHalSoundDoseInterface) { return; } mActiveMelPatches.clear(); mUseHalSoundDoseInterface = true; } Loading
services/audioflinger/sounddose/SoundDoseManager.cpp +50 −33 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ sp<audio_utils::MelProcessor> SoundDoseManager::getOrCreateProcessorForDevice( size_t channelCount, audio_format_t format) { std::lock_guard _l(mLock); if (mHalSoundDose != nullptr && mEnabledCsd) { if (mHalSoundDose.size() > 0 && mEnabledCsd) { ALOGD("%s: using HAL MEL computation, no MelProcessor needed.", __func__); return nullptr; } Loading Loading @@ -83,19 +83,27 @@ sp<audio_utils::MelProcessor> SoundDoseManager::getOrCreateProcessorForDevice( return melProcessor; } bool SoundDoseManager::setHalSoundDoseInterface(const std::shared_ptr<ISoundDose>& halSoundDose) { bool SoundDoseManager::setHalSoundDoseInterface(const std::string &module, const std::shared_ptr<ISoundDose> &halSoundDose) { ALOGV("%s", __func__); if (halSoundDose == nullptr) { ALOGI("%s: passed ISoundDose object is null", __func__); return false; } std::shared_ptr<HalSoundDoseCallback> halSoundDoseCallback; { std::lock_guard _l(mLock); mHalSoundDose = halSoundDose; if (halSoundDose == nullptr) { ALOGI("%s: passed ISoundDose object is null, switching to internal CSD", __func__); if (mHalSoundDose.find(module) != mHalSoundDose.end()) { ALOGW("%s: Module %s already has a sound dose HAL assigned, skipping", __func__, module.c_str()); return false; } mHalSoundDose[module] = halSoundDose; if (!mHalSoundDose->setOutputRs2UpperBound(mRs2UpperBound).isOk()) { if (!halSoundDose->setOutputRs2UpperBound(mRs2UpperBound).isOk()) { ALOGW("%s: Cannot set RS2 value for momentary exposure %f", __func__, mRs2UpperBound); Loading @@ -119,16 +127,26 @@ bool SoundDoseManager::setHalSoundDoseInterface(const std::shared_ptr<ISoundDose return true; } void SoundDoseManager::resetHalSoundDoseInterfaces() { ALOGV("%s", __func__); const std::lock_guard _l(mLock); mHalSoundDose.clear(); } void SoundDoseManager::setOutputRs2UpperBound(float rs2Value) { ALOGV("%s", __func__); std::lock_guard _l(mLock); if (mHalSoundDose != nullptr) { if (mHalSoundDose.size() > 0) { for (auto& halSoundDose : mHalSoundDose) { // using the HAL sound dose interface if (!mHalSoundDose->setOutputRs2UpperBound(rs2Value).isOk()) { if (!halSoundDose.second->setOutputRs2UpperBound(rs2Value).isOk()) { ALOGE("%s: Cannot set RS2 value for momentary exposure %f", __func__, rs2Value); return; continue; } } mRs2UpperBound = rs2Value; return; } Loading Loading @@ -200,14 +218,16 @@ void SoundDoseManager::clearMapDeviceIdEntries(audio_port_handle_t deviceId) { ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWarning( float in_currentDbA, const AudioDevice& in_audioDevice) { auto soundDoseManager = mSoundDoseManager.promote(); sp<SoundDoseManager> soundDoseManager; { const std::lock_guard _l(mCbLock); soundDoseManager = mSoundDoseManager.promote(); if (soundDoseManager == nullptr) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } } std::shared_ptr<ISoundDose> halSoundDose; soundDoseManager->getHalSoundDose(&halSoundDose); if(halSoundDose == nullptr) { if (!soundDoseManager->useHalSoundDose()) { ALOGW("%s: HAL sound dose interface deactivated. Ignoring", __func__); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } Loading @@ -227,14 +247,16 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWa ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onNewMelValues( const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord, const AudioDevice& in_audioDevice) { auto soundDoseManager = mSoundDoseManager.promote(); sp<SoundDoseManager> soundDoseManager; { const std::lock_guard _l(mCbLock); soundDoseManager = mSoundDoseManager.promote(); if (soundDoseManager == nullptr) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } } std::shared_ptr<ISoundDose> halSoundDose; soundDoseManager->getHalSoundDose(&halSoundDose); if(halSoundDose == nullptr) { if (!soundDoseManager->useHalSoundDose()) { ALOGW("%s: HAL sound dose interface deactivated. Ignoring", __func__); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } Loading Loading @@ -508,7 +530,7 @@ bool SoundDoseManager::shouldComputeCsdForDeviceWithAddress(const audio_devices_ void SoundDoseManager::setUseFrameworkMel(bool useFrameworkMel) { // invalidate any HAL sound dose interface used setHalSoundDoseInterface(nullptr); resetHalSoundDoseInterfaces(); std::lock_guard _l(mLock); mUseFrameworkMel = useFrameworkMel; Loading @@ -534,17 +556,12 @@ bool SoundDoseManager::isSoundDoseHalSupported() const { return false; } std::shared_ptr<ISoundDose> halSoundDose; getHalSoundDose(&halSoundDose); if (mHalSoundDose == nullptr) { return false; } return true; return useHalSoundDose(); } void SoundDoseManager::getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const { std::lock_guard _l(mLock); *halSoundDose = mHalSoundDose; bool SoundDoseManager::useHalSoundDose() const { const std::lock_guard _l(mLock); return mHalSoundDose.size() > 0; } void SoundDoseManager::resetSoundDose() { Loading
services/audioflinger/sounddose/SoundDoseManager.h +13 −6 Original line number Diff line number Diff line Loading @@ -94,12 +94,15 @@ public: sp<media::ISoundDose> getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback); /** * Sets the HAL sound dose interface to use for the MEL computation. Use nullptr * for using the internal MEL computation. * Sets the HAL sound dose interface for a specific module to use for the MEL computation. * * @return true if setting the HAL sound dose value was successful, false otherwise. */ bool setHalSoundDoseInterface(const std::shared_ptr<ISoundDose>& halSoundDose); bool setHalSoundDoseInterface(const std::string &module, const std::shared_ptr<ISoundDose> &halSoundDose); /** Reset all the stored HAL sound dose interface. */ void resetHalSoundDoseInterfaces(); /** Returns the cached audio port id from the active devices. */ audio_port_handle_t getIdForAudioDevice( Loading Loading @@ -193,6 +196,7 @@ private: const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override; wp<SoundDoseManager> mSoundDoseManager; std::mutex mCbLock; }; void resetSoundDose(); Loading @@ -206,8 +210,11 @@ private: void setUseFrameworkMel(bool useFrameworkMel); void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices); bool isSoundDoseHalSupported() const; /** Returns the HAL sound dose interface or null if internal MEL computation is used. */ void getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const; /** * Returns true if there is one active HAL sound dose interface or null if internal MEL * computation is used. **/ bool useHalSoundDose() const; mutable std::mutex mLock; Loading Loading @@ -241,7 +248,7 @@ private: sp<SoundDose> mSoundDose GUARDED_BY(mLock); std::shared_ptr<ISoundDose> mHalSoundDose GUARDED_BY(mLock); std::unordered_map<std::string, std::shared_ptr<ISoundDose>> mHalSoundDose GUARDED_BY(mLock); std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock); bool mUseFrameworkMel GUARDED_BY(mLock) = false; Loading
services/audioflinger/sounddose/tests/sounddosemanager_tests.cpp +25 −7 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ public: MOCK_METHOD(void, stopMelComputationForDeviceId, (audio_port_handle_t), (override)); }; constexpr char kPrimaryModule[] = "primary"; constexpr char kSecondaryModule[] = "secondary"; class SoundDoseManagerTest : public ::testing::Test { protected: Loading @@ -52,17 +54,24 @@ protected: mMelReporterCallback = sp<MelReporterCallback>::make(); mSoundDoseManager = sp<SoundDoseManager>::make(mMelReporterCallback); mHalSoundDose = ndk::SharedRefBase::make<HalSoundDoseMock>(); mSecondaryHalSoundDose = ndk::SharedRefBase::make<HalSoundDoseMock>(); ON_CALL(*mHalSoundDose.get(), setOutputRs2UpperBound) .WillByDefault([] (float rs2) { EXPECT_EQ(rs2, ISoundDose::DEFAULT_MAX_RS2); return ndk::ScopedAStatus::ok(); }); ON_CALL(*mSecondaryHalSoundDose.get(), setOutputRs2UpperBound) .WillByDefault([] (float rs2) { EXPECT_EQ(rs2, ISoundDose::DEFAULT_MAX_RS2); return ndk::ScopedAStatus::ok(); }); } sp<MelReporterCallback> mMelReporterCallback; sp<SoundDoseManager> mSoundDoseManager; std::shared_ptr<HalSoundDoseMock> mHalSoundDose; std::shared_ptr<HalSoundDoseMock> mSecondaryHalSoundDose; }; TEST_F(SoundDoseManagerTest, GetProcessorForExistingStream) { Loading Loading @@ -110,7 +119,7 @@ TEST_F(SoundDoseManagerTest, NewMelValuesCacheNewRecord) { } TEST_F(SoundDoseManagerTest, InvalidHalInterfaceIsNotSet) { EXPECT_FALSE(mSoundDoseManager->setHalSoundDoseInterface(nullptr)); EXPECT_FALSE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, nullptr)); } TEST_F(SoundDoseManagerTest, SetHalSoundDoseDisablesNewMelProcessorCallbacks) { Loading @@ -122,7 +131,7 @@ TEST_F(SoundDoseManagerTest, SetHalSoundDoseDisablesNewMelProcessorCallbacks) { return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_EQ(nullptr, mSoundDoseManager->getOrCreateProcessorForDevice(/*deviceId=*/2, /*streamHandle=*/1, Loading @@ -139,8 +148,17 @@ TEST_F(SoundDoseManagerTest, SetHalSoundDoseRegistersHalCallbacks) { EXPECT_NE(nullptr, callback); return ndk::ScopedAStatus::ok(); }); EXPECT_CALL(*mSecondaryHalSoundDose.get(), setOutputRs2UpperBound).Times(1); EXPECT_CALL(*mSecondaryHalSoundDose.get(), registerSoundDoseCallback) .Times(1) .WillOnce([&] (const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& callback) { EXPECT_NE(nullptr, callback); return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kSecondaryModule, mSecondaryHalSoundDose)); } TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalWithNoAddressIllegalArgument) { Loading @@ -154,7 +172,7 @@ TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalWithNoAddressIllegalArgumen return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_NE(nullptr, halCallback); AudioDevice audioDevice = {}; Loading @@ -175,9 +193,9 @@ TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalAfterInternalSelectedReturn return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_NE(nullptr, halCallback); EXPECT_FALSE(mSoundDoseManager->setHalSoundDoseInterface(nullptr)); mSoundDoseManager->resetHalSoundDoseInterfaces(); AudioDevice audioDevice = {}; audioDevice.address.set<AudioDeviceAddress::id>("test"); Loading @@ -197,7 +215,7 @@ TEST_F(SoundDoseManagerTest, OnNewMelValuesFromHalWithNoAddressIllegalArgument) return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(kPrimaryModule, mHalSoundDose)); EXPECT_NE(nullptr, halCallback); AudioDevice audioDevice = {}; Loading