Android筆記之藍牙enble過程源碼追蹤

SalStallcup 8年前發布 | 7K 次閱讀 安卓開發 Android開發 移動開發

前言

在Android開發異常火熱的如今,各類的Android開發的文檔也異常豐富,但是很奇怪的是關于android藍牙開發的文檔確是少之又少,現在android 7都出來好久了,中文社區藍牙開發的資料大多都停留在了android 4.3之前,僅有的新鮮的文章也是那幾篇抄來抄去,也沒有相關的書籍作為參考,找點資料也是心累。

所以想要把自己整理的東西慢慢寫下來,除了作為自己知識的沉淀,也希望將能夠分享和交流。

而追蹤藍牙使能過程目的有這么幾個:

  • 增進對藍牙框架的了解
  • 提供了一種Android源碼的閱讀方式
  • 對整個Android的框架和代碼結構有進一步的了解
  • 了解Jni、binder、廣播等機制在其中的運用

Bt框架

BT 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定義:
    private final LocalBluetoothAdapter mLocalAdapter;
  2. LocalBluetoothAdapter.java(frameworks\base\packages\settingslib\src\com\android\settingslib\bluetooth)
    |setBluetoothEnabled()
      |mAdapter.enable()
    查看mAdapter的定義
    private final BluetoothAdapter mAdapter;
  3. BluetoothAdapter.java (frameworks\base\core\java\android\bluetooth)
    |enable()
      |mManagerService.enable()
    查看mManagerService定義
    private final IBluetoothManager mManagerService;
    這里是通過AIDL機制完成進程間的通信,調用的是BluetoothManagerService的enable()函數。
  4. BluetoothManagerService.java(frameworks\base\services\core\java\com\android\server)
    |enable()
      |sendEnableMsg(false);
         |mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,0, 0));
    在他的內部類BluetoothHandler繼承了Handler類,處理傳遞的消息:
    |handleMessage(Message msg)
      |case MESSAGE_ENABLE    
         |handleEnable(msg.arg1 == 1);
             |mBluetooth.enable()
    查看mBluetooth的定義:
    private IBluetooth mBluetooth;
  5. AdapterService.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
    |enable(boolean quietMode)
      |Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON);
        |mAdapterStateMachine.sendMessage(m);
    查看mAdapterStateMachine的定義:
    private AdapterState mAdapterStateMachine;
  6. AdapterState.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
    |processMessage(Message msg)
      |case BLE_TURN_ON
         |adapterService.processStart();
    查看定義:
    AdapterService adapterService = mAdapterService;
  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:
    /*package*/ native boolean 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
    使用命令抓取一下:
    find .|grep "enableNative" -rn .
    發現enable函數是在com_android_bluetooth_btservice_AdapterService.cpp中實現的。
  10. com_android_bluetooth_btservice_AdapterService.cpp (packages\apps\bluetooth\jni)
    |enableNative(JNIEnv* env, jobject obj)
      |sBluetoothInterface->enable()
    查看定義
    static const bt_interface_t *sBluetoothInterface = NULL;
    bt_interface_t是Bluetooth.h (hardware\libhardware\include\hardware)中定義的結構體。
    我們需要找到它的實現,在文件中查找sBluetoothInterface找到它賦值的地方:
    sBluetoothInterface = btStack->get_bluetooth_interface();
    它是由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模塊:
    load(class_id, path, module);
  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)
      |bte_main_enable()
  13. Bte_main.c (external\bluetooth\bluedroid\main)
    |bte_main_enable()
      |bte_hci_enable() 
         |bt_hc_if->set_power(BT_HC_CHIP_PWR_ON)
    查看定義
    static bt_hc_interface_t *bt_hc_if=NULL;
    以及賦值的語句
    bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()
  14. Bt_hci_bdroid.c (external\bluetooth\bluedroid\hci\src)
    |static const bt_hc_interface_t bluetoothHCLibInterface
      |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_send_command(bt_vendor_opcode_t opcode, void *param)
      |vendor_interface->op(opcode, param)
    vendor_interface賦值語句:
    VENDOR_LIBRARY_NAME = "libbt-vendor.so";
    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這個動態鏈接庫中。
  16. Bt_vendor_qcom.c (hardware\qcom\bt\libbt-vendor\src)
    全局抓取一下libbt-vendor.so,我們在hardware/qcom/bt/libbt-vendor下的Android.mk中找到了libbt-vendor.so的包含的源文件。
    抓取一下bt_vendor_interface_t,發現在Bt_vendor_qcom.c找到了它的實現:
    |const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE
      |op(bt_vendor_opcode_t opcode, void *param)
        |hw_config(nState)
  17. Hardware.c (hardware\qcom\bt\libbt-vendor\src)
    |hw_config(int nState)
      |property_set("bluetooth.hciattach", true)
    進行芯片framework的config操作。

小結

本文為enable過程的源碼追蹤,總結完了吐了一口老血,但不得不說,android程序員還是厲害啊,基本上一個函數是干什么的看看函數名就知道了,以現在的水平還無法對過程進行展開分析,其中也有很多的錯誤,以后慢慢的補充和修改。

 

來自:http://www.jianshu.com/p/3344f8d6d079

 

 本文由用戶 SalStallcup 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!