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

Commit d8f178d6 authored by John Grossman's avatar John Grossman
Browse files

Change audio flinger to user HAL master mute if available



(cherry picked from commit 91de9b56)

> Change audio flinger to user HAL master mute if available
>
> Hand merge from ics-aah
>
> > Change audio flinger to user HAL master mute if available: DO NOT MERGE
> >
> > Replicate the pattern used for HAL master volume support to make use
> > of master mute support if the HAL supports it.  This is part of the
> > change needed to address bug 6828363.  Because of the divergences
> > between ICS and master, this change will need to be merged by hand.
> >
> > Signed-off-by: default avatarJohn Grossman <johngro@google.com>
> > Change-Id: I6d83be524021d273d093bcb117b8f2fe57c23685
>
> Change-Id: I32280582905c969aaec2bb166ec5c61df82d737a
> Signed-off-by: default avatarJohn Grossman <johngro@google.com>

Change-Id: I5cd709187221d307fe25c5117ccaadca5f6b197b
Signed-off-by: default avatarJohn Grossman <johngro@google.com>
parent 3478eaa2
Loading
Loading
Loading
Loading
+86 −9
Original line number Diff line number Diff line
@@ -219,6 +219,8 @@ AudioFlinger::AudioFlinger()
      mMasterVolumeSW(1.0f),
      mMasterVolumeSupportLvl(MVS_NONE),
      mMasterMute(false),
      mMasterMuteSW(false),
      mMasterMuteSupportLvl(MMS_NONE),
      mNextUniqueId(1),
      mMode(AUDIO_MODE_INVALID),
      mBtNrecIsOff(false)
@@ -699,16 +701,40 @@ bool AudioFlinger::getMicMute() const

status_t AudioFlinger::setMasterMute(bool muted)
{
    status_t ret = initCheck();
    if (ret != NO_ERROR) {
        return ret;
    }

    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

    bool swmm = muted;

    // when hw supports master mute, don't mute in sw mixer
    if (MMS_NONE != mMasterMuteSupportLvl) {
        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
            AutoMutex lock(mHardwareLock);
            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();

            mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
            if (NULL != dev->set_master_mute) {
                dev->set_master_mute(dev, muted);
            }
            mHardwareStatus = AUDIO_HW_IDLE;
        }

        swmm = false;
    }

    Mutex::Autolock _l(mLock);
    // This is an optimization, so PlaybackThread doesn't have to look at the one from AudioFlinger
    mMasterMute   = muted;
    mMasterMuteSW = swmm;
    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
        mPlaybackThreads.valueAt(i)->setMasterMute(muted);
        mPlaybackThreads.valueAt(i)->setMasterMute(swmm);

    return NO_ERROR;
}
@@ -731,6 +757,12 @@ bool AudioFlinger::masterMute() const
    return masterMute_l();
}

bool AudioFlinger::masterMuteSW() const
{
    Mutex::Autolock _l(mLock);
    return masterMuteSW_l();
}

