Loading services/audioflinger/MelReporter.cpp +21 −9 Original line number Diff line number Diff line Loading @@ -33,8 +33,14 @@ namespace android { constexpr std::string_view kSoundDoseInterfaceModule = "/default"; bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::string& module) { if (mSoundDoseManager->forceUseFrameworkMel()) { ALOGD("%s: Forcing use of internal MEL computation.", __func__); activateInternalSoundDoseComputation(); return false; } if (mSoundDoseFactory == nullptr) { ALOGW("%s sound dose HAL reporting not available", __func__); ALOGW("%s: sound dose HAL reporting not available", __func__); activateInternalSoundDoseComputation(); return false; } Loading @@ -42,14 +48,14 @@ bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::strin std::shared_ptr<ISoundDose> soundDoseInterface; auto result = mSoundDoseFactory->getSoundDose(module, &soundDoseInterface); if (!result.isOk()) { ALOGW("%s HAL cannot provide sound dose interface for module %s", ALOGW("%s: HAL cannot provide sound dose interface for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } if (!mSoundDoseManager->setHalSoundDoseInterface(soundDoseInterface)) { ALOGW("%s cannot activate HAL MEL reporting for module %s", __func__, module.c_str()); ALOGW("%s: cannot activate HAL MEL reporting for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } Loading @@ -61,10 +67,16 @@ bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::strin } void AudioFlinger::MelReporter::activateInternalSoundDoseComputation() { mSoundDoseManager->setHalSoundDoseInterface(nullptr); { std::lock_guard _l(mLock); if (!mUseHalSoundDoseInterface) { // no need to start internal MEL on active patches return; } mUseHalSoundDoseInterface = false; } mSoundDoseManager->setHalSoundDoseInterface(nullptr); for (const auto& activePatches : mActiveMelPatches) { for (const auto& deviceId : activePatches.second.deviceHandles) { Loading @@ -88,7 +100,7 @@ void AudioFlinger::MelReporter::onFirstRef() { } bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) { if (mSoundDoseManager->computeCsdOnAllDevices()) { if (mSoundDoseManager->forceComputeCsdOnAllDevices()) { return true; } Loading Loading @@ -130,10 +142,10 @@ void AudioFlinger::MelReporter::onCreateAudioPatch(audio_patch_handle_t handle, patch.mAudioPatch.sinks[i].ext.device.address}; mSoundDoseManager->mapAddressToDeviceId(adt, deviceId); bool useHalSoundDoseInterface; bool useHalSoundDoseInterface = !mSoundDoseManager->forceUseFrameworkMel(); { std::lock_guard _l(mLock); useHalSoundDoseInterface = mUseHalSoundDoseInterface; useHalSoundDoseInterface &= mUseHalSoundDoseInterface; } if (!useHalSoundDoseInterface) { startMelComputationForNewPatch(streamHandle, deviceId); Loading services/audioflinger/sounddose/SoundDoseManager.cpp +25 −2 Original line number Diff line number Diff line Loading @@ -194,6 +194,13 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWa return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } std::shared_ptr<ISoundDose> halSoundDose; soundDoseManager->getHalSoundDose(&halSoundDose); if(halSoundDose == nullptr) { ALOGW("%s: HAL sound dose interface deactivated. Ignoring", __func__); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } auto id = soundDoseManager->getIdForAudioDevice(in_audioDevice); if (id == AUDIO_PORT_HANDLE_NONE) { ALOGW("%s: no mapped id for audio device with type %d and address %s", Loading @@ -213,6 +220,14 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onNewMelValues( if (soundDoseManager == nullptr) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } std::shared_ptr<ISoundDose> halSoundDose; soundDoseManager->getHalSoundDose(&halSoundDose); if(halSoundDose == nullptr) { ALOGW("%s: HAL sound dose interface deactivated. Ignoring", __func__); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } auto id = soundDoseManager->getIdForAudioDevice(in_audioDevice); if (id == AUDIO_PORT_HANDLE_NONE) { ALOGW("%s: no mapped id for audio device with type %d and address %s", Loading Loading @@ -294,11 +309,14 @@ binder::Status SoundDoseManager::SoundDose::forceComputeCsdOnAllDevices( } void SoundDoseManager::setUseFrameworkMel(bool useFrameworkMel) { // invalidate any HAL sound dose interface used setHalSoundDoseInterface(nullptr); std::lock_guard _l(mLock); mUseFrameworkMel = useFrameworkMel; } bool SoundDoseManager::useFrameworkMel() const { bool SoundDoseManager::forceUseFrameworkMel() const { std::lock_guard _l(mLock); return mUseFrameworkMel; } Loading @@ -308,11 +326,16 @@ void SoundDoseManager::setComputeCsdOnAllDevices(bool computeCsdOnAllDevices) { mComputeCsdOnAllDevices = computeCsdOnAllDevices; } bool SoundDoseManager::computeCsdOnAllDevices() const { bool SoundDoseManager::forceComputeCsdOnAllDevices() const { std::lock_guard _l(mLock); return mComputeCsdOnAllDevices; } void SoundDoseManager::getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const { std::lock_guard _l(mLock); *halSoundDose = mHalSoundDose; } void SoundDoseManager::resetSoundDose() { std::lock_guard lock(mLock); mSoundDose = nullptr; Loading services/audioflinger/sounddose/SoundDoseManager.h +7 −6 Original line number Diff line number Diff line Loading @@ -104,11 +104,10 @@ public: std::string dump() const; // used for testing // used for testing only size_t getCachedMelRecordsSize() const; bool useFrameworkMel() const; bool computeCsdOnAllDevices() const; bool forceUseFrameworkMel() const; bool forceComputeCsdOnAllDevices() const; /** Method for converting from audio_utils::CsdRecord to media::SoundDoseRecord. */ static media::SoundDoseRecord csdRecordToSoundDoseRecord(const audio_utils::CsdRecord& legacy); Loading Loading @@ -166,6 +165,8 @@ private: void setUseFrameworkMel(bool useFrameworkMel); void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices); /** Returns the HAL sound dose interface or null if internal MEL computation is used. */ void getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const; mutable std::mutex mLock; Loading @@ -185,8 +186,8 @@ private: std::shared_ptr<ISoundDose> mHalSoundDose GUARDED_BY(mLock); std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock); bool mUseFrameworkMel GUARDED_BY(mLock); bool mComputeCsdOnAllDevices GUARDED_BY(mLock); bool mUseFrameworkMel GUARDED_BY(mLock) = false; bool mComputeCsdOnAllDevices GUARDED_BY(mLock) = false; }; } // namespace android services/audioflinger/sounddose/tests/sounddosemanager_tests.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,28 @@ TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalWithNoAddressIllegalArgumen EXPECT_FALSE(status.isOk()); } TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalAfterInternalSelectedReturnsException) { std::shared_ptr<ISoundDose::IHalSoundDoseCallback> halCallback; EXPECT_CALL(*mHalSoundDose.get(), setOutputRs2).Times(1); EXPECT_CALL(*mHalSoundDose.get(), registerSoundDoseCallback) .Times(1) .WillOnce([&] (const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& callback) { halCallback = callback; return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_NE(nullptr, halCallback); EXPECT_FALSE(mSoundDoseManager->setHalSoundDoseInterface(nullptr)); AudioDevice audioDevice = {}; audioDevice.address.set<AudioDeviceAddress::id>("test"); auto status = halCallback->onMomentaryExposureWarning( /*in_currentDbA=*/101.f, audioDevice); EXPECT_FALSE(status.isOk()); } TEST_F(SoundDoseManagerTest, OnNewMelValuesFromHalWithNoAddressIllegalArgument) { std::shared_ptr<ISoundDose::IHalSoundDoseCallback> halCallback; Loading Loading @@ -207,5 +229,13 @@ TEST_F(SoundDoseManagerTest, GetUnmappedIdReturnsHandleNone) { EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, mSoundDoseManager->getIdForAudioDevice(audioDevice)); } TEST_F(SoundDoseManagerTest, GetDefaultForceComputeCsdOnAllDevices) { EXPECT_FALSE(mSoundDoseManager->forceComputeCsdOnAllDevices()); } TEST_F(SoundDoseManagerTest, GetDefaultForceUseFrameworkMel) { EXPECT_FALSE(mSoundDoseManager->forceUseFrameworkMel()); } } // namespace } // namespace android Loading
services/audioflinger/MelReporter.cpp +21 −9 Original line number Diff line number Diff line Loading @@ -33,8 +33,14 @@ namespace android { constexpr std::string_view kSoundDoseInterfaceModule = "/default"; bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::string& module) { if (mSoundDoseManager->forceUseFrameworkMel()) { ALOGD("%s: Forcing use of internal MEL computation.", __func__); activateInternalSoundDoseComputation(); return false; } if (mSoundDoseFactory == nullptr) { ALOGW("%s sound dose HAL reporting not available", __func__); ALOGW("%s: sound dose HAL reporting not available", __func__); activateInternalSoundDoseComputation(); return false; } Loading @@ -42,14 +48,14 @@ bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::strin std::shared_ptr<ISoundDose> soundDoseInterface; auto result = mSoundDoseFactory->getSoundDose(module, &soundDoseInterface); if (!result.isOk()) { ALOGW("%s HAL cannot provide sound dose interface for module %s", ALOGW("%s: HAL cannot provide sound dose interface for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } if (!mSoundDoseManager->setHalSoundDoseInterface(soundDoseInterface)) { ALOGW("%s cannot activate HAL MEL reporting for module %s", __func__, module.c_str()); ALOGW("%s: cannot activate HAL MEL reporting for module %s", __func__, module.c_str()); activateInternalSoundDoseComputation(); return false; } Loading @@ -61,10 +67,16 @@ bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::strin } void AudioFlinger::MelReporter::activateInternalSoundDoseComputation() { mSoundDoseManager->setHalSoundDoseInterface(nullptr); { std::lock_guard _l(mLock); if (!mUseHalSoundDoseInterface) { // no need to start internal MEL on active patches return; } mUseHalSoundDoseInterface = false; } mSoundDoseManager->setHalSoundDoseInterface(nullptr); for (const auto& activePatches : mActiveMelPatches) { for (const auto& deviceId : activePatches.second.deviceHandles) { Loading @@ -88,7 +100,7 @@ void AudioFlinger::MelReporter::onFirstRef() { } bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) { if (mSoundDoseManager->computeCsdOnAllDevices()) { if (mSoundDoseManager->forceComputeCsdOnAllDevices()) { return true; } Loading Loading @@ -130,10 +142,10 @@ void AudioFlinger::MelReporter::onCreateAudioPatch(audio_patch_handle_t handle, patch.mAudioPatch.sinks[i].ext.device.address}; mSoundDoseManager->mapAddressToDeviceId(adt, deviceId); bool useHalSoundDoseInterface; bool useHalSoundDoseInterface = !mSoundDoseManager->forceUseFrameworkMel(); { std::lock_guard _l(mLock); useHalSoundDoseInterface = mUseHalSoundDoseInterface; useHalSoundDoseInterface &= mUseHalSoundDoseInterface; } if (!useHalSoundDoseInterface) { startMelComputationForNewPatch(streamHandle, deviceId); Loading
services/audioflinger/sounddose/SoundDoseManager.cpp +25 −2 Original line number Diff line number Diff line Loading @@ -194,6 +194,13 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWa return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } std::shared_ptr<ISoundDose> halSoundDose; soundDoseManager->getHalSoundDose(&halSoundDose); if(halSoundDose == nullptr) { ALOGW("%s: HAL sound dose interface deactivated. Ignoring", __func__); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } auto id = soundDoseManager->getIdForAudioDevice(in_audioDevice); if (id == AUDIO_PORT_HANDLE_NONE) { ALOGW("%s: no mapped id for audio device with type %d and address %s", Loading @@ -213,6 +220,14 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onNewMelValues( if (soundDoseManager == nullptr) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } std::shared_ptr<ISoundDose> halSoundDose; soundDoseManager->getHalSoundDose(&halSoundDose); if(halSoundDose == nullptr) { ALOGW("%s: HAL sound dose interface deactivated. Ignoring", __func__); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } auto id = soundDoseManager->getIdForAudioDevice(in_audioDevice); if (id == AUDIO_PORT_HANDLE_NONE) { ALOGW("%s: no mapped id for audio device with type %d and address %s", Loading Loading @@ -294,11 +309,14 @@ binder::Status SoundDoseManager::SoundDose::forceComputeCsdOnAllDevices( } void SoundDoseManager::setUseFrameworkMel(bool useFrameworkMel) { // invalidate any HAL sound dose interface used setHalSoundDoseInterface(nullptr); std::lock_guard _l(mLock); mUseFrameworkMel = useFrameworkMel; } bool SoundDoseManager::useFrameworkMel() const { bool SoundDoseManager::forceUseFrameworkMel() const { std::lock_guard _l(mLock); return mUseFrameworkMel; } Loading @@ -308,11 +326,16 @@ void SoundDoseManager::setComputeCsdOnAllDevices(bool computeCsdOnAllDevices) { mComputeCsdOnAllDevices = computeCsdOnAllDevices; } bool SoundDoseManager::computeCsdOnAllDevices() const { bool SoundDoseManager::forceComputeCsdOnAllDevices() const { std::lock_guard _l(mLock); return mComputeCsdOnAllDevices; } void SoundDoseManager::getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const { std::lock_guard _l(mLock); *halSoundDose = mHalSoundDose; } void SoundDoseManager::resetSoundDose() { std::lock_guard lock(mLock); mSoundDose = nullptr; Loading
services/audioflinger/sounddose/SoundDoseManager.h +7 −6 Original line number Diff line number Diff line Loading @@ -104,11 +104,10 @@ public: std::string dump() const; // used for testing // used for testing only size_t getCachedMelRecordsSize() const; bool useFrameworkMel() const; bool computeCsdOnAllDevices() const; bool forceUseFrameworkMel() const; bool forceComputeCsdOnAllDevices() const; /** Method for converting from audio_utils::CsdRecord to media::SoundDoseRecord. */ static media::SoundDoseRecord csdRecordToSoundDoseRecord(const audio_utils::CsdRecord& legacy); Loading Loading @@ -166,6 +165,8 @@ private: void setUseFrameworkMel(bool useFrameworkMel); void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices); /** Returns the HAL sound dose interface or null if internal MEL computation is used. */ void getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const; mutable std::mutex mLock; Loading @@ -185,8 +186,8 @@ private: std::shared_ptr<ISoundDose> mHalSoundDose GUARDED_BY(mLock); std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock); bool mUseFrameworkMel GUARDED_BY(mLock); bool mComputeCsdOnAllDevices GUARDED_BY(mLock); bool mUseFrameworkMel GUARDED_BY(mLock) = false; bool mComputeCsdOnAllDevices GUARDED_BY(mLock) = false; }; } // namespace android
services/audioflinger/sounddose/tests/sounddosemanager_tests.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,28 @@ TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalWithNoAddressIllegalArgumen EXPECT_FALSE(status.isOk()); } TEST_F(SoundDoseManagerTest, MomentaryExposureFromHalAfterInternalSelectedReturnsException) { std::shared_ptr<ISoundDose::IHalSoundDoseCallback> halCallback; EXPECT_CALL(*mHalSoundDose.get(), setOutputRs2).Times(1); EXPECT_CALL(*mHalSoundDose.get(), registerSoundDoseCallback) .Times(1) .WillOnce([&] (const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& callback) { halCallback = callback; return ndk::ScopedAStatus::ok(); }); EXPECT_TRUE(mSoundDoseManager->setHalSoundDoseInterface(mHalSoundDose)); EXPECT_NE(nullptr, halCallback); EXPECT_FALSE(mSoundDoseManager->setHalSoundDoseInterface(nullptr)); AudioDevice audioDevice = {}; audioDevice.address.set<AudioDeviceAddress::id>("test"); auto status = halCallback->onMomentaryExposureWarning( /*in_currentDbA=*/101.f, audioDevice); EXPECT_FALSE(status.isOk()); } TEST_F(SoundDoseManagerTest, OnNewMelValuesFromHalWithNoAddressIllegalArgument) { std::shared_ptr<ISoundDose::IHalSoundDoseCallback> halCallback; Loading Loading @@ -207,5 +229,13 @@ TEST_F(SoundDoseManagerTest, GetUnmappedIdReturnsHandleNone) { EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, mSoundDoseManager->getIdForAudioDevice(audioDevice)); } TEST_F(SoundDoseManagerTest, GetDefaultForceComputeCsdOnAllDevices) { EXPECT_FALSE(mSoundDoseManager->forceComputeCsdOnAllDevices()); } TEST_F(SoundDoseManagerTest, GetDefaultForceUseFrameworkMel) { EXPECT_FALSE(mSoundDoseManager->forceUseFrameworkMel()); } } // namespace } // namespace android