Merge "configs: lito: update backend in handset device for lito qrd"
diff --git a/configs/lito/audio_configs.xml b/configs/lito/audio_configs.xml
new file mode 100644
index 0000000..bcc617d
--- /dev/null
+++ b/configs/lito/audio_configs.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+Copyright (c) 2019, 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.
+-->
+<configs>
+        <!-- APM Configs -->
+        <property name="audio.deep_buffer.media" value="true"/>
+        <property name="audio.offload.disable" value="false"/>
+        <property name="audio.offload.min.duration.secs" value="60"/>
+        <property name="audio.offload.video" value="true"/>
+        <property name="persist.vendor.audio.sva.conc.enabled" value="false"/>
+        <property name="persist.vendor.audio.va_concurrency_enabled" value="false"/>
+        <property name="vendor.audio.av.streaming.offload.enable" value="false"/>
+        <property name="vendor.audio.offload.track.enable" value="true"/>
+        <property name="vendor.audio.offload.multiple.enabled" value="false"/>
+        <property name="vendor.audio.rec.playback.conc.disabled" value="false"/>
+        <property name="vendor.voice.conc.fallbackpath" value=""/>
+        <property name="vendor.voice.dsd.playback.conc.disabled" value="true"/>
+        <property name="vendor.voice.path.for.pcm.voip" value="true"/>
+        <property name="vendor.voice.playback.conc.disabled" value="false"/>
+        <property name="vendor.voice.record.conc.disabled" value="false"/>
+        <property name="vendor.voice.voip.conc.disabled" value="false"/>
+        <flag name="audio_extn_formats_enabled" value="true" />
+        <flag name="audio_extn_hdmi_spk_enabled" value="true" />
+        <flag name="use_xml_audio_policy_conf" value="true" />
+        <flag name="voice_concurrency" value="false" />
+
+        <!-- AV Configs -->
+        <property name="vendor.audio.use.sw.alac.decoder" value="true"/>
+        <property name="vendor.audio.use.sw.ape.decoder" value="true"/>
+        <property name="vendor.audio.use.sw.mpegh.decoder" value="false"/>
+        <property name="vendor.audio.flac.sw.decoder.24bit" value="true"/>
+        <property name="vendor.audio.hw.aac.encoder" value="true"/>
+        <flag name="aac_adts_offload_enabled" value="true" />
+        <flag name="alac_offload_enabled" value="true" />
+        <flag name="ape_offload_enabled" value="true" />
+        <flag name="flac_offload_enabled" value="true" />
+        <flag name="pcm_offload_enabled_16" value="true" />
+        <flag name="pcm_offload_enabled_24" value="true" />
+        <flag name="qti_flac_decoder" value="true" />
+        <flag name="vorbis_offload_enabled" value="true" />
+        <flag name="wma_offload_enabled" value="true" />
+
+        <!-- AHAL Configs -->
+        <flag name="a2dp_offload_enabled" value="true" />
+        <flag name="anc_headset_enabled" value="true" />
+        <flag name="audiosphere_enabled" value="true" />
+        <flag name="audio_zoom_enabled" value="false" />
+        <flag name="battery_listener_enabled" value="true" />
+        <flag name="compress_capture_enabled" value="false" />
+        <flag name="compress_in_enabled" value="true" />
+        <flag name="compress_metadata_needed" value="true" />
+        <flag name="concurrent_capture_enabled" value="true" />
+        <flag name="custom_stereo_enabled" value="true" />
+        <flag name="display_port_enabled" value="true" />
+        <flag name="dsm_feedback_enabled" value="false" />
+        <flag name="dynamic_ecns_enabled" value="true" />
+        <flag name="ext_hw_plugin_enabled" value="true" />
+        <flag name="ext_qdsp_enabled" value="false" />
+        <flag name="ext_spkr_enabled" value="false" />
+        <flag name="ext_spkr_tfa_enabled" value="false" />
+        <flag name="fluence_enabled" value="true" />
+        <flag name="hdmi_edid_enabled" value="true" />
+        <flag name="hdmi_passthrough_enabled" value="true" />
+        <flag name="hfp_enabled" value="true" />
+        <flag name="hifi_audio_enabled" value="false" />
+        <flag name="hwdep_cal_enabled" value="false" />
+        <flag name="incall_music_enabled" value="true" />
+        <flag name="keep_alive_enabled" value="true" />
+        <flag name="kpi_optimize_enabled" value="true" />
+        <flag name="maxx_audio_enabled" value="false" />
+        <flag name="receiver_aided_stereo" value="true" />
+        <flag name="snd_monitor_enabled" value="true" />
+        <flag name="source_track_enabled" value="true" />
+        <flag name="spkr_prot_enabled" value="true" />
+        <flag name="ssrec_enabled" value="true" />
+        <flag name="usb_offload_burst_mode" value="true" />
+        <flag name="usb_offload_enabled" value="true" />
+        <flag name="usb_offload_sidetone_vol_enabled" value="false" />
+        <flag name="use_deep_buffer_as_primary_output" value="false" />
+        <flag name="vbat_enabled" value="true" />
+        <flag name="wsa_enabled" value="false" />
+
+        <!-- Common configs between APM and AHAL -->
+        <flag name="afe_proxy_enabled" value="true" />
+        <flag name="compress_voip_enabled" value="false" />
+        <flag name="fm_power_opt" value="true" />
+        <flag name="record_play_concurrency" value="false" />
+</configs>
diff --git a/configs/lito/audio_configs_stock.xml b/configs/lito/audio_configs_stock.xml
new file mode 100644
index 0000000..e26ef14
--- /dev/null
+++ b/configs/lito/audio_configs_stock.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+Copyright (c) 2019, 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.
+-->
+<configs>
+        <!-- AHAL Configs -->
+        <flag name="a2dp_offload_enabled" value="true" />
+        <flag name="afe_proxy_enabled" value="false" />
+        <flag name="anc_headset_enabled" value="false" />
+        <flag name="audio_zoom_enabled" value="false" />
+        <flag name="audiosphere_enabled" value="false" />
+        <flag name="battery_listener_enabled" value="false" />
+        <flag name="compress_capture_enabled" value="false" />
+        <flag name="compress_in_enabled" value="false" />
+        <flag name="compress_metadata_needed" value="false" />
+        <flag name="compress_voip_enabled" value="false" />
+        <flag name="concurrent_capture_enabled" value="true" />
+        <flag name="custom_stereo_enabled" value="false" />
+        <flag name="display_port_enabled" value="false" />
+        <flag name="dsm_feedback_enabled" value="false" />
+        <flag name="dynamic_ecns_enabled" value="false" />
+        <flag name="ext_hw_plugin_enabled" value="false" />
+        <flag name="ext_qdsp_enabled" value="true" />
+        <flag name="ext_spkr_enabled" value="true" />
+        <flag name="ext_spkr_tfa_enabled" value="false" />
+        <flag name="fluence_enabled" value="false" />
+        <flag name="fm_power_opt" value="false" />
+        <flag name="hdmi_edid_enabled" value="false" />
+        <flag name="hdmi_passthrough_enabled" value="false" />
+        <flag name="hfp_enabled" value="true" />
+        <flag name="hifi_audio_enabled" value="false" />
+        <flag name="hwdep_cal_enabled" value="true" />
+        <flag name="incall_music_enabled" value="true" />
+        <flag name="keep_alive_enabled" value="false" />
+        <flag name="kpi_optimize_enabled" value="false" />
+        <flag name="receiver_aided_stereo" value="false" />
+        <flag name="record_play_concurrency" value="false" />
+        <flag name="snd_monitor_enabled" value="true" />
+        <flag name="source_track_enabled" value="false" />
+        <flag name="spkr_prot_enabled" value="true" />
+        <flag name="ssrec_enabled" value="false" />
+        <flag name="usb_offload_burst_mode" value="false" />
+        <flag name="usb_offload_enabled" value="true" />
+        <flag name="usb_offload_sidetone_vol_enabled" value="false" />
+        <flag name="use_deep_buffer_as_primary_output" value="false" />
+        <flag name="vbat_enabled" value="false" />
+        <flag name="wsa_enabled" value="false" />
+</configs>
diff --git a/configs/lito/audio_io_policy.conf b/configs/lito/audio_io_policy.conf
index 350fe11..7e00464 100644
--- a/configs/lito/audio_io_policy.conf
+++ b/configs/lito/audio_io_policy.conf
@@ -84,16 +84,22 @@
 }
 
 inputs {
+  record_16bit {
+    formats AUDIO_FORMAT_PCM_16_BIT
+    sampling_rates 8000|16000|32000|44100|48000|88200|96000|176400|192000
+    bit_width 16
+    app_type 69938
+  }
   record_24bit {
     formats AUDIO_FORMAT_PCM_24_BIT_PACKED|AUDIO_FORMAT_PCM_24_BIT
     sampling_rates 44100|48000|88200|96000|176400|192000
     bit_width 24
-    app_type 69938
+    app_type 69948
   }
   record_32bit {
     formats AUDIO_FORMAT_PCM_32_BIT|AUDIO_FORMAT_PCM_FLOAT
     sampling_rates 44100|48000|88200|96000|176400|192000
     bit_width 32
-    app_type 69938
+    app_type 69949
   }
 }
