Android 9.0 蓝牙配对流程

关注我,更多程序猿的日常信息等你哦
Android 9.0 蓝牙配对流程
文章图片

1 、UI DeviceListPreferenceFragment是蓝牙扫描到的设备列表,点击其中一个蓝牙设备,调用onPreferenceTreeClick方法开始蓝牙的配对过程。
/packages/apps/Settings/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java

public boolean onPreferenceTreeClick(Preference preference) { if (KEY_BT_SCAN.equals(preference.getKey())) { mLocalAdapter.startScanning(true); return true; }if (preference instanceof BluetoothDevicePreference) { BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference; CachedBluetoothDevice device = btPreference.getCachedDevice(); mSelectedDevice = device.getDevice(); onDevicePreferenceClick(btPreference); return true; }return super.onPreferenceTreeClick(preference); }

void onDevicePreferenceClick(BluetoothDevicePreference btPreference) { btPreference.onClicked(); }

/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
void onClicked() { Context context = getContext(); int bondState = mCachedDevice.getBondState(); final MetricsFeatureProvider metricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); if (mCachedDevice.isConnected()) { metricsFeatureProvider.action(context, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT); askDisconnect(); } else if (bondState == BluetoothDevice.BOND_BONDED) { metricsFeatureProvider.action(context, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT); mCachedDevice.connect(true); } else if (bondState == BluetoothDevice.BOND_NONE) { metricsFeatureProvider.action(context, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR); if (!mCachedDevice.hasHumanReadableName()) { metricsFeatureProvider.action(context, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES); } pair(); } }

这里先获取mCachedDevice的绑定状态,如果已经连接,则询问是否断开;如果已经绑定未连接,则开始连接;如果未连接也未绑定,则开始配对。这里我们先看配对。配对调用的是本地的pair方法:
private void pair() { if (!mCachedDevice.startPairing()) { Utils.showError(getContext(), mCachedDevice.getName(), R.string.bluetooth_pairing_error_message); } }

2 、framework /frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
public boolean startPairing() { // Pairing is unreliable while scanning, so cancel discovery if (mLocalAdapter.isDiscovering()) { mLocalAdapter.cancelDiscovery(); }if (!mDevice.createBond()) { return false; }return true; }

/frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
public boolean createBond() { final IBluetooth service = sService; if (service == null) { Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device"); return false; } try { Log.i(TAG, "createBond() for device " + getAddress() + " called by pid: " + Process.myPid() + " tid: " + Process.myTid()); return service.createBond(this, TRANSPORT_AUTO); } catch (RemoteException e) { Log.e(TAG, "", e); } return false; }

3 、Bluetooth app 和蓝牙扫描一样,实现IBluetooth接口的类是AdapterServiceBinder,AdapterServiceBinder实现IBluetooth.Stub接口,是AdapterService的私有内部类,AdapterServiceBinder收到的操作,都会转交AdapterService处理,所以会调用AdapterService的createBond方法。
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
boolean createBond(BluetoothDevice device, int transport, OobData oobData) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) { return false; }mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device)); // Pairing is unreliable while scanning, so cancel discovery // Note, remove this when native stack improves cancelDiscoveryNative(); Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); msg.obj = device; msg.arg1 = transport; if (oobData != null) { Bundle oobDataBundle = new Bundle(); oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData); msg.setData(oobDataBundle); } mBondStateMachine.sendMessage(msg); return true; }

createBond 方法会检查一下远程设备属性信息,取消蓝牙扫描任务,将配对任务转交mBondStateMachine,由状态机处理该信息。
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
private boolean createBond(BluetoothDevice dev, int transport, OobData oobData, boolean transition) { if (dev.getBondState() == BluetoothDevice.BOND_NONE) { infoLog("Bond address is:" + dev); byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); boolean result; if (oobData != null) { result = mAdapterService.createBondOutOfBandNative(addr, transport, oobData); } else { result = mAdapterService.createBondNative(addr, transport); }if (!result) { sendIntent(dev, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED); return false; } else if (transition) { transitionTo(mPendingCommandState); } return true; } return false; }

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
native boolean createBondNative(byte[] address, int transport);

