天天看點

Android Bluetooth藍牙enable過程

Android Bluetooth藍牙enable過程

Android Bluetooth架構

Android Bluetooth藍牙enable過程

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