Android 提供支持經典藍牙和藍牙低功耗的默認藍牙堆棧。藉助藍牙,Android 設備能夠建立我的區域網絡,以便經過附近的藍牙設備發送和接收數據,在 Android 4.3 及更高版本中,Android 藍牙堆棧可提供實現藍牙低功耗 (BLE) 的功能。要充分利用 BLE API,請遵循 Android 藍牙 HCI 要求。具備合格芯片組的 Android 設備能夠實現經典藍牙或同時實現經典藍牙和 BLE。BLE 不能向後兼容較舊版本的藍牙芯片組。在 Android 8.0 中,原生藍牙堆棧徹底符合藍牙 5 的要求。要使用可用的藍牙 5 功能,該設備須要具備符合藍牙 5 要求的芯片組。
java
處於應用框架級別的是應用代碼,它使用 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 下。
1. 藍牙管理服務android
frameworks\base\core\java\android\bluetooth\BluetoothProfile.java
藍牙配置文件均實現了BluetoothProfile接口git
public interface BluetoothProfile { .......
public interface ServiceListener {......} //回調接口
} //接口網絡
frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
以BluetoothHeadset爲例, IBluetoothManager是AIDL文件,實現體爲BluetoothManagerServiceapp
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
}less
frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
向 BluetoothManagerService 註冊添加Profilesocket
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;
}ide
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給開發者使用,同時驅動系統藍牙應用工做。
2. 藍牙適配器
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\下主要是藍牙協議,適配服務,協議服務。整個協議和服務由狀態機驅動執行。
3. 系統藍牙設置
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, "<init>", "(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等。