Android

个人Android学习总结


Android4.4 之Bluetooth整理

<pre><code class="language-java">Android 4.4上蓝牙协议栈采用的是BRCM和Google共同开发的bluedroid,代替了之前的Bluez. 一、 Bluetooth 源码分布 (基于Android 4.4 ) 1. packages/apps/Settings/src/com/android/settings/bluetooth bluetooth Settings 代码 2. packages/apps/Bluetooth BT 应用层代码,及BT profile(如:A2dp,gatt,hdp,hfp,hid,map,opp,pan,pbap ...) 上层代码 packages/apps/Bluetooth/jni 3. frameworks/base/core/java/android/bluetooth framework 层相关 java 代码与aidl 4. external/bluetooth/bluedroid BRCM和Google共同开发的官方蓝牙协议栈 5. linux/kernel/drivers/bluetooth 6. linux/kernel/net/bluetooth 7. 以下是近期项目intel 平台 hardware/broadcom/libbt hardware/libhardware vendor/intel/fw/PRIVATE/bt 厂商bt固件</code></pre> <pre><code class="language-java"> 二、Bluetooth 常用类及相关profile A2dp: Advanced Audio Distribution Profile 蓝牙音频传输模型协定 蓝牙立体声,和蓝牙耳机听歌有关那些,另还有个AVRCP--(Audio/Video Remote Control Profile)音频/视频远程控制配置文件,是用来听歌时暂停,上下歌曲选择的 GATT: Generic Attribute Profile 通用属性配置文件 GATT是基于ATT Protocol的,ATT针对BLE设备做了专门的优化,具体就是在传输过程中使用尽量少的数据。每个属性都有一个唯一的UUID,属性将以characteristics and services的形式传输 https://developer.bluetooth.org/TechnologyOverview/Pages/GATT.aspx HDP:Bluetooth Health Device Profile 蓝牙关于医疗方面的应用 HFP : Hands-free Profile 和电话相关,蓝牙接听、挂断电话 HID : Human Interface Device 定义了蓝牙在人机接口设备中的协议、特征和使用规程。典型的应用包括蓝牙鼠标、蓝牙键盘、蓝牙游戏手柄等。该协议改编自USB HID Protocol MAP : Message Access Profile OPP : Object Push Profile PAN : Personal Area Network Profile 描述了两个或更多个 Bluetooth 设备如何构成一个即时网络,和网络有关的还有串行端口功能(SPP),拨号网络功能(DUN) PBAP: Phonebook Access Profile 电话号码簿访问协议</code></pre> <pre><code class="language-java">三、Enable Bluetooth 1. 服务启动: frameworks/base/services/java/com/android/server/SystemServer.java 系统启动时在SystemServer中注册蓝牙服务管理BluetoothManagerService服务: Bt 服务 其它进程通过binder机制调用该服务,该服务属于综合服务管理类,包括AdapterService的启动、蓝牙适配器Adapter的管理等。 2. BluetoothAdapter Android的蓝牙Enable是由BluetoothAdapter提供的。只需要调用BluetoothAdapter.enable()即可启动蓝牙。下面我就分析这一个过程 frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java mManagerService.enable() mManagerService其实就是bluetoothAdapter的一个proxy, getDefaultAdapter BluetoothAdapter 3. BluetoothManagerService frameworks/base/services/java/com/android/server/BluetoothManagerService.java BluetoothManagerService:enable() sendEnableMsg sendEnableMsg 交给handleMessage 处理,可以看到case MESSAGE_ENABLE: 里调用了handleEnable handleEnable 可以看到是调用了mBluetooth.enable() 4. AdapterService,AdapterState packages/app/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java AdapterService:enable() 此处用了用了StateMachine,它会在AdapterState 里processMessage 处理(StateMachine就是状态机,在不同的状态下,收到相同的Event,做不同的事情),直接搜索UER_TURN_ON 可以看到下面: USER_TURN_ON 接下来是调用了adapterService.processStart() processStart setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 是用来开启Bluetooth Profile 的,log 中可以看到: BT Profile log 然后可以看到:mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED)); 交给了PendingCommandState下的processMessage处理 case STARTED 由mAdapterService.enableNative(); 可以看到 /*package*/ native boolean enableNative(); 此时就进入了JNI了 5. JNI 调用 enableNative() 是在 packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp enableNative static const bt_interface_t *sBluetoothInterface = NULL; bt_interface_t 定义 bt_interface_t 定义 在hardware/libhardware/include/hardware/bluetooth.h sBluetoothInterface的初始化在classInitNative(),这个函数大概做了以下的事情: 1)、注册java的回调函数(就是当下层已经打开蓝牙了,然后要通知上层,蓝牙已经打开了,java层就可以发送蓝牙打开的Broadcast了。) 2)、初始化蓝牙模块的HAL接口。 3)、得到sBluetoothInterface 6. Bluedroid -&amp;gt;bluetooth.c external/bluetooth/bluedroid/btif/src/bluetooth.c sBluetoothInterface-&amp;gt;enable(); 会调到下方 bluetooth:enable() 接下来调用:external/bluetooth/bluedroid/btif/src/Btif_core.c btif_enable_bluetooth external/bluetooth/bluedroid/main/Bte_main.c bte_main_enable bte_hci_enable 我们先看下bt_hc_if-&amp;gt;set_power,前面有做一些初始化Bluedroid的动作 由 bt_hc_if-&amp;gt;set_power(BT_HC_CHIP_PWR_ON);可以看出: static bt_hc_interface_t *bt_hc_if=NULL; 下面是bt_hc_if 的初始化 bte_main_in_hw_init external/bluetooth/bluedroid/hci/src/Bt_hci_bdroid.c bt_hc_get_interface bluetoothHCLibInterface 由以上可以看到set_power set_power 可以看到,bt_vnd_if-&amp;gt;op(BT_VND_OP_POWER_CTRL, &amp;amp;pwr_state); external/bluetooth/bluedroid/hci/src/Bt_hw.c bt_vendor_interface_t *bt_vnd_if=NULL; bt_vnd_if 初始化: init_vnd_if 在init_vnd_if()函数可以看到其实是一个libbt-vendor.so的interface。这个是Vendor(芯片厂商)的library Vendor就是芯片供应商的意思,在他们做好一块蓝牙芯片后,需要提供一些硬件相关的动作,比如上下电,设置波特率之类的。但是这些 操作一般不会对没有许可的开放。Bluedroid提供了一个统一的接口bt_vendor_interface_t,供应商只需要实现这个接口定义的蓝 牙相关的操作就可以交给bluedroid去做剩下的事情了 下面主要是broadcom 为例,我们进入/hardware/里面: $ find . -name Android.mk |xargs grep libbt ./broadcom/libbt/Android.mk:LOCAL_MODULE := libbt-vendor ./broadcom/libbt/Android.mk:LOCAL_MODULE := libbt-vendor ./broadcom/libbt/Android.mk: LOCAL_SRC_FILES := $(TI_BT_VENDOR_PATH)/libbt-vendor-ti.c ./qcom/bt/Android.mk:include $(call all-named-subdir-makefiles,libbt-vendor) ./qcom/bt/libbt-vendor/Android.mk:LOCAL_MODULE := libbt-vendor 或者 $ grep -nr BT_VND_OP_POWER_CTRL broadcom/libbt/src/bt_vendor_brcm.c:147: case BT_VND_OP_POWER_CTRL: broadcom/libbt/src/bt_vendor_brcm.c:149: BTVNDDBG(&amp;quot;op: BT_VND_OP_POWER_CTRL&amp;quot;); qcom/bt/libbt-vendor/src/bt_vendor_qcom.c:105: case BT_VND_OP_POWER_CTRL: 在broadcom/libbt/src/bt_vendor_brcm.c op upio_set_bluetooth_power static char *rfkill_state_path = NULL; rfkill_state_path 是在下面初始化的。 init_rfkill 原来就是在rfkill_state_path(/sys/class/rfkill/rfkill[x]/state)虚拟设备里写入了1 shell@android :/sys/class/rfkill/rfkill0 $ cat state 0 // 表示蓝牙是关闭状态 shell@android :/sys/class/rfkill/rfkill0 $ cat state 1 // 开启蓝牙后可以看到 rfkill是Linux下的一个标准的无线控制的虚拟设备,Linux也提供了rfkill的命令去查看以及控制所有的注册的无线设备。它们会在/dev/(PC的Linux)或者/sys/class(一般是Android)下生成相应的虚拟设备。 结合set_power 下面的log 和 bluetoothHCLibInterface 定义,可以看到接下来是调用的 bluetoothHCLibInterface 里的 proload-&amp;gt;bthc_signal_event(HC_EVENT_PRELOAD)-&amp;gt;bt_hc_worker_thread -》 userial_open(USERIAL_PORT_1)-&amp;gt;bt_vnd_if-&amp;gt;op(BT_VND_OP_USERIAL_OPEN, &amp;amp;fd_array);-&amp;gt;userial_vendor_open((tUSERIAL_CFG *) &amp;amp;userial_init_cfg); 接下来是Hardware.c里 hw_config_start-》hw_config_cback Ref: http://blog.csdn.net/baimy1985/article/details/8892410 http://my.oschina.net/u/1436933/blog/192060 http://blog.csdn.net/yutao52shi/article/details/12690353</code></pre> <pre><code class="language-java">Enable Bluetooth 执行流程了解 以下是基于Android 4.2代码,对Bluetooth BR/EDR Enable process的分析。BluetoothAdapter类代表的是local device Bluetooth adapter,而BluetoothDevice类代表的是remote Bluetooth device。在Android 4.3中引入了一个新的类BluetoothManager,它是一个high level manager,被用于”to obtain an instance of an BluetoothAdapter and conduct overall Bluetooth Management“。 Bluetooth Enable process比较复杂,层次比较多,最好的分析方法是:对照logcat输出的Bluetooth相关log来阅读代码。首先从总体上介绍以下Enable process。UI上的入口是Settings,拨动Bluetooth开关,就启动了Bluetooth Enable process,最后由Bluedroid去enable Bluetooth hardware。当Bluetooth hardware enabled,这个enabled消息会一层层从Bluedroid上传到UI层,Settings收到这个消息就可以更新Bluetooth开关的状态了。具体过程如下图: Settings的BluetoothEnabler类(对应于UI上看到的Bluetooth开关),得到代表local device的BluetoothAdapter,再调用BluetoothAdapter::enable()。 BluetoothAdapter基本上是个wrapper,不做具体的事情的。它直接调用BluetoothManagerService::enable()。 BluetoothManagerService利用Binder机制会去connect AdapterService,最终会导致AdapterService::enable()被调用。BluetoothManagerService还会向AdapterService注册callback函数,用于接收Adapter State Change消息。 AdapterService维护着一个状态机AdapterState,所有工作都是通过驱动状态机来完成的。AdapterState收到AdapterService发过来的USER_TURN_ON消息,就会调用AdapterService::processStart()来启动Profie Services的初始化和Bluetooth hardware enable process。此时Bluetooth Adapter的状态是BluetoothAdapter.STATE_TURNING_ON。 每一个profile都有一个service。每个profile service启动完成后,都会通知AdapterService。当AdapterService::processProfileServiceStateChanged()确认所有的profile services都启动完成了,就会给状态机AdapterState发AdapterState.STARTED消息。 状态机AdapterState::PendingCommandState::processMessage()收到AdapterState.STARTED消息后就立刻调用AdapterService::enableNative()。 AdapterService::enableNative()就是用来enable Bluetooth的Bluetooth JNI接口。enableNative()会调用Bluetooth HAL的enable()。 Bluedroid用btif_enable_bluetooth()来实现了Bluetooth HAL的enable()。 当Bluedroid真正完成了enable Bluetooth hardware,就通过btif_enable_bluetooth_evt()中的HAL_CBACK调用Bluetooth JNI的adapter_state_change_callback(),这样就把BT_STATE_ON消息传递给了状态机AdapterState。 AdapterState会把Bluetooth Adapter的状态转换到BluetoothAdapter.STATE_ON,并通过AdapterState::notifyAdapterStateChanged()通知AdapterService。 AdapterService::updateAdapterState()会通过callback函数通知BluetoothManagerService,Adapter状态改变了。 BluetoothManagerService确认状态发生了改变就会发出一个BluetoothAdapter.ACTION_STATE_CHANGE的intent。 Settings的BluetoothEnabler收到这个intent之后,就会去更新UI上Bluetooth开关的状态。 ![](https://www.showdoc.cc/home/common/visitfile/sign/8eec3951b5204c770e41e961ae7646e0?showdoc=.jpg)</code></pre>

页面列表

ITEM_HTML