audio: unify hal

Unify audio hal components

CRs-Fixed: 2380934
Change-Id: Iacafdc44d935de5f343240421a1572a0a3241bd0
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index f08f379..b193d67 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-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
@@ -26,12 +26,13 @@
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
-#define LOG_TAG "split_a2dp"
+#define LOG_TAG "a2dp_offload"
 /*#define LOG_NDEBUG 0*/
 #define LOG_NDDEBUG 0
 #include <errno.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <dlfcn.h>
+#include <pthread.h>
 #include "audio_hw.h"
 #include "platform.h"
 #include "platform_api.h"
@@ -48,7 +49,7 @@
 #include <log_utils.h>
 #endif
 
-#ifdef SPLIT_A2DP_ENABLED
+#ifdef A2DP_OFFLOAD_ENABLED
 #define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
 #define BT_IPC_SOURCE_LIB_NAME  "libbthost_if.so"
 #define BT_IPC_SINK_LIB_NAME    "libbthost_if_sink.so"
@@ -93,6 +94,7 @@
 #define MIXER_ENC_FMT_APTX         "APTX"
 #define MIXER_FMT_TWS_CHANNEL_MODE "TWS Channel Mode"
 #define MIXER_ENC_FMT_APTXHD       "APTXHD"
+#define MIXER_END_FMT_LDAC         "LDAC"
 #define MIXER_ENC_FMT_NONE         "NONE"
 #define ENCODER_LATENCY_SBC        10
 #define ENCODER_LATENCY_APTX       40
@@ -101,6 +103,7 @@
 //To Do: Fine Tune Encoder CELT/LDAC latency.
 #define ENCODER_LATENCY_CELT       40
 #define ENCODER_LATENCY_LDAC       40
+#define ENCODER_LATENCY_PCM        50
 #define DEFAULT_SINK_LATENCY_SBC       140
 #define DEFAULT_SINK_LATENCY_APTX      160
 #define DEFAULT_SINK_LATENCY_APTX_HD   180
@@ -108,6 +111,17 @@
 //To Do: Fine Tune Default CELT/LDAC Latency.
 #define DEFAULT_SINK_LATENCY_CELT      180
 #define DEFAULT_SINK_LATENCY_LDAC      180
+#define DEFAULT_SINK_LATENCY_PCM       140
+
+#define SYSPROP_A2DP_OFFLOAD_SUPPORTED "ro.bluetooth.a2dp_offload.supported"
+#define SYSPROP_A2DP_OFFLOAD_DISABLED  "persist.bluetooth.a2dp_offload.disabled"
+#define SYSPROP_A2DP_CODEC_LATENCIES   "vendor.audio.a2dp.codec.latency"
+
+// Default encoder bit width
+#define DEFAULT_ENCODER_BIT_FORMAT 16
+
+// Default encoder latency
+#define DEFAULT_ENCODER_LATENCY    200
 
 // Slimbus Tx sample rate for ABR feedback channel
 #define ABR_TX_SAMPLE_RATE             "KHZ_8"
@@ -146,6 +160,7 @@
     CODEC_TYPE_LDAC = AUDIO_FORMAT_LDAC, // 0x23000000UL
     CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
     CODEC_TYPE_APTX_AD = 620756992u, // 0x25000000UL
+    CODEC_TYPE_PCM = AUDIO_FORMAT_PCM_16_BIT, // 0x1u
 }codec_t;
 
 /*
@@ -605,6 +620,7 @@
     uint32_t sampling_rate;
     uint32_t bitrate;
     uint32_t bits_per_sample;
+    struct aac_frame_size_control_t frame_ctl;
 } audio_aac_encoder_config;
 #endif
 
@@ -667,60 +683,15 @@
 
 /*********** END of DSP configurable structures ********************/
 
