CSD: Add logic for forcing the use of internal MEL
This flag should be used for testing purposes only. Sometimes it might
make sense to disable the HAL sound dose interface to test the internal
MEL computation and sound dose logic end-2-end.
Test: sounddosemanager_tests UT
Bug: 248565894
Change-Id: Ieaf506511c0aee3b9a5a262831b950d9dcaf3535
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index 7902444..b185959 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -33,8 +33,14 @@
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;
}
@@ -42,14 +48,14 @@
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;
}
@@ -61,10 +67,16 @@
}
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;
+ }
- std::lock_guard _l(mLock);
- mUseHalSoundDoseInterface = false;
+ mSoundDoseManager->setHalSoundDoseInterface(nullptr);
for (const auto& activePatches : mActiveMelPatches) {
for (const auto& deviceId : activePatches.second.deviceHandles) {
@@ -88,7 +100,7 @@
}
bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) {
- if (mSoundDoseManager->computeCsdOnAllDevices()) {
+ if (mSoundDoseManager->forceComputeCsdOnAllDevices()) {
return true;
}
@@ -130,10 +142,10 @@
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);
diff --git a/services/audioflinger/sounddose/SoundDoseManager.cpp b/services/audioflinger/sounddose/SoundDoseManager.cpp
index ad19fb1..df6eb5b 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.cpp
+++ b/services/audioflinger/sounddose/SoundDoseManager.cpp
@@ -194,6 +194,13 @@
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",
@@ -213,6 +220,14 @@
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",
@@ -294,11 +309,14 @@
}
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;
}
@@ -308,11 +326,16 @@
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;
diff --git a/services/audioflinger/sounddose/SoundDoseManager.h b/services/audioflinger/sounddose/SoundDoseManager.h
index 199e8c9..b10874f 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.h
+++ b/services/audioflinger/sounddose/SoundDoseManager.h
@@ -104,11 +104,10 @@
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);
@@ -166,6 +165,8 @@
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;
@@ -185,8 +186,8 @@
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
diff --git a/services/audioflinger/sounddose/tests/sounddosemanager_tests.cpp b/services/audioflinger/sounddose/tests/sounddosemanager_tests.cpp
index 658efe1..ba2edcf 100644
--- a/services/audioflinger/sounddose/tests/sounddosemanager_tests.cpp
+++ b/services/audioflinger/sounddose/tests/sounddosemanager_tests.cpp
@@ -154,6 +154,28 @@
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;
@@ -207,5 +229,13 @@
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