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);