零. 前言
由于Bluedroid的介绍文档有限,以及对Android的一些基本的知识需要了(Android 四大组件/AIDL/Framework/Binder机制/JNI/HIDL等),加上需要掌握的语言包括Java/C/C++等,加上网络上其实没有一个完整的介绍Bluedroid系列的文档,所以不管是蓝牙初学者还是蓝牙从业人员,都有不小的难度,学习曲线也相对较陡,所以我有了这个想法,专门对Bluedroid做一个系统性的介绍,尽可能的涵盖所有内容。
-------------------------------------------------------------------------------------------------------------------------
蓝牙视频教程(跟韦东山老师合作), 其中专题21就是专门针对Bluedroid做的系统介绍
https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.20.5aeb41f98e267j&id=693788592796
--------------------------------------------------------------------------------------------------------------------------
我们之前介绍过Android的架构,我们本节就介绍下如下图部分:
整个AOSP蓝牙的代码如下:
备注:不同的Android版本下可能路径不同,需要自行去查看下
一. 蓝牙系统服务
这块代码主要在/frameworks/base/services/java/com/android/server/SystemServer.java
在Android系统启动过程中,SystemServer是第一个被启动的进程。当Android设备被开机后,内核会创建一个名为init的进程,init进程会启动Zygote进程,Zygote进程会启动SystemServer进程。因此,SystemServer是整个Android系统启动的核心进程,它负责初始化并启动大部分系统服务和应用程序,是整个Android系统的主要启动入口。
具体来说,SystemServer主要完成以下几个任务:
- 启动和初始化系统服务:SystemServer会启动和初始化大部分系统服务,例如ActivityManagerService、WindowManagerService、PackageManagerService、PowerManagerService等等。这些服务会在启动过程中被创建并注册到系统服务中心,供其他应用程序和服务调用。
- 启动和初始化核心应用程序:SystemServer会启动和初始化Android系统中的核心应用程序,例如SystemUI、Settings等等。这些应用程序会在启动过程中被创建并运行,提供各种用户界面和功能。
- 加载和初始化系统属性:SystemServer会加载和初始化/system/build.prop文件中定义的系统属性,例如设备型号、厂商信息等等。这些属性可以在系统运行时被访问和修改。
- 启动Adb守护进程:SystemServer会启动Adb守护进程,使得开发者可以通过adb工具来访问设备。
总之,SystemServer是整个Android系统启动过程中的核心进程,负责启动和初始化大部分系统服务和应用程序,为整个系统的运行提供基础支持。SystemServer的启动时间通常在内核启动之后的几秒钟内,具体时间取决于设备的硬件性能和系统配置。
/frameworks/base/services/java/com/android/server/SystemServer.java
SystemServer启动代码通过main函数运行。
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
SystemServer().run();执行startOtherServices(t);
/frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
...
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
然后startOtherServices(t);执行如下代码,开启Bluetooth service类
/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
Slog.i(TAG, "No Bluetooth Service (factory test)");
} else if (!context.getPackageManager().hasSystemFeature
(PackageManager.FEATURE_BLUETOOTH)) {
Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)");
} else {
t.traceBegin("StartBluetoothService");
// 启动蓝牙fwk manager service
mSystemServiceManager.startService(BluetoothService.class);
t.traceEnd();
}
...
}
/frameworks/base/services/core/java/com/android/server/BluetoothService.java
public BluetoothService(Context context) {
super(context);
mBluetoothManagerService = new BluetoothManagerService(context);
}
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
BluetoothManagerService(Context context) {
Slog.e(TAG, "new BluetoothManagerService");
// BluetoothManagerService的私有类,主要用于处理一些message
mHandler = new BluetoothHandler(IoThread.get().getLooper());
mContext = context;
mWirelessConsentRequired = context.getResources()
.getBoolean(com.android.internal.R.bool.config_wirelessConsentRequired);
mCrashes = 0;
mBluetooth = null;
mBluetoothBinder = null;
mBluetoothGatt = null;
mBinding = false;
mUnbinding = false;
mEnable = false;
mState = BluetoothAdapter.STATE_OFF;
mQuietEnableExternal = false;
mEnableExternal = false;
mAddress = null;
mName = null;
mErrorRecoveryRetryCounter = 0;
mContentResolver = context.getContentResolver();
// Observe BLE scan only mode settings change.
registerForBleScanModeChange();
mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
mIsHearingAidProfileSupported = context.getResources()
.getBoolean(com.android.internal.R.bool.config_hearing_aid_profile_supported);
// TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
if (!TextUtils.isEmpty(value)) {
boolean isHearingAidEnabled = Boolean.parseBoolean(value);
Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
if (isHearingAidEnabled && !mIsHearingAidProfileSupported) {
// Overwrite to enable support by FeatureFlag
mIsHearingAidProfileSupported = true;
}
}
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
filter.addAction(Intent.ACTION_SETTING_RESTORED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(mReceiver, filter);
loadStoredNameAndAddress();
if (isBluetoothPersistedStateOn()) {
if (DBG) {
Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
}
mEnableExternal = true;
}
String airplaneModeRadios =
Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
if (airplaneModeRadios == null || airplaneModeRadios.contains(
Settings.Global.RADIO_BLUETOOTH)) {
mBluetoothAirplaneModeListener = new BluetoothAirplaneModeListener(
this, IoThread.get().getLooper(), context);
}
int systemUiUid = -1;
// Check if device is configured with no home screen, which implies no SystemUI.
boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
if (!noHome) {
PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
systemUiUid = pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(),
MATCH_SYSTEM_ONLY, USER_SYSTEM);
}
if (systemUiUid >= 0) {
Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
} else {
// Some platforms, such as wearables do not have a system ui.
Slog.w(TAG, "Unable to resolve SystemUI's UID.");
}
mSystemUiUid = systemUiUid;
}
到此为止,BluetoothManagerService 就停止在这里等待Binder connection
二. Settings开启蓝牙的流程
其中Apps就是我们所说的Settings app或者你自己写的app
Settings的代码路径如下:packages\apps\Settings
蓝牙的framework 路径如下:frameworks\base\core\java\android\bluetooth
1. 下行方向
我所谓的下行方向就是通过应用层调用到fwk到service到system bt到hidl service到controller这个方向!
framework的函数你可以理解为是API,那么Settings apk或者你自己写的就是调用fwk的api
首先在创建BluetoothEnabler的类中,会获取fwk的BluetoothAdapter class的静态方法getDefaultAdapter获取adapter. 这个api就相当于调用的函数。
/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java
public BluetoothEnabler(Context context, SwitchWidgetController switchController,
MetricsFeatureProvider metricsFeatureProvider, int metricsEvent,
RestrictionUtils restrictionUtils) {
...
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Bluetooth is not supported
mSwitchController.setEnabled(false);
}
...
}
/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
public static synchronized BluetoothAdapter getDefaultAdapter() {
if (sAdapter == null) {
IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
if (b != null) {
IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
sAdapter = new BluetoothAdapter(managerService);
} else {
Log.e(TAG, "Bluetooth binder is null");
}
}
return sAdapter;
}
其中IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
如果蓝牙管理服务(BluetoothManagerService)已经在系统中运行,并且它的服务代理已经被注册到ServiceManager中,那么调用 ServiceManager.getService()
将会直接返回这个已经存在的代理对象,而不会立即触发Binder通信。
后面调用蓝牙enable跟disable方法
/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java
private boolean setBluetoothEnabled(boolean isEnabled) {
return isEnabled ? mBluetoothAdapter.enable() : mBluetoothAdapter.disable();
}
我们可以看下aidl接口
/system/bt/binder/android/bluetooth/IBluetoothManager.aidl
interface IBluetoothManager
{
IBluetooth registerAdapter(in IBluetoothManagerCallback callback);
void unregisterAdapter(in IBluetoothManagerCallback callback);
void registerStateChangeCallback(in IBluetoothStateChangeCallback callback);
void unregisterStateChangeCallback(in IBluetoothStateChangeCallback callback);
boolean isEnabled();
boolean enable(String packageName);
boolean enableNoAutoConnect(String packageName);
boolean disable(String packageName, boolean persist);
int getState();
IBluetoothGatt getBluetoothGatt();
boolean bindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
void unbindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
String getAddress();
String getName();
boolean isBleScanAlwaysAvailable();
int updateBleAppCount(IBinder b, boolean enable, String packageName);
boolean isBleAppPresent();
boolean isHearingAidProfileSupported();
}
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
public boolean enable(String packageName) throws RemoteException {
...
synchronized (mReceiver) {
mQuietEnableExternal = false;
mEnableExternal = true;
// waive WRITE_SECURE_SETTINGS permission check
sendEnableMsg(false,
BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
}
...
}
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
addActiveLog(reason, packageName, true);
mLastEnabledTime = SystemClock.elapsedRealtime();
}
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
public void handleMessage(Message msg)
{
switch(msg.what)
{
...
case MESSAGE_ENABLE:
handleEnable(mQuietEnable);
....
}
}
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode;
try {
mBluetoothLock.writeLock().lock();
if ((mBluetooth == null) && (!mBinding)) {
//Start bind timeout and bind
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) {
//Enable bluetooth
try {
if (!mQuietEnable) {
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();
}
}
这个会触发bind,那么被绑定的服务在哪里声明的呢?
/packages/apps/Bluetooth/AndroidManifest.xml
bond后会调用这个函数onServiceConnected
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
private class BluetoothServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName componentName, IBinder service) {
String name = componentName.getClassName();
if (DBG) {
Slog.d(TAG, "BluetoothServiceConnection: " + name);
}
Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
msg.arg1 = SERVICE_IBLUETOOTH;
} else if (name.equals("com.android.bluetooth.gatt.GattService")) {
msg.arg1 = SERVICE_IBLUETOOTHGATT;
} else {
Slog.e(TAG, "Unknown service connected: " + name);
return;
}
msg.obj = service;
mHandler.sendMessage(msg);
}
}
另外,绑定AdapterService, 这个会触发两个动作:
1)AdapterService静态方法调用
2)AdapterService onCreate方法调用
我们先说第一点哈·,AdapterService静态方法调用
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
static {
System.loadLibrary("bluetooth_jni");
classInitNative();
}
System.loadLibrary("bluetooth_jni");
加载bluetooth_jni动态库会触发JNI_OnLoad,这个方法就是把jni的cpp方法注册到java中,这样jave层就可以直接调用jni的cpp代码了,比如后面调用的classInitNative就是jni cpp代码,我们来简单看下一个注册过程
packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void*)classInitNative},
{"initNative", "(ZZZ)Z", (void*)initNative},
{"cleanupNative", "()V", (void*)cleanupNative},
{"enableNative", "()Z", (void*)enableNative},
{"disableNative", "()Z", (void*)disableNative},
{"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative},
{"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative},
{"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative},
{"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative},
{"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative},
{"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
{"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative},
{"createBondNative", "([BI)Z", (void*)createBondNative},
{"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z",
(void*)createBondOutOfBandNative},
{"removeBondNative", "([B)Z", (void*)removeBondNative},
{"cancelBondNative", "([B)Z", (void*)cancelBondNative},
{"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative},
{"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative},
{"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative},
{"getRemoteServicesNative", "([B)Z", (void*)getRemoteServicesNative},
{"getSocketManagerNative", "()Landroid/os/IBinder;",
(void*)getSocketManagerNative},
{"setSystemUiUidNative", "(I)V", (void*)setSystemUiUidNative},
{"setForegroundUserIdNative", "(I)V", (void*)setForegroundUserIdNative},
{"alarmFiredNative", "()V", (void*)alarmFiredNative},
{"readEnergyInfo", "()I", (void*)readEnergyInfo},
{"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V",
(void*)dumpNative},
{"dumpMetricsNative", "()[B", (void*)dumpMetricsNative},
{"factoryResetNative", "()Z", (void*)factoryResetNative},
{"interopDatabaseClearNative", "()V", (void*)interopDatabaseClearNative},
{"interopDatabaseAddNative", "(I[BI)V", (void*)interopDatabaseAddNative},
{"obfuscateAddressNative", "([B)[B", (void*)obfuscateAddressNative}};
int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
return jniRegisterNativeMethods(
env, "com/android/bluetooth/btservice/AdapterService", sMethods,
NELEM(sMethods));
}
然后注册好了,下面就可以调用了classInitNative
static void classInitNative(JNIEnv* env, jclass clazz) {
jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic");
android_bluetooth_UidTraffic.constructor =
env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V");
jclass jniCallbackClass =
env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
sJniCallbacksField = env->GetFieldID(
clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;");
method_stateChangeCallback =
env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
method_adapterPropertyChangedCallback = env->GetMethodID(
jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V");
method_discoveryStateChangeCallback = env->GetMethodID(
jniCallbackClass, "discoveryStateChangeCallback", "(I)V");
method_devicePropertyChangedCallback = env->GetMethodID(
jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V");
method_deviceFoundCallback =
env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
method_pinRequestCallback =
env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V");
method_sspRequestCallback =
env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V");
method_bondStateChangeCallback =
env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V");
method_aclStateChangeCallback =
env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V");
method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
method_acquireWakeLock =
env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
method_releaseWakeLock =
env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
method_energyInfo = env->GetMethodID(
clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");
if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {
ALOGE("No Bluetooth Library found");
}
}
这里面主要是获取jave类中的方法,也及时为了jni cpp可以调用jave代码,给回调函数,第二个是加载蓝牙协议栈的库文件,#define DEFAULT_BT_LIBRARY_NAME "libbluetooth.so"
所以第一点就打通了jni cpp代码跟service java上下通信的途径!
然后我们再说第二点AdapterService onCreate方法调用
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
public void onCreate() {
super.onCreate();
debugLog("onCreate()");
...
initNative(isGuest(), isNiapMode(), isAtvDevice);
...
}
因为前面我们已经jni跟jave的沟通渠道已经导通,所以initNative就是调用jni的函数
/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest,
jboolean isNiapMode, jboolean isAtvDevice) {
ALOGV("%s", __func__);
...
int ret = sBluetoothInterface->init(&sBluetoothCallbacks,
isGuest == JNI_TRUE ? 1 : 0,
isNiapMode == JNI_TRUE ? 1 : 0,
isAtvDevice == JNI_TRUE ? 1 : 0);
if (ret != BT_STATUS_SUCCESS && ret != BT_STATUS_DONE) {
ALOGE("Error while setting the callbacks: %d\n", ret);
sBluetoothInterface = NULL;
return JNI_FALSE;
}
...
return JNI_TRUE;
}
这里就进入到system bt中
另外,当binder通信成功后除了AdapterService静态方法调用以及onCreate方法调用,还有BluetoothManagerService.java中的onServiceConnected调用,这个不能忘记哈· 否则追不下去代码,另外,这些代码分析确实会感觉跳来跳去,还是结合流程图一起看!
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
public void onServiceConnected(ComponentName componentName, IBinder service) {
String name = componentName.getClassName();
if (DBG) {
Slog.d(TAG, "BluetoothServiceConnection: " + name);
}
Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
msg.arg1 = SERVICE_IBLUETOOTH;
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else if (name.equals("com.android.bluetooth.gatt.GattService")) {
msg.arg1 = SERVICE_IBLUETOOTHGATT;
} else {
Slog.e(TAG, "Unknown service connected: " + name);
return;
}
msg.obj = service;
mHandler.sendMessage(msg);
}
会发送MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息出来,我们看下消息处理
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
if (DBG) {
Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
}
IBinder service = (IBinder) msg.obj;
try {
mBluetoothLock.writeLock().lock();
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
mBluetoothGatt =
IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
continueFromBleOnState();
break;
} // else must be SERVICE_IBLUETOOTH
mBinding = false;
mTryBindOnBindTimeout = false;
mBluetoothBinder = service;
mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
if (!isNameAndAddressSet()) {
Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
mHandler.sendMessage(getMsg);
if (mGetNameAddressOnly) {
return;
}
}
...
//Do enable request
try {
if (!mQuietEnable) {
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();
}
...
break;
}
获取aidl接口,也就是调用到了这个类下面的enable
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
public synchronized boolean enable(boolean quietMode) {
// Enforce the user restriction for disallowing Bluetooth if it was set.
if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) {
debugLog("enable() called when Bluetooth was disallowed");
return false;
}
Log.e(TAG, "AdapterService enable");
debugLog("enable() - Enable called with quiet mode status = " + quietMode);
mQuietmode = quietMode;
mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
return true;
}
这个会触发status machine,会调用到OffState中processMessage
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
public boolean processMessage(Message msg) {
switch (msg.what) {
case BLE_TURN_ON:
transitionTo(mTurningBleOnState);
break;
default:
infoLog("Unhandled message - " + messageString(msg.what));
return false;
}
return true;
}
然后进入到TurningBleOnState类中的enter
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
public void enter() {
super.enter();
sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
mAdapterService.bringUpBle();
}
void bringUpBle() {
...
//Start Gatt service
setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);
}
开启gattservice服务
另外,ProfileService的状态改变会触发AdapterService的onProfileServiceStateChanged
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
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);
}
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
private void processProfileServiceStateChanged(ProfileService profile, int state) {
switch (state) {
case BluetoothAdapter.STATE_ON:
if (!mRegisteredProfiles.contains(profile)) {
Log.e(TAG, profile.getName() + " not registered (STATE_ON).");
return;
}
if (mRunningProfiles.contains(profile)) {
Log.e(TAG, profile.getName() + " already running.");
return;
}
mRunningProfiles.add(profile);
if (GattService.class.getSimpleName().equals(profile.getName())) {
Log.e(TAG, "processProfileServiceStateChanged enableNative");
// 这个地方就是调用libjni.so的方法,通过jni native调用
enableNative();
} else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
&& mRegisteredProfiles.size() == mRunningProfiles.size()) {
mAdapterProperties.onBluetoothReady();
updateUuids();
setBluetoothClassFromConfig();
initProfileServices();
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS);
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE);
mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
}
break;
default:
Log.e(TAG, "Unhandled profile state: " + state);
}
}
然后这个动作会触发com_android_bluetooth_btservice_adapterService.cpp中的
/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static jboolean enableNative(JNIEnv* env, jobject obj) {
ALOGV("%s", __func__);
if (!sBluetoothInterface) return JNI_FALSE;
int ret = sBluetoothInterface->enable();
return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
: JNI_FALSE;
}
其中sBluetoothInterface 是hal接口,定义如下:
typedef struct {
/** set to sizeof(bt_interface_t) */
size_t size;
/**
* Opens the interface and provides the callback routines
* to the implemenation of this interface.
* The |is_atv| flag indicates whether the local device is an Android TV
*/
int (*init)(bt_callbacks_t* callbacks, bool is_atv);
/** Enable Bluetooth. */
int (*enable)(bool guest_mode);
/** Disable Bluetooth. */
int (*disable)(void);
/** Closes the interface. */
void (*cleanup)(void);
/** Get all Bluetooth Adapter properties at init */
int (*get_adapter_properties)(void);
/** Get Bluetooth Adapter property of 'type' */
int (*get_adapter_property)(bt_property_type_t type);
/** Set Bluetooth Adapter property of 'type' */
/* Based on the type, val shall be one of
* RawAddress or bt_bdname_t or bt_scanmode_t etc
*/
int (*set_adapter_property)(const bt_property_t *property);
/** Get all Remote Device properties */
int (*get_remote_device_properties)(RawAddress *remote_addr);
/** Get Remote Device property of 'type' */
int (*get_remote_device_property)(RawAddress *remote_addr,
bt_property_type_t type);
/** Set Remote Device property of 'type' */
int (*set_remote_device_property)(RawAddress *remote_addr,
const bt_property_t *property);
/** Get Remote Device's service record for the given UUID */
int (*get_remote_service_record)(const RawAddress& remote_addr,
const bluetooth::Uuid& uuid);
/** Start SDP to get remote services */
int (*get_remote_services)(RawAddress *remote_addr);
/** Start Discovery */
int (*start_discovery)(void);
/** Cancel Discovery */
int (*cancel_discovery)(void);
/** Create Bluetooth Bonding */
int (*create_bond)(const RawAddress *bd_addr, int transport);
/** Create Bluetooth Bond using out of band data */
int (*create_bond_out_of_band)(const RawAddress *bd_addr, int transport,
const bt_out_of_band_data_t *oob_data);
/** Remove Bond */
int (*remove_bond)(const RawAddress *bd_addr);
/** Cancel Bond */
int (*cancel_bond)(const RawAddress *bd_addr);
/**
* Get the connection status for a given remote device.
* return value of 0 means the device is not connected,
* non-zero return status indicates an active connection.
*/
int (*get_connection_state)(const RawAddress *bd_addr);
/** BT Legacy PinKey Reply */
/** If accept==FALSE, then pin_len and pin_code shall be 0x0 */
int (*pin_reply)(const RawAddress *bd_addr, uint8_t accept,
uint8_t pin_len, bt_pin_code_t *pin_code);
/** BT SSP Reply - Just Works, Numeric Comparison and Passkey
* passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON &
* BT_SSP_VARIANT_CONSENT
* For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey
* shall be zero */
int (*ssp_reply)(const RawAddress *bd_addr, bt_ssp_variant_t variant,
uint8_t accept, uint32_t passkey);
/** Get Bluetooth profile interface */
const void* (*get_profile_interface) (const char *profile_id);
/** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */
/* Configure DUT Mode - Use this mode to enter/exit DUT mode */
int (*dut_mode_configure)(uint8_t enable);
/* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */
int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len);
/** BLE Test Mode APIs */
/* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */
int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len);
/** Sets the OS call-out functions that bluedroid needs for alarms and wake locks.
* This should be called immediately after a successful |init|.
*/
int (*set_os_callouts)(bt_os_callouts_t *callouts);
/** Read Energy info details - return value indicates BT_STATUS_SUCCESS or BT_STATUS_NOT_READY
* Success indicates that the VSC command was sent to controller
*/
int (*read_energy_info)();
/**
* Native support for dumpsys function
* Function is synchronous and |fd| is owned by caller.
* |arguments| are arguments which may affect the output, encoded as
* UTF-8 strings.
*/
void (*dump)(int fd, const char **arguments);
/**
* Clear /data/misc/bt_config.conf and erase all stored connections
*/
int (*config_clear)(void);
/**
* Clear (reset) the dynamic portion of the device interoperability database.
*/
void (*interop_database_clear)(void);
/**
* Add a new device interoperability workaround for a remote device whose
* first |len| bytes of the its device address match |addr|.
* NOTE: |feature| has to match an item defined in interop_feature_t (interop.h).
*/
void (*interop_database_add)(uint16_t feature, const RawAddress *addr, size_t len);
} bt_interface_t;
这个enable是调用libbluetooth.so中的enable,也就是bluedroid bluetooth.cc或者android8之前的bluetooth.c
static int enable() {
if (!interface_ready()) return BT_STATUS_NOT_READY;
stack_manager_get_interface()->start_up_stack_async();
return BT_STATUS_SUCCESS;
}
然后就是走bluedroid流程了
2. 上行方向
上行方向就是hidl service->system bt -> service -> framework -> Settings
协议层上传蓝牙协议栈初始化的callback如下:
/system/bt/btif/src/stack_manager.cc
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);
}
这个就是system bt给bluetooth service jni发送蓝牙初始化成功的callback
/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static void adapter_state_change_callback(bt_state_t status) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ALOGV("%s: Status is: %d", __func__, status);
sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback,
(jint)status);
}
因为我们前面已经打通了jni跟adapter service的通信通道,所以直接通过sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback,(jint)status) 就是调用了
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java 中的stateChangeCallback
void stateChangeCallback(int status) {
if (status == AbstractionLayer.BT_STATE_OFF) {
debugLog("stateChangeCallback: disableNative() completed");
mAdapterStateMachine.sendMessage(AdapterState.STACK_DISABLED);
} else if (status == AbstractionLayer.BT_STATE_ON) {
String BT_SOC = getSocName();
if (BT_SOC.equals("pronto")) {
Log.i(TAG, "setting max audio connection to 2");
mAdapterProperties.setMaxConnectedAudioDevices(2);
}
mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
} else {
Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
}
}
然后此部分到AdapterState中处理,由于目前是TurningBleOnState状态,所以入
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
public boolean processMessage(Message msg) {
switch (msg.what) {
case BLE_STARTED:
transitionTo(mBleOnState);
break;
...
}
return true;
}
状态转换,进入mBleOnState状态,所以会触发父类的BaseAdapterState 的enter函数
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
public void enter() {
int currState = getStateValue();
infoLog("entered ");
mAdapterService.updateAdapterState(mPrevState, currState);
mPrevState = currState;
}
然后进入AdapterService中处理状态概念
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
void updateAdapterState(int prevState, int newState) {
mAdapterProperties.setState(newState);
if (mCallbacks != null) {
int n = mCallbacks.beginBroadcast();
debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
newState) + " to " + n + " receivers.");
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();
}
...
}
然后进入到framework层来处理
/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
public void onBluetoothStateChange(boolean on) {
mCallback.onBluetoothStateChange(on);}
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
Message msg =
mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
mHandler.sendMessage(msg);
}
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
case MESSAGE_BLUETOOTH_STATE_CHANGE: {
int prevState = msg.arg1;
int newState = msg.arg2;
if (DBG) {
Slog.d(TAG,
"MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
prevState) + " > " + BluetoothAdapter.nameForState(
newState));
}
mState = newState;
bluetoothStateChangeHandler(prevState, newState);
...
break;
}
由于gatt服务没有起来,所以进入bluetoothStateChangeHandler需要先进行gatt service的bind
private void bluetoothStateChangeHandler(int prevState, int newState) {
...
Intent i = new Intent(IBluetoothGatt.class.getName());
doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
UserHandle.CURRENT);
...
}
这个同样进进入到bind成功,又进入到这个onServiceConnected流程,是不是很熟悉
public void onServiceConnected(ComponentName componentName, IBinder service) {
String name = componentName.getClassName();
if (DBG) {
Slog.d(TAG, "BluetoothServiceConnection: " + name);
}
Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
msg.arg1 = SERVICE_IBLUETOOTH;
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else if (name.equals("com.android.bluetooth.gatt.GattService")) {
msg.arg1 = SERVICE_IBLUETOOTHGATT;
} else {
Slog.e(TAG, "Unknown service connected: " + name);
return;
}
msg.obj = service;
mHandler.sendMessage(msg);
}
发送MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息,然后进入到
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java,调用continueFromBleOnState
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
...
IBinder service = (IBinder) msg.obj;
try {
mBluetoothLock.writeLock().lock();
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
mBluetoothGatt =
IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
continueFromBleOnState();
break;
} // else must be SERVICE_IBLUETOOTH
...
}
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
在里面调用mBluetooth.onLeServiceUp();
private void continueFromBleOnState() {
...
else if (isBluetoothPersistedStateOnBluetooth() ||
mEnableExternal) {
// This triggers transition to STATE_ON
mBluetooth.updateQuietModeStatus(mQuietEnable);
mBluetooth.onLeServiceUp();
persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
}
...
}
通过aidl接口调用mBluetooth.onLeServiceUp(),然后从service回到了service部分
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
void onLeServiceUp() {
mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
}
因为我们前面已经进入了BleOnState状态,所以在这里直接在BleOnState类中处理
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
public boolean processMessage(Message msg) {
switch (msg.what) {
case USER_TURN_ON:
mAdapterService.startBrEdrStartup();
transitionTo(mTurningOnState);
break;
...
}
return true;
}
进入TurningOnState的状态后,调用enter,然后会调用startProfileServices函数
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
public void enter() {
super.enter();
sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
mAdapterService.startProfileServices();
}
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
void startProfileServices() {
debugLog("startCoreServices()");
Class[] supportedProfileServices = Config.getSupportedProfiles();
if (supportedProfileServices.length == 1 && GattService.class.getSimpleName()
.equals(supportedProfileServices[0].getSimpleName())) {
mAdapterProperties.onBluetoothReady();
updateUuids();
setBluetoothClassFromConfig();
mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
} else {
setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON);
}
}
然后又回到packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java处理
public boolean processMessage(Message msg) {
switch (msg.what) {
case BREDR_STARTED:
transitionTo(mOnState);
break;
...
}
return true;
}
进入父类的enter处理mAdapterService.updateAdapterState(mPrevState, currState);
所以会触发父类的BaseAdapterState 的enter函数
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
public void enter() {
int currState = getStateValue();
infoLog("entered ");
mAdapterService.updateAdapterState(mPrevState, currState);
mPrevState = currState;
}
然后进入AdapterService中处理状态概念
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
void updateAdapterState(int prevState, int newState) {
mAdapterProperties.setState(newState);
if (mCallbacks != null) {
int n = mCallbacks.beginBroadcast();
debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
newState) + " to " + n + " receivers.");
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();
}
...
}
然后进入到framework层来处理
/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
public void onBluetoothStateChange(boolean on) {
mCallback.onBluetoothStateChange(on);}
/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
Message msg =
mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
mHandler.sendMessage(msg);
}
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
case MESSAGE_BLUETOOTH_STATE_CHANGE: {
int prevState = msg.arg1;
int newState = msg.arg2;
if (DBG) {
Slog.d(TAG,
"MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
prevState) + " > " + BluetoothAdapter.nameForState(
newState));
}
mState = newState;
bluetoothStateChangeHandler(prevState, newState);
...
break;
}
然后调用bluetoothStateChangeHandler,这个函数中处理由于前面的服务已经起来,所以我们直接送广播上去
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
private void bluetoothStateChangeHandler(int prevState, int newState) {
...
if (isStandardBroadcast) {
if (prevState == BluetoothAdapter.STATE_BLE_ON) {
// Show prevState of BLE_ON as OFF to standard users
prevState = BluetoothAdapter.STATE_OFF;
}
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
}
}
那么广播送上去后,谁来接收呢?当然是Settings apk的BluetoothEnabler类
/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Broadcast receiver is always running on the UI thread here,
// so we don't need consider thread synchronization.
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
handleStateChanged(state);
}
};
然后就对应的把android的空间蓝牙开关打开了
/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java
void handleStateChanged(int state) {
switch (state) {
case BluetoothAdapter.STATE_TURNING_ON:
mSwitchController.setEnabled(false);
break;
case BluetoothAdapter.STATE_ON:
mSwitchController.setEnabled(true);
setChecked(true);
break;
case BluetoothAdapter.STATE_TURNING_OFF:
mSwitchController.setEnabled(false);
break;
case BluetoothAdapter.STATE_OFF:
mSwitchController.setEnabled(true);
setChecked(false);
break;
default:
mSwitchController.setEnabled(true);
setChecked(false);
}
}