本文中进行的Bluedroid 源码学习是基于Android P(9) 进行.
对于bluedroid(system/bt)最终是以一个动态库(libbluetooth)的方式对外提供, 在Bluetooth APK中使用的时候是以动态的方式进行加载的
对外接口定义
在include/hardware/bluetooth.h中声明了bt_interface_t这种包含函数指针类型的结构体.
/** Represents the standard Bluetooth DM interface. */
typedef struct {
/** set to sizeof(bt_interface_t) */
size_t size;
/**
* Opens the interface and provides the callback routines
* to the implemenation of this interface.
*/
int (*init)(bt_callbacks_t* callbacks);
}bt_interface_t;
#define BLUETOOTH_INTERFACE_STRING "bluetoothInterface"
在下面的代码中定义bt_interface_t类型的bluetoothInterface 并对其成员进行赋值.
btif/src/bluetooth.cc
/*****************************************************************************
*
* BLUETOOTH HAL INTERFACE FUNCTIONS
*
****************************************************************************/
static int init(bt_callbacks_t* callbacks) {
LOG_INFO(LOG_TAG, "%s", __func__);
if (interface_ready()) return BT_STATUS_DONE;
#ifdef BLUEDROID_DEBUG
allocation_tracker_init();
#endif
bt_hal_cbacks = callbacks;
stack_manager_get_interface()->init_stack();
btif_debug_init();
return BT_STATUS_SUCCESS;
}
EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
sizeof(bluetoothInterface),
init,
};
这里只是摘取了init这一接口的实现,
从这里可以看出以下两点:
- init 是外部需要调用的接口,但这里修饰为了static. 这里通过bluetoothInterface 这一结构体封装了对外的接口init
- 通过结构体函数指针的方式,一定的面向对象的思维,封装性
补充说明: “EXPORT_SYMBOL=attribute((visibility(“default”)))”
如何使用Bluedorid(system/bt)中对外的接口
上面的内容讲了接口的定义,那外部该怎么调用该接口呢?
在在 bt_core/src/hal_util.cc 中
int hal_util_load_bt_library(const bt_interface_t** interface) {
const char* sym = BLUETOOTH_INTERFACE_STRING;
bt_interface_t* itf = nullptr;
// Always try to load the default Bluetooth stack on GN builds.
void* handle = dlopen(BLUETOOTH_LIBRARY_NAME, RTLD_NOW);
if (!handle) {
const char* err_str = dlerror();
LOG(ERROR) << __func__ << ": failed to load bluetooth library, error="
<< (err_str ? err_str : "error unknown");
goto error;
}
// Get the address of the bt_interface_t.
itf = (bt_interface_t*)dlsym(handle, sym);
if (!itf) {
LOG(ERROR) << __func__ << ": failed to load symbol from Bluetooth library "
<< sym;
goto error;
}
// Success.
LOG(INFO) << __func__ << " loaded HAL path=" << BLUETOOTH_LIBRARY_NAME
<< " btinterface=" << itf << " handle=" << handle;
*interface = itf;
return 0;
error:
*interface = NULL;
if (handle) dlclose(handle);
return -EINVAL;
}
在上述代码中,通过dlopen和dlsym 将bluetoothInterface 这一结构体的地址载入内存,然后进行init等接口的调用.
在btcore/include/hal_util.h中,
#pragma once
#include <hardware/bluetooth.h>
// Loads the Bluetooth library. This function looks explicitly for
// libbluetooth.so and loads it.
int hal_util_load_bt_library(const bt_interface_t** interface);
补充说明: 这里需要注意的是: hal_util_load_bt_library 在Bluetooth APK中重新定义了