在权限允许的情况下,通过enable()
函数可以打开Android设备的本地蓝牙。调用该函数需要权限Manifest.permission.BLUETOOTH_ADMIN
。它是BluetoothAdapter
的函数,那就先从这开始分析:
private final IBluetoothManager mManagerService;
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean enable() {
if (isEnabled()) {
// 蓝牙已经可用,直接返回true
return true;
}
try {
return mManagerService.enable(ActivityThread.currentPackageName());
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
BluetoothAdapter
的enable()
函数很简单,通过aidl的方式,调用远程服务BluetoothManagerService
的enable(packageName)
函数:
public boolean enable(String packageName) throws RemoteException {
final int callingUid = Binder.getCallingUid();
final boolean callerSystem = UserHandle.getAppId(callingUid) ==Process.SYSTEM_UID;
// 如果蓝牙被禁用,直接返回false
if (isBluetoothDisallowed()) {
return false;
}
if (!callerSystem) {
if (!checkIfCallerIsForegroundUser()) {
return false;
}
// 检测是否拥有BLUETOOTH_ADMIN权限
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,"Need BLUETOOTH ADMIN permission");
if (!isEnabled() && mPermissionReviewRequired
&& startConsentUiIfNeeded(packageName, callingUid,
BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
return false;
}
}
synchronized(mReceiver) {
mQuietEnableExternal = false;
mEnableExternal = true;
// 通过BluetoothHandler去处理enable的消息
sendEnableMsg(false, packageName);
}
return true;
}
在函数中先是检查各种权限,权限都通过之后,向BluetoothHandler
发送消息,交给它去完成接下来的开启任务,到这意味着开启任务已经开始,该函数的任务已经结束返回true
。因此这里返回true
并不代表蓝牙功能开启成功,仅仅表示这项工作通过了层层检测,步上了正轨。继续看sendEnableMsg()
函数
private void sendEnableMsg(boolean quietMode, String packageName) {
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
quietMode ? 1 : 0, 0));
}
接着看BluetoothHandler
的handleMessage()
函数,这个函数很长,有450行代码,这里只看MESSAGE_ENABLE
分支:
private IBluetooth mBluetooth;
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ENABLE:
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mEnable = true;
try {
// 通过读写锁来保证线程安全
mBluetoothLock.readLock().lock();
if (mBluetooth != null) {
// 获取当前蓝牙状态,如果当前处于STATE_BLE_ON状态,那就切换到USER_TURN_ON状态,并返回
int state = mBluetooth.getState();
if (state == BluetoothAdapter.STATE_BLE_ON) {
mBluetooth.onLeServiceUp();
persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
break;
}
}
} catch (RemoteException e) {
Slog.e(TAG, "", e);
} finally {
mBluetoothLock.readLock().unlock();
}
mQuietEnable = (msg.arg1 == 1);
if (mBluetooth == null) {
// 执行enable()的函数
handleEnable(mQuietEnable);
} else {
//
// We need to wait until transitioned to STATE_OFF and
// the previous Bluetooth process has exited. The
// waiting period has three components:
// (a) Wait until the local state is STATE_OFF. This
// is accomplished by "waitForOnOff(false, true)".
// (b) Wait until the STATE_OFF state is updated to
// all components.
// (c) Wait until the Bluetooth process exits, and
// ActivityManager detects it.
// The waiting for (b) and (c) is accomplished by
// delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
// message. On slower devices, that delay needs to be
// on the order of (2 * SERVICE_RESTART_TIME_MS).
//
// 远程服务已连接,并且当前不是STATE_BLE_ON状态,那么需要重启蓝牙服务。
// 需要等待本地蓝牙功能关闭,然后重启蓝牙服务
waitForOnOff(false, true);
Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
}
break;
}
重点看handleEnable(bool)
函数:
private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode;
try {
mBluetoothLock.writeLock().lock();
if ((mBluetooth == null) && (!mBinding)) {
// 没有绑定服务,发起服务绑定,并设置绑定超时时间为3s
Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
Intent i = new Intent(IBluetooth.class.getName());
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) {
try {
if (!mQuietEnable) {
// 调用enable函数,开启蓝牙
if(!mBluetooth.enable()) {
Slog.e(TAG,"IBluetooth.enable() returned false");
}
}
else {
if(!mBluetooth.enableNoAutoConnect()) {
Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
}
}
} catch (RemoteException e) {
Slog.e(TAG,"Unable to call enable()",e);
}
}
} finally {
mBluetoothLock.writeLock().unlock();
}
}
核心代码就是mBluetooth.enable()
,其余的忽略。通过AIDL调用的是远程服务AdapterService
中的enable()
函数。
接着看AdapterService
:
private AdapterState mAdapterStateMachine;
public boolean enable() {
return enable(false);
}
public synchronized boolean enable(boolean quietMode) {
// 检测权限
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) {
// 蓝牙不允许使用
return false;
}
mQuietmode = quietMode;
mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
return true;
}
核心代码是mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
,那么mAdapterStateMachine
又是什么对象呢,从命名上可以看出它是个状态机,因此这里是往状态机AdapterState
中发送了一条BLE_TURN_ON
的消息。接着看状态机AdapterState
:
/**
* This state machine handles Bluetooth Adapter State.
* Stable States:
* {@link OffState}: Initial State
* {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on
* {@link OnState} : Bluetooth is on (All supported profiles)
*
* Transition States:
* {@link TurningBleOnState} : OffState to BleOnState
* {@link TurningBleOffState} : BleOnState to OffState
* {@link TurningOnState} : BleOnState to OnState
* {@link TurningOffState} : OnState to BleOnState
*
* +------ Off <-----+
* | |
* v |
* TurningBleOn TO---> TurningBleOff
* | ^ ^
* | | |
* +-----> ----+ |
* BleOn |
* +------ <---+ O
* v | T
* TurningOn TO----> TurningOff
* | ^
* | |
* +-----> On ------+
*
*/
final class AdapterState extends StateMachine {
private AdapterService mAdapterService;
private TurningOnState mTurningOnState = new TurningOnState();
private TurningBleOnState mTurningBleOnState = new TurningBleOnState();
private TurningOffState mTurningOffState = new TurningOffState();
private TurningBleOffState mTurningBleOffState = new TurningBleOffState();
private OnState mOnState = new OnState();
private OffState mOffState = new OffState();
private BleOnState mBleOnState = new BleOnState();
private AdapterState(AdapterService service) {
super(TAG);
addState(mOnState);
addState(mBleOnState);
addState(mOffState);
addState(mTurningOnState);
addState(mTurningOffState);
addState(mTurningBleOnState);
addState(mTurningBleOffState);
mAdapterService = service;
setInitialState(mOffState);
}
public static AdapterState make(AdapterService service) {
AdapterState as = new AdapterState(service);
as.start();
return as;
}
private class OffState extends BaseAdapterState {
@Override
int getStateValue() {
return BluetoothAdapter.STATE_OFF;
}
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case BLE_TURN_ON:
transitionTo(mTurningBleOnState);
break;
default:
return false;
}
return true;
}
}
}
从源码注释上可以清楚了解到状态机拥有的所有状态,状态机的使用以及原理之前分析过,这里再看一下:
-
addState(state)
,蓝牙状态机总共有7中状态,都没有父状态; -
setInitialState(state)
,蓝牙初始状态是offState
; - 在
State
的processMessage()
函数中处理消息。
AdapterService
中向状态机发送了BLE_TURN_ON
消息,此时状态机的状态是OffState
。在OffState
类的processMessage()
函数中对BLE_TURN_ON
消息的处理是:调用transitionTo(mTurningBleOnState)
,将状态切换到TurningBleOnState
。那么TurningBleOnState()
将会执行enter()
方法,接着看看在enter()
函数里做了什么事情:
private class TurningBleOnState extends BaseAdapterState {
@Override
public void enter() {
super.enter();
sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
mAdapterService.bringUpBle();
}
}
先设置了4s超时时间,然后调用AdapterService
的bringUpBle()
函数。
那么接着回到AdapterService
类中,看一下bringUpBle()
函数:
// 删减了无关代码
void bringUpBle() {
// 重置蓝牙设备
mRemoteDevices.reset();
// 初始化蓝牙相关属性
mAdapterProperties.init(mRemoteDevices);
// 启动蓝牙绑定状态机
mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);
// 初始化JNI回调类
mJniCallbacks.init(mBondStateMachine, mRemoteDevices);
try {
// 标记重置蓝牙Ble扫描的电池统计
mBatteryStats.noteResetBleScan();
} catch (RemoteException e) {
}
// 启动Gatt协议服务
setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);
}
在这个函数里头,首先做了一系列初始化工作,然后启动Gatt协议服务,接着看setProfileServiceState()
函数:
private void setProfileServiceState(Class service, int state) {
Intent intent = new Intent(this, service);
intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, state);
startService(intent);
}
代码很简单,就是启动GattService
,告知GattService
执行ACTION_SERVICE_STATE_CHANGED
相关操作。
在GattService
父类ProfileService
的onStartCommand()
函数看到了对ACTION_SERVICE_STATE_CHANGED
action的处理:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
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) {
doStop();
} else if (state == BluetoothAdapter.STATE_ON) {
doStart();
}
}
return PROFILE_SERVICE_MODE;
}
private void doStart() {
// 省略了其他代码
mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON);
}
在doStart()
中调用start()
方法启动了一系列Manager
,做了一些预处理,最后调用AdapterService
的onProfileServiceStateChanged()
方法。
private final AdapterServiceHandler mHandler = new AdapterServiceHandler();
public void onProfileServiceStateChanged(ProfileService profile, int state) {
// 只处理蓝牙打开与关闭状态
if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
throw new IllegalArgumentException(BluetoothAdapter.nameForState(state));
}
Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
m.obj = profile;
m.arg1 = state;
mHandler.sendMessage(m);
}
向AdapterServiceHandler
发送一条MESSAGE_PROFILE_SERVICE_STATE_CHANGED
的消息,接着看AdapterServiceHandler
的handlerMessage()
方法。
class AdapterServiceHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_PROFILE_SERVICE_STATE_CHANGED:
processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1);
break;
}
}
private void processProfileServiceStateChanged(ProfileService profile, int state) {
switch (state) {
case BluetoothAdapter.STATE_ON:
mRunningProfiles.add(profile);
if (GattService.class.getSimpleName().equals(profile.getName())) {
//
enableNativeWithGuestFlag();
} else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
&& mRegisteredProfiles.size() == mRunningProfiles.size()) {
mAdapterProperties.onBluetoothReady();
updateUuids();
setBluetoothClassFromConfig();
mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
}
break;
}
}
}
}
这里的ProfileService
指的就是GattService
,因此进入enableNativeWithGuestFlag()
函数:
private void enableNativeWithGuestFlag() {
boolean isGuest = UserManager.get(this).isGuestUser();
if (!enableNative(isGuest)) {
Log.e(TAG, "enableNative() returned false");
}
}
native boolean enableNative(boolean startRestricted);
最终调用JNI的enableNative()
,在com_android_bluetooth_btservice_AdapterService.cpp
static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
ALOGV("%s", __func__);
if (!sBluetoothInterface) return JNI_FALSE;
int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);
return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE: JNI_FALSE;
}
通过sBluetoothInterface->enable()
方法去调用蓝牙的底层驱动来实现蓝牙的打开操作。那么sBluetoothInterface
又是什么呢???它对应的是bluetooth.cc
,在bluetooth.cc
中可以看到:
EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
sizeof(bluetoothInterface),
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,
create_bond_out_of_band,
remove_bond,
cancel_bond,
get_connection_state,
pin_reply,
ssp_reply,
get_profile_interface,
dut_mode_configure,
dut_mode_send,
le_test_mode,
set_os_callouts,
read_energy_info,
dump,
dumpMetrics,
config_clear,
interop_database_clear,
interop_database_add,
get_avrcp_service,
};
可以理解为导出对应的内核方法供其他模块使用。回到正题,看一下enable()
方法:
static int enable(bool start_restricted) {
restricted_mode = start_restricted;
// 接口未就绪,返回未就绪的状态码
if (!interface_ready()) return BT_STATUS_NOT_READY;
stack_manager_get_interface()->start_up_stack_async();
return BT_STATUS_SUCCESS;
}
接着执行stack_manager_get_interface()
的start_up_stack_async()
,stack_manager_get_interface()
函数指的是stack_manager.cc
,接着看:
static void start_up_stack_async(void) {
thread_post(management_thread, event_start_up_stack, NULL);
}
这里通过thread_post
异步去执行event_start_up_stack
函数:
// start_up过程是一个同步过程
static void event_start_up_stack(UNUSED_ATTR void* context) {
// 确保栈已经初始化
ensure_stack_is_initialized();
// 加载配置文件
module_start_up(get_module(BTIF_CONFIG_MODULE));
// 执行enable
bte_main_enable();
// 上一步的enable失败
if (future_await(local_hack_future) != FUTURE_SUCCESS) {
stack_is_running = true;
event_shut_down_stack(NULL);
return;
}
stack_is_running = true;
// enable成功
btif_thread_post(event_signal_stack_up, NULL);
}
bte_main_enable()
是在bte_main.cc
中执行的,具体的实现就不再深入。接下来让我们看看成功的结果是如何返回到Java层的。
bte_main_enable()
执行成功之后,会在event_signal_stack_up()
函数中执行回掉,将BT_STATE_ON
状态通过HAL_CBACK
函数回传给adapter_state_changed_cb ()
函数 。
static void event_signal_stack_up(UNUSED_ATTR void* context) {
// Notify BTIF connect queue that we've brought up the stack. It's
// now time to dispatch all the pending profile connect requests.
btif_queue_connect_next();
HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
}
函数adapter_state_changed_cb()
对应的是com_android_bluetooth_btservice_AdapterService.cpp
中的adapter_state_change_callback()
函数
static void adapter_state_change_callback(bt_state_t status) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);
}
这里有一个疑惑,stack_manager.cc
中调用的adapter_state_changed_cb()
函数是如何对应到com_android_bluetooth_btservice_AdapterService.cpp
中的adapter_state_change_callback()
函数的????在bluetooth.h
中看到了结构体bt_callbacks_t
中声明:
typedef struct {
adapter_state_changed_callback adapter_state_changed_cb;
} bt_callbacks_t;
在com_android_bluetooth_btservice_AdapterService.cpp
中创建了bt_callbacks_t
对象。由于c/c++基础不好,所以这部分很多都是个人的猜测。
static bt_callbacks_t sBluetoothCallbacks = {
adapter_state_change_callback
};
JNI层通过CallVoidMethod(xx, method_stateChangeCallback, BT_STATE_ON)
去调用Java层AdapterService.java
中的stateChangeCallback()
函数:
void stateChangeCallback(int status) {
if (status == AbstractionLayer.BT_STATE_OFF) {
debugLog("stateChangeCallback: disableNative() completed");
} else if (status == AbstractionLayer.BT_STATE_ON) {
//
mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
} else {
Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
}
}
返回的状态是BT_STATE_ON
,所以接着给状态机AdapterState
发送消息BLE_STARTED
。
private class TurningBleOnState extends BaseAdapterState {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case BLE_STARTED:
transitionTo(mBleOnState);
break;
}
return true;
}
}
状态机接收到该消息之后,将状态切换成BleOnState
。进入新的状态之后,告知AdapterService
更新到新的状态。
@Override
public void enter() {
int currState = getStateValue();
mAdapterService.updateAdapterState(mPrevState, currState);
mPrevState = currState;
}
接着看AdapterService
中是如何处理新状态STATE_BLE_ON
的:
void updateAdapterState(int prevState, int newState) {
mAdapterProperties.setState(newState);
if (mCallbacks != null) {
int n = mCallbacks.beginBroadcast();
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();
}
}
AdapterService
接收到新状态之后,通过AIDL回调给BluetoothManagerService
,接着看BluetoothManagerService
是如何处理回调的:
private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
@Override
public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
Message msg =
mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
mHandler.sendMessage(msg);
}
};
跟调用enable()
的时候一样,同样是交给BluetoothHandler
去处理:
// 省略了很多非核心代码
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_BLUETOOTH_STATE_CHANGE: {
int prevState = msg.arg1;
int newState = msg.arg2;
mState = newState;
bluetoothStateChangeHandler(prevState, newState);
}
}
private void bluetoothStateChangeHandler(int prevState, int newState) {
if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
&& newState == BluetoothAdapter.STATE_BLE_ON);
if (!intermediate_off) {
if (mBluetoothGatt != null || !mContext.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
continueFromBleOnState();
}
sendBleStateChanged(prevState, newState);
}
}
private void continueFromBleOnState() {
try {
mBluetoothLock.readLock().lock();
if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
// mBluetooth指的是AdapterService
mBluetooth.onLeServiceUp();
persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
}
} catch (RemoteException e) {
Slog.e(TAG, "Unable to call onServiceUp", e);
} finally {
mBluetoothLock.readLock().unlock();
}
}
BluetoothHandler
获取到STATE_BLE_ON
的状态信息之后,会继续通过AIDL让AdapterService
将状态切换成OnState
@Override
public void onLeServiceUp() {
AdapterService service = getService();
if (service == null) {
return;
}
service.onLeServiceUp();
}
void onLeServiceUp() {
mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
}
接着又回到状态机中切换状态,实现的代码很简单跟之前的状态切换类似,这就不再分析,最终BluetoothHandler
会通过AIDL回调给BluetoothAdapter
,最后会执行BluetoothStateChangeCallback
的onBluetoothStateChange(boolean on)
函数,但是这个回调接口被@hide
了,因此我们无法监听此回调。
整个enable()
过程就分析到这了,可能很多都没有分析到位,或者存在错误,后期再优化。