/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, jint transport) { ALOGV("%s", __func__); if (!sBluetoothInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (addr == NULL) { jniThrowIOException(env, EINVAL); return JNI_FALSE; }int ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport); env->ReleaseByteArrayElements(address, addr, 0); return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; }

4 、蓝牙协议栈 /system/bt/btif/src/bluetooth.cc
static int create_bond(const RawAddress* bd_addr, int transport) { /* sanity check */ if (!interface_ready()) return BT_STATUS_NOT_READY; return btif_dm_create_bond(bd_addr, transport); }

/system/bt/btif/src/btif_dm.cc
bt_status_t btif_dm_create_bond(const RawAddress* bd_addr, int transport) { btif_dm_create_bond_cb_t create_bond_cb; create_bond_cb.transport = transport; create_bond_cb.bdaddr = *bd_addr; BTIF_TRACE_EVENT("%s: bd_addr=%s, transport=%d", __func__, bd_addr->ToString().c_str(), transport); if (pairing_cb.state != BT_BOND_STATE_NONE) return BT_STATUS_BUSY; btif_stats_add_bond_event(*bd_addr, BTIF_DM_FUNC_CREATE_BOND, pairing_cb.state); btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_CREATE_BOND, (char*)&create_bond_cb, sizeof(btif_dm_create_bond_cb_t), NULL); return BT_STATUS_SUCCESS; }

static void btif_dm_generic_evt(uint16_t event, char* p_param) { BTIF_TRACE_EVENT("%s: event=%d", __func__, event); switch (event) { case BTIF_DM_CB_DISCOVERY_STARTED: { HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb, BT_DISCOVERY_STARTED); } break; case BTIF_DM_CB_CREATE_BOND: { pairing_cb.timeout_retries = NUM_TIMEOUT_RETRIES; btif_dm_create_bond_cb_t* create_bond_cb = (btif_dm_create_bond_cb_t*)p_param; btif_dm_cb_create_bond(create_bond_cb->bdaddr, create_bond_cb->transport); } break; case BTIF_DM_CB_REMOVE_BOND: { btif_dm_cb_remove_bond((RawAddress*)p_param); } break; case BTIF_DM_CB_HID_REMOTE_NAME: { btif_dm_cb_hid_remote_name((tBTM_REMOTE_DEV_NAME*)p_param); } break; case BTIF_DM_CB_BOND_STATE_BONDING: { bond_state_changed(BT_STATUS_SUCCESS, *((RawAddress*)p_param), BT_BOND_STATE_BONDING); } break; case BTIF_DM_CB_LE_TX_TEST: case BTIF_DM_CB_LE_RX_TEST: { uint8_t status; STREAM_TO_UINT8(status, p_param); HAL_CBACK(bt_hal_cbacks, le_test_mode_cb, (status == 0) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL, 0); } break; case BTIF_DM_CB_LE_TEST_END: { uint8_t status; uint16_t count = 0; STREAM_TO_UINT8(status, p_param); if (status == 0) STREAM_TO_UINT16(count, p_param); HAL_CBACK(bt_hal_cbacks, le_test_mode_cb, (status == 0) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL, count); } break; default: { BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event); } break; } }

