Fm: Use btconfigstore interface to fetch vendor features

Use btconfigstore interface to fetch vendor features.

Change-Id: Ic89a03f1231610c61b9d3cc932fd7da0bf82cae8
diff --git a/jni/Android.mk b/jni/Android.mk
index bf12d79..957947a 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -15,10 +15,13 @@
         libandroid_runtime \
         libnativehelper \
         liblog \
-        libcutils
+        libcutils \
+        libbtconfigstore
 
 LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
-                   $(TOP)/libnativehelper/include/nativehelper
+                   $(TOP)/libnativehelper/include/nativehelper \
+                   $(TOP)/vendor/qcom/opensource/commonsys-intf/bluetooth/include \
+                   $(TOP)/vendor/qcom/opensource/commonsys/bluetooth_ext/system_bt_ext/btconfigstore
 LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
 
 LOCAL_MODULE := libqcomfm_jni
diff --git a/jni/android_hardware_fm.cpp b/jni/android_hardware_fm.cpp
index 789d52f..bb0b25e 100644
--- a/jni/android_hardware_fm.cpp
+++ b/jni/android_hardware_fm.cpp
@@ -43,6 +43,9 @@
 #include <dlfcn.h>
 #include "android_runtime/Log.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "bt_configstore.h"
+#include <vector>
+
 
 #define RADIO "/dev/radio0"
 #define FM_JNI_SUCCESS 0L
@@ -88,6 +91,12 @@
 void *lib_handle;
 static int slimbus_flag = 0;
 
+static char soc_name[16];
+bool isSocNameAvailable = false;
+static bt_configstore_interface_t* bt_configstore_intf = NULL;
+static void *bt_configstore_lib_handle = NULL;
+
+
 typedef void (*enb_result_cb)();
 typedef void (*tune_rsp_cb)(int Freq);
 typedef void (*seek_rsp_cb)(int Freq);
@@ -156,6 +165,8 @@
 jmethodID method_enableSlimbusCallback;
 jmethodID method_enableSoftMuteCallback;
 
+int load_bt_configstore_lib();
+
 static bool checkCallbackThread() {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    if (mCallbackEnv != env || mCallbackEnv == NULL)
@@ -685,11 +696,7 @@
        return FM_JNI_FAILURE;
     }
 
