FM AIDL: Add FM AIDL client support

CRs-Fixed: 3752112
Change-Id: Ica28992757fab98c0b7e142ba8ba3ca957e81721
diff --git a/fm_hci/Android.bp b/fm_hci/Android.bp
index 764b6c4..366f7a8 100644
--- a/fm_hci/Android.bp
+++ b/fm_hci/Android.bp
@@ -12,6 +12,10 @@
         "libhidlbase",
         "liblog",
         "libutils",
+        "libbinder_ndk",
+        "libbinder",
+        "android.hardware.bluetooth.audio-V3-ndk",
+        "vendor.qti.hardware.fm-V1-ndk",
         "vendor.qti.hardware.fm@1.0",
     ],
 
diff --git a/fm_hci/fm_hci.cpp b/fm_hci/fm_hci.cpp
index c08b884..527ecb4 100644
--- a/fm_hci/fm_hci.cpp
+++ b/fm_hci/fm_hci.cpp
@@ -41,6 +41,11 @@
 #include <condition_variable> // std::condition_variable
 #include <cstdlib>
 #include <thread>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+//#include <binder_auto_utils.h>
+#include <cassert>
 
 #include <utils/Log.h>
 #include <unistd.h>
@@ -52,6 +57,17 @@
 
 #include <hwbinder/ProcessState.h>
 
+#include <aidl/vendor/qti/hardware/fm/BnFmHci.h>
+#include <aidl/vendor/qti/hardware/fm/BnFmHciCallbacks.h>
+#include <aidl/vendor/qti/hardware/fm/IFmHci.h>
+
+#define ASSERT_LOG(condition, fmt, args...)                                 \
+  do {                                                                      \
+    if (!(condition)) {                                                     \
+      LOG_ALWAYS_FATAL("assertion '" #condition "' failed - " fmt, ##args); \
+    }                                                                       \
+  } while (false)
+
 using vendor::qti::hardware::fm::V1_0::IFmHci;
 using vendor::qti::hardware::fm::V1_0::IFmHciCallbacks;
 using vendor::qti::hardware::fm::V1_0::HciPacket;
@@ -62,11 +78,19 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::hidl_death_recipient;
 
+using ::aidl::vendor::qti::hardware::fm::BnFmHci;
+using fm_aidl = ::aidl::vendor::qti::hardware::fm::IFmHci;
+//using IBluetoothHci_1_1 = ::android::hardware::bluetooth::V1_1::IBluetoothHci;
+using AidlStatus = ::aidl::vendor::qti::hardware::fm::Status;
+
 static struct fm_hci_t hci;
 
 typedef std::unique_lock<std::mutex> Lock;
 static std::recursive_mutex mtx;
 android::sp<IFmHci> fmHci;
+std::shared_ptr<::aidl::vendor::qti::hardware::fm::IFmHci> fmAidlHci;
+::ndk::ScopedAIBinder_DeathRecipient aidl_death_recipient_;
+std::shared_ptr<::aidl::vendor::qti::hardware::fm::IFmHciCallbacks> aidl_callbacks_;
 
 static int enqueue_fm_rx_event(struct fm_event_header_t *hdr);
 static void dequeue_fm_rx_event();
@@ -82,8 +106,10 @@
 static bool hci_initialize();
 static void hci_transmit(struct fm_command_header_t *hdr);
 static void hci_close();
+static void initialization_complete(bool is_hci_initialize);
 #define HCI_EV_HW_ERR_EVENT             0x1A
 
+
 void hal_service_died() {
     struct fm_event_header_t *temp = (struct fm_event_header_t *)
                        malloc(sizeof(struct fm_event_header_t));
@@ -96,6 +122,40 @@
         ALOGE("%s: Memory Allocation failed for event buffer ",__func__);
     }
 }