static void btif_dm_cb_create_bond(const RawAddress& bd_addr, tBTA_TRANSPORT transport) { bool is_hid = check_cod(&bd_addr, COD_HID_POINTING); bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING); int device_type; int addr_type; std::string addrstr = bd_addr.ToString(); const char* bdstr = addrstr.c_str(); if (transport == BT_TRANSPORT_LE) { if (!btif_config_get_int(bdstr, "DevType", &device_type)) { btif_config_set_int(bdstr, "DevType", BT_DEVICE_TYPE_BLE); } if (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS) { // Try to read address type. OOB pairing might have set it earlier, but // didn't store it, it defaults to BLE_ADDR_PUBLIC uint8_t tmp_dev_type; uint8_t tmp_addr_type; BTM_ReadDevInfo(bd_addr, &tmp_dev_type, &tmp_addr_type); addr_type = tmp_addr_type; btif_storage_set_remote_addr_type(&bd_addr, addr_type); } } if ((btif_config_get_int(bdstr, "DevType", &device_type) && (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) == BT_STATUS_SUCCESS) && (device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE) || (transport == BT_TRANSPORT_LE)) { BTA_DmAddBleDevice(bd_addr, addr_type, device_type); }if (is_hid && (device_type & BT_DEVICE_TYPE_BLE) == 0) { bt_status_t status; status = (bt_status_t)btif_hh_connect(&bd_addr); if (status != BT_STATUS_SUCCESS) bond_state_changed(status, bd_addr, BT_BOND_STATE_NONE); } else { BTA_DmBondByTransport(bd_addr, transport); } /*Trackoriginator of bond creation*/ pairing_cb.is_local_initiated = true; }

/system/bt/bta/dm/bta_dm_api.cc
void BTA_DmBondByTransport(const RawAddress& bd_addr, tBTA_TRANSPORT transport) { do_in_bta_thread(FROM_HERE, base::Bind(bta_dm_bond, bd_addr, transport)); }

/system/bt/bta/dm/bta_dm_act.cc
void bta_dm_bond(const RawAddress& bd_addr, tBTA_TRANSPORT transport) { tBTM_STATUS status; tBTA_DM_SEC sec_event; char* p_name; if (transport == BTA_TRANSPORT_UNKNOWN) status = BTM_SecBond(bd_addr, 0, NULL, 0); else status = BTM_SecBondByTransport(bd_addr, transport, 0, NULL, 0); if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) { memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); sec_event.auth_cmpl.bd_addr = bd_addr; p_name = BTM_SecReadDevName(bd_addr); if (p_name != NULL) { memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN - 1)); sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0; }/*taken care of by memset [above] sec_event.auth_cmpl.key_present = false; sec_event.auth_cmpl.success = false; */ sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND; if (status == BTM_SUCCESS) { sec_event.auth_cmpl.success = true; } else { /* delete this device entry from Sec Dev DB */ bta_dm_remove_sec_dev_entry(bd_addr); } bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event); } }

/system/bt/stack/btm/btm_sec.cc
tBTM_STATUS BTM_SecBondByTransport(const RawAddress& bd_addr, tBT_TRANSPORT transport, uint8_t pin_len, uint8_t* p_pin, uint32_t trusted_mask[]) { tBT_DEVICE_TYPE dev_type; tBLE_ADDR_TYPE addr_type; BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type); /* LE device, do SMP pairing */ if ((transport == BT_TRANSPORT_LE && (dev_type & BT_DEVICE_TYPE_BLE) == 0) || (transport == BT_TRANSPORT_BR_EDR && (dev_type & BT_DEVICE_TYPE_BREDR) == 0)) { return BTM_ILLEGAL_ACTION; } return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask); }

