Merge 620ed41abc91b9d09c254f7203ea379dc291fc48 on remote branch

Change-Id: I589eec398b1d03362832b4042a11d3402a3dcdc8
diff --git a/audio-effects/post_proc/bundle.c b/audio-effects/post_proc/bundle.c
index ada1b40..45e8dfd 100644
--- a/audio-effects/post_proc/bundle.c
+++ b/audio-effects/post_proc/bundle.c
@@ -2,6 +2,8 @@
  * Copyright (c) 2013-2017, 2019-2020, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
  * Copyright (C) 2013 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -650,7 +652,8 @@
             pReplyData == NULL ||
             *replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint16_t)) ||
             // constrain memcpy below
-            ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t)) {
+            ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t) ||
+            ((effect_param_t *)pCmdData)->psize > cmdSize - sizeof(effect_param_t)) {
             status = -EINVAL;
             ALOGW("EFFECT_CMD_GET_PARAM invalid command cmdSize %d *replySize %d",
                   cmdSize, *replySize);
diff --git a/audio-effects/post_proc/volume_listener.c b/audio-effects/post_proc/volume_listener.c
index ecd64e6..fd3071b 100644
--- a/audio-effects/post_proc/volume_listener.c
+++ b/audio-effects/post_proc/volume_listener.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2015-2017, 2019, 2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -587,7 +589,7 @@
             bool recompute_gain_dep_cal_Level = false;
             ALOGV("cmd called EFFECT_CMD_SET_DEVICE ");
 
-            if (p_cmd_data == NULL) {
+            if (p_cmd_data == NULL || cmd_size < sizeof(uint32_t)) {
                 ALOGE("%s: EFFECT_CMD_SET_DEVICE: cmd data NULL", __func__);
                 status = -EINVAL;
                 goto exit;
diff --git a/audio-effects/visualizer/offload_visualizer.c b/audio-effects/visualizer/offload_visualizer.c
index f019153..3462ce7 100644
--- a/audio-effects/visualizer/offload_visualizer.c
+++ b/audio-effects/visualizer/offload_visualizer.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1224,7 +1225,10 @@
         if (pCmdData == NULL ||
             cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t)) ||
             pReplyData == NULL ||
-            *replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t))) {
+            *replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t)) ||
+            // constrain memcpy below
+            ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t) ||
+            ((effect_param_t *)pCmdData)->psize > cmdSize - sizeof(effect_param_t)) {
             status = -EINVAL;
             goto exit;
         }
diff --git a/audio-effects/voice_processing/voice_processing.c b/audio-effects/voice_processing/voice_processing.c
index 50cb7af..2847c90 100644
--- a/audio-effects/voice_processing/voice_processing.c
+++ b/audio-effects/voice_processing/voice_processing.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -582,7 +583,8 @@
                     pReplyData == NULL ||
                     *replySize < (int)sizeof(effect_param_t) ||
                     // constrain memcpy below
-                    ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t)) {
+                    ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t) ||
+                    ((effect_param_t *)pCmdData)->psize > cmdSize - sizeof(effect_param_t)) {
                 ALOGV("fx_command() EFFECT_CMD_GET_PARAM invalid args");
                 return -EINVAL;
             }
diff --git a/configs/anorak/android.hardware.audio@7.1.xml b/configs/anorak/android.hardware.audio@7.1.xml
new file mode 100644
index 0000000..c4bd68b
--- /dev/null
+++ b/configs/anorak/android.hardware.audio@7.1.xml
@@ -0,0 +1,43 @@
+<!-- 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.
+-->
+
+<!-- Changes from Qualcomm Innovation Center are provided under the following license:
+*    Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+*    SPDX-License-Identifier: BSD-3-Clause-Clear -->
+
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.audio</name>
+        <transport>hwbinder</transport>
+        <version>7.1</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/hal/Android.mk b/hal/Android.mk
index e813841..c7fb412 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -24,6 +24,10 @@
 LOCAL_ARM_MODE := arm
 
 LOCAL_VINTF_FRAGMENTS := ../configs/common/manifest_non_qmaa.xml
+ifeq ($(TARGET_BOARD_PLATFORM), anorak)
+$(warning "Update manifest fragement for anorak")
+LOCAL_VINTF_FRAGMENTS += ../configs/anorak/android.hardware.audio@7.1.xml
+endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_LSM_HIDL)),true)
 LOCAL_VINTF_FRAGMENTS += ../configs/common/manifest_non_qmaa_extn.xml
