Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d6d39d3 authored by Vlad Popa's avatar Vlad Popa
Browse files

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
parent 1d5f0d5c
Loading
Loading
Loading
Loading
+21 −9
Original line number Diff line number Diff line
@@ -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;
    }
@@ -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;
    }
@@ -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) {
@@ -88,7 +100,7 @@ void AudioFlinger::MelReporter::onFirstRef() {
}

bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) {
    if (mSoundDoseManager->computeCsdOnAllDevices()) {
    if (mSoundDoseManager->forceComputeCsdOnAllDevices()) {
        return true;
    }

@@ -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);
+25 −2
Original line number Diff line number Diff line
@@ -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",
@@ -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",
@@ -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;
}
@@ -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;
+7 −6
Original line number Diff line number Diff line
@@ -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);
@@ -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;

@@ -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
+30 −0
Original line number Diff line number Diff line
@@ -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;

@@ -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