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

Commit 1f9b5e66 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio flinger: fix initial mmap stream volume

The initial stream volume values received by a MMAP thread
while the mmap stream is being open by audio policy manager
were ignored because the stream type was not yet initialized (the stream
type is received from audio policy manager when getOutputForAttr
returns).

The fix consists in using the same volume/mute data structure array for
MmapPlaybackThread as for PlaybackThread in order to store all stream
volume and mute values but only use the one corresponding to the
configured mStreamType.

Bug: 284836454
Test: repro steps in bug
Change-Id: If4654c1d9ea7fd109a8ab2b9b2431db71b966243
parent 95916c5b
Loading
Loading
Loading
Loading
+20 −14
Original line number Diff line number Diff line
@@ -10571,14 +10571,24 @@ AudioFlinger::MmapPlaybackThread::MmapPlaybackThread(
        AudioHwDevice *hwDev,  AudioStreamOut *output, bool systemReady)
    : MmapThread(audioFlinger, id, hwDev, output->stream, systemReady, true /* isOut */),
      mStreamType(AUDIO_STREAM_MUSIC),
      mStreamVolume(1.0),
      mStreamMute(false),
      mOutput(output)
{
    snprintf(mThreadName, kThreadNameLength, "AudioMmapOut_%X", id);
    mChannelCount = audio_channel_count_from_out_mask(mChannelMask);
    mMasterVolume = audioFlinger->masterVolume_l();
    mMasterMute = audioFlinger->masterMute_l();

    for (int i = AUDIO_STREAM_MIN; i < AUDIO_STREAM_FOR_POLICY_CNT; ++i) {
        const audio_stream_type_t stream{static_cast<audio_stream_type_t>(i)};
        mStreamTypes[stream].volume = 0.0f;
        mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);
    }
    // Audio patch and call assistant volume are always max
    mStreamTypes[AUDIO_STREAM_PATCH].volume = 1.0f;
    mStreamTypes[AUDIO_STREAM_PATCH].mute = false;
    mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].volume = 1.0f;
    mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].mute = false;

    if (mAudioHwDev) {
        if (mAudioHwDev->canSetMasterVolume()) {
            mMasterVolume = 1.0;
@@ -10635,8 +10645,8 @@ void AudioFlinger::MmapPlaybackThread::setMasterMute(bool muted)
void AudioFlinger::MmapPlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
{
    Mutex::Autolock _l(mLock);
    mStreamTypes[stream].volume = value;
    if (stream == mStreamType) {
        mStreamVolume = value;
        broadcast_l();
    }
}
@@ -10644,17 +10654,14 @@ void AudioFlinger::MmapPlaybackThread::setStreamVolume(audio_stream_type_t strea
float AudioFlinger::MmapPlaybackThread::streamVolume(audio_stream_type_t stream) const
{
    Mutex::Autolock _l(mLock);
    if (stream == mStreamType) {
        return mStreamVolume;
    }
    return 0.0f;
    return mStreamTypes[stream].volume;
}

void AudioFlinger::MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
{
    Mutex::Autolock _l(mLock);
    mStreamTypes[stream].mute = muted;
    if (stream == mStreamType) {
        mStreamMute= muted;
        broadcast_l();
    }
}
@@ -10694,14 +10701,13 @@ NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l
{
    float volume;

    if (mMasterMute || mStreamMute) {
    if (mMasterMute || streamMuted_l()) {
        volume = 0;
    } else {
        volume = mMasterVolume * mStreamVolume;
        volume = mMasterVolume * streamVolume_l();
    }

    if (volume != mHalVolFloat) {

        // Convert volumes from float to 8.24
        uint32_t vol = (uint32_t)(volume * (1 << 24));

@@ -10735,8 +10741,8 @@ NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l
            track->setMetadataHasChanged();
            track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
                /*muteState=*/{mMasterMute,
                               mStreamVolume == 0.f,
                               mStreamMute,
                               streamVolume_l() == 0.f,
                               streamMuted_l(),
                               // TODO(b/241533526): adjust logic to include mute from AppOps
                               false /*muteFromPlaybackRestricted*/,
                               false /*muteFromClientVolume*/,
@@ -10849,7 +10855,7 @@ void AudioFlinger::MmapPlaybackThread::dumpInternals_l(int fd, const Vector<Stri
    MmapThread::dumpInternals_l(fd, args);

    dprintf(fd, "  Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n",
            mStreamType, mStreamVolume, mHalVolFloat, mStreamMute);
            mStreamType, streamVolume_l(), mHalVolFloat, streamMuted_l());
    dprintf(fd, "  Master volume: %f Master mute %d\n", mMasterVolume, mMasterMute);
}

+7 −2
Original line number Diff line number Diff line
@@ -2316,12 +2316,17 @@ public:

protected:
                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
                float       streamVolume_l() const {
                    return mStreamTypes[mStreamType].volume;
                }
                bool     streamMuted_l() const {
                    return mStreamTypes[mStreamType].mute;
                }

                stream_type_t               mStreamTypes[AUDIO_STREAM_CNT];
                audio_stream_type_t         mStreamType;
                float                       mMasterVolume;
                float                       mStreamVolume;
                bool                        mMasterMute;
                bool                        mStreamMute;
                AudioStreamOut*             mOutput;

                mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;