-/* API to identify DSP encoder captabilities */
-static void a2dp_offload_codec_cap_parser(char *value)
-{
-    char *tok = NULL,*saveptr;
-
-    tok = strtok_r(value, "-", &saveptr);
-    while (tok != NULL) {
-        if (strcmp(tok, "sbc") == 0) {
-            ALOGD("%s: SBC offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "aptx") == 0) {
-            ALOGD("%s: aptx offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "aptxtws") == 0) {
-            ALOGD("%s: aptx dual mono offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "aptxhd") == 0) {
-            ALOGD("%s: aptx HD offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "aac") == 0) {
-            ALOGD("%s: aac offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "celt") == 0) {
-            ALOGD("%s: celt offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "ldac") == 0) {
-            ALOGD("%s: ldac offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if( strcmp(tok, "aptxadaptive") == 0) {
-            ALOGD("%s: aptx adaptive offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-        }
-        tok = strtok_r(NULL, "-", &saveptr);
-    };
-}
-
 static void update_offload_codec_capabilities()
 {
-    char value[PROPERTY_VALUE_MAX] = {'\0'};
 
-    property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
-    ALOGD("get_offload_codec_capabilities = %s",value);
     a2dp.is_a2dp_offload_supported =
-            property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
-    if (strcmp(value, "false") != 0)
-        a2dp_offload_codec_cap_parser(value);
-    ALOGD("%s: codec cap = %s",__func__,value);
+            property_get_bool(SYSPROP_A2DP_OFFLOAD_SUPPORTED, false) &&
+            !property_get_bool(SYSPROP_A2DP_OFFLOAD_DISABLED, false);
+
+    ALOGD("%s: A2DP offload supported = %d",__func__,
+          a2dp.is_a2dp_offload_supported);
 }
 
 static int stop_abr()
@@ -852,17 +823,17 @@
             a2dp.audio_source_open = (audio_source_open_t)
                           dlsym(a2dp.bt_lib_source_handle, "audio_stream_open");
             a2dp.audio_source_start = (audio_source_start_t)
-                          dlsym(a2dp.bt_lib_source_handle, "audio_start_stream");
+                          dlsym(a2dp.bt_lib_source_handle, "audio_stream_start");
             a2dp.audio_get_enc_config = (audio_get_enc_config_t)
                           dlsym(a2dp.bt_lib_source_handle, "audio_get_codec_config");
             a2dp.audio_source_suspend = (audio_source_suspend_t)
-                          dlsym(a2dp.bt_lib_source_handle, "audio_suspend_stream");
+                          dlsym(a2dp.bt_lib_source_handle, "audio_stream_suspend");
             a2dp.audio_source_handoff_triggered = (audio_source_handoff_triggered_t)
                           dlsym(a2dp.bt_lib_source_handle, "audio_handoff_triggered");
             a2dp.clear_source_a2dpsuspend_flag = (clear_source_a2dpsuspend_flag_t)
                           dlsym(a2dp.bt_lib_source_handle, "clear_a2dpsuspend_flag");
             a2dp.audio_source_stop = (audio_source_stop_t)
-                          dlsym(a2dp.bt_lib_source_handle, "audio_stop_stream");
+                          dlsym(a2dp.bt_lib_source_handle, "audio_stream_stop");
             a2dp.audio_source_close = (audio_source_close_t)
                           dlsym(a2dp.bt_lib_source_handle, "audio_stream_close");
             a2dp.audio_source_check_a2dp_ready = (audio_source_check_a2dp_ready_t)
@@ -1026,6 +997,11 @@
         sampling_rate = sampling_rate *2;
     }
 
+    // No need to configure backend for PCM format.
+    if (a2dp.bt_encoder_format == CODEC_TYPE_PCM) {
+        return 0;
+    }
+
     //Configure backend sampling rate
     switch (sampling_rate) {
     case 44100:
@@ -2168,6 +2144,11 @@
                  configure_a2dp_source_decoder_format(MEDIA_FMT_APTX_AD));
             break;
 #endif
+        case CODEC_TYPE_PCM:
+            ALOGD("Received PCM format for BT device");
+            a2dp.bt_encoder_format = CODEC_TYPE_PCM;
+            is_configured = true;
+            break;
         default:
             ALOGD(" Received Unsupported encoder formar");
             is_configured = false;
@@ -2318,7 +2299,7 @@
 {
     int ret =0;
 
-    struct mixer_ctl *ctl_enc_config, *ctrl_bit_format, *ctl_channel_mode;
+    struct mixer_ctl *ctl_enc_config, *ctl_channel_mode;
     struct sbc_enc_cfg_t dummy_reset_config;
     char* channel_mode;
 
@@ -2332,16 +2313,9 @@
                                         sizeof(struct sbc_enc_cfg_t));
          a2dp.bt_encoder_format = MEDIA_FMT_NONE;
     }
-    ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
-                                            MIXER_ENC_BIT_FORMAT);
-    if (!ctrl_bit_format) {
-        ALOGE(" ERROR  bit format CONFIG data mixer control not identified");
-    } else {
-        ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
-        if (ret != 0) {
-            ALOGE("%s: Failed to set bit format to encoder", __func__);
-        }
-    }
+
+    a2dp_set_bit_format(DEFAULT_ENCODER_BIT_FORMAT);
+
     ctl_channel_mode = mixer_get_ctl_by_name(a2dp.adev->mixer,MIXER_FMT_TWS_CHANNEL_MODE);
 
     if (!ctl_channel_mode) {
@@ -2420,6 +2394,8 @@
 
     if (a2dp.a2dp_source_total_active_session_requests > 0)
         a2dp.a2dp_source_total_active_session_requests--;
+    else
+        ALOGE("%s: No active playback session requests on A2DP", __func__);
 
     if ( a2dp.a2dp_source_started && !a2dp.a2dp_source_total_active_session_requests) {
         ALOGV("calling BT module stream stop");
@@ -2474,16 +2450,17 @@
     return 0;
 }
 
-void audio_extn_a2dp_set_parameters(struct str_parms *parms)
+int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig)
 {
-     int ret, val;
+     int ret = 0, val, status = 0;
      char value[32]={0};
      struct audio_usecase *uc_info;
      struct listnode *node;
 
      if(a2dp.is_a2dp_offload_supported == false) {
-        ALOGV("no supported codecs identified,ignoring a2dp setparam");
-        return;
+        ALOGV("no supported encoders identified,ignoring a2dp setparam");
+        status = -EINVAL;
+        goto param_handled;
      }
 
      ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
@@ -2532,6 +2509,10 @@
      if (ret >= 0) {
          if (a2dp.bt_lib_source_handle) {
              if ((!strncmp(value,"true",sizeof(value)))) {
+                if (a2dp.a2dp_source_suspended) {
+                    ALOGD("%s: A2DP is already suspended", __func__);
+                    goto param_handled;
+                }
                 ALOGD("Setting a2dp to suspend state");
                 a2dp.a2dp_source_suspended = true;
                 if (a2dp.bt_state_source == A2DP_STATE_DISCONNECTED)
@@ -2590,8 +2571,20 @@
         }
         goto param_handled;
      }
+
+     ret = str_parms_get_str(parms, AUDIO_PARAMETER_RECONFIG_A2DP, value,
+                         sizeof(value));
+     if (ret >= 0) {
+         if (a2dp.is_a2dp_offload_supported &&
+                a2dp.bt_state_source != A2DP_STATE_DISCONNECTED) {
+             *reconfig = true;
+         }
+         goto param_handled;
+     }
+
 param_handled:
      ALOGV("end of a2dp setparam");
+     return status;
 }
 
 void audio_extn_a2dp_set_handoff_mode(bool is_on)
@@ -2688,7 +2681,7 @@
     char value[PROPERTY_VALUE_MAX];
 
     memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
-    avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
+    avsync_runtime_prop = property_get(SYSPROP_A2DP_CODEC_LATENCIES, value, NULL);
     if (avsync_runtime_prop > 0) {
         if (sscanf(value, "%d/%d/%d/%d/%d%d",
                   &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset, &ldac_offset) != 6) {
@@ -2730,10 +2723,31 @@
         case CODEC_TYPE_APTX_AD: // for aptx adaptive the latency depends on the mode (HQ/LL) and
             latency = slatency;      // BT IPC will take care of accomodating the mode factor and return latency
             break;
+        case CODEC_TYPE_PCM:
+            latency = ENCODER_LATENCY_PCM;
+            latency += DEFAULT_SINK_LATENCY_PCM;
+            break;
         default:
             latency = 200;
             break;
     }
     return latency;
 }
-#endif // SPLIT_A2DP_ENABLED
+
+int audio_extn_a2dp_get_parameters(struct str_parms *query,
+                                   struct str_parms *reply)
+{
+    int ret, val = 0;
+    char value[32]={0};
+
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED,
+                            value, sizeof(value));
+    if (ret >= 0) {
+        val = a2dp.is_a2dp_offload_supported;
+        str_parms_add_int(reply, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED, val);
+        ALOGV("%s: called ... isReconfigA2dpSupported %d", __func__, val);
+    }
+
+    return 0;
+}
+#endif // A2DP_OFFLOAD_ENABLED