Merge "configs: sdm450: add support for VoIP over audio path"
diff --git a/configs/common_au/audio_policy_configuration.xml b/configs/common_au/audio_policy_configuration.xml
index 01fa0de..47bdc92 100644
--- a/configs/common_au/audio_policy_configuration.xml
+++ b/configs/common_au/audio_policy_configuration.xml
@@ -64,6 +64,7 @@
                 <item>Primary In Bus</item>
                 <item>Front Passenger In Bus</item>
                 <item>Rear Seat In Bus</item>
+                <item>Echo Reference</item>
             </attachedDevices>
             <defaultOutputDevice>Media Bus</defaultOutputDevice>
             <mixPorts>
@@ -281,6 +282,11 @@
                                 minValueMB="-6000" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
+                <devicePort tagName="Echo Reference" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="16000,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
             </devicePorts>
             <routes>
                 <route type="mix" sink="Media Bus"
@@ -310,7 +316,7 @@
                 <route type="mix" sink="Telephony Tx"
                        sources="voice_tx,incall_music_uplink"/>
                 <route type="mix" sink="primary input"
-                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Primary In Bus,Front Passenger In Bus,Rear Seat In Bus"/>
+                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Primary In Bus,Front Passenger In Bus,Rear Seat In Bus,Echo Reference"/>
                 <route type="mix" sink="fast input"
                        sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic"/>
                 <route type="mix" sink="voice_rx"
diff --git a/configs/lahaina/audio_platform_info.xml b/configs/lahaina/audio_platform_info.xml
index bafbb34..8d05776 100644
--- a/configs/lahaina/audio_platform_info.xml
+++ b/configs/lahaina/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2020, The Linux Foundation. All rights reserved. -->
+<!-- Copyright (c) 2014, 2016-2021, 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 -->
@@ -267,7 +267,6 @@
         <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="WSA_CDC_DMA_RX_0-and-SLIMBUS_7_RX"/>
diff --git a/configs/lahaina/audio_platform_info_hdk.xml b/configs/lahaina/audio_platform_info_hdk.xml
index 3f161bb..5902e72 100644
--- a/configs/lahaina/audio_platform_info_hdk.xml
+++ b/configs/lahaina/audio_platform_info_hdk.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.   -->
+<!-- Copyright (c) 2018-2021, 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 -->
@@ -301,7 +301,6 @@
         <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="WSA_CDC_DMA_RX_0-and-SLIMBUS_7_RX"/>
diff --git a/configs/lahaina/audio_platform_info_intcodec.xml b/configs/lahaina/audio_platform_info_intcodec.xml
index 64e6cef..8115ce2 100644
--- a/configs/lahaina/audio_platform_info_intcodec.xml
+++ b/configs/lahaina/audio_platform_info_intcodec.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2020, The Linux Foundation. All rights reserved.   -->
+<!-- Copyright (c) 2014, 2016-2021, 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 -->
@@ -302,7 +302,6 @@
         <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="WSA_CDC_DMA_RX_0-and-SLIMBUS_7_RX"/>
diff --git a/configs/lahaina/audio_platform_info_qrd.xml b/configs/lahaina/audio_platform_info_qrd.xml
index 6d45569..fd06511 100644
--- a/configs/lahaina/audio_platform_info_qrd.xml
+++ b/configs/lahaina/audio_platform_info_qrd.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.   -->
+<!-- Copyright (c) 2018-2021, 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 -->
@@ -301,7 +301,6 @@
         <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="WSA_CDC_DMA_RX_0-and-SLIMBUS_7_RX"/>
diff --git a/configs/lahaina/audio_platform_info_shimaidp.xml b/configs/lahaina/audio_platform_info_shimaidp.xml
index bb77ab4..b1edc20 100644
--- a/configs/lahaina/audio_platform_info_shimaidp.xml
+++ b/configs/lahaina/audio_platform_info_shimaidp.xml
@@ -282,7 +282,6 @@
         <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="WSA_CDC_DMA_RX_0-and-SLIMBUS_7_RX"/>
diff --git a/configs/lahaina/audio_platform_info_shimaqrd.xml b/configs/lahaina/audio_platform_info_shimaqrd.xml
index 0353a77..de717e9 100644
--- a/configs/lahaina/audio_platform_info_shimaqrd.xml
+++ b/configs/lahaina/audio_platform_info_shimaqrd.xml
@@ -284,7 +284,6 @@
         <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="WSA_CDC_DMA_RX_0-and-SLIMBUS_7_RX"/>
diff --git a/configs/lahaina/audio_platform_info_yupikidp.xml b/configs/lahaina/audio_platform_info_yupikidp.xml
index dc742ff..3ed1cee 100644
--- a/configs/lahaina/audio_platform_info_yupikidp.xml
+++ b/configs/lahaina/audio_platform_info_yupikidp.xml
@@ -302,7 +302,6 @@
         <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="WSA_CDC_DMA_RX_0-and-SLIMBUS_7_RX"/>
diff --git a/configs/lahaina/audio_platform_info_yupikqrd.xml b/configs/lahaina/audio_platform_info_yupikqrd.xml
index c6b6075..9bdcf52 100644
--- a/configs/lahaina/audio_platform_info_yupikqrd.xml
+++ b/configs/lahaina/audio_platform_info_yupikqrd.xml
@@ -284,7 +284,6 @@
         <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET" backend="speaker-and-headphones" interface="WSA_CDC_DMA_RX_0-and-RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="WSA_CDC_DMA_RX_0-and-SLIMBUS_7_RX"/>