diff --git a/configs/lito/audio_policy_configuration.xml b/configs/lito/audio_policy_configuration.xml
index f98f9d2..50920b3 100644
--- a/configs/lito/audio_policy_configuration.xml
+++ b/configs/lito/audio_policy_configuration.xml
@@ -262,15 +262,18 @@
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
-                <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink">
+                <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
-                <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink">
+                <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
-                <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink">
+                <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
diff --git a/configs/lito/lito.mk b/configs/lito/lito.mk
index f307de9..096c6de 100644
--- a/configs/lito/lito.mk
+++ b/configs/lito/lito.mk
@@ -1,12 +1,22 @@
 #BOARD_USES_GENERIC_AUDIO := true
 #
 #AUDIO_FEATURE_FLAGS
+ifeq ($(TARGET_USES_QMAA_OVERRIDE_AUDIO), false)
+ifeq ($(TARGET_USES_QMAA),true)
+AUDIO_USE_STUB_HAL := true
+endif
+endif
+
+ifneq ($(AUDIO_USE_STUB_HAL), true)
 BOARD_USES_ALSA_AUDIO := true
 TARGET_USES_AOSP_FOR_AUDIO := false
 
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 USE_CUSTOM_AUDIO_POLICY := 1
+AUDIO_FEATURE_QSSI_COMPLIANCE := false
 AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
