代码位置:
frameworks/base/services/java/com/android/server/BluetoothManagerService.java
这部分代码,生成libandroid_runtime.so
完成功能,中转BluetoothAdapter和Bluetooth.apk,所有来自其他应用的请求,都通过IBluetooth接口,转发到Bluetooth.apk
启动方式:
Intent i =
new Intent(IBluetooth.class.getName());
if (!mContext.bindService(i,
mConnection,Context.BIND_AUTO_CREATE,
UserHandle.USER_CURRENT)) {
这里IBluetooth.class.getName实际返回android.bluetooth.IBluetooth
这个action正好是packages/app/Bluetooth/AdapterService要处理的action。
BluetoothManagerService保持一个BluetoothServiceConnection的回调,当AdapterService启动时,就可以拿到IBluetooth接口了。
代码位置:
packages/apps/Bluetooth
这部分代码,生成Bluetooth.apk
完成功能:
1、IBluetooh.aidl的服务端,由AdapterService的内部类AdapterServiceBinder实现
2、在BluetoothManagerService调用IBluetooth接口时,实际上是在AdapterServiceBinder端来处理。
3、IBluetooth.enable
-> AdapterServiceBinder->enable
-> BluetoothManagerService.enable
BluetoothManagerService初始化了一个蓝牙状态机AdapterState实例,mAdapterStateMachine,调用enable是给状态机发一个消息AdapterState.USER_TURN_ON
4、再往下层的调用是通过,AdapterService的JNI接口enableNative
代码位置:
packages/apps/Bluetooth/jni
这部分代码,是AdapterService的JNI实现
完成功能:
1、获取bluetooth.default接口,这个接口是android获取HAL的通用方式,
err =
hw_get_module(id, (hw_module_t const**)&module);
2、因此调用JNI enableNative实际是调用bluetooth.default的实现enable
蓝牙关闭过程:
1、客户端调用AdapterService.java的disable接口
2、AdapterService给AdapterStateMachine发送一个USER_TURN_OFF的Message
3、AdapterStateMachine调用AdapterProperties的onBluetoothDisable接口
4、AdapterProperties把scan
mode设置为AbstractionLayer.BT_SCAN_MODE_NONE
5、AdapterProperties调用AdapterService的setAdapterPropertyNative接口,往底层调用
6、在JNI层com_android_bluetooth_btservice_AdapterServices的
setAdapterPropertyNative,调用蓝牙HAL接口
sBluetoothInterface->set_adapter_property(&prop);
7、蓝牙HAL接口的实现,在external/bluetooth/bluedroid/btif/src/bluetooth.c中
8、bluetooth.c :: set_adapter_property ->
btif_core.c :: btif_set_adapter_property
9、btif_set_adapter_property对属性
BT_PROPERTY_ADAPTER_SCAN_MODE设置的处理,先保存discovery
mode为BTA_DM_NON_DISC,表示不可发现,保存connecable
mode为BTA_DM_NON_CONN,表示不可连接。然后,调用external/bluetooth/bluedroid/bta/dm
/bta_dm_api.c :: BTA_DmSetVisibility方法
10、BTA_DmSetVisibility构造一个tBTA_DM_API_SET_VISIBILITY *p_msg,填入discovery mode, connetiable
mode等参数,然后调用external/bluetooth/bluedroid/bta/sys/bta_sys_main.c
:: bta_sys_sendmsg
11、bta_sys_sendmsg调用external/bluetooth/bluedroid/gki
/common/gki_buffer.c ::
GKI_send_msg发送一条GKI信息到BTA,GKI_send_msg有三个参数,第一个参数是线程id,也作为task id,
通过bta_sys_init获得,第二个参数是mailbox id,第三个是上一步封装好的p_msg
12、GKI_send_msg首先对p_msg进一步封装成event,通过链表存到mailbox
id对应的任务队列中,调用external/bluetooth/bluedroid/gki/ulinux/gki_ulinux.c
:: GKI_send_event进行发送
13、GKI_send_event设置事件掩码gki_cb.com.OSWaitEvt[task_id] |= event;,
通过pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);通知另外线程。
14、这样,在另外一个等待线程函数中gki_ulinux.c
:: GKI_wait可以返回了,现在来看这个等待线程是怎么起来的
在调用HAL接口bluetoothInterface集合中的init的时候,
1、btif/src/bluetooth.c :: init
会调用 btif/src/btif_core.c
:: btif_init_bluetooth 启动一个BTIF任务
2、btif_init_bluetooth 调用gki/ulinux/gki_ulinux.c
:: GKI_create_task(btif_task, BTIF_TASK,
BTIF_TASK_STR,
(UINT16 *) ((UINT8 *)btif_task_stack +
BTIF_TASK_STACK_SIZE),
sizeof(btif_task_stack)); 启动这个任务,第一个参数btif_task是任务处理函数,第二个参数是task
id,第三个是对应string表示形式,第四个是任务列表的起始指针,第四个是任务栈最大深度。
3、GKI_create_task
启动一个线程,等待任务事件 ret = pthread_create( &gki_cb.os.thread_id[task_id],
//保存了线程id
&attr1,
(void *)gki_task_entry,
&gki_pthread_info[task_id]);//gki_pthread_info保存了任务信息:task_id,task_entry。
可向而知,刚刚创建的任务线程,就是那个等待线程,来看gki_task_entry,即是btif_task的实现:
btif/src/btif_core.c
1、因为我们已经要开始等待事件了,因此要通知JAVA/JNI层,记得刚刚我们有注册了回调,那么就通过宏HAL_CBACK(bt_hal_cbacks,
thread_evt_cb, ASSOCIATE_JVM);来通知JNI
2、进入for(;;)
3、调用GKI_wait,等待一个事件的返回
4、判断事件 event ==
BT_EVT_TRIGGER_STACK_INIT,如果是,就调用BTA_EnableBluetooth(bte_dm_evt)初始化蓝牙芯片组
5、判断事件event & EVENT_MASK(GKI_SHUTDOWN_EVT,如果是,就对出任务循环
6、判断事件event & TASK_MBOX_1_EVT_MASK 判断是否是1好mbox里面的事件。
7、如果第6步满足判断事件,那么判断事件 event & BT_EVT_CONTEXT_SWITCH_EVT,如果是,调用btif_context_switched(p_msg)切换上下文
8、回第三步
到这里,很奇怪,为什么没有我们要处理的事件,难道在另外的任务线程里面处理?
在回过头来,看GKI对TASK_MBOX, TASK_MBOX_EVT_MASK的规划
TIMER事件,TASK事件,APPL事件(应用程序请求事件?)
gki/common/gki.h
#define
TASK_MBOX_0 0
#define
TASK_MBOX_1 1
#define
TASK_MBOX_2 2
#define
TASK_MBOX_3 3
#define NUM_TASK_MBOX 4
#define
MAX_EVENTS 16
#define TASK_MBOX_0_EVT_MASK 0x0001
#define TASK_MBOX_1_EVT_MASK 0x0002
#define TASK_MBOX_2_EVT_MASK 0x0004
#define TASK_MBOX_3_EVT_MASK 0x0008
#ifndef BTU_TASK
#define
BTU_TASK 0
#endif
#ifndef BTIF_TASK
#define
BTIF_TASK 1
#endif
#ifndef A2DP_MEDIA_TASK
#define
A2DP_MEDIA_TASK 2
#endif
#ifndef GKI_MAX_TASKS
#define
GKI_MAX_TASKS 3
#endif
在第11步bta_sys_sendmsg调用GKI_send_msg(bta_sys_cb.task_id,
p_bta_sys_cfg->mbox, p_msg);
他的TASK_ID就是bta_sys_cb.task_id,现在看下这个task_id的初始化过程,也就是BTA系统的初始化过程
BTA的初始化,要从在BTU的任务处理函数(btu_task)中开始的,那么btu_task又是怎么起来的,
这就要从bt开启的时候说起了。
1、在开启蓝牙之时,JNI调用HAL接口bluetoothInterface的enable函数,即btif/src/btif_core.c
:: btif_enable_bluetooth
2、btif_enable_bluetooth调用main/bte_main.c的BTE
API函数bte_main_enable(btif_local_bd_addr.address); 其从bte
task,这个address怎么来的?
3、bte_main_enable,首先,初始化BTE控制块(HCI相关回调)
4、调用hci接口,(替代4.1的hciattach进程?),给bt设备上电。
5、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));//启动BTU任务
6、pthread_create( &timer_thread_id,
&timer_attr,
timer_thread,
NULL);
//根据NO_GKI_RUN_RETURN是否执行timer_thread线程,NO_GKI_RUN_RETURN是什么意思?LINUX是否需要定义此宏?
再来看btu_task的实现:
1、btu_init_core(); 初始化核心control block,比如BTU, BTM, L2CAP, and
SDP
2、BTE_InitStack();初始化BTE控制块,比如RFCOMM, DUN, SPP, HSP2, HFP, OBX,
BIP
3、#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED ==
TRUE) //初始化BTA
bta_sys_init();
#endif
4、#if ( BT_USE_TRACES==TRUE )
BTE_InitTraceLevels();
#endif
5、进入for(;;)
6、处理事件的列表://为什么不是全部?
TASK_MBOX_0_EVT_MASK
TIMER_0_EVT_MASK
TIMER_1_EVT_MASK
TIMER_2_EVT_MASK
RPCGEN_MSG_EVT
TASK_MBOX_2_EVT_MASK
EVENT_MASK(APPL_EVT_7) //APPL_EVT_7事件
再来看bta_sys_init的实现
bta/sys/bta_sys_main.c
bta_sys_init //注意到这里并没有建一个bta_task
1、bta_sys_cb.task_id = GKI_get_taskid();//获取task id,是什么?
这里的GKI_get_taskid()仅是调用pthread_self()获取pthread_t,那么这段代码很明显是跟btu_task是同一个pthread,因此发给bta_sys_cb.task_id自然而然的由btu_task来处理了。
再回过头来看bta_sys_sendmsg的实现
void bta_sys_sendmsg(void *p_msg)
{
GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox,
p_msg);
}
这里GKI_send_msg的第一个参数已经确定,第二个参数见BTA相关参数的映射:
BTA相关映射关系如下:
#ifndef BTA_MBOX_EVT
#define
BTA_MBOX_EVT TASK_MBOX_2_EVT_MASK
#endif
#ifndef BTA_MBOX
#define
BTA_MBOX TASK_MBOX_2
#endif
#ifndef BTA_TIMER
#define
BTA_TIMER TIMER_1
#endif
const tBTA_SYS_CFG bta_sys_cfg =
{
BTA_MBOX_EVT, BTA_MBOX, BTA_TIMER, APPL_INITIAL_TRACE_LEVEL }; tBTA_SYS_CFG *p_bta_sys_cfg = (tBTA_SYS_CFG
*)&bta_sys_cfg;
那么第二个参数也确定下来了,就是TASK_MBOX_2
再回过头来看btu_task处理的时间列表,里面正包含了TASK_MBOX_2_EVT_MASK
这样,我们终于找到处理设置BT_PROPERTY_ADAPTER_SCAN_MODE的债主了,就是btu_task
再来看btu_task对TASK_MBOX_2_EVT_MASK的实现
if (event & TASK_MBOX_2_EVT_MASK)
{
while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
//取出p_msg
{
bta_sys_event(p_msg); //处理p_msg
}
}
也就是说bta_sys_event会调用子系统回调函数去处理p_msg,看怎么实现的。bta/sys/bta_sys_main.c
:: bta_sys_event
BTA_API void bta_sys_event(BT_HDR *p_msg) //这里名字也正好与BTA对应上
1、UINT8 id = (UINT8) (p_msg->event >> 8); 获取id 右移8位
2、 if ((id
< BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL))
{
freebuf =
(*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
}
3、再看当初event的形成
void
BTA_DmSetVisibility(tBTA_DM_DISC disc_mode, tBTA_DM_CONN conn_mode,
UINT8 pairable_mode, UINT8 conn_filter )
p_msg->hdr.event =
BTA_DM_API_SET_VISIBILITY_EVT;
4、BTA_DM_API_SET_VISIBILITY_EVT的取值定义在bta/dm/bta_dm_int.h
enum
{ BTA_DM_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_DM),
//注意这里BTA_SYS_EVT_START(BTA_ID_DM)实现#define
BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 << (id));因为BTA_ID_DM是1,
BTA_DM_API_DISABLE_EVT,
BTA_DM_API_SET_NAME_EVT,
BTA_DM_API_SET_VISIBILITY_EVT,
BTA_DM_API_SET_AFH_CHANNELS_EVT,
BTA_API_DM_SIG_STRENGTH_EVT,
BTA_DM_API_VENDOR_SPECIFIC_COMMAND_EVT, BTA_DM_API_TX_INQPWR_EVT,
BTA_DM_ACL_CHANGE_EVT,
BTA_DM_API_ADD_DEVICE_EVT,
...
};
5、因此计算刚才的id,也是1
BTA_ID_DM的回调函数的注册的过程
1、还记得btif_task刚起来的时候,会等待一个BT_EVT_TRIGGER_STACK_INIT的事件,对那个事件的处理,就是调用BTA_EnableBluetooth进行初始化硬件。
if (event ==
BT_EVT_TRIGGER_STACK_INIT)
{
BTIF_TRACE_DEBUG0("btif_task: received trigger stack init
event");
BTA_EnableBluetooth(bte_dm_evt);
}
2、bta/dm/bta_dm_api.c :: tBTA_STATUS
BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback)
在这里面,注册两个子系统处理回调
bta_sys_register (BTA_ID_DM, &bta_dm_reg
);
bta_sys_register (BTA_ID_DM_SEARCH,
&bta_dm_search_reg );
那么,我们来看他的定义
static
const tBTA_SYS_REG bta_dm_reg =
{
bta_dm_sm_execute,
bta_dm_sm_disable
};
那么,bta_dm_sm_execute正是bta_sys_event要调用的实现
bta_dm_sm_execute的实现:
1、UINT16 event = p_msg->event & 0x00ff;
//获得event事件,BTA_DM_API_SET_VISIBILITY_EVT
2、 (*bta_dm_action[event])( (tBTA_DM_MSG*) p_msg); 调用这个函数来处理
3、bta_dm_action列表:
const
tBTA_DM_ACTION bta_dm_action[]
= { bta_dm_enable, bta_dm_disable, bta_dm_set_dev_name, bta_dm_set_visibility, bta_dm_set_afhchannels, bta_dm_signal_strength, bta_dm_vendor_spec_command,
bta_dm_tx_inqpower, bta_dm_acl_change, bta_dm_add_device,