Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7eb0c5ea authored by SongFerng Wang's avatar SongFerng Wang Committed by Automerger Merge Worker
Browse files

Merge "[LE Unicast] Using the active device as main device after grouping"...

Merge "[LE Unicast] Using the active device as main device after grouping" into tm-d1-dev am: 8a8b69d7

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



Change-Id: I5993394f0e237b8a7f88b67f43f9d762b896f58b
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 6d6a373d 8a8b69d7
Loading
Loading
Loading
Loading
+73 −17
Original line number Diff line number Diff line
@@ -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,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);
@@ -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.
+32 −0
Original line number Diff line number Diff line
@@ -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) {