diff --git a/configs/msm8937/audio_platform_info_sdm429w.xml b/configs/msm8937/audio_platform_info_sdm429w.xml
index 91a7a20..9509f18 100644
--- a/configs/msm8937/audio_platform_info_sdm429w.xml
+++ b/configs/msm8937/audio_platform_info_sdm429w.xml
@@ -56,6 +56,7 @@
         <param key="spkr_1_tz_name" value="wsa881x.0f"/>
         <param key="spkr_2_tz_name" value=""/>
         <param key="hfp_pcm_dev_id" value="18"/>
+        <param key="afe_loopback" value="1"/>
     </config_params>
     <acdb_ids>
         <device name="SND_DEVICE_OUT_SPEAKER_PROTECTED" acdb_id="136"/>
diff --git a/configs/msm8937/audio_platform_info_sdm429w_dvt2.xml b/configs/msm8937/audio_platform_info_sdm429w_dvt2.xml
index 8dacccf..65450e5 100644
--- a/configs/msm8937/audio_platform_info_sdm429w_dvt2.xml
+++ b/configs/msm8937/audio_platform_info_sdm429w_dvt2.xml
@@ -59,6 +59,7 @@
         <param key="spkr_2_tz_name" value=""/>
         <param key="hfp_vol_mixer_ctl" value="SLIMBUS_7 LOOPBACK Volume"/>
         <param key="hfp_pcm_dev_id" value="18"/>
+        <param key="afe_loopback" value="1"/>
     </config_params>
     <acdb_ids>
         <device name="SND_DEVICE_OUT_SPEAKER_PROTECTED" acdb_id="136"/>
diff --git a/configs/msm8937/msm8937.mk b/configs/msm8937/msm8937.mk
index 7ffe8e2..a801809 100644
--- a/configs/msm8937/msm8937.mk
+++ b/configs/msm8937/msm8937.mk
@@ -157,10 +157,10 @@
       $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_policy_configuration_sdm429w.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
    else ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
       PRODUCT_COPY_FILES += \
-      $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_policy_configuration_common.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+      $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_policy_configuration_common.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
    else
       PRODUCT_COPY_FILES += \
-      $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
+      $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
    endif
 PRODUCT_COPY_FILES += \
     $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/bluetooth_qti_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
diff --git a/configs/msmnile_au/audio_policy_configuration.xml b/configs/msmnile_au/audio_policy_configuration.xml
index 07b27d3..183206c 100644
--- a/configs/msmnile_au/audio_policy_configuration.xml
+++ b/configs/msmnile_au/audio_policy_configuration.xml
@@ -62,6 +62,7 @@
                 <item>Built-In Mic</item>
                 <item>Built-In Back Mic</item>
                 <item>FM Tuner</item>
+                <item>Echo Reference</item>
             </attachedDevices>
             <defaultOutputDevice>Media Bus</defaultOutputDevice>
             <mixPorts>
@@ -380,6 +381,11 @@
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                 </devicePort>
+                <devicePort tagName="Echo Reference" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="16000,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
 
             </devicePorts>
             <!-- route declaration, i.e. list all available sources for a given sink -->
@@ -423,7 +429,7 @@
                 <route type="mix" sink="voice_rx"
                        sources="Telephony Rx"/>
                 <route type="mix" sink="primary input"
-                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx"/>
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx,Echo Reference"/>
                 <route type="mix" sink="voip_tx"
                        sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic"/>
                 <route type="mix" sink="record_24"
diff --git a/configs/msmnile_au/mixer_paths_adp.xml b/configs/msmnile_au/mixer_paths_adp.xml
index 3c21e2e..8761181 100644
--- a/configs/msmnile_au/mixer_paths_adp.xml
+++ b/configs/msmnile_au/mixer_paths_adp.xml
@@ -1371,6 +1371,10 @@
         <ctl name="MultiMedia1 Mixer TERT_TDM_TX_0" value="1" />
     </path>
 
+    <path name="echo-reference-external">
+        <ctl name="MultiMedia2 Mixer SEC_TDM_TX_0" value="1" />
+    </path>
+
     <path name="audio-record-compress">
         <ctl name="TERT_TDM_TX_0 Channels" value="One" />
         <ctl name="MultiMedia8 Mixer TERT_TDM_TX_0" value="1" />
diff --git a/configs/msmnile_au/msmnile_au.mk b/configs/msmnile_au/msmnile_au.mk
index 8e7f833..0cc188e 100644
--- a/configs/msmnile_au/msmnile_au.mk
+++ b/configs/msmnile_au/msmnile_au.mk
@@ -101,6 +101,9 @@
 endif
 AUDIO_FEATURE_ENABLED_FM_TUNER_EXT := true
 AUDIO_FEATURE_ENABLED_ICC := true
+ifneq ( ,$(filter S 12, $(PLATFORM_VERSION)))
+AUDIO_FEATURE_ENABLED_POWER_POLICY := true
+endif
 ##AUTOMOTIVE_AUDIO_FEATURE_FLAGS
 
 ifneq ($(strip $(TARGET_USES_RRO)), true)