-    property_get("vendor.bluetooth.soc", value, NULL);
-
-    ALOGD("BT soc is %s\n", value);
-
-    if ((strcmp(value, "rome") != 0) && (strcmp(value, "hastings") != 0))
+    if ((strcmp(soc_name, "rome") != 0) && (strcmp(soc_name, "hastings") != 0))
     {
        /*Set the mode for soc downloader*/
        property_set("vendor.hw.fm.mode", "normal");
@@ -724,13 +731,8 @@
     int i = 0;
     int cleanup_success = 0;
     char retval =0;
-    char value[PROPERTY_VALUE_MAX] = {'\0'};
 
-    property_get("vendor.bluetooth.soc", value, NULL);
-
-    ALOGD("BT soc is %s\n", value);
-
-    if ((strcmp(value, "rome") != 0) && (strcmp(value, "hastings") != 0))
+    if ((strcmp(soc_name, "rome") != 0) && (strcmp(soc_name, "hastings") != 0))
     {
        property_set("ctl.stop", "fm_dl");
     }
@@ -739,12 +741,7 @@
 }
 
 static bool is_soc_cherokee() {
-
-    char value[PROPERTY_VALUE_MAX] = {'\0'};
-    property_get("vendor.bluetooth.soc", value, NULL);
-    ALOGD("BT soc is %s\n", value);
-
-    if(strcmp(value, "cherokee") == 0)
+    if(strcmp(soc_name, "cherokee") == 0)
         return true;
     else
         return false;
@@ -1198,17 +1195,13 @@
 /* native interface */
 static jint android_hardware_fmradio_FmReceiverJNI_setNotchFilterNative(JNIEnv * env, jobject thiz,jint fd, jint id, jboolean aValue)
 {
-    char value[PROPERTY_VALUE_MAX] = {'\0'};
     int init_success = 0,i;
     char notch[PROPERTY_VALUE_MAX] = {0x00};
+    char value[PROPERTY_VALUE_MAX];
     int band;
     int err = 0;
 
-    property_get("vendor.bluetooth.soc", value, NULL);
-
-    ALOGD("BT soc is %s\n", value);
-
-    if ((strcmp(value, "rome") != 0) && (strcmp(value, "hastings") != 0))
+    if ((strcmp(soc_name, "rome") != 0) && (strcmp(soc_name, "hastings") != 0))
     {
        /*Enable/Disable the WAN avoidance*/
        property_set("vendor.hw.fm.init", "0");
@@ -1264,11 +1257,7 @@
     char value[PROPERTY_VALUE_MAX] = {'\0'};
     char firmwareVersion[80];
 
-    property_get("vendor.bluetooth.soc", value, NULL);
-
-    ALOGD("BT soc is %s\n", value);
-
-    if ((strcmp(value, "rome") != 0) && (strcmp(value, "hastings") != 0))
+    if ((strcmp(soc_name, "rome") != 0) && (strcmp(soc_name, "hastings") != 0))
     {
        /*Enable/Disable Analog Mode FM*/
        property_set("vendor.hw.fm.init", "0");
@@ -1648,6 +1637,27 @@
     return err;
 }
 
+static jstring android_hardware_fmradio_FmReceiverJNI_getSocNameNative
+ (JNIEnv* env)
+{
+    ALOGI("%s, bt_configstore_intf: %p isSocNameAvailable: %d",
+        __FUNCTION__, bt_configstore_intf, isSocNameAvailable);
+
+    if (bt_configstore_intf != NULL && isSocNameAvailable == false) {
+       std::vector<vendor_property_t> vPropList;
+
+       bt_configstore_intf->get_vendor_properties(BT_PROP_SOC_TYPE, vPropList);
+       for (auto&& vendorProp : vPropList) {
+          if (vendorProp.type == BT_PROP_SOC_TYPE) {
+            strlcpy(soc_name, vendorProp.value, sizeof(soc_name));
+            isSocNameAvailable = true;
+            ALOGI("%s:: soc_name = %s",__func__, soc_name);
+          }
+       }
+    }
+    return env->NewStringUTF(soc_name);
+}
+
 static void classInitNative(JNIEnv* env, jclass clazz) {
 
     ALOGI("ClassInit native called \n");
@@ -1702,7 +1712,6 @@
 }
 
 static void initNative(JNIEnv *env, jobject object) {
-
 if (is_soc_cherokee()) {
     int status;
     ALOGI("Init native called \n");
@@ -1799,12 +1808,64 @@
              (void*)android_hardware_fmradio_FmReceiverJNI_enableSlimbusNative},
         { "enableSoftMute", "(II)I",
              (void*)android_hardware_fmradio_FmReceiverJNI_enableSoftMuteNative},
+        {"getSocNameNative", "()Ljava/lang/String;",
+             (void*) android_hardware_fmradio_FmReceiverJNI_getSocNameNative},
 };
 
 int register_android_hardware_fm_fmradio(JNIEnv* env)
 {
+        ALOGI("%s, bt_configstore_intf", __FUNCTION__, bt_configstore_intf);
+        if (bt_configstore_intf == NULL) {
+          load_bt_configstore_lib();
+        }
+
         return jniRegisterNativeMethods(env, "qcom/fmradio/FmReceiverJNI", gMethods, NELEM(gMethods));
 }
+
+int deregister_android_hardware_fm_fmradio(JNIEnv* env)
+{
+        if (bt_configstore_lib_handle) {
+            dlclose(bt_configstore_lib_handle);
+            bt_configstore_lib_handle = NULL;
+            bt_configstore_intf = NULL;
+        }
+        return 0;
+}
+
+int load_bt_configstore_lib() {
+    const char* sym = BT_CONFIG_STORE_INTERFACE_STRING;
+
+    bt_configstore_lib_handle = dlopen("libbtconfigstore.so", RTLD_NOW);
+    if (!bt_configstore_lib_handle) {
+        const char* err_str = dlerror();
+        ALOGE("%s:: failed to load Bt Config store library, error= %s",
+            __func__, (err_str) ? err_str : "error unknown");
+        goto error;
+    }
+
+    // Get the address of the bt_configstore_interface_t.
+    bt_configstore_intf = (bt_configstore_interface_t*)dlsym(bt_configstore_lib_handle, sym);
+    if (!bt_configstore_intf) {
+        ALOGE("%s:: failed to load symbol from bt config store library = %s",
+            __func__, sym);
+        goto error;
+    }
+
+    // Success.
+    ALOGI("%s::  loaded HAL: bt_configstore_interface_t = %p , bt_configstore_lib_handle= %p",
+        __func__, bt_configstore_intf, bt_configstore_lib_handle);
+    return 0;
+
+  error:
+    if (bt_configstore_lib_handle) {
+      dlclose(bt_configstore_lib_handle);
+      bt_configstore_lib_handle = NULL;
+      bt_configstore_intf = NULL;
+    }
+
+    return -EINVAL;
+}
+
 } // end namespace
 
 jint JNI_OnLoad(JavaVM *jvm, void *reserved)
@@ -1825,3 +1886,22 @@
     }
     return JNI_VERSION_1_6;
 }
+
+jint JNI_OnUnLoad(JavaVM *jvm, void *reserved)
+{
+    JNIEnv *e;
+    int status;
+    g_jVM = jvm;
+
+    ALOGI("FM : unLoading QCOMM FM-JNI");
+    if (jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {
+        ALOGE("JNI version mismatch error");
+        return JNI_ERR;
+    }
+
+    if ((status = android::deregister_android_hardware_fm_fmradio(e)) < 0) {
+        ALOGE("jni adapter service unregistration failure, status: %d", status);
+        return JNI_ERR;
+    }
+    return JNI_VERSION_1_6;
+}