赞
踩
上篇博客我总结了Android打开蓝牙分为4个阶段,第一阶段就是打开蓝牙的方法从APP调到systemServer再到Bluetooth协议栈,最后走到了hardware蓝牙硬件设备。如下图绿色虚线的流程:
经过了硬件的一些列操作,正真打开了蓝牙设备,下面继续分析。
第二阶段:(对应图中蓝色虚线流程)
在蓝牙打开成功之后,JNI层会通过JniCallbacks的stateChangeCallback方法把消息回调给AdapterService处理,AdapterService则继续把消息给到状态机处理:
void stateChangeCallback(int status) {
if (status == AbstractionLayer.BT_STATE_OFF) {
debugLog("stateChangeCallback: disableNative() completed");
mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
} else if (status == AbstractionLayer.BT_STATE_ON) {
mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
} else {
Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
}
}
此时的AdapterState处于TurningBleOnState状态,TurningBleOnState在接收到BLE_STARTED消息后,迁入到BleOnState状态:
private class TurningBleOnState extends BaseAdapterState {
.......
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case BLE_STARTED:
transitionTo(mBleOnState);
break;
........
}
每一个状态的迁移,都会触发AdapterService的updateAdapterState,这个方法内部会把状态改变回调给远程的监听者:
void updateAdapterState(int prevState, int newState) {
mAdapterProperties.setState(newState);
if (mCallbacks != null) {
int n = mCallbacks.beginBroadcast();
debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
newState) + " to " + n + " receivers.");
for (int i = 0; i < n; i++) {
try {
mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState); //远程回调
} catch (RemoteException e) {
debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
}
}
mCallbacks.finishBroadcast();
}
这里会远程回调到BluetoothManagerService里面的监听接口,经过handler消息处理机制会调用到bluetoothStateChangeHandler方法:
private void bluetoothStateChangeHandler(int prevState, int newState) {
if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
.......
continueFromBleOnState();
}
}
/**
* Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
*/
private void continueFromBleOnState() {
..........
if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
// This triggers transition to STATE_ON
mBluetooth.onLeServiceUp();
persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
}
}
在这里,正常情况下都会走到mBluetooth.onLeServiceUp()这个方法,至此,第二阶段的流程已经走完。接下来就是进入第三阶段,让Bluetooth继续去完成BLE打开之后的后续的流程。
第三阶段:(对应图中紫色虚线流程)
Bluetooth协议栈的AdapterService在接收到onLeServiceUp的调用之后,会给AdapterState状态机发一条AdapterState.USER_TURN_ON的消息,于是这次操作又交到了AdapterState状态机去处理了。其实我们可以看到,状态机对于整个蓝牙状态的管理是非常重要,同时也让逻辑更加清晰。
void onLeServiceUp() {
mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
}
此时状态机处于BleOnState状态,在接收到USER_TURN_ON后,把状态迁入TurningOnState状态:
private class BleOnState extends BaseAdapterState {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case USER_TURN_ON:
transitionTo(mTurningOnState);
break;
TurningOnState在进入的时候,会去调用AdapterService的startProfileServices方法,从名字就可以看出它是去开启各个ProfileService:
private class TurningOnState extends BaseAdapterState {
@Override
int getStateValue() {
return BluetoothAdapter.STATE_TURNING_ON;
}
@Override
public void enter() {
super.enter();
sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
mAdapterService.startProfileServices();
}
那具体是哪些Profile呢,我们可以了解一下:
private static final ProfileConfig[] PROFILE_SERVICES_AND_FLAGS = { new ProfileConfig(HeadsetService.class, R.bool.profile_supported_hs_hfp, (1 << BluetoothProfile.HEADSET)), new ProfileConfig(A2dpService.class, R.bool.profile_supported_a2dp, (1 << BluetoothProfile.A2DP)), new ProfileConfig(A2dpSinkService.class, R.bool.profile_supported_a2dp_sink, (1 << BluetoothProfile.A2DP_SINK)), new ProfileConfig(HidHostService.class, R.bool.profile_supported_hid_host, (1 << BluetoothProfile.HID_HOST)), new ProfileConfig(PanService.class, R.bool.profile_supported_pan, (1 << BluetoothProfile.PAN)), new ProfileConfig(GattService.class, R.bool.profile_supported_gatt, (1 << BluetoothProfile.GATT)), new ProfileConfig(BluetoothMapService.class, R.bool.profile_supported_map, (1 << BluetoothProfile.MAP)), new ProfileConfig(HeadsetClientService.class, R.bool.profile_supported_hfpclient, (1 << BluetoothProfile.HEADSET_CLIENT)), new ProfileConfig(AvrcpTargetService.class, R.bool.profile_supported_avrcp_target, (1 << BluetoothProfile.AVRCP)), new ProfileConfig(AvrcpControllerService.class, R.bool.profile_supported_avrcp_controller, (1 << BluetoothProfile.AVRCP_CONTROLLER)), new ProfileConfig(SapService.class, R.bool.profile_supported_sap, (1 << BluetoothProfile.SAP)), new ProfileConfig(PbapClientService.class, R.bool.profile_supported_pbapclient, (1 << BluetoothProfile.PBAP_CLIENT)), new ProfileConfig(MapClientService.class, R.bool.profile_supported_mapmce, (1 << BluetoothProfile.MAP_CLIENT)), new ProfileConfig(HidDeviceService.class, R.bool.profile_supported_hid_device, (1 << BluetoothProfile.HID_DEVICE)), new ProfileConfig(BluetoothOppService.class, R.bool.profile_supported_opp, (1 << BluetoothProfile.OPP)), new ProfileConfig(BluetoothPbapService.class, R.bool.profile_supported_pbap, (1 << BluetoothProfile.PBAP)), new ProfileConfig(HearingAidService.class, com.android.internal.R.bool.config_hearing_aid_profile_supported, (1 << BluetoothProfile.HEARING_AID)) };
协议还真是不少啊!每一个服务启动后,都会通知到AdapterService,当所有的协议服务都启动完毕之后,也就意味着蓝牙真正的打开了。
第四阶段:(对应图中橙色虚线流程)
在所有ProfileService都启动完毕之后,AdapterService会判断到此条件,然后会给AdapterState状态机发送AdapterState.BREDR_STARTED,然后迁移到OnState状态:
private void processProfileServiceStateChanged(ProfileService profile, int state) {
switch (state) {
case BluetoothAdapter.STATE_ON:
........
if (GattService.class.getSimpleName().equals(profile.getName())) {
enableNative();
} else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
&& mRegisteredProfiles.size() == mRunningProfiles.size()) { //所有ProfileService都启动完毕
.......
mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
}
break;
private class TurningOnState extends BaseAdapterState {
..........
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case BREDR_STARTED:
transitionTo(mOnState);
break;
前面已经说了,每次状态的迁移都会通过远程回调接口通知监听者,迁入到OnState也一样。BluetoothManagerService在收到STATE_ON的消息后,在经过Handler消息机制处理后,会走到如下的分支:
else if (newState == BluetoothAdapter.STATE_ON) {
boolean isUp = (newState == BluetoothAdapter.STATE_ON);
sendBluetoothStateCallback(isUp);
sendBleStateChanged(prevState, newState);
显然,这里就是把蓝牙打开的状态通过远程回调接口,以及广播两种方式通知给上层应用。至此,从应用调用打开蓝牙的方法,到收到蓝牙打开的广播,整个蓝牙打开的流程就已经分析完毕!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。