diff --git a/hal/AudioDevice.cpp b/hal/AudioDevice.cpp
index 6db8967..9071cf7 100644
--- a/hal/AudioDevice.cpp
+++ b/hal/AudioDevice.cpp
@@ -2056,16 +2056,18 @@
     ret = str_parms_get_str(query, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED,
                             value, sizeof(value));
     if (ret >= 0) {
-        pal_param_bta2dp_t *param_bt_a2dp;
+        pal_param_bta2dp_t *param_bt_a2dp_ptr, param_bt_a2dp;
+        param_bt_a2dp_ptr = &param_bt_a2dp;
 
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
         ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_RECONFIG_SUPPORTED,
-                            (void **)&param_bt_a2dp, &size, nullptr);
+                            (void **)&param_bt_a2dp_ptr, &size, nullptr);
         if (!ret) {
             if (size < sizeof(pal_param_bta2dp_t)) {
                 AHAL_ERR("size returned is smaller for BT_A2DP_RECONFIG_SUPPORTED");
                 goto exit;
             }
-            val = param_bt_a2dp->reconfig_supported;
+            val = param_bt_a2dp_ptr->reconfig_supported;
             str_parms_add_int(reply, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED, val);
             AHAL_VERBOSE("isReconfigA2dpSupported = %d", val);
         }
@@ -2073,16 +2075,18 @@
 
     ret = str_parms_get_str(query, "A2dpSuspended", value, sizeof(value));
     if (ret >= 0) {
-        pal_param_bta2dp_t *param_bt_a2dp_suspended;
+        pal_param_bta2dp_t *param_bt_a2dp_ptr, param_bt_a2dp;
+        param_bt_a2dp_ptr = &param_bt_a2dp;
 
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
         ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED,
-                      (void **)&param_bt_a2dp_suspended, &size, nullptr);
+                      (void **)&param_bt_a2dp_ptr, &size, nullptr);
         if (!ret) {
             if (size < sizeof(pal_param_bta2dp_t)) {
                 AHAL_ERR("size returned is smaller for BT_A2DP_SUSPENDED");
                 goto exit;
             }
-            val = param_bt_a2dp_suspended->a2dp_suspended;
+            val = param_bt_a2dp_ptr->a2dp_suspended;
             str_parms_add_int(reply, "A2dpSuspended", val);
             AHAL_VERBOSE("A2dpSuspended = %d", val);
         }
diff --git a/hal/AudioStream.cpp b/hal/AudioStream.cpp
index 95212cc..20b1126 100644
--- a/hal/AudioStream.cpp
+++ b/hal/AudioStream.cpp
@@ -794,19 +794,26 @@
     }
 
     // accounts for A2DP encoding and sink latency
-    pal_param_bta2dp_t *param_bt_a2dp = NULL;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr, param_bt_a2dp;
+    param_bt_a2dp_ptr = &param_bt_a2dp;
     size_t size = 0;
     int32_t ret;
-    //TODO : check on PAL_PARAM_ID_BT_A2DP_ENCODER_LATENCY for BLE
-    if ((astream_out->isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_A2DP)) ||
-            (astream_out->isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE)) ||
-            (astream_out->isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST))) {
-        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_ENCODER_LATENCY,
-                            (void **)&param_bt_a2dp, &size, nullptr);
-        if (!ret && param_bt_a2dp)
-            latency += param_bt_a2dp->latency;
-    }
 
+    if (astream_out->isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_A2DP)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
+    } else if (astream_out->isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE;
+    } else if (astream_out->isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST;
+    } else {
+        goto exit;
+    }
+    ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_ENCODER_LATENCY,
+        (void**)&param_bt_a2dp_ptr, &size, nullptr);
+    if (!ret && size && param_bt_a2dp_ptr && param_bt_a2dp_ptr->latency) {
+        latency += param_bt_a2dp_ptr->latency;
+    }
+exit:
     AHAL_VERBOSE("Latency %d", latency);
     return latency;
 }
@@ -1400,18 +1407,25 @@
 
     // Adjustment accounts for A2dp decoder latency
     // Note: Decoder latency is returned in ms, while platform_source_latency in us.