@@ -390,7 +393,8 @@
 vendor.audio.feature.audiozoom.enable=false \
 vendor.audio.feature.snd_mon.enable=false \
 vendor.audio.feature.auto_hal.enable=true \
-vendor.audio.feature.synth.enable=true
+vendor.audio.feature.synth.enable=true \
+vendor.audio.feature.powerpolicy.enable=true
 else
 # Non-Generic ODM varient related
 PRODUCT_ODM_PROPERTIES += \
@@ -437,7 +441,8 @@
 vendor.audio.feature.audiozoom.enable=false \
 vendor.audio.feature.snd_mon.enable=false \
 vendor.audio.feature.auto_hal.enable=true \
-vendor.audio.feature.synth.enable=true
+vendor.audio.feature.synth.enable=true \
+vendor.audio.feature.powerpolicy.enable=true
 endif
 
 # for HIDL related packages
diff --git a/configs/msmsteppe_au/audio_policy_configuration.xml b/configs/msmsteppe_au/audio_policy_configuration.xml
index e85abe1..d407262 100644
--- a/configs/msmsteppe_au/audio_policy_configuration.xml
+++ b/configs/msmsteppe_au/audio_policy_configuration.xml
@@ -62,6 +62,7 @@
                 <item>Built-In Mic</item>
                 <item>Built-In Back Mic</item>
                 <item>FM Tuner</item>
+                <item>Echo Reference</item>
             </attachedDevices>
             <defaultOutputDevice>Media Bus</defaultOutputDevice>
             <mixPorts>
@@ -380,7 +381,11 @@
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                 </devicePort>
-
+                <devicePort tagName="Echo Reference" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="16000,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
             </devicePorts>
             <!-- route declaration, i.e. list all available sources for a given sink -->
             <routes>
@@ -423,7 +428,7 @@
                 <route type="mix" sink="voice_rx"
                        sources="Telephony Rx"/>
                 <route type="mix" sink="primary input"
-                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx"/>
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx,Echo Reference"/>
                 <route type="mix" sink="voip_tx"
                        sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic"/>
                 <route type="mix" sink="record_24"
diff --git a/configs/msmsteppe_au/mixer_paths_adp.xml b/configs/msmsteppe_au/mixer_paths_adp.xml
index 2dfca35..a881aee 100644
--- a/configs/msmsteppe_au/mixer_paths_adp.xml
+++ b/configs/msmsteppe_au/mixer_paths_adp.xml
@@ -1208,6 +1208,10 @@
         <ctl name="MultiMedia1 Mixer TERT_TDM_TX_0" value="1" />
     </path>
 
+    <path name="echo-reference-external">
+        <ctl name="MultiMedia2 Mixer SEC_TDM_TX_0" value="1" />
+    </path>
+
     <path name="audio-record-compress">
         <ctl name="TERT_TDM_TX_0 Channels" value="One" />
         <ctl name="MultiMedia8 Mixer TERT_TDM_TX_0" value="1" />
diff --git a/configs/msmsteppe_au/msmsteppe_au.mk b/configs/msmsteppe_au/msmsteppe_au.mk
index 5e083bb..9d990a5 100644
--- a/configs/msmsteppe_au/msmsteppe_au.mk
+++ b/configs/msmsteppe_au/msmsteppe_au.mk
@@ -84,6 +84,9 @@
 endif
 AUDIO_FEATURE_ENABLED_FM_TUNER_EXT := true
 AUDIO_FEATURE_ENABLED_ICC := true
+ifneq ( ,$(filter S 12, $(PLATFORM_VERSION)))
+AUDIO_FEATURE_ENABLED_POWER_POLICY := true
+endif
 ##AUTOMOTIVE_AUDIO_FEATURE_FLAGS
 
 ifneq ($(strip $(TARGET_USES_RRO)), true)
@@ -366,7 +369,8 @@
 vendor.audio.feature.audiozoom.enable=false \
 vendor.audio.feature.snd_mon.enable=false \
 vendor.audio.feature.auto_hal.enable=true \
-vendor.audio.feature.synth.enable=true
+vendor.audio.feature.synth.enable=true \
+vendor.audio.feature.powerpolicy.enable=true
 else
 # Non-Generic ODM varient related
 PRODUCT_ODM_PROPERTIES += \
@@ -413,7 +417,8 @@
 vendor.audio.feature.audiozoom.enable=false \
 vendor.audio.feature.snd_mon.enable=false \
 vendor.audio.feature.auto_hal.enable=true \
-vendor.audio.feature.synth.enable=true
+vendor.audio.feature.synth.enable=true \
+vendor.audio.feature.powerpolicy.enable=true
 endif
 
 # for HIDL related packages
diff --git a/hal/audio_extn/Android.mk b/hal/audio_extn/Android.mk
index aba6592..db80656 100755
--- a/hal/audio_extn/Android.mk
+++ b/hal/audio_extn/Android.mk
@@ -1139,3 +1139,41 @@
 endif
 include $(BUILD_SHARED_LIBRARY)
 endif
