Merge "[LE Unicast] Using the active device as main device after grouping"
This commit is contained in:
@@ -20,15 +20,19 @@ import android.bluetooth.BluetoothCsipSetCoordinator;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.BluetoothUuid;
|
||||
import android.os.Build;
|
||||
import android.os.ParcelUuid;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.ChecksSdkIntAtLeast;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@VisibleForTesting
|
||||
void onGroupIdChanged(int groupId) {
|
||||
int firstMatchedIndex = -1;
|
||||
CachedBluetoothDevice mainDevice = null;
|
||||
if (!isValidGroupId(groupId)) {
|
||||
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--) {
|
||||
final CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
|
||||
if (cachedDevice.getGroupId() != groupId) {
|
||||
continue;
|
||||
newMainDevice.addMemberDevice(memberDeviceItem);
|
||||
mCachedDevices.remove(memberDeviceItem);
|
||||
mBtManager.getEventManager().dispatchDeviceRemoved(memberDeviceItem);
|
||||
}
|
||||
|
||||
if (firstMatchedIndex == -1) {
|
||||
// Found the first one
|
||||
firstMatchedIndex = i;
|
||||
mainDevice = cachedDevice;
|
||||
continue;
|
||||
if (!mCachedDevices.contains(newMainDevice)) {
|
||||
mCachedDevices.add(newMainDevice);
|
||||
mBtManager.getEventManager().dispatchDeviceAdded(newMainDevice);
|
||||
}
|
||||
} else {
|
||||
log("onGroupIdChanged: There is no main device from the LE profile.");
|
||||
int firstMatchedIndex = -1;
|
||||
|
||||
log("onGroupIdChanged: removed from UI device =" + cachedDevice
|
||||
+ ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex);
|
||||
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
|
||||
final CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
|
||||
if (cachedDevice.getGroupId() != groupId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mainDevice.addMemberDevice(cachedDevice);
|
||||
mCachedDevices.remove(i);
|
||||
mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
|
||||
break;
|
||||
if (firstMatchedIndex == -1) {
|
||||
// Found the first one
|
||||
firstMatchedIndex = i;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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_FORBIDDEN;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothCodecConfig;
|
||||
@@ -183,6 +184,37 @@ public class LeAudioProfile implements LocalBluetoothProfile {
|
||||
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
|
||||
public boolean isEnabled(BluetoothDevice device) {
|
||||
if (mService == null || device == null) {
|
||||
|
||||
Reference in New Issue
Block a user