-    pal_param_bta2dp_t* param_bt_a2dp = NULL;
+    pal_param_bta2dp_t* param_bt_a2dp_ptr, param_bt_a2dp;
+    param_bt_a2dp_ptr = &param_bt_a2dp;
     size_t size = 0;
     int32_t ret;
 
-    if (isDeviceAvailable(PAL_DEVICE_IN_BLUETOOTH_A2DP) ||
-        isDeviceAvailable(PAL_DEVICE_IN_BLUETOOTH_BLE)) {
-        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_DECODER_LATENCY,
-            (void**)&param_bt_a2dp, &size, nullptr);
-        if (!ret && param_bt_a2dp) {
-            *time -= param_bt_a2dp->latency * 1000000LL;
-        }
+    if (isDeviceAvailable(PAL_DEVICE_IN_BLUETOOTH_A2DP)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_IN_BLUETOOTH_A2DP;
+    } else if(isDeviceAvailable(PAL_DEVICE_IN_BLUETOOTH_BLE)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_IN_BLUETOOTH_BLE;
+    } else {
+        goto exit;
     }
+    ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_DECODER_LATENCY,
+        (void**)&param_bt_a2dp_ptr, &size, nullptr);
+    if (!ret && size && param_bt_a2dp_ptr && param_bt_a2dp_ptr->latency) {
+        *time -= param_bt_a2dp_ptr->latency * 1000000LL;
+    }
+
+exit:
     stream_mutex_.unlock();
 
     AHAL_VERBOSE("signed frames %lld", (long long)signed_frames);
@@ -2345,7 +2359,7 @@
     bool *payload_hifiFilter = &isHifiFilterEnabled;
     size_t param_size = 0;
 
-    pal_param_bta2dp_t *param_bt_a2dp = nullptr;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr = nullptr;
     size_t bt_param_size = 0;
 
     stream_mutex_.lock();
@@ -2481,9 +2495,14 @@
                                          (audio_devices_t)AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
             AudioExtn::audio_devices_cmp(mAndroidOutDevices,
                                          (audio_devices_t)AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
-            ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp,
+            pal_param_bta2dp_t param_bt_a2dp;
+            param_bt_a2dp_ptr = &param_bt_a2dp;
+            param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
+
+            ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp_ptr,
                                 &bt_param_size, nullptr);
-            if (!ret && param_bt_a2dp && !param_bt_a2dp->a2dp_suspended ) {
+            if (!ret && bt_param_size && param_bt_a2dp_ptr &&
+                !param_bt_a2dp_ptr->a2dp_suspended ) {
                 AHAL_ERR("Cannot route stream to SCO if A2dp is not suspended");
                 ret = -EINVAL;
                 goto done;
@@ -2646,7 +2665,6 @@
     uint64_t kernel_frames = 0;
     uint64_t dsp_frames = 0;
     uint64_t bt_extra_frames = 0;
-    pal_param_bta2dp_t *param_bt_a2dp = NULL;
     size_t size = 0, kernel_buffer_size = 0;
     int32_t ret;
 
@@ -2678,20 +2696,29 @@
 
     // Adjustment accounts for A2dp encoder latency with non offload usecases
     // Note: Encoder latency is returned in ms, while platform_render_latency in us.
-    if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_A2DP) ||
-           isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE) ||
-           isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST)) {
-        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_ENCODER_LATENCY,
-                            (void **)&param_bt_a2dp, &size, nullptr);
-        if (!ret && param_bt_a2dp) {
-            bt_extra_frames = param_bt_a2dp->latency *
-                (streamAttributes_.out_media_config.sample_rate) / 1000;
-            if (signed_frames >= bt_extra_frames)
-                signed_frames -= bt_extra_frames;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr, param_bt_a2dp;
+    param_bt_a2dp_ptr = &param_bt_a2dp;
 
-        }
+    if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_A2DP)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
+    } else if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE;
+    } else if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST;
+    } else {
+        goto exit;
+    }
+    ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_ENCODER_LATENCY,
+        (void**)&param_bt_a2dp_ptr, &size, nullptr);
+    if (!ret && size && param_bt_a2dp_ptr && param_bt_a2dp_ptr->latency) {
+        bt_extra_frames = param_bt_a2dp_ptr->latency *
+            (streamAttributes_.out_media_config.sample_rate) / 1000;
+        if (signed_frames >= bt_extra_frames)
+            signed_frames -= bt_extra_frames;
+
     }
 
