audio: Add support for multiple metainfo keys update

Add changes to read acdb metainfo key and module name from platform
info xml. Changes to add acdb key values to a list and query key value
based on module name.

CRs-Fixed: 1081424
Change-Id: Ia287a27c86f63fea16cdb35d553de6e2e853b4e9
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index d9c7642..d4f9710 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -38,6 +38,8 @@
 #include "sound/msmcal-hwdep.h"
 #include <dirent.h>
 #include <linux/msm_audio.h>
+#include "linux/msm_audio_calibration.h"
+
 #define SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID (100)
 #define MAX_MIXER_XML_PATH  100
 #define MIXER_XML_PATH_QRD_SKUH "/system/etc/mixer_paths_qrd_skuh.xml"
@@ -212,6 +214,7 @@
 /* Audio calibration related functions */
 typedef void (*acdb_deallocate_t)();
 typedef int  (*acdb_init_t)(const char *, char *, int);
+typedef int  (*acdb_init_v3_t)(const char *, char *, struct listnode *);
 typedef void (*acdb_send_audio_cal_t)(int, int, int , int);
 typedef void (*acdb_send_voice_cal_t)(int, int);
 typedef int (*acdb_reload_vocvoltable_t)(int);
@@ -224,6 +227,7 @@
 typedef int (*acdb_set_codec_data_t) (void *, char *);
 typedef int (*acdb_reload_t) (char *, char *, char *, int);
 typedef int (*acdb_send_gain_dep_cal_t)(int, int, int, int, int);
+typedef int (*acdb_reload_v2_t) (char *, char *, char *, struct listnode *);
 
 typedef struct codec_backend_cfg {
     uint32_t sample_rate;
@@ -237,6 +241,12 @@
 static native_audio_prop na_props = {0, 0, 0};
 static bool supports_true_32_bit = false;
 
+struct meta_key_list {
+    struct listnode list;
+    struct audio_cal_info_metainfo cal_info;
+    char name[ACDB_METAINFO_KEY_MODULE_NAME_LEN];
+};
+
 struct platform_data {
     struct audio_device *adev;
     bool fluence_in_spkr_mode;
@@ -263,6 +273,7 @@
     void                       *acdb_handle;
     int                        voice_feature_set;
     acdb_init_t                acdb_init;
+    acdb_init_v3_t             acdb_init_v3;
     acdb_deallocate_t          acdb_deallocate;
     acdb_send_audio_cal_t      acdb_send_audio_cal;
     acdb_set_audio_cal_t       acdb_set_audio_cal;
@@ -273,6 +284,7 @@
     acdb_send_common_top_t     acdb_send_common_top;
     acdb_set_codec_data_t      acdb_set_codec_data;
     acdb_reload_t              acdb_reload;
+    acdb_reload_v2_t           acdb_reload_v2;
 #ifdef RECORD_PLAY_CONCURRENCY
     bool rec_play_conc_set;
 #endif
@@ -288,11 +300,11 @@
     int hw_dep_fd;
     char cvd_version[MAX_CVD_VERSION_STRING_SIZE];
     char snd_card_name[MAX_SND_CARD_STRING_SIZE];
-    int metainfo_key;
     int source_mic_type;
     int max_mic_count;
     bool is_dsd_supported;
     bool is_asrc_supported;
+    struct listnode acdb_meta_key_list;
 };
 
 static bool is_external_codec = false;
@@ -1631,10 +1643,12 @@
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     char *cvd_version = NULL;
-    int key = 0;
     const char *snd_card_name, *acdb_snd_card_name;
-    int result;
-    char value[PROPERTY_VALUE_MAX];
+    int result = -1;
+    struct listnode *node;
+    struct meta_key_list *key_info;
+    int key = 0;
+
     cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
     if (!cvd_version) {
         ALOGE("Failed to allocate cvd version");
@@ -1643,19 +1657,23 @@
         get_cvd_version(cvd_version, my_data->adev);
     }
 
-    property_get("audio.ds1.metainfo.key",value,"0");
-    key = atoi(value);
     snd_card_name = mixer_get_name(my_data->adev->mixer);
     acdb_snd_card_name = get_snd_card_name_for_acdb_loader(snd_card_name);
 
-    result = my_data->acdb_init(acdb_snd_card_name, cvd_version, key);
-
+    if (my_data->acdb_init_v3) {
+        result = my_data->acdb_init_v3(acdb_snd_card_name, cvd_version,
+                                           &my_data->acdb_meta_key_list);
+    } else if (my_data->acdb_init) {
+        node = list_head(&my_data->acdb_meta_key_list);
+        key_info = node_to_item(node, struct meta_key_list, list);
+        key = key_info->cal_info.nKey;
+        result = my_data->acdb_init(acdb_snd_card_name, cvd_version, key);
+    }
     /* Save these variables in platform_data. These will be used
        while reloading ACDB files during run time. */
     strlcpy(my_data->cvd_version, cvd_version, MAX_CVD_VERSION_STRING_SIZE);
     strlcpy(my_data->snd_card_name, acdb_snd_card_name,
                                                MAX_SND_CARD_STRING_SIZE);
-    my_data->metainfo_key = key;
 
     if (cvd_version)
         free(cvd_version);
@@ -1940,6 +1958,16 @@
     if (ret || is_external_codec)
         my_data->hifi_audio = true;
 
+    list_init(&my_data->acdb_meta_key_list);
+
+    set_platform_defaults(my_data);
+
+    /* Initialize ACDB and PCM ID's */
+    if (is_external_codec)
+        platform_info_init(PLATFORM_INFO_XML_PATH_EXTCODEC, my_data);
+    else
+        platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
+
     my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
     if (my_data->acdb_handle == NULL) {
@@ -2009,6 +2037,12 @@
             ALOGV("%s: Could not find the symbol acdb_loader_send_gain_dep_cal from %s",
                   __func__, LIB_ACDB_LOADER);
 
+        my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
+                                                    "acdb_loader_init_v3");
+        if (my_data->acdb_init_v3 == NULL) {
+            ALOGE("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());
+        }
+
         my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
                                                     "acdb_loader_init_v2");
         if (my_data->acdb_init == NULL) {
@@ -2016,12 +2050,19 @@
             goto acdb_init_fail;
         }
 
+        my_data->acdb_reload_v2 = (acdb_reload_v2_t)dlsym(my_data->acdb_handle,
+                                                    "acdb_loader_reload_acdb_files_v2");
+        if (my_data->acdb_reload_v2 == NULL) {
+            ALOGE("%s: dlsym error %s for acdb_loader_reload_acdb_files_v2", __func__, dlerror());
+        }
+
         my_data->acdb_reload = (acdb_reload_t)dlsym(my_data->acdb_handle,
                                                     "acdb_loader_reload_acdb_files");
         if (my_data->acdb_reload == NULL) {
             ALOGE("%s: dlsym error %s for acdb_loader_reload_acdb_files", __func__, dlerror());
             goto acdb_init_fail;
         }
+
         platform_acdb_init(my_data);
     }
     audio_extn_pm_vote();