+AUDIO_FEATURE_ENABLED_COMPRESS_INPUT := true
+AUDIO_FEATURE_ENABLED_CONCURRENT_CAPTURE := true
 AUDIO_FEATURE_ENABLED_COMPRESS_VOIP := false
 AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS := true
 AUDIO_FEATURE_ENABLED_EXTN_FORMATS := true
@@ -30,18 +40,18 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := true
+AUDIO_FEATURE_ENABLED_AHAL_EXT := true
 DOLBY_ENABLE := false
 endif
 
-USE_XML_AUDIO_POLICY_CONF := 1
 AUDIO_FEATURE_ENABLED_DLKM := true
 BOARD_SUPPORTS_SOUND_TRIGGER := true
 BOARD_SUPPORTS_GCS := false
 AUDIO_FEATURE_ENABLED_INSTANCE_ID := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -86,8 +96,11 @@
     vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
     vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
     vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/sound_trigger_mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_qrd.xml \
-    vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
     vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/audio_configs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_configs.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/audio_configs_stock.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_configs_stock.xml \
+    frameworks/native/data/etc/android.hardware.audio.pro.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.audio.pro.xml
 
 #XML Audio configuration files
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
@@ -118,6 +131,11 @@
 persist.vendor.audio.fluence.speaker=true\
 persist.vendor.audio.fluence.tmic.enabled=false
 
+##speaker protection v3 switch and ADSP AFE API version
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.vendor.audio.spv3.enable=true\
+persist.vendor.audio.avs.afe_api_version=2
+
 #disable tunnel encoding
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.tunnel.encode=false
@@ -187,6 +205,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac-ldac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -221,10 +251,29 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.adm.buffering.ms=2
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+endif
+
+USE_XML_AUDIO_POLICY_CONF := 1
+
 #enable keytone FR
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.hal.output.suspend.supported=true
 
+#Enable AAudio MMAP/NOIRQ data path
+#2 is AAUDIO_POLICY_AUTO so it will try MMAP then fallback to Legacy path
+PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_policy=2
+#Allow EXCLUSIVE then fall back to SHARED.
+PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_exclusive_policy=2
+PRODUCT_PROPERTY_OVERRIDES += aaudio.hw_burst_min_usec=2000
+
+
 #enable mirror-link feature
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.enable.mirrorlink=false
@@ -248,4 +297,14 @@
     android.hardware.audio.common@4.0-util \
     android.hardware.audio@4.0-impl \
     android.hardware.audio.effect@4.0 \
