zenfone6: Sync Policy_hal to CAF QSSI
Change-Id: I52f577ed71e9e65a0d0cf11fbacd8afa5c0c26f0
diff --git a/policy_hal/APMConfigHelper.cpp b/policy_hal/APMConfigHelper.cpp
index 1815e77..5b17096 100644
--- a/policy_hal/APMConfigHelper.cpp
+++ b/policy_hal/APMConfigHelper.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -37,6 +37,36 @@
namespace android {
+void APMConfigHelper::dump(String8 *dst) const
+{
+ // apmconfig struct dump
+ dst->appendFormat("\nAudioPolicyManagerCustom Dump: %p\n", this);
+ dst->appendFormat("audio_offload_video: %d \n", mConfigs.audio_offload_video);
+ dst->appendFormat("audio_offload_disable: %d \n", mConfigs.audio_offload_disable);
+ dst->appendFormat("audio_deepbuffer_media: %d \n", mConfigs.audio_deepbuffer_media);
+ dst->appendFormat("audio_av_streaming_offload_enable: %d \n", mConfigs.audio_av_streaming_offload_enable);
+ dst->appendFormat("audio_offload_track_enable: %d \n", mConfigs.audio_offload_track_enable);
+ dst->appendFormat("audio_offload_multiple_enabled: %d \n", mConfigs.audio_offload_multiple_enabled);
+ dst->appendFormat("voice_dsd_playback_conc_disabled: %d \n", mConfigs.voice_dsd_playback_conc_disabled);
+ dst->appendFormat("audio_sva_conc_enabled: %d \n", mConfigs.audio_sva_conc_enabled);
+ dst->appendFormat("audio_va_concurrency_enabled: %d \n", mConfigs.audio_va_concurrency_enabled);
+ dst->appendFormat("audio_rec_playback_conc_disabled: %d \n", mConfigs.audio_rec_playback_conc_disabled);
+ dst->appendFormat("voice_path_for_pcm_voip: %d \n", mConfigs.voice_path_for_pcm_voip);
+ dst->appendFormat("voice_playback_conc_disabled: %d \n", mConfigs.voice_playback_conc_disabled);
+ dst->appendFormat("voice_record_conc_disabled: %d \n", mConfigs.voice_record_conc_disabled);
+ dst->appendFormat("voice_voip_conc_disabled: %d \n", mConfigs.voice_voip_conc_disabled);
+ dst->appendFormat("audio_offload_min_duration_secs: %u \n", mConfigs.audio_offload_min_duration_secs);
+ dst->appendFormat("voice_conc_fallbackpath: %s \n", mConfigs.voice_conc_fallbackpath.c_str());
+ dst->appendFormat("audio_extn_hdmi_spk_enabled: %d \n", mConfigs.audio_extn_hdmi_spk_enabled);
+ dst->appendFormat("audio_extn_formats_enabled: %d \n", mConfigs.audio_extn_formats_enabled);
+ dst->appendFormat("audio_extn_afe_proxy_enabled: %d \n", mConfigs.audio_extn_afe_proxy_enabled);
+ dst->appendFormat("compress_voip_enabled: %d \n", mConfigs.compress_voip_enabled);
+ dst->appendFormat("fm_power_opt: %d \n", mConfigs.fm_power_opt);
+ dst->appendFormat("voice_concurrency: %d \n", mConfigs.voice_concurrency);
+ dst->appendFormat("record_play_concurrency: %d \n", mConfigs.record_play_concurrency);
+ dst->appendFormat("use_xml_audio_policy_conf: %d \n", mConfigs.use_xml_audio_policy_conf);
+}
+
void APMConfigHelper::retrieveConfigs()
{
#ifdef AHAL_EXT_ENABLED
diff --git a/policy_hal/APMConfigHelper.h b/policy_hal/APMConfigHelper.h
index 137f2d7..e92fcaa 100644
--- a/policy_hal/APMConfigHelper.h
+++ b/policy_hal/APMConfigHelper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,6 +31,7 @@
#define _APM_CONFIG_HELPER_H_
#include <string>
+#include <utils/String8.h>
#include <media/stagefright/foundation/ABase.h>
#include <utils/RefBase.h>
@@ -109,7 +110,7 @@
bool isVoiceConcEnabled();
bool isRecPlayConcEnabled();
bool useXMLAudioPolicyConf();
-
+ void dump(String8 *dst) const;
private:
inline void retrieveConfigs();
diff --git a/policy_hal/Android.mk b/policy_hal/Android.mk
index 8df84b9..eda2cc8 100644
--- a/policy_hal/Android.mk
+++ b/policy_hal/Android.mk
@@ -18,14 +18,17 @@
$(call include-path-for, avextension) \
LOCAL_HEADER_LIBRARIES := \
+ libaudioclient_headers \
+ libaudiofoundation_headers \
libbase_headers \
+ libmedia_headers \
libstagefright_foundation_headers
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
liblog \
- libsoundtrigger \
+ libaudiofoundation \
libaudiopolicymanagerdefault
LOCAL_STATIC_LIBRARIES := \
@@ -69,7 +72,6 @@
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AHAL_EXT)), true)
LOCAL_CFLAGS += -DAHAL_EXT_ENABLED
LOCAL_SHARED_LIBRARIES += libhidlbase
- LOCAL_SHARED_LIBRARIES += libhidltransport
LOCAL_SHARED_LIBRARIES += vendor.qti.hardware.audiohalext@1.0
LOCAL_SHARED_LIBRARIES += vendor.qti.hardware.audiohalext-utils
endif
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 48f7a53..833b783 100755
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2009 The Android Open Source Project
@@ -43,7 +43,6 @@
#include <hardware/audio.h>
#include <hardware/audio_effect.h>
#include <media/AudioParameter.h>
-#include <soundtrigger/SoundTrigger.h>
#include "AudioPolicyManager.h"
#include <policy.h>
@@ -58,18 +57,18 @@
audio_output_flags_t AudioPolicyManagerCustom::getFallBackPath()
{
audio_output_flags_t flag = AUDIO_OUTPUT_FLAG_FAST;
- const char *fallback_path = mApmConfigs->getVoiceConcFallbackPath().c_str();
+ std::string fallback_path = mApmConfigs->getVoiceConcFallbackPath();
- if (strlen(fallback_path) > 0) {
- if (!strncmp(fallback_path, "deep-buffer", 11)) {
+ if (strlen(fallback_path.c_str()) > 0) {
+ if (!strncmp(fallback_path.c_str(), "deep-buffer", 11)) {
flag = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
}
- else if (!strncmp(fallback_path, "fast", 4)) {
+ else if (!strncmp(fallback_path.c_str(), "fast", 4)) {
flag = AUDIO_OUTPUT_FLAG_FAST;
}
else {
ALOGD("voice_conc:not a recognised path(%s) in prop vendor.voice.conc.fallbackpath",
- fallback_path);
+ fallback_path.c_str());
}
}
else {
@@ -82,13 +81,39 @@
return flag;
}
+template <typename T>
+bool operator== (const SortedVector<T> &left, const SortedVector<T> &right)
+{
+ if (left.size() != right.size()) {
+ return false;
+ }
+ for (size_t index = 0; index < right.size(); index++) {
+ if (left[index] != right[index]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <typename T>
+bool operator!= (const SortedVector<T> &left, const SortedVector<T> &right)
+{
+ return !(left == right);
+}
+
// ----------------------------------------------------------------------------
// AudioPolicyInterface implementation
// ----------------------------------------------------------------------------
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
- return new AudioPolicyManagerCustom(clientInterface);
+ AudioPolicyManagerCustom *apm = new AudioPolicyManagerCustom(clientInterface);
+ status_t status = apm->initialize();
+ if (status != NO_ERROR) {
+ delete apm;
+ apm = nullptr;
+ }
+ return apm;
}
extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
@@ -144,7 +169,9 @@
__func__, device->toString().c_str(), encodedFormat);
// register new device as available
- index = mAvailableOutputDevices.add(device);
+ if (mAvailableOutputDevices.add(device) < 0) {
+ return NO_MEMORY;
+ }
if (mApmConfigs->isHDMISpkEnabled() &&
(popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
if (!strncmp(device_address, "hdmi_spkr", 9)) {
@@ -158,19 +185,6 @@
return INVALID_OPERATION;
}
}
- if (index >= 0) {
- sp<HwModule> module = mHwModules.getModuleForDevice(device, encodedFormat);
- if (module == 0) {
- ALOGD("setDeviceConnectionState() could not find HW module for device %s",
- device->toString().c_str());
- mAvailableOutputDevices.remove(device);
- return INVALID_OPERATION;
- }
- ALOGV("setDeviceConnectionState() module name=%s", module->getName());
- mAvailableOutputDevices[index]->attach(module);
- } else {
- return NO_MEMORY;
- }
// Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the outputs...)
@@ -305,15 +319,17 @@
DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevices);
}
-
+ const DeviceVector msdOutDevices = getMsdAudioOutDevices();
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
+ if (desc->isActive() && ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) ||
+ (desc != mPrimaryOutput))) {
DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
// do not force device change on duplicated output because if device is 0, it will
// also force a device 0 for the two outputs it is duplicated to which may override
// a valid device selection on those outputs.
- bool force = !desc->isDuplicated()
+ bool force = (msdOutDevices.isEmpty() || msdOutDevices != desc->devices())
+ && !desc->isDuplicated()
&& (!device_distinguishes_on_address(deviceType)
// always force when disconnecting (a non-duplicated device)
|| (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
@@ -340,11 +356,9 @@
ALOGW("setDeviceConnectionState() device already connected: %d", deviceType);
return INVALID_OPERATION;
}
- sp<HwModule> module = mHwModules.getModuleForDevice(device, AUDIO_FORMAT_DEFAULT);
- if (module == NULL) {
- ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
- deviceType);
- return INVALID_OPERATION;
+
+ if (mAvailableInputDevices.add(device) < 0) {
+ return NO_MEMORY;
}
// Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
@@ -352,6 +366,8 @@
broadcastDeviceConnectionState(device, state);
if (checkInputsForDevice(device, state) != NO_ERROR) {
+ mAvailableInputDevices.remove(device);
+
broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
mHwModules.cleanUpForDevice(device);
@@ -359,13 +375,6 @@
return INVALID_OPERATION;
}
- index = mAvailableInputDevices.add(device);
- if (index >= 0) {
- mAvailableInputDevices[index]->attach(module);
- } else {
- return NO_MEMORY;
- }
-
} break;
// handle input device disconnection
@@ -380,9 +389,10 @@
// Set Disconnect to HALs
broadcastDeviceConnectionState(device, state);
- checkInputsForDevice(device, state);
mAvailableInputDevices.remove(device);
+ checkInputsForDevice(device, state);
+
} break;
default:
@@ -437,7 +447,7 @@
if (followsSameRouting(attr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> newOutputDesc = mOutputs.valueAt(i);
- if (newOutputDesc->mFormat == AUDIO_FORMAT_DSD)
+ if (newOutputDesc->getFormat() == AUDIO_FORMAT_DSD)
return false;
}
}
@@ -832,7 +842,7 @@
if (mApmConfigs->isVoiceDSDConcDisabled() &&
(outputDesc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
- (outputDesc->mFormat == AUDIO_FORMAT_DSD)) {
+ (outputDesc->getFormat() == AUDIO_FORMAT_DSD)) {
ALOGD("voice_conc:calling closeOutput on call mode for DSD COMPRESS output");
closeOutput(mOutputs.keyAt(i));
// call invalidate for music, so that DSD compress will fallback to deep-buffer.
@@ -917,11 +927,11 @@
updateCallRouting(rxDevices, delayMs);
} else if (oldState == AUDIO_MODE_IN_CALL) {
if (mCallRxPatch != 0) {
- mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
+ mpClientInterface->releaseAudioPatch(mCallRxPatch->getAfHandle(), 0);
mCallRxPatch.clear();
}
if (mCallTxPatch != 0) {
- mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
+ mpClientInterface->releaseAudioPatch(mCallTxPatch->getAfHandle(), 0);
mCallTxPatch.clear();
}
setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
@@ -929,12 +939,13 @@
setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
}
}
- //update device for all non-primary outputs
+
+ // reevaluate routing on all outputs in case tracks have been started during the call
for (size_t i = 0; i < mOutputs.size(); i++) {
- audio_io_handle_t output = mOutputs.keyAt(i);
- if (output != mPrimaryOutput->mIoHandle) {
- DeviceVector newDevices = getNewOutputDevices(mOutputs.valueFor(output), false /*fromCache*/);
- setOutputDevices(mOutputs.valueFor(output), newDevices, !newDevices.isEmpty());
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
+ if (state != AUDIO_MODE_IN_CALL || desc != mPrimaryOutput) {
+ setOutputDevices(desc, newDevices, !newDevices.isEmpty(), 0 /*delayMs*/);
}
}
if (isStateInCall(state)) {
@@ -968,7 +979,12 @@
// check for device and output changes triggered by new force usage
checkForDeviceAndOutputChanges();
- /*audio policy: workaround for truncated touch sounds*/
+ // force client reconnection to reevaluate flag AUDIO_FLAG_AUDIBILITY_ENFORCED
+ if (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM) {
+ mpClientInterface->invalidateStream(AUDIO_STREAM_SYSTEM);
+ mpClientInterface->invalidateStream(AUDIO_STREAM_ENFORCED_AUDIBLE);
+ }
+
//FIXME: workaround for truncated touch sounds
// to be removed when the problem is handled by system UI
uint32_t delayMs = 0;
@@ -1024,6 +1040,7 @@
status_t AudioPolicyManagerCustom::stopSource(const sp<SwAudioOutputDescriptor>& outputDesc,
const sp<TrackClientDescriptor>& client)
{
+ // always handle stream stop, check which stream type is stopping
audio_stream_type_t stream = client->stream();
auto clientVolSrc = client->volumeSource();
@@ -1031,7 +1048,6 @@
ALOGW("stopSource() invalid stream %d", stream);
return INVALID_OPERATION;
}
- // always handle stream stop, check which stream type is stopping
handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
if (outputDesc->getActivityCount(clientVolSrc) > 0) {
@@ -1039,7 +1055,7 @@
// Automatically disable the remote submix input when output is stopped on a
// re routing mix of type MIX_TYPE_RECORDERS
sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
- if (audio_is_remote_submix_device(outputDesc->devices().types()) &&
+ if (isSingleDeviceType(outputDesc->devices().types(), &audio_is_remote_submix_device) &&
policyMix != NULL &&
policyMix->mMixType == MIX_TYPE_RECORDERS) {
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
@@ -1079,7 +1095,7 @@
outputDesc->sharesHwModuleWith(desc) &&
(newDevices != desc->devices())) {
DeviceVector dev = getNewOutputDevices(mOutputs.valueFor(curOutput), false /*fromCache*/);
- bool force = prevDevices != dev;
+ bool force = desc->devices() != dev;
uint32_t delayMs;
if (dev == prevDevices) {
delayMs = 0;
@@ -1090,8 +1106,7 @@
dev,
force,
delayMs);
- /*audio policy: fix media volume after ringtone*/
- // re-apply device specific volume if not done by setOutputDevice()
+ // re-apply device specific volume if not done by setOutputDevice()
if (!force) {
applyStreamVolumes(desc, dev.types(), delayMs);
}
@@ -1180,7 +1195,14 @@
outputDesc->setClientActive(client, true);
if (client->hasPreferredDevice(true)) {
- devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
+ if (outputDesc->clientsList(true /*activeOnly*/).size() == 1 &&
+ client->isPreferredDeviceForExclusiveUse()) {
+ // Preferred device may be exclusive, use only if no other active clients on this output
+ devices = DeviceVector(
+ mAvailableOutputDevices.getDeviceFromId(client->preferredDeviceId()));
+ } else {
+ devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
+ }
if (devices != outputDesc->devices()) {
checkStrategyRoute(clientStrategy, outputDesc->mIoHandle);
}
@@ -1269,7 +1291,8 @@
// Automatically enable the remote submix input when output is started on a re routing mix
// of type MIX_TYPE_RECORDERS
- if (audio_is_remote_submix_device(devices.types()) && policyMix != NULL &&
+ if (isSingleDeviceType(devices.types(), &audio_is_remote_submix_device) &&
+ policyMix != NULL &&
policyMix->mMixType == MIX_TYPE_RECORDERS) {
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
@@ -1285,7 +1308,7 @@
VolumeSource volumeSource,
int index,
const sp<AudioOutputDescriptor>& outputDesc,
- audio_devices_t device,
+ DeviceTypeSet deviceTypes,
int delayMs,
bool force)
{
@@ -1312,24 +1335,28 @@
return INVALID_OPERATION;
}
- if (device == AUDIO_DEVICE_NONE) {
- device = outputDesc->devices().types();
+ if (deviceTypes.empty()) {
+ deviceTypes = outputDesc->devices().types();
}
- float volumeDb = computeVolume(curves, volumeSource, index, device);
- if (outputDesc->isFixedVolume(device)) {
+ float volumeDb = computeVolume(curves, volumeSource, index, deviceTypes);
+ if (outputDesc->isFixedVolume(deviceTypes)||
+ // Force VoIP volume to max for bluetooth SCO
+
+ ((isVoiceVolSrc || isBtScoVolSrc) &&
+ isSingleDeviceType(deviceTypes, audio_is_bluetooth_out_sco_device))) {
volumeDb = 0.0f;
}
- outputDesc->setVolume(volumeDb, volumeSource, curves.getStreamTypes(), device, delayMs, force);
+ outputDesc->setVolume(volumeDb, volumeSource, curves.getStreamTypes(), deviceTypes, delayMs, force);
if (isVoiceVolSrc || isBtScoVolSrc) {
float voiceVolume;
- // Force voice volume to max for bluetooth SCO as volume is managed by the headset
+ // Force voice volume to max or mute for Bluetooth SCO as other attenuations are managed by the headset
if (isVoiceVolSrc) {
voiceVolume = (float)index/(float)curves.getVolumeIndexMax();
} else {
- voiceVolume = 1.0;
+ voiceVolume = index == 0 ? 0.0 : 1.0;
}
if (voiceVolume != mLastVoiceVolume) {
@@ -1360,7 +1387,8 @@
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
- std::vector<audio_io_handle_t> *secondaryOutputs)
+ std::vector<audio_io_handle_t> *secondaryOutputs,
+ output_type_t *outputType)
{
audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
audio_config_t tConfig;
@@ -1388,7 +1416,8 @@
flags,
(audio_port_handle_t*)selectedDeviceId,
portId,
- secondaryOutputs);
+ secondaryOutputs,
+ outputType);
}
audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices(
@@ -1418,9 +1447,14 @@
return 0;
}
- if (mApmConfigs->isCompressVOIPEnabled()) {
- if (stream == AUDIO_STREAM_VOICE_CALL &&
- audio_is_linear_pcm(config->format)) {
+ /*
+ * Check for VOIP Flag override for voice streams using linear pcm,
+ * but not when intended for uplink device(i.e. Telephony Tx)
+ */
+ if (stream == AUDIO_STREAM_VOICE_CALL &&
+ audio_is_linear_pcm(config->format) &&
+ !devices.onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
+ if (mApmConfigs->isCompressVOIPEnabled()) {
// let voice stream to go with primary output by default
// in case direct voip is bypassed
bool use_primary_out = true;
@@ -1464,37 +1498,14 @@
if (use_primary_out) {
*flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY);
}
- }
- } else {
- if (stream == AUDIO_STREAM_VOICE_CALL &&
- audio_is_linear_pcm(config->format) &&
- (config->channel_mask == 1) &&
- (config->sample_rate == 8000 || config->sample_rate == 16000 ||
- config->sample_rate == 32000 || config->sample_rate == 48000)) {
- //check if VoIP output is not opened already
- bool voip_pcm_already_in_use = false;
- for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if (desc->mFlags == (AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_DIRECT)) {
- //close voip output if currently open by the same client with different device
- if (desc->mDirectClientSession == session &&
- desc->devices() != devices) {
- closeOutput(desc->mIoHandle);
- } else {
- voip_pcm_already_in_use = true;
- ALOGD("VoIP PCM already in use");
- }
- break;
- }
- }
-
- if (!voip_pcm_already_in_use) {
- *flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
+ } else if ((config->channel_mask == 1 || config->channel_mask == 3) &&
+ (config->sample_rate == 8000 || config->sample_rate == 16000 ||
+ config->sample_rate == 32000 || config->sample_rate == 48000)) {
+ *flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
AUDIO_OUTPUT_FLAG_DIRECT);
- ALOGV("Set VoIP and Direct output flags for PCM format");
- }
+ ALOGV("Set VoIP and Direct output flags for PCM format");
}
- } /* compress_voip_enabled */
+ } /* voip flag override block end */
//IF VOIP is going to be started at the same time as when
//vr is enabled, get VOIP to fallback to low latency
@@ -1614,8 +1625,8 @@
* a non-music stream playback on WFD, so primary output is not reused for ringtone.
*/
if (mApmConfigs->isAFEProxyEnabled()) {
- audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
- if ((availableOutputDeviceTypes & AUDIO_DEVICE_OUT_PROXY)
+ DeviceTypeSet availableOutputDeviceTypes = mAvailableOutputDevices.types();
+ if ((deviceTypesToBitMask(availableOutputDeviceTypes) & AUDIO_DEVICE_OUT_PROXY)
&& (stream != AUDIO_STREAM_MUSIC)) {
ALOGD("WFD audio: use OUTPUT_FLAG_FAST for non music stream. flags:%x", *flags );
//For voip paths
@@ -1671,7 +1682,8 @@
// prevent direct pcm for non-music stream blindly if direct pcm already in use
// for other music stream concurrency is handled after checking direct ouput usage
// and checking client
- if (direct_pcm_already_in_use == true && stream != AUDIO_STREAM_MUSIC) {
+ if (direct_pcm_already_in_use == true && stream != AUDIO_STREAM_MUSIC &&
+ !(*flags & AUDIO_OUTPUT_FLAG_VOIP_RX)) {
ALOGD("disabling offload for non music stream as direct pcm is already in use");
*flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_NONE);
}
@@ -1690,7 +1702,7 @@
if (stream == AUDIO_STREAM_TTS) {
*flags = AUDIO_OUTPUT_FLAG_TTS;
- } else if (devices.types() == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
+ } else if (devices.onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX) &&
stream == AUDIO_STREAM_MUSIC &&
audio_is_linear_pcm(config->format) &&
isInCall()) {
@@ -1707,13 +1719,6 @@
goto non_direct_output;
}
- if (property_get_bool("vendor.audio.pcm.direct.disable", false /* default_value */) &&
- audio_is_linear_pcm(config->format)) {
- ALOGD(":%s Force route mch pcm to deep buffer", __func__);
- forced_deep = true;
- goto non_direct_output;
- }
-
// Do not allow offloading if one non offloadable effect is enabled or MasterMono is enabled.
// This prevents creating an offloaded track and tearing it down immediately after start
// when audioflinger detects there is an active non offloadable effect.
@@ -1750,17 +1755,18 @@
// if multiple concurrent offload decode is supported
// do no check for reuse and also don't close previous output if its offload
// previous output will be closed during track destruction
- if (!mApmConfigs->isAudioMultipleOffloadEnable() &&
- ((*flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0)) {
+ if (!(mApmConfigs->isAudioMultipleOffloadEnable() &&
+ ((*flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
+ ((*flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0))) {
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if (!desc->isDuplicated() && (profile == desc->mProfile)) {
outputDesc = desc;
// reuse direct output if currently open by the same client
// and configured with same parameters
- if ((config->sample_rate == desc->mSamplingRate) &&
- (config->format == desc->mFormat) &&
- (channelMask == desc->mChannelMask) &&
+ if ((config->sample_rate == desc->getSamplingRate()) &&
+ (config->format == desc->getFormat()) &&
+ (channelMask == desc->getChannelMask()) &&
(session == desc->mDirectClientSession)) {
desc->mDirectOpenCount++;
ALOGV("getOutputForDevice() reusing direct output %d for session %d",
@@ -1779,7 +1785,6 @@
outputDesc->mDirectClientSession, session);
goto non_direct_output;
}
- closeOutput(outputDesc->mIoHandle);
}
}
if (!profile->canOpenNewIo()) {
@@ -1788,20 +1793,20 @@
outputDesc =
new SwAudioOutputDescriptor(profile, mpClientInterface);
- DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(devices.types());
- String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->address()
+ DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromTypes(devices.types());
+ String8 address = outputDevices.size() > 0 ? String8(outputDevices.itemAt(0)->address().data())
: String8("");
status = outputDesc->open(config, devices, stream, *flags, &output);
// only accept an output with the requested parameters
if (status != NO_ERROR ||
- (config->sample_rate != 0 && config->sample_rate != outputDesc->mSamplingRate) ||
- (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->mFormat) ||
- (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
+ (config->sample_rate != 0 && config->sample_rate != outputDesc->getSamplingRate()) ||
+ (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->getFormat()) ||
+ (channelMask != 0 && channelMask != outputDesc->getChannelMask())) {
ALOGV("getOutputForDevice() failed opening direct output: output %d sample rate %d %d,"
"format %d %d, channel mask %04x %04x", output, config->sample_rate,
- outputDesc->mSamplingRate, config->format, outputDesc->mFormat,
- channelMask, outputDesc->mChannelMask);
+ outputDesc->getSamplingRate(), config->format, outputDesc->getFormat(),
+ channelMask, outputDesc->getChannelMask());
//Only close o/p descriptor if successfully opened
if (status == NO_ERROR) {
outputDesc->close();
@@ -1852,7 +1857,7 @@
ALOGI("FLAG None hence request for a primary output");
}
- output = selectOutput(outputs, *flags, config->format);
+ output = selectOutput(outputs, *flags, config->format, channelMask);
}
ALOGW_IF((output == 0), "getOutputForDevice() could not find output for stream %d, "
@@ -1929,17 +1934,40 @@
}
}
+ // This workaround prevents Sound Trigger capture streams from
+ // starting on USB headset. Sound Trigger is not supported on
+ // USB headset, so the capture streams should not select USB
+ // headset device. Temporarily remove USB headset devices from
+ // the available devices list while selecting device.
+ bool isSoundTrigger = inputSource == AUDIO_SOURCE_HOTWORD &&
+ mSoundTriggerSessions.indexOfKey(session) >= 0;
+ DeviceVector USBDevices = mAvailableInputDevices.getDevicesFromType(
+ AUDIO_DEVICE_IN_USB_HEADSET);
- return AudioPolicyManager::getInputForAttr(attr,
- input,
- riid,
- session,
- uid,
- config,
- flags,
- selectedDeviceId,
- inputType,
- portId);
+ if (isSoundTrigger) {
+ for (size_t i = 0; i < USBDevices.size(); i++) {
+ mAvailableInputDevices.remove(USBDevices[i]);
+ }
+ }
+
+ status_t status = AudioPolicyManager::getInputForAttr(attr,
+ input,
+ riid,
+ session,
+ uid,
+ config,
+ flags,
+ selectedDeviceId,
+ inputType,
+ portId);
+
+ if (isSoundTrigger) {
+ for (size_t i = 0; i < USBDevices.size(); i++) {
+ mAvailableInputDevices.add(USBDevices[i]);
+ }
+ }
+
+ return status;
}
uint32_t AudioPolicyManagerCustom::activeNonSoundTriggerInputsCountOnDevices(audio_devices_t devices) const
@@ -2061,10 +2089,10 @@
DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
if ((primaryInputDevices.contains(device) && (device->type() & ~AUDIO_DEVICE_BIT_IN)) != 0) {
if (mApmConfigs->isVAConcEnabled()) {
- if (activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices.types()) == 1)
- SoundTrigger::setCaptureState(true);
+ if (activeNonSoundTriggerInputsCountOnDevices(deviceTypesToBitMask(primaryInputDevices.types())) == 1)
+ mpClientInterface->setSoundTriggerCaptureState(true);
} else if (mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1)
- SoundTrigger::setCaptureState(true);
+ mpClientInterface->setSoundTriggerCaptureState(true);
}
// automatically enable the remote submix output when input is started if not
@@ -2109,8 +2137,8 @@
if (mApmConfigs->isVAConcEnabled()) {
sp<AudioInputDescriptor> inputDesc = mInputs.getInputForClient(portId);
if ((primaryInputDevices.contains(inputDesc->getDevice()) &&
- activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices.types())) == 0) {
- SoundTrigger::setCaptureState(false);
+ activeNonSoundTriggerInputsCountOnDevices(deviceTypesToBitMask(primaryInputDevices.types()))) == 0) {
+ mpClientInterface->setSoundTriggerCaptureState(false);
}
}
if (mApmConfigs->isRecPlayConcEnabled()) {
@@ -2153,4 +2181,13 @@
mFallBackflag = getFallBackPath();
}
+status_t AudioPolicyManagerCustom::dump(int fd)
+{
+ AudioPolicyManager::dump(fd);
+ String8 result;
+ mApmConfigs->dump(&result);
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
+
}
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 61f9821..494f354 100755
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2009 The Android Open Source Project
@@ -19,7 +19,6 @@
#include <audiopolicy/managerdefault/AudioPolicyManager.h>
-#include <audio_policy_conf.h>
#include <Volume.h>
#include "APMConfigHelper.h"
@@ -113,6 +112,7 @@
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_port_handle_t portId);
+ status_t dump(int fd) override;
static sp<APMConfigHelper> mApmConfigs;
protected:
@@ -120,7 +120,7 @@
virtual status_t checkAndSetVolume(IVolumeCurves &curves,
VolumeSource volumeSource, int index,
const sp<AudioOutputDescriptor>& outputDesc,
- audio_devices_t device,
+ DeviceTypeSet deviceTypes,
int delayMs = 0, bool force = false);
// avoid invalidation for active music stream on previous outputs
@@ -171,7 +171,8 @@
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
- std::vector<audio_io_handle_t> *secondaryOutputs);
+ std::vector<audio_io_handle_t> *secondaryOutputs,
+ output_type_t *outputType);