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)