diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/AudioPolicyManagerBase.cpp | 62 | ||||
-rw-r--r-- | audio/audio_policy_hal.cpp | 8 |
2 files changed, 59 insertions, 11 deletions
diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index 134fb3b..ccaa035 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -27,6 +27,9 @@ // A device mask for all audio input devices that are considered "virtual" when evaluating // active inputs in getActiveInput() #define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX +// A device mask for all audio output devices that are considered "remote" when evaluating +// active output devices in isStreamActiveRemotely() +#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX #include <utils/Log.h> #include <hardware_legacy/AudioPolicyManagerBase.h> @@ -347,12 +350,12 @@ void AudioPolicyManagerBase::setPhoneState(int state) if (isStateInCall(state)) { for (size_t i = 0; i < mOutputs.size(); i++) { AudioOutputDescriptor *desc = mOutputs.valueAt(i); - //take the biggest latency for all outputs - if (delayMs < (int)desc->mLatency*2) { - delayMs = desc->mLatency*2; - } - //mute STRATEGY_MEDIA on all outputs + // mute strategy media and delay device switch by the largest latency of any output + // where strategy media is active. if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) { + if (delayMs < (int)desc->mLatency*2) { + delayMs = desc->mLatency*2; + } setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); @@ -1178,6 +1181,20 @@ bool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const return false; } +bool AudioPolicyManagerBase::isStreamActiveRemotely(int stream, uint32_t inPastMs) const +{ + nsecs_t sysTime = systemTime(); + for (size_t i = 0; i < mOutputs.size(); i++) { + const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); + if ((outputDesc->mRefCount[stream] != 0 || + ns2ms(sysTime - outputDesc->mStopTime[stream]) < inPastMs) + && ((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) ) { + return true; + } + } + return false; +} + bool AudioPolicyManagerBase::isSourceActive(audio_source_t source) const { for (size_t i = 0; i < mInputs.size(); i++) { @@ -2083,6 +2100,13 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy st case STRATEGY_SONIFICATION_RESPECTFUL: if (isInCall()) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); + } else if (isStreamActiveRemotely(AudioSystem::MUSIC, + SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { + // while media is playing on a remote device, use the the sonification behavior. + // Note that we test this usecase before testing if media is playing because + // the isStreamActive() method only informs about the activity of a stream, not + // if it's for local playback. Note also that we use the same delay between both tests + device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { // while media is playing (or has recently played), use the same device device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); @@ -2314,6 +2338,7 @@ uint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor if (doMute || tempMute) { for (size_t j = 0; j < mOutputs.size(); j++) { AudioOutputDescriptor *desc = mOutputs.valueAt(j); + // skip output if it does not share any device with current output if ((desc->supportedDevices() & outputDesc->supportedDevices()) == AUDIO_DEVICE_NONE) { continue; @@ -2323,12 +2348,13 @@ uint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor mute ? "muting" : "unmuting", i, curDevice, curOutput); setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); if (desc->strategyRefCount((routing_strategy)i) != 0) { - if (tempMute) { + // do tempMute only for current output + if (tempMute && (desc == outputDesc)) { setStrategyMute((routing_strategy)i, true, curOutput); setStrategyMute((routing_strategy)i, false, curOutput, desc->latency() * 2, device); } - if (tempMute || mute) { + if ((tempMute && (desc == outputDesc)) || mute) { if (muteWaitMs < desc->latency()) { muteWaitMs = desc->latency(); } @@ -2360,13 +2386,20 @@ uint32_t AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); AudioParameter param; - uint32_t muteWaitMs = 0; + uint32_t muteWaitMs; if (outputDesc->isDuplicated()) { muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); return muteWaitMs; } + // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current + // output profile + if ((device != AUDIO_DEVICE_NONE) && + ((device & outputDesc->mProfile->mSupportedDevices) == 0)) { + return 0; + } + // filter devices according to output selected device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); @@ -2428,7 +2461,14 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) { uint32_t device = AUDIO_DEVICE_NONE; - switch(inputSource) { + switch (inputSource) { + case AUDIO_SOURCE_VOICE_UPLINK: + if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { + device = AUDIO_DEVICE_IN_VOICE_CALL; + break; + } + // FALL THROUGH + case AUDIO_SOURCE_DEFAULT: case AUDIO_SOURCE_MIC: case AUDIO_SOURCE_VOICE_RECOGNITION: @@ -2449,7 +2489,6 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) device = AUDIO_DEVICE_IN_BUILTIN_MIC; } break; - case AUDIO_SOURCE_VOICE_UPLINK: case AUDIO_SOURCE_VOICE_DOWNLINK: case AUDIO_SOURCE_VOICE_CALL: if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { @@ -2991,7 +3030,7 @@ AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( } } -audio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() +audio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() const { if (isDuplicated()) { return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); @@ -3406,6 +3445,7 @@ const struct StringToEnum sOutChannelsNameToEnumTable[] = { const struct StringToEnum sInChannelsNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), + STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), }; diff --git a/audio/audio_policy_hal.cpp b/audio/audio_policy_hal.cpp index bff6b74..1604809 100644 --- a/audio/audio_policy_hal.cpp +++ b/audio/audio_policy_hal.cpp @@ -302,6 +302,13 @@ static bool ap_is_stream_active(const struct audio_policy *pol, audio_stream_typ return lap->apm->isStreamActive((int) stream, in_past_ms); } +static bool ap_is_stream_active_remotely(const struct audio_policy *pol, audio_stream_type_t stream, + uint32_t in_past_ms) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->isStreamActiveRemotely((int) stream, in_past_ms); +} + static bool ap_is_source_active(const struct audio_policy *pol, audio_source_t source) { const struct legacy_audio_policy *lap = to_clap(pol); @@ -358,6 +365,7 @@ static int create_legacy_ap(const struct audio_policy_device *device, lap->policy.unregister_effect = ap_unregister_effect; lap->policy.set_effect_enabled = ap_set_effect_enabled; lap->policy.is_stream_active = ap_is_stream_active; + lap->policy.is_stream_active_remotely = ap_is_stream_active_remotely; lap->policy.is_source_active = ap_is_source_active; lap->policy.dump = ap_dump; |