Merge "bt: Add late bonding confirmation mechanism" into udc-dev am: f82b94680c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23285797

Change-Id: Idd0b0f255b7e4a6424dc12dd9dfd47a6e790203c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Michał Narajowski
2023-05-19 07:53:43 +00:00
committed by Automerger Merge Worker
3 changed files with 78 additions and 9 deletions

View File

@@ -47,6 +47,7 @@ import com.android.settingslib.Utils;
import com.android.settingslib.utils.ThreadUtils; import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.widget.AdaptiveOutlineDrawable; import com.android.settingslib.widget.AdaptiveOutlineDrawable;
import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@@ -78,6 +79,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
BluetoothDevice mDevice; BluetoothDevice mDevice;
private HearingAidInfo mHearingAidInfo; private HearingAidInfo mHearingAidInfo;
private int mGroupId; private int mGroupId;
private Timestamp mBondTimestamp;
// Need this since there is no method for getting RSSI // Need this since there is no method for getting RSSI
short mRssi; short mRssi;
@@ -889,15 +891,25 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_UNKNOWN);
mDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); mDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_UNKNOWN);
mDevice.setSimAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); mDevice.setSimAccessPermission(BluetoothDevice.ACCESS_UNKNOWN);
mBondTimestamp = null;
} }
refresh(); refresh();
if (bondState == BluetoothDevice.BOND_BONDED && mDevice.isBondingInitiatedLocally()) { if (bondState == BluetoothDevice.BOND_BONDED) {
connect(); mBondTimestamp = new Timestamp(System.currentTimeMillis());
if (mDevice.isBondingInitiatedLocally()) {
connect();
}
} }
} }
public Timestamp getBondTimestamp() {
return mBondTimestamp;
}
public BluetoothClass getBtClass() { public BluetoothClass getBtClass() {
return mDevice.getBluetoothClass(); return mDevice.getBluetoothClass();
} }

View File