/system/bt/stack/btm/btm_sec.cc
tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr, tBT_TRANSPORT transport, uint8_t pin_len, uint8_t* p_pin, uint32_t trusted_mask[]) { tBTM_SEC_DEV_REC* p_dev_rec; tBTM_STATUS status; uint8_t* p_features; uint8_t ii; tACL_CONN* p = btm_bda_to_acl(bd_addr, transport); VLOG(1) << __func__ << " BDA: " << bd_addr; BTM_TRACE_DEBUG("%s: Transport used %d, bd_addr=%s", __func__, transport, bd_addr.ToString().c_str()); /* Other security process is in progress */ if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) { BTM_TRACE_ERROR("BTM_SecBond: already busy in state: %s", btm_pair_state_descr(btm_cb.pairing_state)); return (BTM_WRONG_MODE); }p_dev_rec = btm_find_or_alloc_dev(bd_addr); if (p_dev_rec == NULL) { return (BTM_NO_RESOURCES); }if (!controller_get_interface()->get_is_ready()) { BTM_TRACE_ERROR("%s controller module is not ready", __func__); return (BTM_NO_RESOURCES); }BTM_TRACE_DEBUG("before update sec_flags=0x%x", p_dev_rec->sec_flags); /* Finished if connection is active and already paired */ if (((p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_BR_EDR && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)) || ((p_dev_rec->ble_hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_LE && (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED))) { BTM_TRACE_WARNING("BTM_SecBond -> Already Paired"); return (BTM_SUCCESS); }/* Tell controller to get rid of the link key if it has one stored */ if ((BTM_DeleteStoredLinkKey(&bd_addr, NULL)) != BTM_SUCCESS) return (BTM_NO_RESOURCES); /* Save the PIN code if we got a valid one */ if (p_pin && (pin_len <= PIN_CODE_LEN) && (pin_len != 0)) { btm_cb.pin_code_len = pin_len; p_dev_rec->pin_code_length = pin_len; memcpy(btm_cb.pin_code, p_pin, PIN_CODE_LEN); }btm_cb.pairing_bda = bd_addr; btm_cb.pairing_flags = BTM_PAIR_FLAGS_WE_STARTED_DD; p_dev_rec->security_required = BTM_SEC_OUT_AUTHENTICATE; p_dev_rec->is_originator = true; if (trusted_mask) BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask); if (transport == BT_TRANSPORT_LE) { btm_ble_init_pseudo_addr(p_dev_rec, bd_addr); p_dev_rec->sec_flags &= ~BTM_SEC_LE_MASK; if (SMP_Pair(bd_addr) == SMP_STARTED) { btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE; p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING; btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_AUTH_COMPLETE); return BTM_CMD_STARTED; }btm_cb.pairing_flags = 0; return (BTM_NO_RESOURCES); }p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED | BTM_SEC_LINK_KEY_AUTHED); BTM_TRACE_DEBUG("after update sec_flags=0x%x", p_dev_rec->sec_flags); if (!controller_get_interface()->supports_simple_pairing()) { /* The special case when we authenticate keyboard.Set pin type to fixed */ /* It would be probably better to do it from the application, but it is */ /* complicated */ if (((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) == BTM_COD_MAJOR_PERIPHERAL) && (p_dev_rec->dev_class[2] & BTM_COD_MINOR_KEYBOARD) && (btm_cb.cfg.pin_type != HCI_PIN_TYPE_FIXED)) { btm_cb.pin_type_changed = true; btsnd_hcic_write_pin_type(HCI_PIN_TYPE_FIXED); } }for (ii = 0; ii <= HCI_EXT_FEATURES_PAGE_MAX; ii++) { p_features = p_dev_rec->feature_pages[ii]; BTM_TRACE_EVENT("remote_features page[%1d] = %02x-%02x-%02x-%02x", ii, p_features[0], p_features[1], p_features[2], p_features[3]); BTM_TRACE_EVENT("%02x-%02x-%02x-%02x", p_features[4], p_features[5], p_features[6], p_features[7]); }BTM_TRACE_EVENT("BTM_SecBond: Remote sm4: 0x%xHCI Handle: 0x%04x", p_dev_rec->sm4, p_dev_rec->hci_handle); #if (BTM_SEC_FORCE_RNR_FOR_DBOND == TRUE) p_dev_rec->sec_flags &= ~BTM_SEC_NAME_KNOWN; #endif/* If connection already exists... */ if (p && p->hci_handle != BTM_SEC_INVALID_HANDLE) { btm_sec_start_authentication(p_dev_rec); btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_PIN_REQ); /* Mark lcb as bonding */ l2cu_update_lcb_4_bonding(bd_addr, true); return (BTM_CMD_STARTED); }BTM_TRACE_DEBUG("sec mode: %d sm4:x%x", btm_cb.security_mode, p_dev_rec->sm4); if (!controller_get_interface()->supports_simple_pairing() || (p_dev_rec->sm4 == BTM_SM4_KNOWN)) { if (btm_sec_check_prefetch_pin(p_dev_rec)) return (BTM_CMD_STARTED); } if ((btm_cb.security_mode == BTM_SEC_MODE_SP || btm_cb.security_mode == BTM_SEC_MODE_SP_DEBUG || btm_cb.security_mode == BTM_SEC_MODE_SC) && BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4)) { /* local is 2.1 and peer is unknown */ if ((p_dev_rec->sm4 & BTM_SM4_CONN_PEND) == 0) { /* we are not accepting connection request from peer * -> RNR (to learn if peer is 2.1) * RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */ btm_sec_change_pairing_state(BTM_PAIR_STATE_GET_REM_NAME); status = BTM_ReadRemoteDeviceName(bd_addr, NULL, BT_TRANSPORT_BR_EDR); } else { /* We are accepting connection request from peer */ btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_PIN_REQ); status = BTM_CMD_STARTED; } BTM_TRACE_DEBUG("State:%s sm4: 0x%x sec_state:%d", btm_pair_state_descr(btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state); } else { /* both local and peer are 2.1*/ status = btm_sec_dd_create_conn(p_dev_rec); }if (status != BTM_CMD_STARTED) { BTM_TRACE_ERROR( "%s BTM_ReadRemoteDeviceName or btm_sec_dd_create_conn error: 0x%x", __func__, (int)status); btm_sec_change_pairing_state(BTM_PAIR_STATE_IDLE); }return status; }