+exit:
     struct audio_mmap_position position;
     if (this->GetUseCase() == USECASE_AUDIO_PLAYBACK_MMAP) {
         signed_frames = 0;
@@ -2881,7 +2908,7 @@
     bool *payload_hifiFilter = &isHifiFilterEnabled;
     size_t param_size = 0;
 
-    pal_param_bta2dp_t *param_bt_a2dp = nullptr;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr = nullptr;
     size_t bt_param_size = 0;
 
     AHAL_INFO("Enter: OutPrimary usecase(%d: %s)", GetUseCase(), use_case_table[GetUseCase()]);
@@ -3023,9 +3050,14 @@
                                      (audio_devices_t)AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
         AudioExtn::audio_devices_cmp(mAndroidOutDevices,
                                      (audio_devices_t)AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
-        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp,
+        pal_param_bta2dp_t param_bt_a2dp;
+        param_bt_a2dp_ptr = &param_bt_a2dp;
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
+
+        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp_ptr,
                             &bt_param_size, nullptr);
-        if (!ret && param_bt_a2dp && !param_bt_a2dp->a2dp_suspended) {
+        if (!ret && bt_param_size && param_bt_a2dp_ptr &&
+            !param_bt_a2dp_ptr->a2dp_suspended) {
             AHAL_ERR("Cannot open stream on SCO if A2dp is not suspended");
             ret = -EINVAL;
             goto error_open;
@@ -3213,7 +3245,6 @@
     uint64_t dsp_frames = 0;
     uint64_t offset = 0;
     size_t size = 0;
-    pal_param_bta2dp_t *param_bt_a2dp = NULL;
 
     if (!pal_stream_handle_) {
         AHAL_VERBOSE("pal_stream_handle_ NULL");
@@ -3241,17 +3272,26 @@
 
     // Adjustment accounts for A2dp encoder latency with offload usecases
     // Note: Encoder latency is returned in ms.
-    if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_A2DP) ||
-           isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST) ||
-           isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE)) {
-        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_ENCODER_LATENCY,
-                            (void **)&param_bt_a2dp, &size, nullptr);
-        if (!ret && param_bt_a2dp) {
-            offset = param_bt_a2dp->latency *
-                (streamAttributes_.out_media_config.sample_rate) / 1000;
-            dsp_frames = (dsp_frames > offset) ? (dsp_frames - offset) : 0;
-        }
+    pal_param_bta2dp_t* param_bt_a2dp_ptr, param_bt_a2dp;
+    param_bt_a2dp_ptr = &param_bt_a2dp;
+
+    if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_A2DP)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
+    } else if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE;
+    } else if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST)) {
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST;
+    } else {
+        goto done;
     }
+    ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_ENCODER_LATENCY,
+        (void**)&param_bt_a2dp_ptr, &size, nullptr);
+    if (!ret && size && param_bt_a2dp_ptr && param_bt_a2dp_ptr->latency) {
+        offset = param_bt_a2dp_ptr->latency *
+            (streamAttributes_.out_media_config.sample_rate) / 1000;
+        dsp_frames = (dsp_frames > offset) ? (dsp_frames - offset) : 0;
+    }
+done:
     *frames = dsp_frames + mCachedPosition;
 exit:
     return ret;
@@ -3500,7 +3540,7 @@
     palBuffer.size = bytes;
     palBuffer.offset = 0;
 
-    pal_param_bta2dp_t *param_bt_a2dp = nullptr;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr = nullptr;
     size_t bt_param_size = 0;
     bool is_usage_ringtone = false;
     uint32_t frameSize = 0;
@@ -3531,12 +3571,17 @@
         }
 
         if (is_usage_ringtone && isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE)) {
-            param_bt_a2dp = nullptr;
             bt_param_size = 0;
             std::unique_lock<std::mutex> guard(reconfig_wait_mutex_);
-            ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp,
+
+            pal_param_bta2dp_t param_bt_a2dp;
+            param_bt_a2dp_ptr = &param_bt_a2dp;
+            param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE;
+
+            ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp_ptr,
                                 &bt_param_size, nullptr);