+#-------------------------------------------
+
+#            Build Power_Policy_Client LIB
+#-------------------------------------------
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_POWER_POLICY)),true)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libaudiopowerpolicy
+
+LOCAL_VENDOR_MODULE := true
+
+LOCAL_SRC_FILES:= \
+        PowerPolicyClient.cpp \
+        power_policy_launcher.cpp
+
+LOCAL_C_INCLUDES:= \
+        vendor/qcom/opensource/audio-hal/primary-hal/hal \
+        system/media/audio/include
+
+LOCAL_SHARED_LIBRARIES:= \
+        android.frameworks.automotive.powerpolicy-ndk_platform \
+        libbase \
+        libbinder_ndk \
+        libcutils \
+        liblog \
+        libpowerpolicyclient
+
+ifneq ($(filter kona lahaina holi,$(TARGET_BOARD_PLATFORM)),)
+LOCAL_SANITIZE := integer_overflow
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DAEMON_SUPPORT)),true)
+  LOCAL_CFLAGS += -DDAEMON_SUPPORT_AUTO
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/hal/audio_extn/PowerPolicyClient.cpp b/hal/audio_extn/PowerPolicyClient.cpp
new file mode 100644
index 0000000..e3a9e22
--- /dev/null
+++ b/hal/audio_extn/PowerPolicyClient.cpp
@@ -0,0 +1,117 @@
+/* Copyright (c) 2021, 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
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#include "PowerPolicyClient.h"
+
+#include <android-base/logging.h>
+#include <dlfcn.h>
+
+#ifdef DAEMON_SUPPORT_AUTO
+#define LIB_AUDIO_HAL_PLUGIN "libaudiohalpluginclient.so"
+#else
+#define LIB_AUDIO_HAL_PLUGIN "libaudiohalplugin.so"
+#endif
+
+namespace aafap = aidl::android::frameworks::automotive::powerpolicy;
+
+using aafap::CarPowerPolicy;
+using aafap::CarPowerPolicyFilter;
+using aafap::PowerComponent;
+using ::android::frameworks::automotive::powerpolicy::hasComponent;
+using ::ndk::ScopedAStatus;
+
+namespace {
+
+constexpr PowerComponent kAudioComponent = PowerComponent::AUDIO;
+constexpr PowerComponent kMicComponent = PowerComponent::MICROPHONE;
+
+}  // namespace
+
+PowerPolicyClient::PowerPolicyClient() {
+    plugin_handle = dlopen(LIB_AUDIO_HAL_PLUGIN, RTLD_NOW);
+    if (plugin_handle == NULL) {
+        LOG(ERROR) << "Failed to open plugin library";
+        return;
+    }
+
+    hal_plugin_send_msg = (hal_plugin_send_msg_t) dlsym(plugin_handle,
+                                         "audio_hal_plugin_send_msg");
+    if (hal_plugin_send_msg == NULL) {
+        LOG(ERROR) << "dlsym failed for audio_hal_plugin_send_msg";
+        dlclose(plugin_handle);
+        plugin_handle = NULL;
+    }
+
+    LOG(ERROR) << "PowerPolicyClient Initialzed";
+}
+
+PowerPolicyClient::~PowerPolicyClient() {
+    if (plugin_handle != NULL)
+        dlclose(plugin_handle);
+}
+
+void PowerPolicyClient::onInitFailed() {
+    LOG(ERROR) << "Initializing power policy client failed";
+}
+
+std::vector<PowerComponent> PowerPolicyClient::getComponentsOfInterest() {
+    std::vector<PowerComponent> components{kAudioComponent, kMicComponent};
+    return components;
+}
+
+ScopedAStatus PowerPolicyClient::onPolicyChanged(const CarPowerPolicy& powerPolicy) {
+    uint8_t disable = 0;
+
+    if (hasComponent(powerPolicy.enabledComponents, kAudioComponent)) {
+        LOG(ERROR) << "Power policy: Audio component is enabled";
+        disable = 0;
+        if (hal_plugin_send_msg != NULL)
+            hal_plugin_send_msg(AUDIO_HAL_PLUGIN_MSG_SILENT_MODE,
+                                &disable, sizeof(disable));
+    } else if (hasComponent(powerPolicy.disabledComponents, kAudioComponent)) {
+        LOG(ERROR) << "Power policy: Audio component is disabled";
+        disable = 1;
+        if (hal_plugin_send_msg != NULL)
+            hal_plugin_send_msg(AUDIO_HAL_PLUGIN_MSG_SILENT_MODE,
+                                &disable, sizeof(disable));
+    }
+
+    if (hasComponent(powerPolicy.enabledComponents, kMicComponent)) {
+        LOG(ERROR) << "Power policy: Microphone component is enabled";
+        disable = 0;
+        if (hal_plugin_send_msg != NULL)
+            hal_plugin_send_msg(AUDIO_HAL_PLUGIN_MSG_MIC_STATE,
+                                &disable, sizeof(disable));
+    } else if (hasComponent(powerPolicy.disabledComponents, kMicComponent)) {
+        disable = 1;
+        if (hal_plugin_send_msg != NULL)
+            hal_plugin_send_msg(AUDIO_HAL_PLUGIN_MSG_MIC_STATE,
+                                &disable, sizeof(disable));
+        LOG(ERROR) << "Power policy: Microphone component is disabled";
+    }
+    return ScopedAStatus::ok();
+}
diff --git a/hal/audio_extn/PowerPolicyClient.h b/hal/audio_extn/PowerPolicyClient.h
new file mode 100644
index 0000000..da0b434
--- /dev/null
+++ b/hal/audio_extn/PowerPolicyClient.h
@@ -0,0 +1,53 @@
+/* Copyright (c) 2021, 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
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#ifndef QTI_AUDIO_POWERPOLICYCLIENT_H_
+#define QTI_AUDIO_POWERPOLICYCLIENT_H_
+
+#include "PowerPolicyClientBase.h"
+#include "audio_hal_plugin.h"
+
+typedef int32_t (*hal_plugin_send_msg_t) (audio_hal_plugin_msg_type_t, void*, uint32_t);
+
+class PowerPolicyClient
+    : public ::android::frameworks::automotive::powerpolicy::PowerPolicyClientBase {
+  public:
+    explicit PowerPolicyClient();
+    ~PowerPolicyClient();
+
+    void onInitFailed();
+    std::vector<::aidl::android::frameworks::automotive::powerpolicy::PowerComponent>
+    getComponentsOfInterest() override;
+    ::ndk::ScopedAStatus onPolicyChanged(
+            const ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy&) override;
+
+  private:
+        void* plugin_handle;
+        hal_plugin_send_msg_t hal_plugin_send_msg;
+};
+
+#endif  // QTI_AUDIO_POWERPOLICYCLIENT_H_
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index d3b2935..654128a 100755
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -6096,6 +6096,9 @@
 typedef int (*auto_hal_open_input_stream_t)(struct stream_in*);
 static auto_hal_open_input_stream_t auto_hal_open_input_stream;
 
+typedef int (*auto_hal_open_echo_reference_stream_t)(struct stream_in*);
+static auto_hal_open_echo_reference_stream_t auto_hal_open_echo_reference_stream;
+
 typedef bool (*auto_hal_is_bus_device_usecase_t)(audio_usecase_t);
 static auto_hal_is_bus_device_usecase_t auto_hal_is_bus_device_usecase;
 
@@ -6163,6 +6166,9 @@
             !(auto_hal_open_input_stream =
                  (auto_hal_open_input_stream_t)dlsym(
                             auto_hal_lib_handle, "auto_hal_open_input_stream")) ||
+            !(auto_hal_open_echo_reference_stream =
+                 (auto_hal_open_echo_reference_stream_t)dlsym(
+                            auto_hal_lib_handle, "auto_hal_open_echo_reference_stream")) ||
             !(auto_hal_is_bus_device_usecase =
                  (auto_hal_is_bus_device_usecase_t)dlsym(
                             auto_hal_lib_handle, "auto_hal_is_bus_device_usecase")) ||
@@ -6210,6 +6216,7 @@
     auto_hal_get_car_audio_stream_from_address = NULL;
     auto_hal_open_output_stream = NULL;
     auto_hal_open_input_stream = NULL;
+    auto_hal_open_echo_reference_stream = NULL;
     auto_hal_is_bus_device_usecase = NULL;
     auto_hal_get_audio_port = NULL;
     auto_hal_set_audio_port_config = NULL;
@@ -6293,6 +6300,12 @@
                             auto_hal_open_input_stream(in): -ENOSYS);
 }
 
+int audio_extn_auto_hal_open_echo_reference_stream(struct stream_in *in)
+{
+    return ((auto_hal_open_echo_reference_stream) ?
+                            auto_hal_open_echo_reference_stream(in): 0);
+}
+
 bool audio_extn_auto_hal_is_bus_device_usecase(audio_usecase_t uc_id)
 {
     return ((auto_hal_is_bus_device_usecase) ?
@@ -6438,7 +6451,75 @@
 
 // END: Synth ========================================================================
 
+// START: Power Policy Client ======================================================================
+#ifdef __LP64__
+#define POWER_POLICY_LIB_PATH "/vendor/lib64/libaudiopowerpolicy.so"
+#else
+#define POWER_POLICY_LIB_PATH "/vendor/lib/libaudiopowerpolicy.so"
+#endif
 
+static void* power_policy_lib_handle;
+typedef int (*launch_power_policy_t) ();
+static launch_power_policy_t launch_power_policy;
+
+static void* power_policy_thread_func(void* arg __unused) {
+    if (launch_power_policy == NULL) {
+        ALOGE("%s: Power Policy launcher is NULL", __func__);
+        goto exit;
+    }
+    ALOGD("%s: Launching Power Policy Client", __func__);
+    launch_power_policy();
+
+exit:
+    pthread_exit(NULL);
+}
+
+static int power_policy_feature_init(bool is_feature_enabled)
+{
+    pthread_t tid;
+    pthread_attr_t attr;
+
+    ALOGD("%s: Called with feature %s", __func__,
+                  is_feature_enabled ? "Enabled" : "NOT Enabled");
+    if (is_feature_enabled) {
+        // dlopen lib
+        power_policy_lib_handle = dlopen(POWER_POLICY_LIB_PATH, RTLD_NOW);
+
+        if (!power_policy_lib_handle) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        if (!(launch_power_policy = (launch_power_policy_t)dlsym(
+                                    power_policy_lib_handle, "launchPowerPolicyClient")))
+        {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        pthread_attr_init(&attr);
+        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+        if (pthread_create(&tid, &attr, power_policy_thread_func, NULL))
+        {
+            ALOGE("%s: Failed to create power policy thread", __func__);
+            goto feature_disabled;
+        }
+        ALOGD("%s:: ---- Feature Power Policy Client is Enabled ----", __func__);
+        return 0;
+    }
+
+feature_disabled:
+    if (power_policy_lib_handle) {
+        dlclose(power_policy_lib_handle);
+        power_policy_lib_handle = NULL;
+    }
+
+    launch_power_policy = NULL;
+
+    ALOGW(":: %s: ---- Feature Power Policy Client is disabled ----", __func__);
+    return -ENOSYS;
+
+// END: Power Policy Client ======================================================================
+}
 void audio_extn_feature_init()
 {
     vendor_enhanced_info = audio_extn_utils_get_vendor_enhanced_info();
@@ -6563,6 +6644,9 @@
     synth_feature_init(
         property_get_bool("vendor.audio.feature.synth.enable",
                        false));
+    power_policy_feature_init(
+        property_get_bool("vendor.audio.feature.powerpolicy.enable",
+                       false));
 }
 
 void audio_extn_set_parameters(struct audio_device *adev,
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 64b77e8..d4c8fe6 100755
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1373,6 +1373,7 @@
 int audio_extn_auto_hal_get_car_audio_stream_from_address(const char *address);
 int audio_extn_auto_hal_open_output_stream(struct stream_out *out);
 int audio_extn_auto_hal_open_input_stream(struct stream_in *in);
+int audio_extn_auto_hal_open_echo_reference_stream(struct stream_in *in);
 bool audio_extn_auto_hal_is_bus_device_usecase(audio_usecase_t uc_id);
 int audio_extn_auto_hal_get_audio_port(struct audio_hw_device *dev,
                                 struct audio_port *config);
diff --git a/hal/audio_extn/auto_hal.c b/hal/audio_extn/auto_hal.c
index 39f2838..f51bf49 100755
--- a/hal/audio_extn/auto_hal.c
+++ b/hal/audio_extn/auto_hal.c
@@ -336,6 +336,25 @@
     return ret;
 }
 
+/*
+ * Function: auto_hal_open_echo_reference_stream
+ * ---------------------------------------------
+ * opens an input stream to capture an echo reference
+ * and sets for external echo reference
+ *
+ * param *in: stream to be used for echo reference
+ *
+ * returns: 0
+ */
+int auto_hal_open_echo_reference_stream(struct stream_in *in)
+{
+    /* note: this function may be expanded in the future
+    to accommodate other echo reference sources
+    such as an internal AFE loopback. */
+    in->usecase = USECASE_AUDIO_RECORD_ECHO_REF_EXT;
+    return 0;
+}
+
 int auto_hal_open_output_stream(struct stream_out *out)
 {
     int ret = 0;
diff --git a/hal/audio_extn/ext_hw_plugin.c b/hal/audio_extn/ext_hw_plugin.c
index 571ba54..5f21c3f 100644
--- a/hal/audio_extn/ext_hw_plugin.c
+++ b/hal/audio_extn/ext_hw_plugin.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2021 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
@@ -182,6 +182,7 @@
     case USECASE_AUDIO_RECORD_COMPRESS:
     case USECASE_AUDIO_RECORD_LOW_LATENCY:
     case USECASE_AUDIO_RECORD_FM_VIRTUAL:
+    case USECASE_AUDIO_RECORD_ECHO_REF_EXT:
         *plugin_usecase = AUDIO_HAL_PLUGIN_USECASE_DEFAULT_CAPTURE;
         break;
     case USECASE_AUDIO_HFP_SCO:
diff --git a/hal/audio_extn/power_policy_launcher.cpp b/hal/audio_extn/power_policy_launcher.cpp
new file mode 100644
index 0000000..a85f30c
--- /dev/null
+++ b/hal/audio_extn/power_policy_launcher.cpp
@@ -0,0 +1,51 @@
+/* Copyright (c) 2021, 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
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#include "PowerPolicyClient.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <log/log.h>
+
+extern "C" {
+
+    int launchPowerPolicyClient() {
+        ALOGD("%s: power policy launcher called", __func__);
+        ABinderProcess_setThreadPoolMaxThreadCount(0);
+        std::shared_ptr<PowerPolicyClient> powerPolicyClient =
+                ::ndk::SharedRefBase::make<PowerPolicyClient>();
+        ALOGD("%s:Instantiating power policy client from launcher", __func__);
+        powerPolicyClient->init();
+        ALOGD("%s: Power Policy class inited, joining threadpool", __func__);
+
+        ABinderProcess_joinThreadPool();
+
+        LOG(ERROR) << "Error in PowerPolicyClient binder thread";
+        return EXIT_FAILURE; // should not reach
+    }
+}
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index a97ccf0..330c9cb 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, 2016-2020, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2016-2021, 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
@@ -561,7 +561,7 @@
     struct stream_in *active_input = adev_get_active_input(st_dev->adev);
     audio_source_t  source = (active_input == NULL) ?
                                AUDIO_SOURCE_DEFAULT : active_input->source;
-    if (st_dev->adev->mode == AUDIO_MODE_IN_CALL) {
+    if (voice_is_call_state_active_in_call(st_dev->adev)) {
         ev_info.u.usecase.type = USECASE_TYPE_VOICE_CALL;
     } else if ((st_dev->adev->mode == AUDIO_MODE_IN_COMMUNICATION ||
                 source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
diff --git a/hal/audio_hal_plugin.h b/hal/audio_hal_plugin.h
index 3d77b23..1f56a2f 100644
--- a/hal/audio_hal_plugin.h
+++ b/hal/audio_hal_plugin.h
@@ -87,6 +87,7 @@
     AUDIO_HAL_PLUGIN_MSG_CODEC_GET_PP_EQ_SUBBANDS, /**< get EQ subbands params */
     AUDIO_HAL_PLUGIN_MSG_CODEC_TUNNEL_GET_CMD, /**< pass through get cmds */
     AUDIO_HAL_PLUGIN_MSG_SILENT_MODE, /**<set silent boot mode */
+    AUDIO_HAL_PLUGIN_MSG_MIC_STATE, /**< enable or disable codec mic */
     AUDIO_HAL_PLUGIN_MSG_MAX
 } audio_hal_plugin_msg_type_t;
 
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 83c35c7..a88fd5a 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -428,6 +428,7 @@
     [USECASE_AUDIO_RECORD_BUS_FRONT_PASSENGER] = "front-passenger-record",
     [USECASE_AUDIO_RECORD_BUS_REAR_SEAT] = "rear-seat-record",
     [USECASE_AUDIO_PLAYBACK_SYNTHESIZER] = "synth-loopback",
