Android8.0 蓝牙系统
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 下。
1. 蓝牙管理服务
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给开发者使用,同时驱动系统蓝牙应用工作。
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; }
4. 蓝牙HAL
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;}
5. 蓝牙数据传输
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等。
更多相关文章
- Android AOSP基础(四)Source Insight和Android Studio导入系统源码
- 硬件访问服务4之Android硬件访问服务框架及系统函数全详细实现
- 3D激光扫描三维重建——6.(android)系统框架
- android开发之源码级分析(系统启动流程 & Handler消息机制 & Asyn
- Android输入系统概述
- Android系统做了哪些优化?
- Android之路-------浅淡Android历史、系统架构与开发特色