+class AidlHciCallbacks : public ::aidl::vendor::qti::hardware::fm::BnFmHciCallbacks {
+ public:
+
+  ::ndk::ScopedAStatus initializationComplete(AidlStatus status) {
+    if(status == AidlStatus::SUCCESS)
+    {
+        initialization_complete(true);
+    } else {
+        initialization_complete(false);
+    }
+    return ::ndk::ScopedAStatus::ok();
+  }
+
+  ::ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& event) override {
+    struct fm_event_header_t *temp = (struct fm_event_header_t *) malloc(event.size());
+    if (temp != nullptr) {
+        memcpy(temp, event.data(), event.size());
+        uint8_t evt = temp->evt_code;
+        ALOGI("%s: evt_code:  0x%x", __func__, evt);
+        enqueue_fm_rx_event(temp);
+        ALOGI("%s: evt_code:  0x%x done", __func__, evt);
+    } else {
+        ALOGE("%s: Memory Allocation failed for event buffer ",__func__);
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+  }
+
+ private:
+  IFmHciCallbacks* callback_ = nullptr;
+};
+
+static constexpr char kFmAidlHalServiceName[] =
+    "vendor.qti.hardware.fm.IFmHci/default";
 
 class FmHciDeathRecipient : public hidl_death_recipient {
     public:
@@ -290,7 +350,7 @@
 
     ALOGI("%s command credits %d ", __func__, hci.command_credits);
 
-    while (1) 
+    while (1)
     {
        if (hci.command_credits == 0) {
           return;
@@ -584,6 +644,54 @@
         }
 };
 
+ bool start_aidl() {
+    ndk::SpAIBinder binder(AServiceManager_waitForService(kFmAidlHalServiceName));
+    fmAidlHci = fm_aidl::fromBinder(binder);
+    if (fmAidlHci != nullptr) {
+      ALOGE("Using the AIDL interface");
+      aidl_death_recipient_ =
+          ::ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new([](void* cookie) {
+            ALOGE("The Fm HAL service died. Dumping logs and crashing in 1 second.");
+            LOG_ALWAYS_FATAL("The Bluetooth HAL died.");
+          }));
+
+      auto death_link =
+          AIBinder_linkToDeath(fmAidlHci->asBinder().get(), aidl_death_recipient_.get(), NULL);
+
+       ASSERT_LOG(
+          death_link == STATUS_OK, "Unable to set the death recipient for the Bluetooth HAL");
+
+      hci.state = FM_RADIO_ENABLING;
+      aidl_callbacks_ = ::ndk::SharedRefBase::make<AidlHciCallbacks>();
+      fmAidlHci->initialize(aidl_callbacks_);
+    }
+    return true;
+ }
+
+ bool start_hidl() {
+    fmHci = IFmHci::getService();
+    if(fmHci == nullptr) {
+        ALOGE("FM hal service is not running");
+        return FM_HC_STATUS_NULL_POINTER;
+    }
+
+    auto death_link = fmHci->linkToDeath(fmHciDeathRecipient, 0);
+    if (!death_link.isOk()) {
+        ALOGE("%s: Unable to set the death recipient for the Fm HAL", __func__);
+        abort();
+    }
+    if (fmHci != nullptr) {
+    hci.state = FM_RADIO_ENABLING;
+    android::sp<IFmHciCallbacks> callbacks = new FmHciCallbacks();
+    auto hidl_daemon_status = fmHci->initialize(callbacks);
+    if(!hidl_daemon_status.isOk()) {
+        ALOGE("%s: HIDL daemon is dead", __func__);
+    }
+        return true;
+    } else {
+        return false;
+    }
+ }
 /*******************************************************************************
 **
 ** Function         hci_initialize
@@ -601,20 +709,16 @@
 {
     ALOGI("%s: acquiring mutex", __func__);
     std::lock_guard<std::recursive_mutex> lk(mtx);
-
-    if (fmHci != nullptr) {
-        hci.state = FM_RADIO_ENABLING;
-        android::sp<IFmHciCallbacks> callbacks = new FmHciCallbacks();
-        auto hidl_daemon_status = fmHci->initialize(callbacks);
-        if(!hidl_daemon_status.isOk()) {
-            ALOGE("%s: HIDL daemon is dead", __func__);
-        }
-        return true;
+    if (AServiceManager_isDeclared(kFmAidlHalServiceName)) {
+      start_aidl();
     } else {
-        return false;
+      start_hidl();
     }
+    return true;
+
 }
 
+
 /*******************************************************************************
 **
 ** Function         hci_transmit
@@ -640,6 +744,9 @@
         if(!hidl_daemon_status.isOk()) {
             ALOGE("%s: send Command failed, HIDL daemon is dead", __func__);
         }
+    } else if( fmAidlHci != nullptr) {
+        data.setToExternal((uint8_t *)hdr, 3 + hdr->len);
+        auto hidl_daemon_status = fmAidlHci->sendHciCommand(data);
     } else {
         ALOGI("%s: fmHci is NULL", __func__);
     }
@@ -675,6 +782,17 @@
             ALOGE("%s: HIDL daemon is dead", __func__);
         }
         fmHci = nullptr;
+    } else if(fmAidlHci != nullptr) {
+        auto death_unlink =
+            AIBinder_unlinkToDeath(fmAidlHci->asBinder().get(), aidl_death_recipient_.get(), NULL);
+        if (death_unlink != STATUS_OK) {
+          ALOGE("Error unlinking death recipient from the Bluetooth HAL");
+        }
+        auto close_status = fmAidlHci->close();
+        if (!close_status.isOk()) {
+          ALOGE("Error calling close on the Bluetooth HAL");
+        }
+        fmAidlHci = nullptr;
     }
 }
 
@@ -707,18 +825,6 @@
         return FM_HC_STATUS_NULL_POINTER;
     }
 
-    fmHci = IFmHci::getService();
-    if(fmHci == nullptr) {
-        ALOGE("FM hal service is not running");
-        return FM_HC_STATUS_NULL_POINTER;
-    }
-
-    auto death_link = fmHci->linkToDeath(fmHciDeathRecipient, 0);
-    if (!death_link.isOk()) {
-        ALOGE("%s: Unable to set the death recipient for the Fm HAL", __func__);
-        abort();
-    }
-
     memset(&hci, 0, sizeof(struct fm_hci_t));
 
     hci.cb = hci_hal->cb;
@@ -814,5 +920,4 @@
     }
 
     hci.state = FM_RADIO_DISABLED;
-}
-
+}
\ No newline at end of file
diff --git a/jni/Android.bp b/jni/Android.bp
index 1d6e8e0..2a70f1a 100755
--- a/jni/Android.bp
+++ b/jni/Android.bp
@@ -12,7 +12,6 @@
         "libnativehelper",
         "liblog",
         "libcutils",
-        "libbtconfigstore",
     ],
 
     include_dirs: [
diff --git a/jni/android_hardware_fm.cpp b/jni/android_hardware_fm.cpp
index 6809a27..167e9f2 100644
--- a/jni/android_hardware_fm.cpp
+++ b/jni/android_hardware_fm.cpp
@@ -157,10 +157,8 @@
 void *lib_handle;
 static int slimbus_flag = 0;
 
-static char soc_name[16];
+static char soc_name[PROPERTY_VALUE_MAX];
 bool isSocNameAvailable = false;
-static bt_configstore_interface_t* bt_configstore_intf = NULL;
-static void *bt_configstore_lib_handle = NULL;
 
 static JNIEnv *mCallbackEnv = NULL;
 static jobject mCallbacksObj = NULL;
@@ -651,13 +649,12 @@
 
 static void get_property(int ptype, char *value)
 {
-    std::vector<vendor_property_t> vPropList;
-    bt_configstore_intf->get_vendor_properties(ptype, vPropList);
-
-    for (auto&& vendorProp : vPropList) {
-        if (vendorProp.type == ptype) {
-            strlcpy(value, vendorProp.value,PROPERTY_VALUE_MAX);
-        }
+    if (FM_STATS_PROP == ptype) {
+        property_get("persist.vendor.fm.stats", value, "false");
+    } else if( FM_PROP_WAN_RATCONF == ptype) {
+        property_get("persist.vendor.fm_wan.ratconf", value, "0");
+    } else if ( FM_PROP_BTWLAN_LPFENABLER == ptype) {
+        property_get("persist.vendor.btwlan.lpfenabler", value, "0");
     }
 }
 
@@ -954,20 +951,12 @@
 static jstring android_hardware_fmradio_FmReceiverJNI_getSocNameNative
  (JNIEnv* env)
 {
-    ALOGI("%s, bt_configstore_intf: %p isSocNameAvailable: %d",
-        __FUNCTION__, bt_configstore_intf, isSocNameAvailable);
+    ALOGI("%s, isSocNameAvailable: %d", __FUNCTION__, 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);
-          }
-       }
+    if (isSocNameAvailable == false) {
+        property_get("persist.vendor.qcom.bluetooth.soc", soc_name, "pronto");
+        isSocNameAvailable = true;
+        ALOGI("%s:: soc_name = %s",__func__, soc_name);
     }
     return env->NewStringUTF(soc_name);
 }
@@ -1103,58 +1092,14 @@
 
 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)