Android蓝牙打开和关闭的流程基本一致,这里就从打开的流程进行分析。
1 UI
从UI上看蓝牙开关就是设置settings里那个switch开关,蓝牙开关操作封装在Settings/bluetooth/BluetoothEnabler.java中,BluetoothEnabler便于蓝牙开关管理。里面实现SwitchBar.OnSwitchChangeListener接口,监听状态改变。
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
...........
//在LocalBluetoothAdapter中打开蓝牙
if (mLocalAdapter != null) {
mLocalAdapter.setBluetoothEnabled(isChecked);
}
mSwitch.setEnabled(false);
}
onSwitchChanged里面调用LocalBluetoothAdapter的setBluetoothEnabled方法,这是蓝牙打开或者关闭的一个接口。接下来看一下LocalBluetoothAdapter:
public void setBluetoothEnabled(boolean enabled) {
boolean success = enabled ? mAdapter.enable() : mAdapter.disable();
......设置蓝牙状态.....
}
LocalBluetoothAdapter在Settings app和Framworks之间提供了一个接口去改变蓝牙开关状态。setBluetoothEnabled调用BluetoothAdapter.enable方法。然后我们就进入framework的BluetoothAdapter中继续分析。
2 framework
public boolean enable() {
int state = STATE_OFF;
//已经打开返回
if (isEnabled() == true){
if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
return true;
}
//Use service interface to get the exact state
if (mService != null) {
try {
state = mService.getState();
} catch (RemoteException e) {Log.e(TAG, "", e);}
}
//当前状态为打开
if (state == BluetoothAdapter.STATE_BLE_ON) {
Log.e(TAG, "BT is in BLE_ON State");
notifyUserAction(true);
return true;
}
try {
//通过远程服务打开蓝牙
return mManagerService.enable();
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
这个方法中的关键代码是“return mManagerService.enable();” mManagerService 对象是由IBluetoothManager 接口代码实现的,IBluetoothManager实际定义的是AIDL文件,对应的类就是 BluetoothManagerService 类,在路径 frameworks/base/core/java/android/bluetooth/BluetoothManagerService 下面 。
public boolean enable() {
if (isBluetoothDisallowed()) {
if (DBG) {
Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
}
return false;
}
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
sendEnableMsg(false); //通过handler集中处理消息
}
if (DBG) Log.d(TAG, "enable returning");
return true;
}
方法中先判断是否是系统app操作蓝牙,检查是否有操作蓝牙的权限等,然后关键的代码是“sendEnableMsg(false)”,handler最后调用handleEnable方法处理该消息。
private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode;
synchronized(mConnection) {
//检查服务是否已经启动并且已经绑定
if ((mBluetooth == null) && (!mBinding)) {
//Start bind timeout and bind
Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
mConnection.setGetNameAddressOnly(false);
Intent i = new Intent(IBluetooth.class.getName());
//绑定服务,UserHandle为多用户考虑
if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT)) {
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else {
mBinding = true;
}
} else if (mBluetooth != null) {
if (mConnection.isGetNameAddressOnly()) {
// if GetNameAddressOnly is set, we can clear this flag,
// so the service won't be unbind
// after name and address are saved
mConnection.setGetNameAddressOnly(false);
//Register callback object
try {
mBluetooth.registerCallback(mBluetoothCallback);
} catch (RemoteException re) {
Log.e(TAG, "Unable to register BluetoothCallback",re);
}
//Inform BluetoothAdapter instances that service is up
sendBluetoothServiceUpCallback();
}
//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);
}
}
这里通过AIDL的方式,调用Bluetooth App 中的AdapterService 。先绑定服务,然后注册Ibluetooth回调函数,之后调用enable方法方法开启蓝牙。所以之后就从Framworks 跳到 Bluetooth APP 中继续分析。
——————————————————————————————————
3 Bluetooth APP
代码路径“Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService ”,看里面的 enable(boolean) 的实现
public synchronized boolean enable(boolean quietMode) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
debugLog("enable() - Enable called with quiet mode status = " + mQuietmode);
mQuietmode = quietMode;
//由状态机处理开启操作
mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
return true;
}
AdapterService.enable方法最终向状态机AdapterState发送AdapterState.BLE_TURN_ON消息,由状态机处理消息。蓝牙状态机的代码在Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState 下面,AdapterState状态机在AdapterService的onCreate方法中他通过一个静态函数AdapterState.make初始化。
private AdapterState(AdapterService service, AdapterProperties adapterProperties) {
super("BluetoothAdapterState:");
addState(mOnState);
addState(mBleOnState);
addState(mOffState);
addState(mPendingCommandState);
mAdapterService = service;
mAdapterProperties = adapterProperties;
setInitialState(mOffState); //初始状态为offstate
}
setInitialState设置了该状态机的初始状态是OffState,AdapterState.BLE_TURN_ON消息由OffState首先处理,状态机中每个状态通过调用public boolean processMessage方法处理每个消息。
public boolean processMessage(Message msg) {
AdapterService adapterService = mAdapterService;
if (adapterService == null) {
errorLog("Received message in OffState after cleanup: "+msg.what);
return false;
}
debugLog("Current state: OFF, message: " + msg.what);
switch(msg.what) {
//初始状态是OffState,由OffState处理蓝牙开启操作
case BLE_TURN_ON:
//通知BluetoothmangerService蓝牙正在开启
notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);
mPendingCommandState.setBleTurningOn(true);
transitionTo(mPendingCommandState);
//发送延迟消息,检测打开超时任务
sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
//批量启动 profile service
adapterService.BleOnProcessStart();
break;
case USER_TURN_OFF:
//TODO: Handle case of service started
//and stopped without enable
break;
default:
return false;
}
return true;
}
BLE_TURN_ON里面通过回调通知BluetoothMangerService,蓝牙正在启动中,然后将状态机中下个状态设置为PendingCommandState,最后调用adapterService .BleOnProcessStart批量启动所需的各个profile server。
void BleOnProcessStart() {
debugLog("BleOnProcessStart()");
//支持的profile service
Class[] supportedProfileServices = Config.getSupportedProfiles();
//Initialize data objects
for (int i=0; i < supportedProfileServices.length;i++) {
mProfileServicesState.put(supportedProfileServices[i].getName(),
BluetoothAdapter.STATE_OFF);
}
//初始化远程蓝牙设备
mRemoteDevices = new RemoteDevices(this);
mAdapterProperties.init(mRemoteDevices);
debugLog("BleOnProcessStart() - Make Bond State Machine");
//启动蓝牙绑定状态状态
mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);
mJniCallbacks.init(mBondStateMachine,mRemoteDevices);
//FIXME: Set static instance here???
setAdapterService(this);
//Start Gatt service
setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
}
BleOnProcessStart首先获取支持的profile,支持的profile在 Config.java 中。接着启动新的状态机BondStateMachine,最后调用setGattProfileServiceState方法,批量启动支持的Profile server,包括GattService,启动服务时会传入参数:ACTION_SERVICE_STATE_CHANGED和BluetoothAdapter.STATE_ON 。
然后看packages/apps/Bluetooth/src/com/android/bluetooth/gatt/GattService.java启动的入口onStartCommand,里面没有什么内容,真正的实现在父类中:
public int onStartCommand(Intent intent, int flags, int startId) {
if (DBG) log("onStartCommand()");
if (mStartError || mAdapter == null) {
Log.w(mName, "Stopping profile service: device does not have BT");
doStop(intent);
return PROFILE_SERVICE_MODE;
}
if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM) != PackageManager.PERMISSION_GRANTED) {
Log.e(mName, "Permission denied!");
return PROFILE_SERVICE_MODE;
}
if (intent == null) {
Log.d(mName, "Restarting profile service...");
return PROFILE_SERVICE_MODE;
} else {
String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
if (AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if(state==BluetoothAdapter.STATE_OFF) {
Log.d(mName, "Received stop request...Stopping profile...");
doStop(intent); //停止
} else if (state == BluetoothAdapter.STATE_ON) {
Log.d(mName, "Received start request. Starting profile...");
doStart(intent); //启动
}}}
return PROFILE_SERVICE_MODE;
}
因为启动服务时传入的参数是ACTION_SERVICE_STATE_CHANGED和BluetoothAdapter.STATE_ON,所以调用doStart。doStart里面调用了抽象方法start(实现是在子类GattService里面,做了一些预处理,包括initializeNative、启动一些manager)再调notifyProfileServiceStateChanged(BluetoothAdapter.STATE_ON),此方法会调用AdapterService.onProfileServiceStateChanged方法,传递STATE_ON消息,该消息会包装在MESSAGE_PROFILE_SERVICE_STATE_CHANGED类型里,由AdapterService的handler方法处理
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
debugLog("handleMessage() - Message: " + msg.what);
switch (msg.what) {
case MESSAGE_PROFILE_SERVICE_STATE_CHANGED:
debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
processProfileServiceStateChanged((String) msg.obj, msg.arg1);
break;
}
........................
}
}
};
processProfileServiceStateChanged处理profile 状态改变,里面
//在OffState中,isBleTurningOn设置为true
if (isBleTurningOn) {
if (serviceName.equals("com.android.bluetooth.gatt.GattService")) {
debugLog("GattService is started");
mAdapterStateMachine.sendMessage(mAdapterStateMachine.
obtainMessage(AdapterState.BLE_STARTED));
return;
}
}
会向AdapterStateMachine状态机发送BLE_STARTED消息,根据之前状态机已经由OffState切换成PendingCommandState,所以消息由PendingCommandState状态处理,看processMessage的处理
case BLE_STARTED:
//Remove start timeout
removeMessages(BLE_START_TIMEOUT);
//Enable,调用底层方法,开启蓝牙
if (!adapterService.enableNative()) {
errorLog("Error while turning Bluetooth on");
//开启失败,状态通知,切换到OffState状态
notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
transitionTo(mOffState);
} else {
//超时检测
sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);
}
break;
通过调用adapterService.enableNative()方法,开始调用JNI方法,进入C/C++层。adapterService.enableNative对应的cpp文件为Packages/apps/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 || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE; //判断是打开还是关闭状态;
return result;
}
通过调用“int ret = sBluetoothInterface->enable()”来驱动底层打开蓝牙开关。接下来就是C里面对打开蓝牙的实现。
——————————————————————————————————
4 蓝牙协议栈
对应的代码在/system/bt/btif/src/bluetooth.cc里面:
static int enable(void) {
LOG_INFO("%s", __func__);
if (!interface_ready())//状态判断,已经初始化,向下执行
return BT_STATUS_NOT_READY;
stack_manager_get_interface()->start_up_stack_async();
return BT_STATUS_SUCCESS;
}
enable方法会调用start_up_stack_async方法,start_up_stack_async的实现在stack_manager.c 文件中:
static void start_up_stack_async(void) {
thread_post(management_thread, event_start_up_stack, NULL);
}
通过thread_post异步event_start_up_stack,来启动蓝牙栈
// Synchronous function to start up the stack
static void event_start_up_stack(UNUSED_ATTR void *context) {
if (stack_is_running) {
LOG_DEBUG("%s stack already brought up.", __func__);
return;
}
ensure_stack_is_initialized();//确保,栈已经初始化
LOG_DEBUG("%s is bringing up the stack.", __func__);
hack_future = future_new();
// Include this for now to put btif config into a shutdown-able state
//加载配置文件,配置文件位于手机系统目录/data/misc/bluedroid/bt_config.xml
module_start_up(get_module(BTIF_CONFIG_MODULE));
bte_main_enable();//BTE部分的enable
if (future_await(hack_future) != FUTURE_SUCCESS) {//启动失败
stack_is_running = true; // So stack shutdown actually happens
event_shut_down_stack(NULL); //关闭蓝牙栈,里面还会调用
return;}
stack_is_running = true;
LOG_DEBUG("%s finished", __func__);
btif_thread_post(event_signal_stack_up, NULL); //发送蓝牙栈启动信息:
}
bte_main_enable()方法中进行btsnoop_module和hci_module的启动以及启动BTU操作,这里就不深入下去了。
如果打开蓝牙成功,走到btif_thread_post(event_signal_stack_up, NULL)这里,会在event_signal_stack_up函数里面调用HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON) ,然后通过回调调用adapter_state_changed_cb方法,通知蓝牙当前状态BT_STATE_ON。
adapter_state_changed_cb在hardware/libhardware/include/hardware/bluetooth.h文件中被定义:
/** Bluetooth DM callback structure. */
typedef struct {
/** set to sizeof(bt_callbacks_t) */
size_t size;
adapter_state_changed_callback adapter_state_changed_cb;
...........
} bt_callbacks_t;
如果C++层有消息传递到java层,回调接口都定义在这里,adapter_state_changed_cb对应的是adapter_state_changed_callback 。然后通过JNI回调通知到JAVA层,上层就会收到打开蓝牙的通知。至此,打开蓝牙流程分析到这里。