Merge "hal: enhance vndk fwk detection"
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index bb3437a..11ee448 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -68,7 +68,7 @@
 #define MAX_NUM_CHANNELS 8
 #define Q14_GAIN_UNITY 0x4000
 
-static int is_running_vendor_enhanced_fwk = 0;
+static int  vendor_enhanced_info = 0;
 static bool is_compress_meta_data_enabled = false;
 
 struct snd_card_split cur_snd_card_split = {
@@ -1774,10 +1774,10 @@
 
 //START: SPEAKER_PROTECTION ==========================================================
 #ifdef __LP64__
-#define SPKR_PROT_LIB_PATH  "/vendor/lib64/libspkrprot.so"
+#define SPKR_PROT_LIB_PATH         "/vendor/lib64/libspkrprot.so"
 #define CIRRUS_SPKR_PROT_LIB_PATH  "/vendor/lib64/libcirrusspkrprot.so"
 #else
-#define SPKR_PROT_LIB_PATH  "/vendor/lib/libspkrprot.so"
+#define SPKR_PROT_LIB_PATH         "/vendor/lib/libspkrprot.so"
 #define CIRRUS_SPKR_PROT_LIB_PATH  "/vendor/lib/libcirrusspkrprot.so"
 #endif
 
@@ -1817,22 +1817,22 @@
 
 void spkr_prot_feature_init(bool is_feature_enabled)
 {
-    ALOGD("%s: Called with feature %s, is_running_with_enhanced_fwk %d", __func__,
-            is_feature_enabled?"Enabled":"NOT Enabled", is_running_vendor_enhanced_fwk);
+    ALOGD("%s: Called with feature %s, vendor_enhanced_info 0x%x", __func__,
+            is_feature_enabled ? "Enabled" : "NOT Enabled", vendor_enhanced_info);
     if (is_feature_enabled) {
-        //dlopen lib
-        if (is_running_vendor_enhanced_fwk)
-            spkr_prot_lib_handle = dlopen(SPKR_PROT_LIB_PATH, RTLD_NOW);
-        else
+        // dlopen lib
+        if ((vendor_enhanced_info & 0x3) == 0x0) // Pure AOSP
             spkr_prot_lib_handle = dlopen(CIRRUS_SPKR_PROT_LIB_PATH, RTLD_NOW);
+        else
+            spkr_prot_lib_handle = dlopen(SPKR_PROT_LIB_PATH, RTLD_NOW);
 
         if (spkr_prot_lib_handle == NULL) {
             ALOGE("%s: dlopen failed", __func__);
             goto feature_disabled;
         }
-        //map each function
-        //if mandatoy functions are not found, disble feature
 
+        // map each function
+        // if mandatoy functions are not found, disble feature
         // Mandatory functions
         if (((spkr_prot_init =
              (spkr_prot_init_t)dlsym(spkr_prot_lib_handle, "spkr_prot_init")) == NULL) ||
@@ -1853,7 +1853,6 @@
         }
 
         // optional functions, can be NULL
-
         spkr_prot_set_parameters = NULL;
         fbsp_set_parameters = NULL;
         fbsp_get_parameters = NULL;
@@ -5701,7 +5700,7 @@
 
 void audio_extn_feature_init()
 {
-    is_running_vendor_enhanced_fwk = audio_extn_utils_is_vendor_enhanced_fwk();
+    vendor_enhanced_info = audio_extn_utils_get_vendor_enhanced_info();
 
     // register feature init functions here
     // each feature needs a vendor property
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 5402b81..db769da 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -820,7 +820,8 @@
 int audio_extn_utils_get_sample_rate_from_string(const char *);
 int audio_extn_utils_get_channels_from_string(const char *);
 void audio_extn_utils_release_snd_device(snd_device_t snd_device);
-int audio_extn_utils_is_vendor_enhanced_fwk();
+bool audio_extn_utils_is_vendor_enhanced_fwk();
+int audio_extn_utils_get_vendor_enhanced_info();
 int audio_extn_utils_get_app_sample_rate_for_device(struct audio_device *adev,
                                     struct audio_usecase *usecase, int snd_device);
 
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index b25fe3c..5bdc881 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -117,9 +117,15 @@
 #define VNDK_FWK_LIB_PATH "/vendor/lib/libqti_vndfwk_detect.so"
 #endif
 
-static void *vndk_fwk_lib_handle = NULL;
-typedef int (*vndk_fwk_isVendorEnhancedFwk_t)();
-static vndk_fwk_isVendorEnhancedFwk_t vndk_fwk_isVendorEnhancedFwk;
+typedef struct vndkfwk_s {
+    void *lib_handle;
+    int (*isVendorEnhancedFwk)(void);
+    int (*getVendorEnhancedInfo)(void);
+    const char *lib_name;
+} vndkfwk_t;
+
+static vndkfwk_t mVndkFwk = {
+    NULL, NULL, NULL, VNDK_FWK_LIB_PATH};
 
 typedef struct {
     const char *id_string;
@@ -2978,15 +2984,15 @@
             LISTEN_EVENT_SND_DEVICE_FREE);
 }
 
-int audio_extn_utils_get_license_params
-(
-const struct audio_device *adev,
-struct audio_license_params *license_params
-)
+int audio_extn_utils_get_license_params(
+        const struct audio_device *adev,
+        struct audio_license_params *license_params)
 {
     if(!license_params)
         return -EINVAL;
-    return platform_get_license_by_product(adev->platform, (const char*)license_params->product, &license_params->key, license_params->license);
+
+    return platform_get_license_by_product(adev->platform,
+            (const char*)license_params->product, &license_params->key, license_params->license);
 }
 
 int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
@@ -3011,32 +3017,78 @@
                                sizeof(gain_cfg)/sizeof(gain_cfg[0]));
 }
 
-int audio_extn_utils_is_vendor_enhanced_fwk()
+static void vndk_fwk_init()
 {
-    static int is_running_with_enhanced_fwk = -EINVAL;
+    if (mVndkFwk.lib_handle != NULL)
+        return;
 
-    if (is_running_with_enhanced_fwk == -EINVAL) {
-        vndk_fwk_lib_handle = dlopen(VNDK_FWK_LIB_PATH, RTLD_NOW);
-        if (vndk_fwk_lib_handle != NULL) {
-            vndk_fwk_isVendorEnhancedFwk = (vndk_fwk_isVendorEnhancedFwk_t)
-                        dlsym(vndk_fwk_lib_handle, "isRunningWithVendorEnhancedFramework");
-            if (vndk_fwk_isVendorEnhancedFwk == NULL) {
-                ALOGW("%s: dlsym failed, defaulting to enhanced_fwk configuration",
-                       __func__);
-                is_running_with_enhanced_fwk = 1;
-            } else {
-                is_running_with_enhanced_fwk = vndk_fwk_isVendorEnhancedFwk();
-            }
-            dlclose(vndk_fwk_lib_handle);
-            vndk_fwk_lib_handle = NULL;
-        } else {
-            ALOGW("%s: VNDK_FWK_LIB not found, setting stock configuration", __func__);
-            is_running_with_enhanced_fwk = 0;
-        }
-        ALOGV("%s: vndk_fwk_isVendorEnhancedFwk=%d", __func__, is_running_with_enhanced_fwk);
+    mVndkFwk.lib_handle = dlopen(VNDK_FWK_LIB_PATH, RTLD_NOW);
+    if (mVndkFwk.lib_handle == NULL) {
+        ALOGW("%s: failed to dlopen VNDK_FWK_LIB %s", __func__,  strerror(errno));
+        return;
     }
 
-    return is_running_with_enhanced_fwk;
+    *(void **)(&mVndkFwk.isVendorEnhancedFwk) =
+        dlsym(mVndkFwk.lib_handle, "isRunningWithVendorEnhancedFramework");
+    if (mVndkFwk.isVendorEnhancedFwk == NULL) {
+        ALOGW("%s: dlsym failed %s", __func__, strerror(errno));
+        if (mVndkFwk.lib_handle) {
+            dlclose(mVndkFwk.lib_handle);
+            mVndkFwk.lib_handle = NULL;
+        }
+        return;
+    }
+
+
+    *(void **)(&mVndkFwk.getVendorEnhancedInfo) =
+        dlsym(mVndkFwk.lib_handle, "getVendorEnhancedInfo");
+    if (mVndkFwk.getVendorEnhancedInfo == NULL) {
+        ALOGW("%s: dlsym failed %s", __func__, strerror(errno));
+        if (mVndkFwk.lib_handle) {
+            dlclose(mVndkFwk.lib_handle);
+            mVndkFwk.lib_handle = NULL;
+        }
+    }
+
+    return;
+}
+
+bool audio_extn_utils_is_vendor_enhanced_fwk()
+{
+    static int is_vendor_enhanced_fwk = -EINVAL;
+    if (is_vendor_enhanced_fwk != -EINVAL)
+        return (bool)is_vendor_enhanced_fwk;
+
+    vndk_fwk_init();
+
+    if (mVndkFwk.isVendorEnhancedFwk != NULL) {
+        is_vendor_enhanced_fwk = mVndkFwk.isVendorEnhancedFwk();
+        ALOGW("%s: is_vendor_enhanced_fwk %d", __func__, is_vendor_enhanced_fwk);
+    } else {
+        is_vendor_enhanced_fwk = 0;
+        ALOGW("%s: default to non enhanced_fwk config", __func__);
+    }
+
+    return (bool)is_vendor_enhanced_fwk;
+}
+
+int audio_extn_utils_get_vendor_enhanced_info()
+{
+    static int vendor_enhanced_info = -EINVAL;
+    if (vendor_enhanced_info != -EINVAL)
+        return vendor_enhanced_info;
+
+    vndk_fwk_init();
+
+    if (mVndkFwk.getVendorEnhancedInfo != NULL) {
+        vendor_enhanced_info = mVndkFwk.getVendorEnhancedInfo();
+        ALOGW("%s: vendor_enhanced_info 0x%x", __func__, vendor_enhanced_info);
+    } else {
+        vendor_enhanced_info = 0x0;
+        ALOGW("%s: default to vendor_enhanced_info 0x0", __func__);
+    }
+
+    return vendor_enhanced_info;
 }
 
 int audio_extn_utils_get_perf_mode_flag(void)