-    android.hardware.audio.effect@4.0-impl
+    android.hardware.audio.effect@4.0-impl \
+    vendor.qti.hardware.audiohalext@1.0 \
+    vendor.qti.hardware.audiohalext@1.0-impl \
+    vendor.qti.hardware.audiohalext-utils
+
+PRODUCT_PACKAGES_ENG += \
+    VoicePrintTest \
+    VoicePrintDemo
+
+PRODUCT_PACKAGES_DEBUG += \
+    AudioSettings
diff --git a/configs/msmnile/mixer_paths_tavil.xml b/configs/msmnile/mixer_paths_tavil.xml
index 7ce3652..c8e22e8 100644
--- a/configs/msmnile/mixer_paths_tavil.xml
+++ b/configs/msmnile/mixer_paths_tavil.xml
@@ -2303,6 +2303,11 @@
         <path name="amic2" />
     </path>
 
+    <path name="voice-headset-mic-qrd">
+        <path name="amic2" />
+        <ctl name="DEC0 Volume" value="84" />
+    </path>
+
     <path name="speaker-and-headphones">
         <path name="headphones" />
         <path name="speaker" />
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 0d58df6..fa3af6e 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -710,9 +710,9 @@
     uint32_t bit_rate; /*303000,606000,909000(in bits per second)*/
     uint16_t channel_mode; /* 0, 4, 2, 1*/
     uint16_t mtu; /*679*/
+    uint32_t bits_per_sample;
     bool is_abr_enabled;
     struct quality_level_to_bitrate_info level_to_bitrate_map;
