根据前一篇的思路大致走一遍.
先从应用层开始,Settings工程的蓝牙部分,这部分还是挺熟悉的,以前在某知名公司负责ROM开发时熟悉了.当然不同系统版本,代码可能有点不同,
设置蓝牙主界面BluetoothSettings.java,但是这里大概分析开启蓝牙流程和扫描蓝牙流程.
开启蓝牙流程:
直接进入BluetoothEnabler这个类查看.
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// Show toast message if Bluetooth is not allowed in airplane mode
if (isChecked &&
!WirelessSettings.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
// Reset switch to off
buttonView.setChecked(false);
}
if (mLocalAdapter != null) {
mLocalAdapter.setBluetoothEnabled(isChecked);
}
mSwitch.setEnabled(false);
}
一句:
mLocalAdapter.setBluetoothEnabled(isChecked);
找到这个点时开始点,然后看一下LocalBluetoothAdapter类
public void setBluetoothEnabled(boolean enabled) {
boolean success = enabled
? mAdapter.enable()
: mAdapter.disable();
if (success) {
setBluetoothStateInt(enabled
? BluetoothAdapter.STATE_TURNING_ON
: BluetoothAdapter.STATE_TURNING_OFF);
} else {
if (Utils.V) {
Log.v(TAG, "setBluetoothEnabled call, manager didn't return " +
"success for enabled: " + enabled);
}
syncBluetoothState();
}
}
注意:
boolean success = enabled
? mAdapter.enable()
: mAdapter.disable();
开始对蓝牙设备进行了使能操作,打开蓝牙设备mAdapter是BluetoothAdapter的一个对象,而BluetoothAdapter类在framework里面了
public boolean enable() {
if (isEnabled() == true){
if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
return true;
}
try {
return mManagerService.enable();
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
然后进入BluetoothManagerService中:
mManagerService.enable();
public boolean enable() {
if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
(!checkIfCallerIsForegroundUser())) {
Log.w(TAG,"enable(): not allowed for non-active and non system user");
return false;
}
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
if (DBG) {
Log.d(TAG,"enable(): mBluetooth =" + mBluetooth +
" mBinding = " + mBinding);
}
synchronized(mReceiver) {
mQuietEnableExternal = false;
mEnableExternal = true;
// waive WRITE_SECURE_SETTINGS permission check
long callingIdentity = Binder.clearCallingIdentity();
persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Binder.restoreCallingIdentity(callingIdentity);
sendEnableMsg(false);
}
return true;
}
下面:
sendDisableMsg();
private void sendEnableMsg(boolean quietMode) {
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
quietMode ? 1 : 0, 0));
}
搜索一下MESSAGE_ENABLE的handler处理
case MESSAGE_ENABLE:
if (DBG) {
Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);
}
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mEnable = true;
handleEnable(msg.arg1 == 1);
break;
进入handleEnable中:
//Enable bluetooth
try {
if (!mQuietEnable) {
if(!mBluetooth.enable()) {
Log.e(TAG,"IBluetooth.enable() returned false");
}
}
else {
if(!mBluetooth.enableNoAutoConnect()) {
Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
}
}
} catch (RemoteException e) {
Log.e(TAG,"Unable to call enable()",e);
}
mBluetooth.enable(),这个开始进入,经过状态机的消息,一直到:
//Enable
boolean ret = mAdapterService.enableNative();
就到了Bluetooth工程下的jni了,com_android_bluetooth_btservice_AdapterService.cpp
static jboolean enableNative(JNIEnv* env, jobject obj) {
ALOGV("%s:",__FUNCTION__);
jboolean result = JNI_FALSE;
if (!sBluetoothInterface) return result;
int ret = sBluetoothInterface->enable();
result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
return result;
}
继续看看sBluetoothInterface是什么:
bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
sBluetoothInterface = btStack->get_bluetooth_interface();
一看,明显了吧bluetooth_module_t这个结构体很熟悉,到了HAL层,另外还有两个结构体,这个在hardware文件下,bluetooth.h中,真正处理是蓝牙协议栈,android 4.2开始是bluedroid协议栈,路径:
~\external\bluetooth
蓝牙使能是在bluedroid下面的bluetooth.c中:这个是根据hal层的那个结构体进行关联的
static const bt_interface_t bluetoothInterface = {
sizeof(bt_interface_t),
init,
enable,
disable,
cleanup,
get_adapter_properties,
get_adapter_property,
set_adapter_property,
get_remote_device_properties,
get_remote_device_property,
set_remote_device_property,
get_remote_service_record,
get_remote_services,
start_discovery,
cancel_discovery,
create_bond,
remove_bond,
cancel_bond,
pin_reply,
ssp_reply,
get_profile_interface,
dut_mode_configure,
dut_mode_send
};
然后协议栈里面:
static int enable( void )
{
ALOGI("enable");
/* sanity check */
if (interface_ready() == FALSE)
return BT_STATUS_NOT_READY;
return btif_enable_bluetooth();
}
接着到了Btif_core.c中:
bt_status_t btif_enable_bluetooth(void)
{
BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH");
if (btif_core_state != BTIF_CORE_STATE_DISABLED)
{
ALOGD("not disabled\n");
return BT_STATUS_DONE;
}
btif_core_state = BTIF_CORE_STATE_ENABLING;
/* Create the GKI tasks and run them */
bte_main_enable(btif_local_bd_addr.address);
return BT_STATUS_SUCCESS;
}
至于更后面,建议参考:http://blog.youkuaiyun.com/xubin341719/article/details/40402637
这个作者刚好和我的刚好可以衔接,他基本上是从描述bluedroid协议栈的工作流程的.
从上面看,Bluetooth工程负责和framework层对接,并且负责管理蓝牙的状态机,下面与HAL层对接,可以看出Bluetooth编译出来是一个apk,但是这个apk有点牛逼.
然后在回头到settings工程,其他的一些操作基本上是应用的状态广播消息变化之类的:
synchronized void setBluetoothStateInt(int state) {
mState = state;
if (state == BluetoothAdapter.STATE_ON) {
// if mProfileManager hasn't been constructed yet, it will
// get the adapter UUIDs in its constructor when it is.
if (mProfileManager != null) {
mProfileManager.setBluetoothStateOn();
}
}
}
在跳转一个类:LocalBluetoothProfileManager
void setBluetoothStateOn() {
ParcelUuid[] uuids = mLocalAdapter.getUuids();
if (uuids != null) {
updateLocalProfiles(uuids);
}
mEventManager.readPairedDevices();
}
然后先看一下:
void updateLocalProfiles(ParcelUuid[] uuids)
// A2DP
if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSource)) {
if (mA2dpProfile == null) {
Log.d(TAG, "Adding local A2DP profile");
mA2dpProfile = new A2dpProfile(mContext, this);
addProfile(mA2dpProfile, A2dpProfile.NAME,
BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
}
} else if (mA2dpProfile != null) {
Log.w(TAG, "Warning: A2DP profile was previously added but the UUID is now missing.");
}
// Headset / Handsfree
if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) ||
BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP_AG)) {
if (mHeadsetProfile == null) {
Log.d(TAG, "Adding local HEADSET profile");
mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter,
mDeviceManager, this);
addProfile(mHeadsetProfile, HeadsetProfile.NAME,
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
}
} else if (mHeadsetProfile != null) {
Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing.");
}
....
这个地方主要蓝牙的设备UUID识别和添加蓝牙状态注册广播,后面最终还有一个注册到一个广播的.这个都在settings工程里面.
蓝牙扫描的流程也是差不多的.后面介绍从Phone 工程开始的蓝牙部分.