+    [USECASE_AUDIO_RECORD_ECHO_REF_EXT] = "echo-reference-external",
 };
 
 static const audio_usecase_t offload_usecases[] = {
@@ -3426,6 +3427,7 @@
     pthread_mutex_lock(&out->latch_lock);
     out->offload_state = OFFLOAD_STATE_IDLE;
     pthread_mutex_unlock(&out->latch_lock);
+
     out->playback_started = 0;
     out->send_new_metadata = 1;
     if (out->compr != NULL) {
@@ -7749,6 +7751,7 @@
 #ifdef AUDIO_GKI_ENABLED
     __s32 *generic_dec;
 #endif
+    pthread_mutexattr_t latch_attr;
 
     if (is_usb_dev && (!audio_extn_usb_connected(NULL))) {
         is_usb_dev = false;
@@ -7778,7 +7781,10 @@
 
     pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
     pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
-    pthread_mutex_init(&out->latch_lock, (const pthread_mutexattr_t *) NULL);
+    pthread_mutexattr_init(&latch_attr);
+    pthread_mutexattr_settype(&latch_attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&out->latch_lock, &latch_attr);
+    pthread_mutexattr_destroy(&latch_attr);
     pthread_mutex_init(&out->position_query_lock, (const pthread_mutexattr_t *) NULL);
     pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
 
@@ -9480,6 +9486,11 @@
         }
     }
 
+    /* reassign use case for echo reference stream on automotive platforms */
+    if (in->source == AUDIO_SOURCE_ECHO_REFERENCE) {
+        ret = audio_extn_auto_hal_open_echo_reference_stream(in);
+    }
+
     if (in->source == AUDIO_SOURCE_FM_TUNER) {
         if(!get_usecase_from_list(adev, USECASE_AUDIO_RECORD_FM_VIRTUAL))
             in->usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
@@ -10455,10 +10466,12 @@
                     if (out->offload_state == OFFLOAD_STATE_PLAYING)
                         compress_pause(out->compr);
                     out_set_compr_volume(&out->stream, (float)0, (float)0);
-                } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
-                    out_set_voip_volume(&out->stream, (float)0, (float)0);
                 } else {
-                    out_set_pcm_volume(&out->stream, (float)0, (float)0);
+                    if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP)
+                        out_set_voip_volume(&out->stream, (float)0, (float)0);
+                    else
+                        out_set_pcm_volume(&out->stream, (float)0, (float)0);
+
                     /* wait for stale pcm drained before switching to speaker */
                     uint32_t latency =
                         (out->config.period_count * out->config.period_size * 1000) /
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 8caefe8..18f081b 100755
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -250,6 +250,9 @@
 
     USECASE_AUDIO_PLAYBACK_SYNTHESIZER,
 