@@ -25,6 +25,7 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -37,6 +38,8 @@ public class CachedBluetoothDeviceManager {
private static final String TAG = "CachedBluetoothDeviceManager"; private static final String TAG = "CachedBluetoothDeviceManager";
private static final boolean DEBUG = BluetoothUtils.D; private static final boolean DEBUG = BluetoothUtils.D;
@VisibleForTesting static int sLateBondingTimeoutMillis = 5000; // 5s
private Context mContext; private Context mContext;
private final LocalBluetoothManager mBtManager; private final LocalBluetoothManager mBtManager;
@@ -47,6 +50,7 @@ public class CachedBluetoothDeviceManager {
@VisibleForTesting @VisibleForTesting
CsipDeviceManager mCsipDeviceManager; CsipDeviceManager mCsipDeviceManager;
BluetoothDevice mOngoingSetMemberPair; BluetoothDevice mOngoingSetMemberPair;
boolean mIsLateBonding;
public CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) { public CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
mContext = context; mContext = context;
@@ -309,6 +313,7 @@ public class CachedBluetoothDeviceManager {
// To clear the SetMemberPair flag when the Bluetooth is turning off. // To clear the SetMemberPair flag when the Bluetooth is turning off.
mOngoingSetMemberPair = null; mOngoingSetMemberPair = null;
mIsLateBonding = false;
} }
} }
@@ -377,15 +382,53 @@ public class CachedBluetoothDeviceManager {
private synchronized boolean shouldPairByCsip(BluetoothDevice device, int groupId) { private synchronized boolean shouldPairByCsip(BluetoothDevice device, int groupId) {
boolean isOngoingSetMemberPair = mOngoingSetMemberPair != null; boolean isOngoingSetMemberPair = mOngoingSetMemberPair != null;
int bondState = device.getBondState(); int bondState = device.getBondState();
if (isOngoingSetMemberPair || bondState != BluetoothDevice.BOND_NONE boolean groupExists = mCsipDeviceManager.isExistedGroupId(groupId);
|| !mCsipDeviceManager.isExistedGroupId(groupId)) { Log.d(TAG,
Log.d(TAG, "isOngoingSetMemberPair: " + isOngoingSetMemberPair "isOngoingSetMemberPair=" + isOngoingSetMemberPair + ", bondState=" + bondState
+ " , device.getBondState: " + bondState); + ", groupExists=" + groupExists + ", groupId=" + groupId);
if (isOngoingSetMemberPair || bondState != BluetoothDevice.BOND_NONE || !groupExists) {
return false; return false;
} }
return true; return true;
} }
private synchronized boolean checkLateBonding(int groupId) {
CachedBluetoothDevice firstDevice = mCsipDeviceManager.getFirstMemberDevice(groupId);
if (firstDevice == null) {
Log.d(TAG, "No first device in group: " + groupId);
return false;
}
Timestamp then = firstDevice.getBondTimestamp();
if (then == null) {
Log.d(TAG, "No bond timestamp");
return true;
}
Timestamp now = new Timestamp(System.currentTimeMillis());
long diff = (now.getTime() - then.getTime());
Log.d(TAG, "Time difference to first bonding: " + diff + "ms");
return diff > sLateBondingTimeoutMillis;
}
/**
* Called to check if there is an ongoing bonding for the device and it is late bonding.
* If the device is not matching the ongoing bonding device then false will be returned.
*
* @param device The device to check.
*/
public synchronized boolean isLateBonding(BluetoothDevice device) {
if (!isOngoingPairByCsip(device)) {
Log.d(TAG, "isLateBonding: pair not ongoing or not matching device");
return false;
}
return mIsLateBonding;
}
/** /**
* Called when we found a set member of a group. The function will check the {@code groupId} if * Called when we found a set member of a group. The function will check the {@code groupId} if
* it exists and the bond state of the device is BOND_NONE, and if there isn't any ongoing pair * it exists and the bond state of the device is BOND_NONE, and if there isn't any ongoing pair
@@ -398,12 +441,14 @@ public class CachedBluetoothDeviceManager {
if (!shouldPairByCsip(device, groupId)) { if (!shouldPairByCsip(device, groupId)) {
return; return;
} }
Log.d(TAG, "Bond " + device.getAnonymizedAddress() + " by CSIP"); Log.d(TAG, "Bond " + device.getAnonymizedAddress() + " groupId=" + groupId + " by CSIP ");
mOngoingSetMemberPair = device; mOngoingSetMemberPair = device;
mIsLateBonding = checkLateBonding(groupId);
syncConfigFromMainDevice(device, groupId); syncConfigFromMainDevice(device, groupId);
if (!device.createBond(BluetoothDevice.TRANSPORT_LE)) { if (!device.createBond(BluetoothDevice.TRANSPORT_LE)) {
Log.d(TAG, "Bonding could not be started"); Log.d(TAG, "Bonding could not be started");
mOngoingSetMemberPair = null; mOngoingSetMemberPair = null;
mIsLateBonding = false;
} }
} }
@@ -439,7 +484,7 @@ public class CachedBluetoothDeviceManager {
* function, and would not like to update the UI. If not, return {@code false}. * function, and would not like to update the UI. If not, return {@code false}.
*/ */
public synchronized boolean onBondStateChangedIfProcess(BluetoothDevice device, int bondState) { public synchronized boolean onBondStateChangedIfProcess(BluetoothDevice device, int bondState) {
if (mOngoingSetMemberPair == null || !mOngoingSetMemberPair.equals(device)) { if (!isOngoingPairByCsip(device)) {
return false; return false;
} }
@@ -448,6 +493,7 @@ public class CachedBluetoothDeviceManager {
} }
mOngoingSetMemberPair = null; mOngoingSetMemberPair = null;
mIsLateBonding = false;
if (bondState != BluetoothDevice.BOND_NONE) { if (bondState != BluetoothDevice.BOND_NONE) {
if (findDevice(device) == null) { if (findDevice(device) == null) {
final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager(); final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
@@ -471,7 +517,7 @@ public class CachedBluetoothDeviceManager {
* {@code false}. * {@code false}.
*/ */
public boolean isOngoingPairByCsip(BluetoothDevice device) { public boolean isOngoingPairByCsip(BluetoothDevice device) {
return !(mOngoingSetMemberPair == null) && mOngoingSetMemberPair.equals(device); return mOngoingSetMemberPair != null && mOngoingSetMemberPair.equals(device);
} }
private void log(String msg) { private void log(String msg) {

View File

@@ -241,6 +241,17 @@ public class CsipDeviceManager {
return groupDevicesList; return groupDevicesList;
} }
public CachedBluetoothDevice getFirstMemberDevice(int groupId) {
List<CachedBluetoothDevice> members = getGroupDevicesFromAllOfDevicesList(groupId);
if (members.isEmpty())
return null;
CachedBluetoothDevice firstMember = members.get(0);
log("getFirstMemberDevice: groupId=" + groupId
+ " address=" + firstMember.getDevice().getAnonymizedAddress());
return firstMember;
}
@VisibleForTesting @VisibleForTesting
CachedBluetoothDevice getPreferredMainDevice(int groupId, CachedBluetoothDevice getPreferredMainDevice(int groupId,
List<CachedBluetoothDevice> groupDevicesList) { List<CachedBluetoothDevice> groupDevicesList) {