@@ -2035,14 +2076,6 @@
 
 acdb_init_fail:
 
-    set_platform_defaults(my_data);
-
-    /* Initialize ACDB and PCM ID's */
-    if (is_external_codec)
-        platform_info_init(PLATFORM_INFO_XML_PATH_EXTCODEC, my_data);
-    else
-        platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
-
     if (audio_extn_can_use_ras()) {
         if (property_get_bool("persist.speaker.prot.enable", false)) {
             platform_set_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED,
@@ -2075,8 +2108,6 @@
     /* init dap hal */
     audio_extn_dap_hal_init(adev->snd_card);
 
-    audio_extn_dolby_set_license(adev);
-
     /* init audio device arbitration */
     audio_extn_dev_arbi_init();
 
@@ -2497,6 +2528,45 @@
     return ret;
 }
 
+int platform_set_acdb_metainfo_key(void *platform, char *name, int key)
+{
+    struct meta_key_list *key_info;
+    struct platform_data *pdata = (struct platform_data *)platform;
+
+    key_info = (struct meta_key_list *)calloc(1, sizeof(struct meta_key_list));
+    if (!key_info) {
+        ALOGE("%s: Could not allocate memory for key %d", __func__, key);
+        return -ENOMEM;
+    }
+
+    key_info->cal_info.nKey = key;
+    strlcpy(key_info->name, name, sizeof(key_info->name));
+    list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
+    ALOGD("%s: successfully added module %s and key %d to the list", __func__,
+               key_info->name, key_info->cal_info.nKey);
+    return 0;
+}
+
+int platform_get_meta_info_key_from_list(void *platform, char *mod_name)
+{
+    struct listnode *node;
+    struct meta_key_list *key_info;
+    struct platform_data *pdata = (struct platform_data *)platform;
+    int key = 0;
+
+    ALOGV("%s: for module %s", __func__, mod_name);
+
+    list_for_each(node, &pdata->acdb_meta_key_list) {
+        key_info = node_to_item(node, struct meta_key_list, list);
+        if (strcmp(key_info->name, mod_name) == 0) {
+            key = key_info->cal_info.nKey;
+            ALOGD("%s: Found key %d for module %s", __func__, key, mod_name);
+            break;
+        }
+    }
+    return key;
+}
+
 int platform_get_default_app_type(void *platform)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
@@ -4032,6 +4102,9 @@
     int len;
     int ret = 0, err;
     char *kv_pairs = NULL;
+    struct listnode *node;
+    struct meta_key_list *key_info;
+    int key = 0;
 
     kv_pairs = str_parms_to_str(parms);
     if(!kv_pairs)
@@ -4093,9 +4166,16 @@
     if (err >= 0) {
         str_parms_del(parms, AUDIO_PARAMETER_KEY_RELOAD_ACDB);
 
-        my_data->acdb_reload(value, my_data->snd_card_name,
-                              my_data->cvd_version, my_data->metainfo_key);
-
+        if (my_data->acdb_reload_v2) {
+            my_data->acdb_reload_v2(value, my_data->snd_card_name,
+                                  my_data->cvd_version, &my_data->acdb_meta_key_list);
+        } else if (my_data->acdb_reload) {
+            node = list_head(&my_data->acdb_meta_key_list);
+            key_info = node_to_item(node, struct meta_key_list, list);
+            key = key_info->cal_info.nKey;
+            my_data->acdb_reload(value, my_data->snd_card_name,
+                                  my_data->cvd_version, key);
+        }
     }
 
     if (hw_info_is_stereo_spkr(my_data->hw_info)) {