+    /* Echo reference capture usecases */
+    USECASE_AUDIO_RECORD_ECHO_REF_EXT,
+
     /*Audio FM Tuner usecase*/
     USECASE_AUDIO_FM_TUNER_EXT,
     /*voip usecase with low latency path*/
@@ -392,11 +395,12 @@
     pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
     pthread_cond_t  cond;
     /* stream_out->lock is of large granularity, and can only be held before device lock
-     * latch is a supplemetary lock to protect certain fields of out stream and
-     * it can be held after device lock
+     * latch is a supplemetary lock to protect certain fields of out stream (such as
+     * offload_state, a2dp_muted, to add any stream member that needs to be accessed
+     * with device lock held) and it can be held after device lock
      */
     pthread_mutex_t latch_lock;
-    pthread_mutex_t position_query_lock; /* sychronize frame written */
+    pthread_mutex_t position_query_lock;
     struct pcm_config config;
     struct compr_config compr_config;
     struct pcm *pcm;
@@ -424,7 +428,7 @@
 
     int non_blocking;
     int playback_started;
-    int offload_state;
+    int offload_state; /* guarded by latch_lock */
     pthread_cond_t offload_cond;
     pthread_t offload_thread;
     struct listnode offload_cmd_list;
@@ -466,7 +470,7 @@
     qahwi_stream_out_t qahwi_out;
 
     bool is_iec61937_info_available;
