audio: fix memory corruption.

Race condition:

There is a race condition between audio primary hal thread and soundtrigger
hal thread when they want to get snd_card number.

Memory leakage:

my_data.kvpairs in platforom_info_init function doesn't be destroyed
when use str_parms_create().

Bug: 119328981
Test: manual audio test

Change-Id: Ib86b3cf986a7213007bf9f073ef714a02b28a111
Signed-off-by: juyuchen <juyuchen@google.com>
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 79dd9e5..3a1877b 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -581,7 +581,7 @@
         }
 
         /* Initialize snd card name specific ids and/or backends*/
-        if (snd_card_info_init(platform_info_file, my_data,
+        if (platform_info_init(platform_info_file, my_data, false,
                                &acdb_set_parameters) < 0) {
             ALOGE("Failed to find platform_info_file");
             goto cleanup;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 2bf552c..2707c89 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1132,7 +1132,8 @@
     /* Initialize ACDB and PCM ID's */
     strlcpy(platform_info_path, PLATFORM_INFO_XML_PATH, MAX_MIXER_XML_PATH);
     resolve_config_file(platform_info_path);
-    platform_info_init(platform_info_path, my_data);
+    platform_info_init(platform_info_path, my_data,
+                       true, &platform_set_parameters);
 
     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
     if (my_data->acdb_handle == NULL) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index d675a5d..6991a12 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1653,7 +1653,8 @@
 
     my_data->declared_mic_count = 0;
     /* Initialize platform specific ids and/or backends*/
-    platform_info_init(platform_info_file, my_data);
+    platform_info_init(platform_info_file, my_data,
+                       true, &platform_set_parameters);
 
     ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
     adev->audio_route = audio_route_init(snd_card_num, mixer_xml_file);
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 1a7d2c3..8e249da 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -117,11 +117,11 @@
 
 bool platform_sound_trigger_usecase_needs_event(audio_usecase_t uc_id);
 
-/* From platform_info.c */
-int platform_info_init(const char *filename, void *);
-
 typedef int (*set_parameters_fn)(void *platform, struct str_parms *parms);
-int snd_card_info_init(const char *filename, void *, set_parameters_fn);
+
+/* From platform_info.c */
+int platform_info_init(const char *filename, void *,
+                       bool do_full_parse, set_parameters_fn);
 
 int platform_get_usecase_index(const char * usecase);
 int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index c89020d..0695592 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -25,6 +25,7 @@
 #include "platform_api.h"
 #include <platform.h>
 #include <math.h>
+#include <pthread.h>
 
 /*
  * Mandatory microphone characteristics include: device_id, type, address, location, group,
@@ -82,17 +83,19 @@
     [ACDB_METAINFO_KEY] = process_acdb_metainfo_key,
 };
 
-static set_parameters_fn set_parameters = &platform_set_parameters;
-
 static section_t section;
 
 struct platform_info {
+    pthread_mutex_t   lock;
     bool              do_full_parse;
     void             *platform;
     struct str_parms *kvpairs;
+    set_parameters_fn set_parameters;
 };
 
-static struct platform_info my_data = {true, NULL, NULL};
+static struct platform_info my_data = {PTHREAD_MUTEX_INITIALIZER,
+                                       true, NULL, NULL,
+                                       &platform_set_parameters};
 
 struct audio_string_to_enum {
     const char* name;
@@ -415,7 +418,7 @@
     }
 
     str_parms_add_str(my_data.kvpairs, (char*)attr[1], (char*)attr[3]);
-    set_parameters(my_data.platform, my_data.kvpairs);
+    my_data.set_parameters(my_data.platform, my_data.kvpairs);
 done:
     return;
 }
@@ -857,14 +860,8 @@
     }
 }
 
-int snd_card_info_init(const char *filename, void *platform, set_parameters_fn fn)
-{
-    set_parameters = fn;
-    my_data.do_full_parse = false;
-    return platform_info_init(filename, platform);
-}
-
-int platform_info_init(const char *filename, void *platform)
+int platform_info_init(const char *filename, void *platform,
+                       bool do_full_parse, set_parameters_fn fn)
 {
     XML_Parser      parser;
     FILE            *file;
@@ -873,7 +870,6 @@
     void            *buf;
     static const uint32_t kBufSize = 1024;
     char   platform_info_file_name[MIXER_PATH_MAX_LENGTH]= {0};
-    section = ROOT;
 
     if (filename == NULL) {
         strlcpy(platform_info_file_name, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
@@ -899,8 +895,12 @@
         goto err_close_file;
     }
 
+    pthread_mutex_lock(&my_data.lock);
+    section = ROOT;
+    my_data.do_full_parse = do_full_parse;
     my_data.platform = platform;
     my_data.kvpairs = str_parms_create();
+    my_data.set_parameters = fn;
 
     XML_SetElementHandler(parser, start_tag, end_tag);
 
@@ -931,10 +931,12 @@
             break;
     }
 
-    set_parameters = &platform_set_parameters;
-    my_data.do_full_parse = true;
-
 err_free_parser:
+    if (my_data.kvpairs != NULL) {
+        str_parms_destroy(my_data.kvpairs);
+        my_data.kvpairs = NULL;
+    }
+    pthread_mutex_unlock(&my_data.lock);
     XML_ParserFree(parser);
 err_close_file:
     fclose(file);