Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java +73 −17 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -126,11 +130,62 @@ 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) { 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(); } newMainDevice.addMemberDevice(memberDeviceItem); mCachedDevices.remove(memberDeviceItem); mBtManager.getEventManager().dispatchDeviceRemoved(memberDeviceItem); } 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; CachedBluetoothDevice mainDevice = null; for (int i = mCachedDevices.size() - 1; i >= 0; i--) { final CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); Loading @@ -141,19 +196,20 @@ public class CsipDeviceManager { if (firstMatchedIndex == -1) { // Found the first one firstMatchedIndex = i; mainDevice = cachedDevice; newMainDevice = cachedDevice; continue; } log("onGroupIdChanged: removed from UI device =" + cachedDevice + ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex); mainDevice.addMemberDevice(cachedDevice); newMainDevice.addMemberDevice(cachedDevice); mCachedDevices.remove(i); mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice); break; } } } // @return {@code true}, the event is processed inside the method. It is for updating // le audio device on group relationship when receiving connected or disconnected. Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java +32 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java +73 −17 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -126,11 +130,62 @@ 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) { 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(); } newMainDevice.addMemberDevice(memberDeviceItem); mCachedDevices.remove(memberDeviceItem); mBtManager.getEventManager().dispatchDeviceRemoved(memberDeviceItem); } 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; CachedBluetoothDevice mainDevice = null; for (int i = mCachedDevices.size() - 1; i >= 0; i--) { final CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); Loading @@ -141,19 +196,20 @@ public class CsipDeviceManager { if (firstMatchedIndex == -1) { // Found the first one firstMatchedIndex = i; mainDevice = cachedDevice; newMainDevice = cachedDevice; continue; } log("onGroupIdChanged: removed from UI device =" + cachedDevice + ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex); mainDevice.addMemberDevice(cachedDevice); newMainDevice.addMemberDevice(cachedDevice); mCachedDevices.remove(i); mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice); break; } } } // @return {@code true}, the event is processed inside the method. It is for updating // le audio device on group relationship when receiving connected or disconnected. Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java +32 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading