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

Commit 23c9c740 authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Fix tracking of hardware state for dump

At end of AudioFlinger::onFirstRef(), the hardware status was being left
in wrong state.  It should be AUDIO_HW_IDLE but was AUDIO_HW_INIT.

mHardwareStatus was being set to AUDIO_HW_OUTPUT_OPEN too early, and so
a return would leave it in the wrong state until next hardware operation.

Take the hardware lock for dev->get_parameters, and update mHardwareStatus
before and after.

Keep hardware lock only for the duration of the dev->set_parameters.

Rename two constants in enum hardware_call_state to have the prefix
AUDIO_HW so they follow the naming conventions.

Add comments.

Change-Id: I6c7450b11f9b13adaeef9cec874333e478a58fc0
parent be3835c6
Loading
Loading
Loading
Loading
+17 −11
Original line number Original line Diff line number Diff line
@@ -232,7 +232,7 @@ void AudioFlinger::onFirstRef()
            (NO_ERROR != dev->set_master_volume(dev, initialVolume))) {
            (NO_ERROR != dev->set_master_volume(dev, initialVolume))) {
            mMasterVolumeSupportLvl = MVS_NONE;
            mMasterVolumeSupportLvl = MVS_NONE;
        }
        }
        mHardwareStatus = AUDIO_HW_INIT;
        mHardwareStatus = AUDIO_HW_IDLE;
    }
    }


    // Set the mode for each audio HAL, and try to set the initial volume (if
    // Set the mode for each audio HAL, and try to set the initial volume (if
@@ -254,7 +254,7 @@ void AudioFlinger::onFirstRef()
                dev->set_master_volume(dev, initialVolume);
                dev->set_master_volume(dev, initialVolume);
            }
            }


            mHardwareStatus = AUDIO_HW_INIT;
            mHardwareStatus = AUDIO_HW_IDLE;
        }
        }
    }
    }


@@ -822,8 +822,6 @@ bool AudioFlinger::streamMute(audio_stream_type_t stream) const


status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
{
{
    status_t result;

    ALOGV("setParameters(): io %d, keyvalue %s, tid %d, calling pid %d",
    ALOGV("setParameters(): io %d, keyvalue %s, tid %d, calling pid %d",
            ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid());
            ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid());
    // check calling permissions
    // check calling permissions
@@ -833,15 +831,17 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&


    // ioHandle == 0 means the parameters are global to the audio hardware interface
    // ioHandle == 0 means the parameters are global to the audio hardware interface
    if (ioHandle == 0) {
    if (ioHandle == 0) {
        AutoMutex lock(mHardwareLock);
        mHardwareStatus = AUDIO_SET_PARAMETER;
        status_t final_result = NO_ERROR;
        status_t final_result = NO_ERROR;
        {
        AutoMutex lock(mHardwareLock);
        mHardwareStatus = AUDIO_HW_SET_PARAMETER;
        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
            audio_hw_device_t *dev = mAudioHwDevs[i];
            audio_hw_device_t *dev = mAudioHwDevs[i];
            result = dev->set_parameters(dev, keyValuePairs.string());
            status_t result = dev->set_parameters(dev, keyValuePairs.string());
            final_result = result ?: final_result;
            final_result = result ?: final_result;
        }
        }
        mHardwareStatus = AUDIO_HW_IDLE;
        mHardwareStatus = AUDIO_HW_IDLE;
        }
        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
        AudioParameter param = AudioParameter(keyValuePairs);
        AudioParameter param = AudioParameter(keyValuePairs);
        String8 value;
        String8 value;
@@ -904,8 +904,14 @@ String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& k
        String8 out_s8;
        String8 out_s8;


        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
            char *s;
            {
            AutoMutex lock(mHardwareLock);
            mHardwareStatus = AUDIO_HW_GET_PARAMETER;
            audio_hw_device_t *dev = mAudioHwDevs[i];
            audio_hw_device_t *dev = mAudioHwDevs[i];
            char *s = dev->get_parameters(dev, keys.string());
            s = dev->get_parameters(dev, keys.string());
            mHardwareStatus = AUDIO_HW_IDLE;
            }
            out_s8 += String8(s ? s : "");
            out_s8 += String8(s ? s : "");
            free(s);
            free(s);
        }
        }
