1 UI
蓝牙开始扫描位于setting的 /packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPairingDetail.java 中。
void enableScanning() {
// Clear all device states before first scan
if (!mInitialScanStarted) {
if (mAvailableDevicesCategory != null) {
removeAllDevices();
}
mLocalManager.getCachedDeviceManager().clearNonBondedDevices();
mInitialScanStarted = true;
}
super.enableScanning();
}
在这里如果没有开始扫描就清除缓存中所有的设备,然后将缓存的设备中没有配对的设备清除,最后调用了父类 DeviceListPreferenceFragment 的enableScanning()方法:
@VisibleForTesting
void enableScanning() {
// LocalBluetoothAdapter already handles repeated scan requests
mLocalAdapter.startScanning(true);
mScanEnabled = true;
}
这里其实最终调用了/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter的startScanning方法开始扫描。
2 framework
LocalBluetoothAdapter的startScanning方法:
public void startScanning(boolean force) {
// Only start if we're not already scanning
// 只会在没有进行扫描的时候开始扫描
if (!mAdapter.isDiscovering()) {
// 如果不是强制扫描,在SCAN_EXPIRATION_MS间隔内,只扫描一次
if (!force) {
// Don't scan more than frequently than SCAN_EXPIRATION_MS,
// unless forced
if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
return;
}
// If we are playing music, don't scan unless forced.
// 播放蓝牙音乐时,不进行扫描
A2dpProfile a2dp = mProfileManager.getA2dpProfile();
if (a2dp != null && a2dp.isA2dpPlaying()) {
return;
}
}
// 开始扫描
if (mAdapter.startDiscovery()) {
mLastScan = System.currentTimeMillis();
}
}
}
这里最后调用frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java的startDiscovery方法,启动扫描任务
public boolean startDiscovery() {
if (!Utils.checkCaller()) {
Log.w(TAG, "startDiscovery() - Not allowed for non-active user");
return false;
}
AdapterService service = getService();
if (service == null) return false;
return service.startDiscovery();
}
3 Bluetooth App
这里的 service.startDiscovery 属于 aidl 跨进程通信,通过 IBluetooth.aidl 调用远程服务 /packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService 中的 startDiscovery 方法:
boolean startDiscovery() {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
//do not allow new connections with active multicast
A2dpService a2dpService = A2dpService.getA2dpService();
if (a2dpService != null &&
a2dpService.isMulticastFeatureEnabled() &&
a2dpService.isMulticastOngoing(null)) {
Log.i(TAG,"A2dp Multicast is Ongoing, ignore discovery");
return false;
}
// 扫描中则终止操作
if (mAdapterProperties.isDiscovering()) {
Log.i(TAG,"discovery already active, ignore startDiscovery");
return false;
}
return startDiscoveryNative();
}
这里最终调用tartDiscoveryNative()方法,从 Java 层调到 JNI 层的com_android_bluetooth_btservice_AdapterService.cpp文件中的 startDiscoveryNative 方法:
static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
ALOGV("%s:",__FUNCTION__);
jboolean result = JNI_FALSE;
if (!sBluetoothInterface) return result;
int ret = sBluetoothInterface->start_discovery();//该接口调用到hal层的配对函数
result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
return result;
}
int ret = sBluetoothInterface->start_discovery() 这行代码调进了hal层的蓝牙协议栈中。
4 蓝牙协议栈
上面调用的start_discovery 方法位于 /system/bt/btif/src/bluetooth.cc:
static int start_discovery(void)
{
/* sanity check */ //完整性检查
if (interface_ready() == FALSE)
return BT_STATUS_NOT_READY;
return btif_dm_start_discovery();
}