/system/bt/stack/hcic/hcicmds.cc
void btsnd_hcic_write_pin_type(uint8_t type) { BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); uint8_t* pp = (uint8_t*)(p + 1); p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; p->offset = 0; UINT16_TO_STREAM(pp, HCI_WRITE_PIN_TYPE); UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); UINT8_TO_STREAM(pp, type); btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); }

5、 配对状态改变的回传 我们在bta里面调用/system/bt/bta/dm/bta_dm_act.cc里面的bta_dm_bond方法,进行配对,这个方法最后会执行这个函数:
/system/bt/bta/dm/bta_dm_act.cc
bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);

这个就是bta的回调函数,回调事件是BTA_DM_AUTH_CMPL_EVT,根据这个事件标志,我们找到了 /system/bt/btif/src/btif_dm.cc里面的btif_dm_upstreams_evt方法,这个方法就是用于向上层回调消息的,相关代码是:
/system/bt/btif/src/btif_dm.cc
case BTA_DM_AUTH_CMPL_EVT: btif_dm_auth_cmpl_evt(&p_data->auth_cmpl); break;

/system/bt/btif/src/btif_dm.cc
static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { /* Save link key, if not temporary */ bt_status_t status = BT_STATUS_FAIL; bt_bond_state_t state = BT_BOND_STATE_NONE; bool skip_sdp = false; BTIF_TRACE_DEBUG("%s: bond state=%d, success=%d, key_present=%d", __func__, pairing_cb.state, p_auth_cmpl->success, p_auth_cmpl->key_present); RawAddress bd_addr = p_auth_cmpl->bd_addr; if ((p_auth_cmpl->success) && (p_auth_cmpl->key_present)) { if ((p_auth_cmpl->key_type < HCI_LKEY_TYPE_DEBUG_COMB) || (p_auth_cmpl->key_type == HCI_LKEY_TYPE_AUTH_COMB) || (p_auth_cmpl->key_type == HCI_LKEY_TYPE_CHANGED_COMB) || (p_auth_cmpl->key_type == HCI_LKEY_TYPE_AUTH_COMB_P_256) || pairing_cb.bond_type == BOND_TYPE_PERSISTENT) { bt_status_t ret; BTIF_TRACE_DEBUG("%s: Storing link key. key_type=0x%x, bond_type=%d", __func__, p_auth_cmpl->key_type, pairing_cb.bond_type); ret = btif_storage_add_bonded_device(&bd_addr, p_auth_cmpl->key, p_auth_cmpl->key_type, pairing_cb.pin_code_len); ASSERTC(ret == BT_STATUS_SUCCESS, "storing link key failed", ret); } else { BTIF_TRACE_DEBUG( "%s: Temporary key. Not storing. key_type=0x%x, bond_type=%d", __func__, p_auth_cmpl->key_type, pairing_cb.bond_type); if (pairing_cb.bond_type == BOND_TYPE_TEMPORARY) { BTIF_TRACE_DEBUG("%s: sending BT_BOND_STATE_NONE for Temp pairing", __func__); btif_storage_remove_bonded_device(&bd_addr); bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_NONE); return; } } }btif_storage_set_remote_addr_type(&bd_addr, p_auth_cmpl->addr_type); btif_update_remote_properties(p_auth_cmpl->bd_addr, p_auth_cmpl->bd_name, NULL, p_auth_cmpl->dev_type); pairing_cb.timeout_retries = 0; status = BT_STATUS_SUCCESS; state = BT_BOND_STATE_BONDED; bd_addr = p_auth_cmpl->bd_addr; if (check_sdp_bl(&bd_addr) && check_cod_hid(&bd_addr)) { LOG_WARN(LOG_TAG, "%s:skip SDP", __func__); skip_sdp = true; } if (!pairing_cb.is_local_initiated && skip_sdp) { bond_state_changed(status, bd_addr, state); LOG_WARN(LOG_TAG, "%s: Incoming HID Connection", __func__); bt_property_t prop; RawAddress bd_addr; Uuid uuid = Uuid::From16Bit(UUID_SERVCLASS_HUMAN_INTERFACE); prop.type = BT_PROPERTY_UUIDS; prop.val = &uuid; prop.len = Uuid::kNumBytes128; /* Send the event to the BTIF */ HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, BT_STATUS_SUCCESS, &bd_addr, 1, &prop); } else { bool is_crosskey = false; /* If bonded due to cross-key, save the static address too*/ if (pairing_cb.state == BT_BOND_STATE_BONDING && p_auth_cmpl->bd_addr != pairing_cb.bd_addr) { BTIF_TRACE_DEBUG( "%s: bonding initiated due to cross key, adding static address", __func__); pairing_cb.static_bdaddr = bd_addr; is_crosskey = true; } if (!is_crosskey || !(stack_config_get_interface()->get_pts_crosskey_sdp_disable())) { // Ensure inquiry is stopped before attempting service discovery btif_dm_cancel_discovery(); /* Trigger SDP on the device */ pairing_cb.sdp_attempts = 1; btif_dm_get_remote_services(bd_addr); } } // Do not call bond_state_changed_cb yet. Wait until remote service // discovery is complete } else {break; default: status = BT_STATUS_FAIL; } /* Special Handling for HID Devices */ if (check_cod(&bd_addr, COD_HID_POINTING)) { /* Remove Device as bonded in nvram as authentication failed */ BTIF_TRACE_DEBUG("%s(): removing hid pointing device from nvram", __func__); btif_storage_remove_bonded_device(&bd_addr); } bond_state_changed(status, bd_addr, state); } }

可以发现也是通过HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state); 这样的方法进行回调的,bond_state_changed_cb这个函数在bluetooth.h被定义对应的是com_android_bluetooth_btservice_AdapterService.cpp里的bond_state_changed_callback,关键代码如下:
/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr, bt_bond_state_t state) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!bd_addr) { ALOGE("Address is null in %s", __func__); return; }ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { ALOGE("Address allocation failed in %s", __func__); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), (jbyte*)bd_addr); sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint)status, addr.get(), (jint)state); }