@@ -967,7 +973,7 @@ status_t AudioFlinger::setVoiceVolume(float value)
    }
    }


    AutoMutex lock(mHardwareLock);
    AutoMutex lock(mHardwareLock);
    mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
    mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
    ret = mPrimaryHardwareDev->set_voice_volume(mPrimaryHardwareDev, value);
    ret = mPrimaryHardwareDev->set_voice_volume(mPrimaryHardwareDev, value);
    mHardwareStatus = AUDIO_HW_IDLE;
    mHardwareStatus = AUDIO_HW_IDLE;


@@ -5429,7 +5435,6 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices,
{
{
    status_t status;
    status_t status;
    PlaybackThread *thread = NULL;
    PlaybackThread *thread = NULL;
    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
    uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
    uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
    audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT;
    audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT;
    uint32_t channels = pChannels ? *pChannels : 0;
    uint32_t channels = pChannels ? *pChannels : 0;
@@ -5454,8 +5459,10 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices,
    if (outHwDev == NULL)
    if (outHwDev == NULL)
        return 0;
        return 0;


    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
    status = outHwDev->open_output_stream(outHwDev, *pDevices, &format,
    status = outHwDev->open_output_stream(outHwDev, *pDevices, &format,
                                          &channels, &samplingRate, &outStream);
                                          &channels, &samplingRate, &outStream);
    mHardwareStatus = AUDIO_HW_IDLE;
    ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
    ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
            outStream,
            outStream,
            samplingRate,
            samplingRate,
@@ -5463,7 +5470,6 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices,
            channels,
            channels,
            status);
            status);


    mHardwareStatus = AUDIO_HW_IDLE;
    if (outStream != NULL) {
    if (outStream != NULL) {
        AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
        AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
        audio_io_handle_t id = nextUniqueId();
        audio_io_handle_t id = nextUniqueId();
+20 −18
Original line number Original line Diff line number Diff line
@@ -1537,25 +1537,27 @@ mutable Mutex mLock; // mutex for process, commands and handl
                audio_hw_device_t*                  mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL
                audio_hw_device_t*                  mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL
                Vector<audio_hw_device_t*>          mAudioHwDevs;
                Vector<audio_hw_device_t*>          mAudioHwDevs;


    // for dump, indicates which hardware operation is currently in progress (but not stream ops)
    enum hardware_call_state {
    enum hardware_call_state {
        AUDIO_HW_IDLE = 0,
        AUDIO_HW_IDLE = 0,              // no operation in progress
        AUDIO_HW_INIT,
        AUDIO_HW_INIT,                  // init_check
        AUDIO_HW_OUTPUT_OPEN,
        AUDIO_HW_OUTPUT_OPEN,           // open_output_stream
        AUDIO_HW_OUTPUT_CLOSE,
        AUDIO_HW_OUTPUT_CLOSE,          // unused
        AUDIO_HW_INPUT_OPEN,
        AUDIO_HW_INPUT_OPEN,            // unused
        AUDIO_HW_INPUT_CLOSE,
        AUDIO_HW_INPUT_CLOSE,           // unused
        AUDIO_HW_STANDBY,
        AUDIO_HW_STANDBY,               // unused
        AUDIO_HW_SET_MASTER_VOLUME,
        AUDIO_HW_SET_MASTER_VOLUME,     // set_master_volume
        AUDIO_HW_GET_ROUTING,
        AUDIO_HW_GET_ROUTING,           // unused
        AUDIO_HW_SET_ROUTING,
        AUDIO_HW_SET_ROUTING,           // unused
        AUDIO_HW_GET_MODE,
        AUDIO_HW_GET_MODE,              // unused
        AUDIO_HW_SET_MODE,
        AUDIO_HW_SET_MODE,              // set_mode
        AUDIO_HW_GET_MIC_MUTE,
        AUDIO_HW_GET_MIC_MUTE,          // get_mic_mute
        AUDIO_HW_SET_MIC_MUTE,
        AUDIO_HW_SET_MIC_MUTE,          // set_mic_mute
        AUDIO_SET_VOICE_VOLUME,
        AUDIO_HW_SET_VOICE_VOLUME,      // set_voice_volume
        AUDIO_SET_PARAMETER,
        AUDIO_HW_SET_PARAMETER,         // set_parameters
        AUDIO_HW_GET_INPUT_BUFFER_SIZE,
        AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size
        AUDIO_HW_GET_MASTER_VOLUME,
        AUDIO_HW_GET_MASTER_VOLUME,     // get_master_volume
        AUDIO_HW_GET_PARAMETER,         // get_parameters
    };
    };


    mutable     hardware_call_state                 mHardwareStatus;    // for dump only
    mutable     hardware_call_state                 mHardwareStatus;    // for dump only