-    bool a2dp_muted;
+    bool a2dp_muted; /* guarded by latch_lock */
     float volume_l;
     float volume_r;
     bool apply_volume;
@@ -802,6 +806,7 @@
 audio_usecase_t get_usecase_id_from_usecase_type(const struct audio_device *adev,
                                                  usecase_type_t type);
 
+/* adev lock held */
 int check_a2dp_restore_l(struct audio_device *adev, struct stream_out *out, bool restore);
 
 int adev_open_output_stream(struct audio_hw_device *dev,
@@ -859,7 +864,8 @@
 
 /*
  * NOTE: when multiple mutexes have to be acquired, always take the
- * stream_in or stream_out mutex first, followed by the audio_device mutex.
+ * stream_in or stream_out mutex first, followed by the audio_device mutex
+ * and latch at last.
  */
 
 #endif // QCOM_AUDIO_HW_H
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index e97fd5c..d30e777 100755
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -537,6 +537,7 @@
     [USECASE_AUDIO_RECORD_BUS_FRONT_PASSENGER] = {FRONT_PASSENGER_PCM_DEVICE, FRONT_PASSENGER_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_BUS_REAR_SEAT] = {REAR_SEAT_PCM_DEVICE, REAR_SEAT_PCM_DEVICE},
     [USECASE_AUDIO_PLAYBACK_SYNTHESIZER] = {-1, -1},
+    [USECASE_AUDIO_RECORD_ECHO_REF_EXT] = {MULTIMEDIA2_PCM_DEVICE, MULTIMEDIA2_PCM_DEVICE},
 };
 
 /* Array to store sound devices */