这里将bondStateChangeCallback方法对应到jni的method_bondStateChangeCallback方法
static void classInitNative(JNIEnv* env, jclass clazz) { jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic"); android_bluetooth_UidTraffic.constructor = env->GetMethodID(jniUidTrafficClass, "", "(IJJ)V"); jclass jniCallbackClass = env->FindClass("com/android/bluetooth/btservice/JniCallbacks"); sJniCallbacksField = env->GetFieldID( clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks; "); method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V"); if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) { ALOGE("No Bluetooth Library found"); } }

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/JniCallbacks.java
void bondStateChangeCallback(int status, byte[] address, int newState) { mBondStateMachine.bondStateChangeCallback(status, address, newState); }

状态机里面通过sendMessage进行配对状态的变更。
【Android 9.0 蓝牙配对流程】/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
void bondStateChangeCallback(int status, byte[] address, int newState) { BluetoothDevice device = mRemoteDevices.getDevice(address); if (device == null) { infoLog("No record of the device:" + device); // This device will be added as part of the BONDING_STATE_CHANGE intent processing // in sendIntent above device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address)); }infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device + " newState: " + newState); Message msg = obtainMessage(BONDING_STATE_CHANGE); msg.obj = device; if (newState == BOND_STATE_BONDED) { msg.arg1 = BluetoothDevice.BOND_BONDED; } else if (newState == BOND_STATE_BONDING) { msg.arg1 = BluetoothDevice.BOND_BONDING; } else { msg.arg1 = BluetoothDevice.BOND_NONE; } msg.arg2 = status; sendMessage(msg); }

    推荐阅读