Merge " Audio: Fix for sound card status overwrite issue"
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 69f3b20..5f29d71 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -207,7 +207,9 @@
static bool is_supported_format(audio_format_t format)
{
if (format == AUDIO_FORMAT_MP3 ||
- format == AUDIO_FORMAT_AAC ||
+ format == AUDIO_FORMAT_AAC_LC ||
+ format == AUDIO_FORMAT_AAC_HE_V1 ||
+ format == AUDIO_FORMAT_AAC_HE_V2 ||
format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD ||
format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD ||
format == AUDIO_FORMAT_FLAC)
@@ -220,15 +222,14 @@
{
int id = 0;
- switch (format) {
+ switch (format & AUDIO_FORMAT_MAIN_MASK) {
case AUDIO_FORMAT_MP3:
id = SND_AUDIOCODEC_MP3;
break;
case AUDIO_FORMAT_AAC:
id = SND_AUDIOCODEC_AAC;
break;
- case AUDIO_FORMAT_PCM_16_BIT_OFFLOAD:
- case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD:
+ case AUDIO_FORMAT_PCM_OFFLOAD:
id = SND_AUDIOCODEC_PCM;
break;
case AUDIO_FORMAT_FLAC:
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 2309730..553eb46 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1243,6 +1243,81 @@
return output;
}
+status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session)
+{
+ ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
+ ssize_t index = mOutputs.indexOfKey(output);
+ if (index < 0) {
+ ALOGW("stopOutput() unknow output %d", output);
+ return BAD_VALUE;
+ }
+
+ AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+
+ // handle special case for sonification while in call
+ if ((isInCall()) && (outputDesc->mRefCount[stream] == 1)) {
+ handleIncallSonification(stream, false, false);
+ }
+
+ if (outputDesc->mRefCount[stream] > 0) {
+ // decrement usage count of this stream on the output
+ outputDesc->changeRefCount(stream, -1);
+ // store time at which the stream was stopped - see isStreamActive()
+ if (outputDesc->mRefCount[stream] == 0) {
+ outputDesc->mStopTime[stream] = systemTime();
+ audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
+ // delay the device switch by twice the latency because stopOutput() is executed when
+ // the track stop() command is received and at that time the audio track buffer can
+ // still contain data that needs to be drained. The latency only covers the audio HAL
+ // and kernel buffers. Also the latency does not always include additional delay in the
+ // audio path (audio DSP, CODEC ...)
+#ifdef VOICE_CONCURRENCY
+ //if newDevice is invalid for voice stream, cancel the unexecuted device routing
+ //command(if existed)which could be handled later in command queue for current output
+ if (newDevice == AUDIO_DEVICE_NONE && stream == AudioSystem::VOICE_CALL)
+ setOutputDevice(output, newDevice, true);
+ else
+#endif
+ setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
+
+ // force restoring the device selection on other active outputs if it differs from the
+ // one being selected for this output
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ audio_io_handle_t curOutput = mOutputs.keyAt(i);
+ AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+ if (curOutput != output &&
+ desc->isActive() &&
+ outputDesc->sharesHwModuleWith(desc) &&
+ (newDevice != desc->device())) {
+ setOutputDevice(curOutput,
+ getNewDevice(curOutput, false /*fromCache*/),
+ true,
+ outputDesc->mLatency*2);
+ }
+ }
+ // update the outputs if stopping one with a stream that can affect notification routing
+ handleNotificationRoutingForStream(stream);
+ }
+ return NO_ERROR;
+ } else {
+ ALOGW("stopOutput() refcount is already 0 for output %d", output);
+ return INVALID_OPERATION;
+ }
+}
+
+//private function, no changes from AudioPolicyManagerBase
+void AudioPolicyManager::handleNotificationRoutingForStream(AudioSystem::stream_type stream) {
+ switch(stream) {
+ case AudioSystem::MUSIC:
+ checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
+ updateDevicesAndOutputs();
+ break;
+ default:
+ break;
+ }
+}
// This function checks for the parameters which can be offloaded.
// This can be enhanced depending on the capability of the DSP and policy
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 9f2b473..d5cb6c1 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -58,6 +58,10 @@
AudioSystem::OUTPUT_FLAG_INDIRECT,
const audio_offload_info_t *offloadInfo = NULL);
+ virtual status_t stopOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session = 0);
+
virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
virtual void setPhoneState(int state);
@@ -103,6 +107,8 @@
bool mHdmiAudioEvent;
private:
+ void handleNotificationRoutingForStream(AudioSystem::stream_type stream);
+
// Used for voip + voice concurrency usecase
int mPrevPhoneState;
static int mvoice_call_state;