-    uint32_t bits_per_sample;
 } audio_ldac_encoder_config;
 
 /* Information about BT AAC decoder configuration
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
index 11578fc..9e460f0 100644
--- a/hal/audio_extn/sndmonitor.c
+++ b/hal/audio_extn/sndmonitor.c
@@ -223,7 +223,8 @@
             (strncasecmp(card_id, "trinket", 7) != 0) &&
             (strncasecmp(card_id, "apq", 3) != 0) &&
             (strncasecmp(card_id, "sa", 2) != 0) &&
-            (strncasecmp(card_id, "kona", 4) != 0)) {
+            (strncasecmp(card_id, "kona", 4) != 0) &&
+            (strncasecmp(card_id, "lito", 4) != 0)) {
             ALOGW("Skip over non-ADSP snd card %s", card_id);
             continue;
         }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index abd1aba..2343603 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3471,6 +3471,11 @@
                                    &(adev->haptics_config));
             // failure to open haptics pcm shouldnt stop audio,
             // so do not close audio pcm in case of error
+
+            if (property_get_bool("vendor.audio.enable_haptic_audio_sync", false)) {
+                ALOGD("%s: enable haptic audio synchronization", __func__);
+                platform_set_qtime(adev->platform, out->pcm_device_id, adev->haptic_pcm_device_id);
+            }
         }
 
         if (!out->realtime)
@@ -4205,7 +4210,8 @@
          */
         if ((out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
                 (val == AUDIO_DEVICE_NONE) &&
-                !audio_extn_a2dp_source_is_ready()) {
+                !audio_extn_a2dp_source_is_ready() &&
+                !adev->bt_sco_on) {
                 val = AUDIO_DEVICE_OUT_SPEAKER;
         }
         /*
diff --git a/hal/msm8974/hw_info.c b/hal/msm8974/hw_info.c
index 3ccb9fb..e77ab83 100755
--- a/hal/msm8974/hw_info.c
+++ b/hal/msm8974/hw_info.c
@@ -235,6 +235,7 @@
     SND_DEVICE_OUT_HANDSET,
     SND_DEVICE_OUT_VOICE_HANDSET,
     SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
+    SND_DEVICE_IN_VOICE_HEADSET_MIC,
     SND_DEVICE_IN_HANDSET_MIC,
     SND_DEVICE_IN_HANDSET_MIC_AEC,
     SND_DEVICE_IN_HANDSET_MIC_NS,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index e02b9f0..6437009 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -95,6 +95,10 @@
 
 #include <resolv.h>
 
+#define QTIME_FREQ_KHZ  19200
+#define IPC_ERROR_DELAY 10000
+
+#define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
 #define TOSTRING_(x) #x
@@ -3974,6 +3978,186 @@
     return HAPTICS_PCM_DEVICE;
 }
 
+uint64_t getQtime()
+{
+    uint64_t qTimerCount = 0;
+
+#if __aarch64__
+    asm volatile("mrs %0, cntvct_el0" : "=r" (qTimerCount));
+#else
+    asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (qTimerCount));
+#endif
+
+    return qTimerCount;
+}
+
+int platform_get_delay(void *platform, int pcm_device_id)
+{
+    int ctl_len = 0;
+    struct audio_device *adev = ((struct platform_data *)platform)->adev;
+    struct mixer_ctl *ctl = NULL;
+    const char *mixer_ctl_name = "ADSP Path Latency";
+    const char *deviceNo = "NN";
+    char *mixer_str = NULL;
+    int path_delay = 0;
+
+    if (NULL == platform) {
+        ALOGE("%s: platform is NULL", __func__);
+        return -EINVAL;
+    }
+    if (pcm_device_id <= 0) {
+        ALOGE("%s: invalid pcm device id: %d", __func__, pcm_device_id);
+        return -EINVAL;
+    }
+
+    // Mixer control format: "ADSP Path Latency NN"
+    ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
+
+    mixer_str = (char*) calloc(ctl_len, sizeof(char));
+    if (!mixer_str) {
+        ALOGE("%s: Could not allocate memory", __func__);
+        return -ENOMEM;
+    }
+
+    snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, pcm_device_id);
+
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_str);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, mixer_str);
+        free(mixer_str);
+        return -EINVAL;
+    }
+
+    path_delay = mixer_ctl_get_value(ctl, 0);
+    if (path_delay < 0) {
+        ALOGE("%s: Could not get val for mixer cmd - %s", __func__, mixer_str);
+    }
+    ALOGD("%s: Path Delay: %d", __func__, path_delay);
+
+    free(mixer_str);
+    return path_delay;
+}
+
+int send_qtime(void *platform, uint64_t qtime_value, int pcm_device_id)
+{
+    int ret = 0;
+    int ctl_len = 0;
+    struct audio_device *adev = ((struct platform_data *)platform)->adev;
+    struct mixer_ctl *ctl = NULL;
+    const char *mixer_ctl_name = "QTimer";
+    const char *deviceNo = "NN";
+    char *mixer_str = NULL;
+    uint32_t set_values[2];
+
+    set_values[0] = (uint32_t)qtime_value;
+    set_values[1] = (uint32_t)((qtime_value >> 16) >> 16);
+    ALOGD("%s: Send qtime msw: %u, lsw: %u", __func__, set_values[1],
+          set_values[0]);
+
+    // Mixer control format: "Qtimer NN"
+    ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
+
+    mixer_str = (char*) calloc(ctl_len, sizeof(char));
+    if (!mixer_str) {
+        ALOGE("%s: Could not allocate memory", __func__);
+        return -ENOMEM;
+    }
+
+    snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, pcm_device_id);
+
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_str);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s",
+              __func__, mixer_str);
+        free(mixer_str);
+        return -EINVAL;
+    }
+
+    ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+    if (ret < 0) {
+        ALOGE("%s: Could not set array for mixer cmd - %s",
+              __func__, mixer_str);
+    }
+    free(mixer_str);
+
+    return ret;
+}
+
+int platform_set_qtime(void *platform, int audio_pcm_device_id,
+                        int haptic_pcm_device_id)
+{
+    int ret = 0;
+    uint64_t qtime_count = 0;
+    uint64_t qtime_value = 0;
+    uint32_t qtime_remainder = 0;
+    int32_t audio_path_latency = 0;
+    int32_t haptic_path_latency = 0;
+
+    if (NULL == platform) {
+        ALOGE("%s: platform is NULL", __func__);
+        return -EINVAL;
+    }
+    if (audio_pcm_device_id <= 0 || haptic_pcm_device_id <= 0) {
+        ALOGE("%s: Invalid pcm device id - %d", __func__,
+              audio_pcm_device_id <= 0 ? audio_pcm_device_id
+              : haptic_pcm_device_id);
+        return -EINVAL;
+    }
+
+    audio_path_latency = platform_get_delay(platform, audio_pcm_device_id);
+    if (audio_path_latency <= 0) {
+        ALOGE("%s: error getting audio path latency: %d", __func__,
+              audio_path_latency);
+        return -EINVAL;
+    }
+    ALOGD("%s: Audio Path Latency: %d", __func__, audio_path_latency);
+
+    haptic_path_latency = platform_get_delay(platform, haptic_pcm_device_id);
+    if (haptic_path_latency <= 0) {
+        ALOGE("%s: error getting haptic path latency: %d", __func__,
+              haptic_path_latency);
+        return -EINVAL;
+    }
+    ALOGD("%s: Haptic Path Latency: %d", __func__, haptic_path_latency);
+
+    qtime_count = getQtime();
+
+    // Qtime count / Qtime freq (KHZ) = Qtime in milliseconds
+    qtime_value = (uint64_t) (qtime_count / QTIME_FREQ_KHZ);
+
+    // Convert Qtime to microseconds
+    qtime_value *= 1000;
+
+    // Adding max(path_latency)
+    qtime_value += (uint32_t) max(audio_path_latency, haptic_path_latency);
+
+    // Adding IPC delay + error correction ~10ms
+    qtime_value += IPC_ERROR_DELAY;
+
+    // Calculate remainder in microseconds
+    qtime_remainder = ((qtime_count % QTIME_FREQ_KHZ) * 1000) / QTIME_FREQ_KHZ;
+
+    // Add the remainder to qtime
+    qtime_value += qtime_remainder;
+    ALOGD("%s: Set qtime: %llu microsecs\n", __func__,
+          (unsigned long long int)qtime_value);
+
+    ret = send_qtime(platform, qtime_value, haptic_pcm_device_id);
+    if (ret < 0) {
+        ALOGE("%s: Could not send qtime for haptic session - %d",
+              __func__, ret);
+        return ret;
+    }
+
+    ret = send_qtime(platform, qtime_value, audio_pcm_device_id);
+    if (ret < 0) {
+        ALOGE("%s: Could not send qtime for audio session - %d",
+              __func__, ret);
+    }
+
+    return ret;
+}
+
 static int find_index(struct name_to_index * table, int32_t len, const char * name)
 {
     int ret = 0;
@@ -8403,7 +8587,7 @@
     } else if (my_data->is_internal_codec && !audio_is_usb_in_device(snd_device)) {
         sample_rate =  CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
         channels = CODEC_BACKEND_DEFAULT_TX_CHANNELS;
-        if (adev->active_input->bit_width == 24)
+        if (adev->active_input && adev->active_input->bit_width == 24)
             bit_width = platform_get_snd_device_bit_width(snd_device);
     } else {
         struct listnode *node;
diff --git a/hal/platform_api.h b/hal/platform_api.h
index f9e5f2a..f43aa88 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -347,6 +347,9 @@
 
 int platform_get_license_by_product(void *platform, const char* product_name, int *product_id, char* product_license);
 int platform_get_haptics_pcm_device_id();
+int platform_set_qtime(void *platform, int audio_pcm_device_id,
+                       int haptic_pcm_device_id);
+int platform_get_delay(void *platform, int pcm_device_id);
 struct audio_custom_mtmx_params *
     platform_get_custom_mtmx_params(void *platform,
                                     struct audio_custom_mtmx_params_info *info);
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index a478ff6..442ef3e 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -364,11 +364,11 @@
 // Get sound card number from pcm device
 int get_snd_card_num(char *device_info)
 {
-    char *token = NULL;
+    char *token = NULL, *saveptr = NULL;;
     int num = -1;
 
-    token = strtok(device_info, ": ");
-    token = strtok(token, "-");
+    token = strtok_r(device_info, ": ", &saveptr);
+    token = strtok_r(token, "-", &saveptr);
     if (token)
         num = atoi(token);
 
@@ -381,7 +381,7 @@
     char *token = NULL, *saveptr = NULL;
     int id = -1;
 
-    token = strtok(device_info, ": ");
+    token = strtok_r(device_info, ": ", &saveptr);
     token = strtok_r(token, "-", &saveptr);
     while (token != NULL) {
         token = strtok_r(NULL, "-", &saveptr);