From 8abf44d2f2bcd20a2835570efe89d89c19db426a Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Thu, 2 Feb 2012 14:16:03 -0800 Subject: 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 --- services/audioflinger/AudioFlinger.cpp | 28 +++++++++++++++---------- services/audioflinger/AudioFlinger.h | 38 ++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 6256951..4446681 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -232,7 +232,7 @@ void AudioFlinger::onFirstRef() (NO_ERROR != dev->set_master_volume(dev, initialVolume))) { 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 @@ -254,7 +254,7 @@ void AudioFlinger::onFirstRef() 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 result; - ALOGV("setParameters(): io %d, keyvalue %s, tid %d, calling pid %d", ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid()); // 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 if (ioHandle == 0) { - AutoMutex lock(mHardwareLock); - mHardwareStatus = AUDIO_SET_PARAMETER; status_t final_result = NO_ERROR; + { + AutoMutex lock(mHardwareLock); + mHardwareStatus = AUDIO_HW_SET_PARAMETER; for (size_t i = 0; i < mAudioHwDevs.size(); 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; } mHardwareStatus = AUDIO_HW_IDLE; + } // disable AEC and NS if the device is a BT SCO headset supporting those pre processings AudioParameter param = AudioParameter(keyValuePairs); String8 value; @@ -904,8 +904,14 @@ String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& k String8 out_s8; 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]; - char *s = dev->get_parameters(dev, keys.string()); + s = dev->get_parameters(dev, keys.string()); + mHardwareStatus = AUDIO_HW_IDLE; + } out_s8 += String8(s ? s : ""); free(s); } @@ -967,7 +973,7 @@ status_t AudioFlinger::setVoiceVolume(float value) } AutoMutex lock(mHardwareLock); - mHardwareStatus = AUDIO_SET_VOICE_VOLUME; + mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME; ret = mPrimaryHardwareDev->set_voice_volume(mPrimaryHardwareDev, value); mHardwareStatus = AUDIO_HW_IDLE; @@ -5429,7 +5435,6 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices, { status_t status; PlaybackThread *thread = NULL; - mHardwareStatus = AUDIO_HW_OUTPUT_OPEN; uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT; uint32_t channels = pChannels ? *pChannels : 0; @@ -5454,8 +5459,10 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices, if (outHwDev == NULL) return 0; + mHardwareStatus = AUDIO_HW_OUTPUT_OPEN; status = outHwDev->open_output_stream(outHwDev, *pDevices, &format, &channels, &samplingRate, &outStream); + mHardwareStatus = AUDIO_HW_IDLE; ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d", outStream, samplingRate, @@ -5463,7 +5470,6 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices, channels, status); - mHardwareStatus = AUDIO_HW_IDLE; if (outStream != NULL) { AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream); audio_io_handle_t id = nextUniqueId(); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 1a52de5..71afc3c 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -1537,25 +1537,27 @@ mutable Mutex mLock; // mutex for process, commands and handl audio_hw_device_t* mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL Vector mAudioHwDevs; + // for dump, indicates which hardware operation is currently in progress (but not stream ops) enum hardware_call_state { - AUDIO_HW_IDLE = 0, - AUDIO_HW_INIT, - AUDIO_HW_OUTPUT_OPEN, - AUDIO_HW_OUTPUT_CLOSE, - AUDIO_HW_INPUT_OPEN, - AUDIO_HW_INPUT_CLOSE, - AUDIO_HW_STANDBY, - AUDIO_HW_SET_MASTER_VOLUME, - AUDIO_HW_GET_ROUTING, - AUDIO_HW_SET_ROUTING, - AUDIO_HW_GET_MODE, - AUDIO_HW_SET_MODE, - AUDIO_HW_GET_MIC_MUTE, - AUDIO_HW_SET_MIC_MUTE, - AUDIO_SET_VOICE_VOLUME, - AUDIO_SET_PARAMETER, - AUDIO_HW_GET_INPUT_BUFFER_SIZE, - AUDIO_HW_GET_MASTER_VOLUME, + AUDIO_HW_IDLE = 0, // no operation in progress + AUDIO_HW_INIT, // init_check + AUDIO_HW_OUTPUT_OPEN, // open_output_stream + AUDIO_HW_OUTPUT_CLOSE, // unused + AUDIO_HW_INPUT_OPEN, // unused + AUDIO_HW_INPUT_CLOSE, // unused + AUDIO_HW_STANDBY, // unused + AUDIO_HW_SET_MASTER_VOLUME, // set_master_volume + AUDIO_HW_GET_ROUTING, // unused + AUDIO_HW_SET_ROUTING, // unused + AUDIO_HW_GET_MODE, // unused + AUDIO_HW_SET_MODE, // set_mode + AUDIO_HW_GET_MIC_MUTE, // get_mic_mute + AUDIO_HW_SET_MIC_MUTE, // set_mic_mute + AUDIO_HW_SET_VOICE_VOLUME, // set_voice_volume + AUDIO_HW_SET_PARAMETER, // set_parameters + AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size + AUDIO_HW_GET_MASTER_VOLUME, // get_master_volume + AUDIO_HW_GET_PARAMETER, // get_parameters }; mutable hardware_call_state mHardwareStatus; // for dump only -- cgit v1.1