Android 提供支持经典蓝牙和蓝牙低功耗的默认蓝牙堆栈。借助蓝牙,Android 设备可以创建个人区域网络,以便通过附近的蓝牙设备发送和接收数据,在 Android 4.3 及更高版本中,Android 蓝牙堆栈可提供实现蓝牙低功耗 (BLE) 的功能。要充分利用 BLE API,请遵循 Android 蓝牙 HCI 要求。具有合格芯片组的 Android 设备可以实现经典蓝牙或同时实现经典蓝牙和 BLE。BLE 不能向后兼容较旧版本的蓝牙芯片组。在 Android 8.0 中,原生蓝牙堆栈完全符合蓝牙 5 的要求。要使用可用的蓝牙 5 功能,该设备需要具有符合蓝牙 5 要求的芯片组。
处于应用框架级别的是应用代码,它使用 android.bluetooth API 与蓝牙硬件进行交互。此代码在内部通过 Binder IPC 机制调用蓝牙进程。蓝牙系统服务(位于 packages/apps/Bluetooth 中)被打包为 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。此应用通过 JNI 调用原生蓝牙堆栈。与 android.bluetooth 相关联的 JNI 代码位于 packages/apps/Bluetooth/jni 中。当发生特定蓝牙操作时(例如发现设备时),JNI 代码会调用蓝牙堆栈。系统在 AOSP 中提供了默认蓝牙堆栈,它位于 system/bt 中。该堆栈会实现常规蓝牙 HAL,并通过扩展程序和更改配置对其进行自定义。供应商设备使用硬件接口设计语言 (HIDL) 与蓝牙堆栈交互。HIDL 定义了蓝牙堆栈和供应商实现之间的接口。要生成蓝牙 HIDL 文件,请将蓝牙接口文件传递到 HIDL 生成工具中。接口文件位于 hardware/interfaces/bluetooth 下。Android 8.0 蓝牙堆栈是一个完全限定的蓝牙堆栈。限定列表位于蓝牙 SIG 网站上的 QDID 97584 下。核心蓝牙堆栈位于 system/bt 下。
frameworks\base\core\java\android\bluetooth\BluetoothProfile.java
蓝牙配置文件均实现了BluetoothProfile接口
public interface BluetoothProfile { .......
public interface ServiceListener {......} //回调接口
} //接口
frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
以BluetoothHeadset为例, IBluetoothManager是AIDL文件,实现体为BluetoothManagerService
/*package*/ BluetoothHeadset(Context context, ServiceListener l) {
mContext = context;
mServiceListener = l; //上述的回调接口
mAdapter = BluetoothAdapter.getDefaultAdapter();
IBluetoothManager mgr = mAdapter.getBluetoothManager(); //作为BluetoothAdapter的代理
if (mgr != null) {
try {
//mBluetoothStateChangeCallback是一个IBluetoothStateChangeCallback
//此回调主要处理来自BluetoothManagerService的蓝牙状态改变
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); //注册回调
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
doBind(); //绑定Profile
}
frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
向 BluetoothManagerService 注册添加Profile
boolean doBind() {
try {
//mConnection的类型为IBluetoothProfileServiceConnection
return mAdapter.getBluetoothManager().bindBluetoothProfileService(
BluetoothProfile.HEADSET, mConnection);
} catch (RemoteException e) {
Log.e(TAG, "Unable to bind HeadsetService", e);
}
return false;
}
frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
由BluetoothManagerService回调处理
private final IBluetoothProfileServiceConnection mConnection
= new IBluetoothProfileServiceConnection.Stub() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
//返回一个Service 类型为 IBluetoothHeadset
mService = IBluetoothHeadset.Stub.asInterface(Binder.allowBlocking(service));
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_HEADSET_SERVICE_CONNECTED));
}
@Override
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_HEADSET_SERVICE_DISCONNECTED));
}
};
frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_HEADSET_SERVICE_CONNECTED: {
if (mServiceListener != null) {
//调用BluetoothProfile的回调函数
mServiceListener.onServiceConnected(BluetoothProfile.HEADSET,
BluetoothHeadset.this);
}
break;
}
case MESSAGE_HEADSET_SERVICE_DISCONNECTED: {
if (mServiceListener != null) {
mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
}
break;
}
}
}
};
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
向BluetoothManagerService注册状态回调
public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
//交给BluetoothHandler(内部类)处理
Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
msg.obj = callback;
mHandler.sendMessage(msg);
}
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
mStateChangeCallbacks 是一个 RemoteCallbackList
case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK:
{
IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
mStateChangeCallbacks.register(callback);
break;
}
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
bindBluetoothProfileService在IBluetoothManager.aidl文件中定义
IBluetoothProfileServiceConnection 对应一个ProfileServiceConnections
@Override
public boolean bindBluetoothProfileService(int bluetoothProfile,
IBluetoothProfileServiceConnection proxy) {
synchronized (mProfileServices) {
ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
if (psc == null) {
if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
Intent intent = new Intent(IBluetoothHeadset.class.getName());
psc = new ProfileServiceConnections(intent); //新建一个
if (!psc.bindService()) return false;
//放入键值映射集合
mProfileServices.put(new Integer(bluetoothProfile), psc);
}
}
//交给 BluetoothHandler 去做
// Introducing a delay to give the client app time to prepare
Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
addProxyMsg.arg1 = bluetoothProfile;
addProxyMsg.obj = proxy;
mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
return true;
}
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
往 ProfileServiceConnections中加入IBluetoothProfileServiceConnection
case MESSAGE_ADD_PROXY_DELAYED:
{
ProfileServiceConnections psc = mProfileServices.get(
new Integer(msg.arg1));
IBluetoothProfileServiceConnection proxy =
(IBluetoothProfileServiceConnection) msg.obj;
psc.addProxy(proxy);
break;
}
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
mService 是 ProfileServiceConnections 内部持有的 IBinder 远程对象
private void addProxy(IBluetoothProfileServiceConnection proxy) {
mProxies.register(proxy);
if (mService != null) {
try{
proxy.onServiceConnected(mClassName, mService); //执行上述回调
} catch (RemoteException e) {
Slog.e(TAG, "Unable to connect to proxy", e);
}
} else { //服务为空,重新绑定自身 ProfileServiceConnections
if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
msg.obj = this;
mHandler.sendMessage(msg);
}
}
}
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
重新bindService
private boolean bindService() {
if (mIntent != null && mService == null &&
//Connection conn 传的是 this
doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
msg.obj = this;
mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
return true;
}
return false;
}
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
绑定成功后,会对代理逐一执行onServiceConnected回调
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// remove timeout message
mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
mService = service;
mClassName = className;
......
mInvokingProxyCallbacks = true;
final int n = mProxies.beginBroadcast();
try {
for (int i = 0; i < n; i++) {
try {
mProxies.getBroadcastItem(i).onServiceConnected(className, service);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to connect to proxy", e);
}
}
} finally {
mProxies.finishBroadcast();
mInvokingProxyCallbacks = false;
}
}
BluetoothManagerService主要为frameworks\base\core\java\android\bluetooth下的各种BluetoothProfile协议子类提供服务管理,实际充当的是BluetoothAdapter的代理,BluetoothAdapter提供系统API给开发者使用,同时驱动系统蓝牙应用工作。
frameworks\base\core\java\android\bluetooth\BluetoothAdapter.java
mService 类型为IBluetooth, managerService类型为BluetoothManagerService
BluetoothAdapter(IBluetoothManager managerService) {
try {
mServiceLock.writeLock().lock();
mService = managerService.registerAdapter(mManagerCallback); //注册
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.writeLock().unlock();
}
mManagerService = managerService; //BluetoothManagerService
mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
mToken = new Binder(); //令牌
}
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java
private static class AdapterServiceBinder extends IBluetooth.Stub { ...... }
frameworks\base\core\java\android\bluetooth\BluetoothAdapter.java
蓝牙禁用
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean disable() {
try {
return mManagerService.disable(ActivityThread.currentPackageName(), true);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
private void handleDisable() {
try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) {
if (DBG) Slog.d(TAG,"Sending off request.");
if (!mBluetooth.disable()) {
Slog.e(TAG,"IBluetooth.disable() returned false");
}
}
} finally {
mBluetoothLock.readLock().unlock();
}
}
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java
调用 AdapterServiceBinder 的 disable
public boolean disable() {
if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
(!Utils.checkCaller())) {
Log.w(TAG, "disable() - Not allowed for non-active user and non system user");
return false;
}
AdapterService service = getService();
if (service == null) return false;
return service.disable();
}
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java
AdapterService的 disable
boolean disable() {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
debugLog("disable() called...");
//最终交给状态机处理
Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_OFF);
mAdapterStateMachine.sendMessage(m);
return true;
}
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterState.java
状态机对应的处理状态
private class OnState extends State {
......
@Override
public boolean processMessage(Message msg) {
AdapterProperties adapterProperties = mAdapterProperties;
......
switch(msg.what) {
case BLE_TURN_OFF:
notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_OFF);
mPendingCommandState.setTurningOff(true);
transitionTo(mPendingCommandState); //状态转换
// Invoke onBluetoothDisable which shall trigger a
// setScanMode to SCAN_MODE_NONE
Message m = obtainMessage(SET_SCAN_MODE_TIMEOUT);
sendMessageDelayed(m, PROPERTY_OP_DELAY);
adapterProperties.onBluetoothDisable(); //禁用
break;
case USER_TURN_ON:
break;
default:
return false;
}
return true;
}
}
在packages\apps\Bluetooth\src\com\android\bluetooth\下主要是蓝牙协议,适配服务,协议服务。整个协议和服务由状态机驱动执行。
packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothSettings.java
BluetoothSettings是系统蓝牙操作界面
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mInitialScanStarted = false;
mInitiateDiscoverable = true;
final SettingsActivity activity = (SettingsActivity) getActivity();
mSwitchBar = activity.getSwitchBar();
mBluetoothEnabler = new BluetoothEnabler(activity, new SwitchBarController(mSwitchBar),
mMetricsFeatureProvider, Utils.getLocalBtManager(activity),
MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
mBluetoothEnabler.setupSwitchController();
}
packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothEnabler.java
蓝牙操作控制
@Override
public boolean onSwitchToggled(boolean isChecked) {
if (maybeEnforceRestrictions()) {
return true;
}
// Show toast message if Bluetooth is not allowed in airplane mode
if (isChecked &&
!WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
// Reset switch to off
mSwitch.setChecked(false);
return false;
}
mMetricsFeatureProvider.action(mContext, mMetricsEvent, isChecked);
if (mLocalAdapter != null) {
boolean status = mLocalAdapter.setBluetoothEnabled(isChecked); //开关蓝牙
// If we cannot toggle it ON then reset the UI assets:
// a) The switch should be OFF but it should still be togglable (enabled = True)
// b) The switch bar should have OFF text.
if (isChecked && !status) {
mSwitch.setChecked(false);
mSwitch.setEnabled(true);
mSwitchWidget.updateTitle(false);
return false;
}
}
mSwitchWidget.setEnabled(false);
return true;
}
frameworks\base\packages\SettingsLib\src\com\android\settingslib\bluetooth\LocalBluetoothAdapter.java
mAdapter 是 BluetoothAdapter
public boolean setBluetoothEnabled(boolean enabled) {
boolean success = enabled
? mAdapter.enable() //开启
: mAdapter.disable();
return success;
}
frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
调用 BluetoothManagerService 的 enable 函数,最后将操作结果返回
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean enable() {
try {
return mManagerService.enable(ActivityThread.currentPackageName());
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java
static {
classInitNative();
}
packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
static void classInitNative(JNIEnv* env, jclass clazz) {
jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic");
android_bluetooth_UidTraffic.constructor =
env->GetMethodID(jniUidTrafficClass, "" , "(IJJ)V");
.....
char value[PROPERTY_VALUE_MAX];
property_get("bluetooth.mock_stack", value, "");
const char* id =
(strcmp(value, "1") ? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
hw_module_t* module;
int err = hw_get_module(id, (hw_module_t const**)&module);
if (err == 0) {
hw_device_t* abstraction;
err = module->methods->open(module, id, &abstraction); //加载蓝牙模块
if (err == 0) {
bluetooth_module_t* btStack = (bluetooth_module_t*)abstraction;
sBluetoothInterface = btStack->get_bluetooth_interface();
} else {
ALOGE("Error while opening Bluetooth library");
}
} else {
ALOGE("No Bluetooth Library found");
}
}
packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
调用系统蓝牙堆栈处理 system/bt 目录下
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;
}
frameworks\base\core\java\android\bluetooth\BluetoothAdapter.java
通过套接进行数据交换传输 mSocket 是 BluetoothSocket
public BluetoothServerSocket listenUsingRfcommOn(int channel, boolean mitm,
boolean min16DigitPin)
throws IOException {
BluetoothServerSocket socket = new BluetoothServerSocket(
BluetoothSocket.TYPE_RFCOMM, true, true, channel, mitm, min16DigitPin);
int errno = socket.mSocket.bindListen();
if (channel == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
socket.setChannel(socket.mSocket.getPort());
}
if (errno != 0) {
//TODO(BT): Throw the same exception error code
// that the previous code was using.
//socket.mSocket.throwErrnoNative(errno);
throw new IOException("Error: " + errno);
}
return socket;
}
frameworks\base\core\java\android\bluetooth\BluetoothSocket.java
通过IBluetooth 的 createSocketChannel,创建FD, 监听Socket连接
/*package*/ int bindListen() {
int ret;
if (mSocketState == SocketState.CLOSED) return EBADFD;
IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
try {
//创建Socket返回文件描述符
mPfd = bluetoothProxy.createSocketChannel(mType, mServiceName,
mUuid, mPort, getSecurityFlags());
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return -1;
}
// read out port number
try {
synchronized(this) {
if(mSocketState != SocketState.INIT) return EBADFD;
if(mPfd == null) return -1;
FileDescriptor fd = mPfd.getFileDescriptor();
mSocket = LocalSocket.createConnectedLocalSocket(fd);
if (DBG) Log.d(TAG, "bindListen(), new LocalSocket.getInputStream()");
mSocketIS = mSocket.getInputStream();
mSocketOS = mSocket.getOutputStream();
}
int channel = readInt(mSocketIS);
synchronized(this) {
if(mSocketState == SocketState.INIT)
mSocketState = SocketState.LISTENING;
}
if (mPort <= -1) {
mPort = channel;
} // else ASSERT(mPort == channel)
ret = 0;
} catch (IOException e) {
if (mPfd != null) {
try {
mPfd.close();
} catch (IOException e1) {
Log.e(TAG, "bindListen, close mPfd: " + e1);
}
mPfd = null;
}
return -1;
}
return ret;
}
至此我们粗略的查看了蓝牙系统框架,可以看到,系统定义了不同的蓝牙协议的统一行为,让BluetoothAdapter作为交互中心,提供系统和应用交互的接口,BluetoothManagerService作为BluetoothAdapter的代理,对各种协议连接进行处理,Setting 目录的blutooth模块 借助 framwork下的SettingLib模块与 BluetoothAdapter进行交互,最终由系统应用Bluetooth目录下的服务负责与蓝牙底层协议和硬件交互。每一层协议都可以独立处理自己的逻辑,还可以自由得添加新的协议,可扩展性很高。我们就不去逐一分析各层协议的具体实现了,可以说蓝牙的用途是极广泛且重要的,不光用于数据传输,蓝牙耳机,心跳检测,血脂血糖检测,VR等。