float AudioFlinger::masterVolume_l() const
{
    if (MVS_FULL == mMasterVolumeSupportLvl) {
@@ -750,6 +782,24 @@ float AudioFlinger::masterVolume_l() const
    return mMasterVolume;
}

bool AudioFlinger::masterMute_l() const
{
    if (MMS_FULL == mMasterMuteSupportLvl) {
        bool ret_val;
        AutoMutex lock(mHardwareLock);

        mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
        assert(NULL != mPrimaryHardwareDev);
        assert(NULL != mPrimaryHardwareDev->get_master_mute);

        mPrimaryHardwareDev->get_master_mute(mPrimaryHardwareDev, &ret_val);
        mHardwareStatus = AUDIO_HW_IDLE;
        return ret_val;
    }

     return mMasterMute;
}

status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
        audio_io_handle_t output)
{
@@ -1503,7 +1553,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
        mMixBuffer(NULL), mSuspended(0), mBytesWritten(0),
        // Assumes constructor is called by AudioFlinger with it's mLock held,
        // but it would be safer to explicitly pass initial masterMute as parameter
        mMasterMute(audioFlinger->masterMute_l()),
        mMasterMute(audioFlinger->masterMuteSW_l()),
        // mStreamTypes[] initialized in constructor body
        mOutput(output),
        // Assumes constructor is called by AudioFlinger with it's mLock held,
@@ -6863,10 +6913,13 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
            mHardwareStatus = AUDIO_HW_SET_MODE;
            outHwDev->set_mode(outHwDev, mMode);

            // Determine the level of master volume support the primary audio HAL has,
            // and set the initial master volume at the same time.
            // Determine the level of master volume/master mute support the primary
            // audio HAL has, and set the initial master volume/mute state at the same
            // time.
            float initialVolume = 1.0;
            bool initialMute = false;
            mMasterVolumeSupportLvl = MVS_NONE;
            mMasterMuteSupportLvl = MMS_NONE;

            mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
            if ((NULL != outHwDev->get_master_volume) &&
@@ -6882,20 +6935,44 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
                (NO_ERROR != outHwDev->set_master_volume(outHwDev, initialVolume))) {
                mMasterVolumeSupportLvl = MVS_NONE;
            }
            // now that we have a primary device, initialize master volume on other devices

            mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
            if ((NULL != outHwDev->get_master_mute) &&
                (NO_ERROR == outHwDev->get_master_mute(outHwDev, &initialMute))) {
                mMasterMuteSupportLvl = MMS_FULL;
            } else {
                mMasterMuteSupportLvl = MMS_SETONLY;
                initialMute = 0;
            }

            mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
            if ((NULL == outHwDev->set_master_mute) ||
                (NO_ERROR != outHwDev->set_master_mute(outHwDev, initialMute))) {
                mMasterMuteSupportLvl = MMS_NONE;
            }

            // now that we have a primary device, initialize master volume/mute
            // on other devices
            for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
                audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();

                if ((dev != mPrimaryHardwareDev) &&
                    (NULL != dev->set_master_volume)) {
                    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
                    dev->set_master_volume(dev, initialVolume);
                }

                if (NULL != dev->set_master_mute) {
                    mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
                    dev->set_master_mute(dev, initialMute);
                }
            }

            mHardwareStatus = AUDIO_HW_IDLE;
            mMasterVolumeSW = (MVS_NONE == mMasterVolumeSupportLvl)
                                    ? initialVolume
                                    : 1.0;
            mMasterVolumeSW = initialVolume;
            mMasterVolume   = initialVolume;
            mMasterMuteSW   = initialMute;
            mMasterMute     = initialMute;
        }
        return id;
    }
+29 −1
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ public:
    virtual     float       masterVolume() const;
    virtual     float       masterVolumeSW() const;
    virtual     bool        masterMute() const;
    virtual     bool        masterMuteSW() const;

    virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value,
                                            audio_io_handle_t output);
@@ -1911,6 +1912,27 @@ mutable Mutex mLock; // mutex for process, commands and handl
        MVS_FULL,
    };

    enum master_mute_support {
        // MMS_NONE:
        // Audio HAL has no support for master mute, either setting or getting.
        // All master mute control must be implemented in SW by the
        // AudioFlinger mixing core.
        MMS_NONE,

        // MMS_SETONLY:
        // Audio HAL has support for setting master mute, but not for getting
        // master mute.  AudioFlinger needs to keep track of the last set
        // master mute in addition to needing to set an initial, default,
        // master mute at HAL load time.
        MMS_SETONLY,

        // MMS_FULL:
        // Audio HAL has support both for setting and getting master mute.
        // AudioFlinger should send all set and get master mute requests
        // directly to the HAL.
        MMS_FULL,
    };

    class AudioHwDevice {
    public:
        AudioHwDevice(const char *moduleName, audio_hw_device_t *hwDevice) :
@@ -1957,6 +1979,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
        AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size
        AUDIO_HW_GET_MASTER_VOLUME,     // get_master_volume
        AUDIO_HW_GET_PARAMETER,         // get_parameters
        AUDIO_HW_SET_MASTER_MUTE,       // set_master_mute
        AUDIO_HW_GET_MASTER_MUTE,       // get_master_mute
    };

    mutable     hardware_call_state                 mHardwareStatus;    // for dump only
@@ -1969,7 +1993,10 @@ mutable Mutex mLock; // mutex for process, commands and handl
                float                               mMasterVolume;
                float                               mMasterVolumeSW;
                master_volume_support               mMasterVolumeSupportLvl;

                bool                                mMasterMute;
                bool                                mMasterMuteSW;
                master_mute_support                 mMasterMuteSupportLvl;

                DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> >    mRecordThreads;

@@ -1983,7 +2010,8 @@ mutable Mutex mLock; // mutex for process, commands and handl

                float       masterVolume_l() const;
                float       masterVolumeSW_l() const  { return mMasterVolumeSW; }
                bool        masterMute_l() const    { return mMasterMute; }
                bool        masterMute_l() const;
                bool        masterMuteSW_l() const    { return mMasterMuteSW; }
                audio_module_handle_t loadHwModule_l(const char *name);

                Vector < sp<SyncEvent> > mPendingSyncEvents; // sync events awaiting for a session