Merge "[LE Unicast] Using the active device as main device after grouping" am: edc13cc241

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

Change-Id: Ib7158b8b9d510d4f42f88ce61fd02aff268bb46f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
SongFerng Wang
2022-06-28 10:10:22 +00:00
committed by Automerger Merge Worker
2 changed files with 105 additions and 17 deletions

View File

@@ -20,15 +20,19 @@ import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid; import android.bluetooth.BluetoothUuid;
import android.os.Build;
import android.os.ParcelUuid; import android.os.ParcelUuid;
import android.util.Log; import android.util.Log;
import androidx.annotation.ChecksSdkIntAtLeast;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* CsipDeviceManager manages the set of remote CSIP Bluetooth devices. * CsipDeviceManager manages the set of remote CSIP Bluetooth devices.
@@ -126,32 +130,84 @@ public class CsipDeviceManager {
} }
} }
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU)
private static boolean isAtLeastT() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
}
// Group devices by groupId // Group devices by groupId
@VisibleForTesting @VisibleForTesting
void onGroupIdChanged(int groupId) { void onGroupIdChanged(int groupId) {
int firstMatchedIndex = -1; if (!isValidGroupId(groupId)) {
CachedBluetoothDevice mainDevice = null; log("onGroupIdChanged: groupId is invalid");
return;
}
log("onGroupIdChanged: mCachedDevices list =" + mCachedDevices.toString());
final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
final CachedBluetoothDeviceManager deviceManager = mBtManager.getCachedDeviceManager();
final LeAudioProfile leAudioProfile = profileManager.getLeAudioProfile();
final BluetoothDevice mainBluetoothDevice = (leAudioProfile != null && isAtLeastT()) ?
leAudioProfile.getConnectedGroupLeadDevice(groupId) : null;
CachedBluetoothDevice newMainDevice =
mainBluetoothDevice != null ? deviceManager.findDevice(mainBluetoothDevice) : null;
if (newMainDevice != null) {
final CachedBluetoothDevice finalNewMainDevice = newMainDevice;
final List<CachedBluetoothDevice> memberDevices = mCachedDevices.stream()
.filter(cachedDevice -> !cachedDevice.equals(finalNewMainDevice)
&& cachedDevice.getGroupId() == groupId)
.collect(Collectors.toList());
if (memberDevices == null || memberDevices.isEmpty()) {
log("onGroupIdChanged: There is no member device in list.");
return;
}
log("onGroupIdChanged: removed from UI device =" + memberDevices
+ ", with groupId=" + groupId + " mainDevice= " + newMainDevice);
for (CachedBluetoothDevice memberDeviceItem : memberDevices) {
Set<CachedBluetoothDevice> memberSet = memberDeviceItem.getMemberDevice();
if (!memberSet.isEmpty()) {
log("onGroupIdChanged: Transfer the member list into new main device.");
for (CachedBluetoothDevice memberListItem : memberSet) {
if (!memberListItem.equals(newMainDevice)) {
newMainDevice.addMemberDevice(memberListItem);
}
}
memberSet.clear();
}
for (int i = mCachedDevices.size() - 1; i >= 0; i--) { newMainDevice.addMemberDevice(memberDeviceItem);
final CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); mCachedDevices.remove(memberDeviceItem);
if (cachedDevice.getGroupId() != groupId) { mBtManager.getEventManager().dispatchDeviceRemoved(memberDeviceItem);
continue;
} }
if (firstMatchedIndex == -1) { if (!mCachedDevices.contains(newMainDevice)) {
// Found the first one mCachedDevices.add(newMainDevice);
firstMatchedIndex = i; mBtManager.getEventManager().dispatchDeviceAdded(newMainDevice);
mainDevice = cachedDevice;
continue;
} }
} else {
log("onGroupIdChanged: There is no main device from the LE profile.");
int firstMatchedIndex = -1;
log("onGroupIdChanged: removed from UI device =" + cachedDevice for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
+ ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex); final CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
if (cachedDevice.getGroupId() != groupId) {
continue;
}
mainDevice.addMemberDevice(cachedDevice); if (firstMatchedIndex == -1) {
mCachedDevices.remove(i); // Found the first one
mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice); firstMatchedIndex = i;
break; newMainDevice = cachedDevice;
continue;
}
log("onGroupIdChanged: removed from UI device =" + cachedDevice
+ ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex);
newMainDevice.addMemberDevice(cachedDevice);
mCachedDevices.remove(i);
mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
break;
}
} }
} }

View File

@@ -21,6 +21,7 @@ import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_ALL;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothCodecConfig; import android.bluetooth.BluetoothCodecConfig;
@@ -183,6 +184,37 @@ public class LeAudioProfile implements LocalBluetoothProfile {
return mBluetoothAdapter.getActiveDevices(BluetoothProfile.LE_AUDIO); return mBluetoothAdapter.getActiveDevices(BluetoothProfile.LE_AUDIO);
} }
/**
* Get Lead device for the group.
*
* Lead device is the device that can be used as an active device in the system.
* Active devices points to the Audio Device for the Le Audio group.
* This method returns the Lead devices for the connected LE Audio
* group and this device should be used in the setActiveDevice() method by other parts
* of the system, which wants to set to active a particular Le Audio group.
*
* Note: getActiveDevice() returns the Lead device for the currently active LE Audio group.
* Note: When Lead device gets disconnected while Le Audio group is active and has more devices
* in the group, then Lead device will not change. If Lead device gets disconnected, for the
* Le Audio group which is not active, a new Lead device will be chosen
*
* @param groupId The group id.
* @return group lead device.
*
* @hide
*/
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
public @Nullable BluetoothDevice getConnectedGroupLeadDevice(int groupId) {
if (DEBUG) {
Log.d(TAG,"getConnectedGroupLeadDevice");
}
if (mService == null) {
Log.e(TAG,"No service.");
return null;
}
return mService.getConnectedGroupLeadDevice(groupId);
}
@Override @Override
public boolean isEnabled(BluetoothDevice device) { public boolean isEnabled(BluetoothDevice device) {
if (mService == null || device == null) { if (mService == null || device == null) {