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

Commit 91de9b56 authored by John Grossman's avatar John Grossman
Browse files

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>
parent 8bdac969
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)
{
@@ -1500,7 +1550,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,
@@ -6777,10 +6827,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) &&
@@ -6796,20 +6849,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);
@@ -1895,6 +1896,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) :
@@ -1941,6 +1963,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
@@ -1953,7 +1977,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;

@@ -1967,7 +1994,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