Android Bluetooth藍牙enable過程
Android Bluetooth架構
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN2XjlGcjAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL9MGVPNzZE1EMJRVT3V1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2QTO3EzNwgTM4ETMxAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
enable的追蹤從settings app開始,一直到最底層的driver,基本按照上圖的架構,把函數的調用過程代入圖中有助于了解整個藍牙的架構。
源碼追蹤
以下為Bluetooth的enable從settings app開始往下追蹤的過程,當然僅為調用過程。
1.BluetoothEnabler.java(packages\apps\settings\src\com\android\settings\bluetooth)
|onSwitchChanged()
|mLocalAdapter.setBluetoothEnabled(isChecked);
其中BluetoothEnabler實作了SwitchBar.OnSwitchChangeListener監聽藍牙開關的狀态變化;當開關被點選了,onSwitchChanged被回調。
檢視mLocalAdapter定義:
2.LocalBluetoothAdapter.java (packages\apps\settings\src\com\android\settings\bluetooth)
|setBluetoothEnabled()
|mAdapter.enable()
檢視mAdapter的定義
3.BluetoothAdapter.java (frameworks\base\core\java\android\bluetooth)
|enable()
|mManagerService.enable()
檢視mManagerService定義
這裡是通過AIDL機制完成程序間的通信,調用的是BluetoothManagerService的enable()函數。
4.BluetoothManagerService.java(frameworks\base\services\core\java\com\android\server)
class BluetoothManagerService extends IBluetoothManager.Stub
|enable()
|sendEnableMsg(false);
|mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,0, 0));
在他的内部類BluetoothHandler繼承了Handler類,處理傳遞的消息:
|handleMessage(Message msg)
|case MESSAGE_ENABLE
|handleEnable(msg.arg1 == 1); // msg.arg1 = 0
|if ((mBluetooth == null) && (!mBinding))
|Intent i = new Intent(IBluetooth.class.getName());
|doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT);
// 啟動AdapterService服務
|doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
|mContext.bindServiceAsUser(intent, conn, flags, user);
// 啟動AdapterService服務後會回調mConnection的onServiceConnected()方法
| onServiceConnected(ComponentName className, IBinder service)
| Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
| if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService"))
|msg.arg1 = SERVICE_IBLUETOOTH;
|else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService"))
|msg.arg1 = SERVICE_IBLUETOOTHGATT;
|msg.obj = service;
|mHandler.sendMessage(msg);
發出的MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息在handleMessage處理:
|handleMessage(Message msg)
|case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
|IBinder service = (IBinder) msg.obj;
|mBluetooth = IBluetooth.Stub.asInterface(service);
|!mBluetooth.enable()
檢視mBluetooth的定義:
5.AdapterService.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
AdapterService内部類AdapterServiceBinder extends IBluetooth.Stub
|enable(boolean quietMode)
|Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON);
|mAdapterStateMachine.sendMessage(m);
檢視mAdapterStateMachine的定義:
6.AdapterState.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
|processMessage(Message msg)
|case BLE_TURN_ON
|adapterService.processStart();
檢視定義:
7.AdapterService.java (packages\apps\bluetooth\src\com\android\bluetooth\btservice)
|processStart()
| mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED));
8.AdapterState.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
|processMessage(Message msg)
|case STARTED
|adapterService.enableNative()
9.AdapterService.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
其中定義了native函數enableNative:
它加載了動态連結庫libbluetooth_jni.so,也就意味着enableNative函數的具體實作打包在這個動态連結庫中。
進到目錄packages\apps\bluetooth下,有一個jni的目錄,一般跟bluetooth這個原生應用有關的jni都在這裡實作;下面有一個Android.mk,檢視該檔案,其中有打包成庫的名稱
LOCAL_MODULE := libbluetooth_jni
正好是我們要找的動态連結庫,我們要找的函數就是在這個目錄下了。
mk檔案中也提供了編譯的時候包含的源檔案:
LOCAL_SRC_FILES:= \
com_android_bluetooth_btservice_AdapterService.cpp \
com_android_bluetooth_btservice_QAdapterService.cpp \
com_android_bluetooth_hfp.cpp \
com_android_bluetooth_hfpclient.cpp \
com_android_bluetooth_a2dp.cpp \
com_android_bluetooth_a2dp_sink.cpp \
com_android_bluetooth_avrcp.cpp \
com_android_bluetooth_avrcp_controller.cpp \
com_android_bluetooth_hid.cpp \
com_android_bluetooth_hidd.cpp \
com_android_bluetooth_hdp.cpp \
com_android_bluetooth_pan.cpp \
com_android_bluetooth_gatt.cpp \
android_hardware_wipower.cpp
JNI函數最終都是通過jniRegisterNativeMethods完成注冊,将類名和Native函數對應起來。
進入packages/apps/Bluetooth/jni目錄搜尋:
$ grep "com/android/bluetooth/btservice/AdapterService" * -nR
com_android_bluetooth_btservice_AdapterService.cpp:1272: return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService",
發現類AdapterService對應的JNI函數在com_android_bluetooth_btservice_AdapterService.cpp注冊。
10.com_android_bluetooth_btservice_AdapterService.cpp (packages\apps\bluetooth\jni)
|enableNative(JNIEnv* env, jobject obj)
|sBluetoothInterface->enable()
檢視定義
bt_interface_t是Bluetooth.h (hardware\libhardware\include\hardware)中定義的結構體。
我們需要找到它的實作,在檔案中查找sBluetoothInterface找到它指派的地方:
它是由btStack也就是藍牙協定棧傳回的,我們繼續看btStack的關鍵代碼:
const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
//這句應該獲得btStack執行個體
err = hw_get_module(id, (hw_module_t const**)&module);
err = module->methods->open(module, id, &abstraction);
//最終轉換為btStack結構體
bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
找到hw_get_module函數,其中果然有加載btStack子產品:
11.Bluetooth.c (external\bluetooth\bluedroid\btif\src)
我們知道Bluedroid的代碼在external\bluetooth\bluedroid,是以我們在其中搜尋很容易找到sBluetoothInterface的實作代碼。
|static const bt_interface_t bluetoothInterface
|enable
|btif_enable_bluetooth()
12.Btif_core.c (external\bluetooth\bluedroid\btif\src)
|btif_enable_bluetooth(void)
|GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
(UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
sizeof(bte_btu_stack)); // create btu task
|bte_main_enable()
13.Bte_main.c (external\bluetooth\bluedroid\main)
|bte_main_enable()
|bte_hci_enable()
|bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);
|bt_hc_if->set_power(BT_HC_CHIP_PWR_ON)
檢視定義
以及指派的語句
14.Bt_hci_bdroid.c (external\bluetooth\bluedroid\hci\src)
|static const bt_hc_interface_t bluetoothHCLibInterface
|init
vendor_open(local_bdaddr);
p_hci_if = &hci_h4_func_table;
p_hci_if->init();
userial_init();
|set_power
|vendor_send_command(BT_VND_OP_POWER_CTRL, &pwr_state);
hci層發送了BT_VND_OP_POWER_CTRL的指令。
15.Vendor.c (external\bluetooth\bluedroid\hci\src)
VENDOR_LIBRARY_NAME = "libbt-vendor.so";
|vendor_open(const uint8_t *local_bdaddr)
lib_handle = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
vendor_interface = (bt_vendor_interface_t *)dlsym(lib_handle, VENDOR_LIBRARY_SYMBOL_NAME);
dlsym根據動态連結庫操作句柄與符号,傳回符号對應的位址。
可以得到vendor_interface的實作代碼在libbt-vendor.so這個動态連結庫中。
|vendor_send_command(bt_vendor_opcode_t opcode, void *param)
|vendor_interface->op(opcode, param)
16.Bt_vendor_brcm.c (hardware\broadcom\libbt\src)
全局抓取一下libbt-vendor.so,我們在hardware\broadcom\libbt下的Android.mk中找到了libbt-vendor.so的包含的源檔案。
抓取一下bt_vendor_interface_t,發現在Bt_vendor_brcm.c找到了它的實作:
|const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE
|op(bt_vendor_opcode_t opcode, void *param)
|upio_set_bluetooth_power(UPIO_BT_POWER_ON);
17.Upio.c (hardware\broadcom\libbt\src)
|upio_set_bluetooth_power(int on)
|fd = open(rfkill_state_path, O_WRONLY);
|sz = write(fd, &buffer, 1);
檢視一下rfkill_state_path的指派
|int init_rfkill()
|asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id);
通過往/sys/class/rfkill/rfkill0/state寫入1給藍牙上電。
代碼處理檔案流程:
---------------------------------------------Settings---------------------------------------
1.BluetoothEnabler.java(packages\apps\settings\src\com\android\settings\bluetooth)
2.LocalBluetoothAdapter.java(frameworks\base\packages\settingslib\src\com\android\settingslib\bluetooth)
---------------------------------------------framework-----------------------------------------
3.BluetoothAdapter.java (frameworks\base\core\java\android\bluetooth)
4.BluetoothManagerService.java(frameworks\base\services\core\java\com\android\server)
--------------------------------------------bluetooth apk------------------------------------------
5.AdapterService.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
6.AdapterState.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
7.AdapterService.java (packages\apps\bluetooth\src\com\android\bluetooth\btservice)
8.AdapterState.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
9.AdapterService.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
--------------------------------------------jni--------------------------------------------
10.com_android_bluetooth_btservice_AdapterService.cpp (packages\apps\bluetooth\jni)
--------------------------------------------bluetooth.default.so------------------------------------------
11.Bluetooth.c (external\bluetooth\bluedroid\btif\src)
12.Btif_core.c (external\bluetooth\bluedroid\btif\src)
13.Bte_main.c (external\bluetooth\bluedroid\main)
- - - - - - - - - - - - libbt-hci.so - - - - - - - - -
14.Bt_hci_bdroid.c (external\bluetooth\bluedroid\hci\src)
15.Vendor.c (external\bluetooth\bluedroid\hci\src)
--------------------------------------------libbt-vendor.so--------------------------------------------
16.Bt_vendor_brcm.c (hardware\broadcom\libbt\src)
17.Upio.c (hardware\broadcom\libbt\src)
--------------------------------------------rfkill---------------------------------------------
18./sys/class/rfkill/rfkill0/state 1
----------------------------------------------------------------------------------------
From: https://www.jianshu.com/p/3344f8d6d079