-            if (!ret && param_bt_a2dp && param_bt_a2dp->a2dp_suspended) {
+            if (!ret && bt_param_size && param_bt_a2dp_ptr &&
+                param_bt_a2dp_ptr->a2dp_suspended) {
                  byteWidth = streamAttributes_.out_media_config.bit_width / 8;
                  sampleRate = streamAttributes_.out_media_config.sample_rate;
                  channelCount = streamAttributes_.out_media_config.ch_info.channels;
@@ -4324,7 +4369,7 @@
     struct pal_channel_info ch_info = {0, {0}};
     std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance();
 
-    pal_param_bta2dp_t *param_bt_a2dp = nullptr;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr = nullptr;
     size_t bt_param_size = 0;
 
     AHAL_INFO("Enter: InPrimary usecase(%d: %s)", GetUseCase(), use_case_table[GetUseCase()]);
@@ -4445,9 +4490,14 @@
 
         if (AudioExtn::audio_devices_cmp(mAndroidInDevices,
                                          (audio_devices_t)AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
-            ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp,
+            pal_param_bta2dp_t param_bt_a2dp;
+            param_bt_a2dp_ptr = &param_bt_a2dp;
+            param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
+
+            ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp_ptr,
                                 &bt_param_size, nullptr);
-            if (!ret && param_bt_a2dp && !param_bt_a2dp->a2dp_suspended) {
+            if (!ret && bt_param_size && param_bt_a2dp_ptr &&
+                !param_bt_a2dp_ptr->a2dp_suspended) {
                 AHAL_ERR("Cannot route stream from SCO if A2dp is not suspended");
                 ret = -EINVAL;
                 goto done;
@@ -4535,7 +4585,7 @@
     dynamic_media_config_t dynamic_media_config;
     std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance();
 
-    pal_param_bta2dp_t *param_bt_a2dp = nullptr;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr = nullptr;
     size_t bt_param_size = 0;
 
     AHAL_INFO("Enter: InPrimary usecase(%d: %s)", GetUseCase(), use_case_table[GetUseCase()]);
@@ -4691,9 +4741,14 @@
 
     if (AudioExtn::audio_devices_cmp(mAndroidInDevices,
                                      (audio_devices_t)AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
-        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp,
+        pal_param_bta2dp_t param_bt_a2dp;
+        param_bt_a2dp_ptr = &param_bt_a2dp;
+        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
+
+        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void **)&param_bt_a2dp_ptr,
                             &bt_param_size, nullptr);
-        if (!ret && param_bt_a2dp && !param_bt_a2dp->a2dp_suspended) {
+        if (!ret && bt_param_size && param_bt_a2dp_ptr
+            && !param_bt_a2dp_ptr->a2dp_suspended) {
             AHAL_ERR("Cannot open stream on SCO if A2dp is not suspended");
             ret = -EINVAL;
             goto exit;
diff --git a/hal/AudioVoice.cpp b/hal/AudioVoice.cpp
index fb6a387..7f8ba69 100644
--- a/hal/AudioVoice.cpp
+++ b/hal/AudioVoice.cpp
@@ -413,7 +413,7 @@
     pal_device_id_t* pal_device_ids = NULL;
     uint16_t device_count = 0;
 
-    pal_param_bta2dp_t *param_bt_a2dp = nullptr;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr = nullptr;
     size_t bt_param_size = 0;
     bool a2dp_suspended = false;
     bool a2dp_capture_suspended = false;
@@ -479,23 +479,29 @@
 
             if ((pal_voice_rx_device_id_ == PAL_DEVICE_OUT_BLUETOOTH_BLE) &&
                 (pal_voice_tx_device_id_ == PAL_DEVICE_IN_BLUETOOTH_BLE)) {
+                pal_param_bta2dp_t param_bt_a2dp;
                 do {
                     std::unique_lock<std::mutex> guard(reconfig_wait_mutex_);
+                    param_bt_a2dp_ptr = &param_bt_a2dp;
+                    param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE;
+
                     ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED,
-                                        (void **)&param_bt_a2dp, &bt_param_size, nullptr);
-                    if (!ret && param_bt_a2dp)
-                        a2dp_suspended = param_bt_a2dp->a2dp_suspended;
-                    else
+                                        (void **)&param_bt_a2dp_ptr, &bt_param_size, nullptr);
+                    if (!ret && bt_param_size && param_bt_a2dp_ptr) {
+                        a2dp_suspended = param_bt_a2dp_ptr->a2dp_suspended;
+                    } else {
                         AHAL_ERR("getparam for PAL_PARAM_ID_BT_A2DP_SUSPENDED failed");
-                    param_bt_a2dp = nullptr;
+                    }
+                    param_bt_a2dp_ptr = &param_bt_a2dp;
+                    param_bt_a2dp_ptr->dev_id = PAL_DEVICE_IN_BLUETOOTH_BLE;
                     bt_param_size = 0;
                     ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_CAPTURE_SUSPENDED,
-                                        (void **)&param_bt_a2dp, &bt_param_size, nullptr);
-                    if (!ret && param_bt_a2dp)
-                        a2dp_capture_suspended = param_bt_a2dp->a2dp_capture_suspended;
+                                        (void **)&param_bt_a2dp_ptr, &bt_param_size, nullptr);
+                    if (!ret && bt_param_size && param_bt_a2dp_ptr)
+                        a2dp_capture_suspended = param_bt_a2dp_ptr->a2dp_capture_suspended;
                     else
                         AHAL_ERR("getparam for BT_A2DP_CAPTURE_SUSPENDED failed");
-                    param_bt_a2dp = nullptr;
+                    param_bt_a2dp_ptr = nullptr;
                     bt_param_size = 0;
                 } while ((a2dp_suspended || a2dp_capture_suspended) && retry_cnt-- &&
                          !usleep(retry_period_ms * 1000));
@@ -564,7 +570,7 @@
     int i, ret = 0;
     voice_session_t *session = NULL;
 
-    pal_param_bta2dp_t *param_bt_a2dp = nullptr;
+    pal_param_bta2dp_t *param_bt_a2dp_ptr = nullptr;
     size_t bt_param_size = 0;
     bool a2dp_suspended = false;
     bool a2dp_capture_suspended = false;
@@ -588,23 +594,30 @@
 
                     if ((pal_voice_rx_device_id_ == PAL_DEVICE_OUT_BLUETOOTH_BLE) &&
                         (pal_voice_tx_device_id_ == PAL_DEVICE_IN_BLUETOOTH_BLE)) {
+                        pal_param_bta2dp_t param_bt_a2dp;
                         do {
                             std::unique_lock<std::mutex> guard(reconfig_wait_mutex_);
+                            param_bt_a2dp_ptr = &param_bt_a2dp;
+                            param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_BLE;
+
                             ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED,
-                                                (void **)&param_bt_a2dp, &bt_param_size, nullptr);
-                            if (!ret && param_bt_a2dp)
-                                a2dp_suspended = param_bt_a2dp->a2dp_suspended;
-                            else
+                                                (void **)&param_bt_a2dp_ptr, &bt_param_size, nullptr);
+                            if (!ret && bt_param_size && param_bt_a2dp_ptr) {
+                                a2dp_suspended = param_bt_a2dp_ptr->a2dp_suspended;
+                            } else {
                                 AHAL_ERR("getparam for PAL_PARAM_ID_BT_A2DP_SUSPENDED failed");
-                            param_bt_a2dp = nullptr;
+                            }
+                            param_bt_a2dp_ptr = &param_bt_a2dp;
+                            param_bt_a2dp_ptr->dev_id = PAL_DEVICE_IN_BLUETOOTH_BLE;
                             bt_param_size = 0;
                             ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_CAPTURE_SUSPENDED,
-                                                (void **)&param_bt_a2dp, &bt_param_size, nullptr);
-                            if (!ret && param_bt_a2dp)
-                                a2dp_capture_suspended = param_bt_a2dp->a2dp_capture_suspended;
-                            else
+                                                (void **)&param_bt_a2dp_ptr, &bt_param_size, nullptr);
+                            if (!ret && bt_param_size && param_bt_a2dp_ptr) {
+                                a2dp_capture_suspended = param_bt_a2dp_ptr->a2dp_capture_suspended;
+                            } else {
                                 AHAL_ERR("getparam for BT_A2DP_CAPTURE_SUSPENDED failed");
-                            param_bt_a2dp = nullptr;
+                            }
+                            param_bt_a2dp_ptr = nullptr;
                             bt_param_size = 0;
                         } while ((a2dp_suspended || a2dp_capture_suspended) && retry_cnt-- &&
                                  !usleep(retry_period_ms * 1000));