summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/AudioPolicyManagerBase.cpp62
-rw-r--r--audio/audio_policy_hal.cpp8
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;