@@ -803,6 +804,7 @@
     [SND_DEVICE_IN_CALL_PROXY] = "call-proxy-in",
     [SND_DEVICE_IN_ICC] = "speaker-mic",
     [SND_DEVICE_IN_SYNTH_MIC] = "speaker-mic",
+    [SND_DEVICE_IN_ECHO_REFERENCE] = "echo-reference",
 };
 
 // Platform specific backend bit width table
@@ -1040,6 +1042,7 @@
     [SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC_AEC] = 162,
     [SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MULTI_CHANNEL_MIC] = 162,
     [SND_DEVICE_IN_CAPTURE_FM] = 0,
+    [SND_DEVICE_IN_ECHO_REFERENCE] = 100,
     [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
     [SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = 105,
     [SND_DEVICE_IN_QUAD_MIC] = 46,
@@ -1294,6 +1297,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MULTI_CHANNEL_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_FM)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_ECHO_REFERENCE)},
     {TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
@@ -2680,6 +2684,7 @@
     hw_interface_table[SND_DEVICE_OUT_ICC] = strdup("TERT_TDM_RX_0");
     hw_interface_table[SND_DEVICE_OUT_SYNTH_SPKR] = strdup("TERT_TDM_RX_0");
     hw_interface_table[SND_DEVICE_IN_SYNTH_MIC] = strdup("TERT_TDM_TX_0");
+    hw_interface_table[SND_DEVICE_IN_ECHO_REFERENCE] = strdup("SEC_TDM_TX_0");
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
 
      /*remove ALAC & APE from DSP decoder list based on software decoder availability*/
@@ -7566,6 +7571,9 @@
         }
     } else if (source == AUDIO_SOURCE_FM_TUNER) {
         snd_device = SND_DEVICE_IN_CAPTURE_FM;
+    } else if ((source == AUDIO_SOURCE_ECHO_REFERENCE) &&
+        (uc_id == USECASE_AUDIO_RECORD_ECHO_REF_EXT)) {
+        snd_device = SND_DEVICE_IN_ECHO_REFERENCE;
     } else if (source == AUDIO_SOURCE_DEFAULT) {
         goto exit;
     }
@@ -7639,6 +7647,9 @@
             snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
         } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_FM_TUNER)) {
             snd_device = SND_DEVICE_IN_CAPTURE_FM;
+        } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_ECHO_REFERENCE) &&
+            (uc_id == USECASE_AUDIO_RECORD_ECHO_REF_EXT)) {
+            snd_device = SND_DEVICE_IN_ECHO_REFERENCE;
         } else if (audio_extn_usb_connected(NULL) &&
                    is_usb_in_device_type(&in_devices)) {
             snd_device = fixup_usb_headset_mic_snd_device(platform,
@@ -9040,6 +9051,13 @@
 /* Delay in Us */
 int64_t platform_get_audio_source_delay(audio_source_t audio_source)
 {
+    if (audio_source == AUDIO_SOURCE_ECHO_REFERENCE) {
+        /* return 0 because audio source delay is not
+        currently implemented on automotive in the
+        audio_platform_info.xml */
+        return 0;
+    }
+
     if ((audio_source < AUDIO_SOURCE_DEFAULT) ||
             (audio_source > AUDIO_SOURCE_MAX)) {
         ALOGE("%s: Invalid audio_source = %d", __func__, audio_source);
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 5f67510..07cf8be 100755
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -364,6 +364,7 @@
     SND_DEVICE_IN_CALL_PROXY,
     SND_DEVICE_IN_ICC,
     SND_DEVICE_IN_SYNTH_MIC,
+    SND_DEVICE_IN_ECHO_REFERENCE,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,