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

Commit 00838e9c authored by Rongxuan Liu's avatar Rongxuan Liu
Browse files

[le audio] Broadcast only control primary group volume with setVolume

Previously we made a workaround to control all broadcast sink devices
with setVolume API.
Now systemUI is introducing the new support for separate group volume
control, we can update this to only control the primary group volume now.

Bug: 353451397
Bug: 354201794
Test: atest LeAudioServiceTest
Test: manual test with broadcast to confirm only primary volume changed
Change-Id: I70f0595cb2b793deb50b5df1077913177cb3eec5
parent 5d1da914
Loading
Loading
Loading
Loading
+29 −9
Original line number Diff line number Diff line
@@ -1409,6 +1409,12 @@ public class LeAudioService extends ProfileService {
        return descriptor.mGroupId == mUnicastGroupIdDeactivatedForBroadcastTransition;
    }

    /** Return true if group is primary - is active or was active before switch to broadcast */
    private boolean isPrimaryGroup(int groupId) {
        return groupId != IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID
                && groupId == mUnicastGroupIdDeactivatedForBroadcastTransition;
    }

    private boolean areBroadcastsAllStopped() {
        if (mBroadcastDescriptors == null) {
            Log.e(TAG, "areBroadcastsAllStopped: Invalid Broadcast Descriptors");
@@ -4342,6 +4348,19 @@ public class LeAudioService extends ProfileService {
            if (Flags.leaudioBroadcastVolumeControlWithSetVolume()
                    && currentlyActiveGroupId == LE_AUDIO_GROUP_ID_INVALID
                    && !activeBroadcastSinks.isEmpty()) {
                if (Flags.leaudioBroadcastVolumeControlPrimaryGroupOnly()) {
                    if (activeBroadcastSinks.stream()
                            .anyMatch(dev -> isPrimaryGroup(getGroupId(dev)))) {
                        Log.d(
                                TAG,
                                "Setting volume for broadcast sink primary group: "
                                        + mUnicastGroupIdDeactivatedForBroadcastTransition);
                        volumeControlService.setGroupVolume(
                                mUnicastGroupIdDeactivatedForBroadcastTransition, volume);
                    } else {
                        Log.w(TAG, "Setting volume when no active or broadcast primary group");
                    }
                } else {
                    Set<Integer> broadcastGroups =
                            activeBroadcastSinks.stream()
                                    .map(dev -> getGroupId(dev))
@@ -4351,6 +4370,7 @@ public class LeAudioService extends ProfileService {
                    Log.d(TAG, "Setting volume for broadcast sink groups: " + broadcastGroups);
                    broadcastGroups.forEach(
                            groupId -> volumeControlService.setGroupVolume(groupId, volume));
                }
            } else {
                volumeControlService.setGroupVolume(currentlyActiveGroupId, volume);
            }
+13 −2
Original line number Diff line number Diff line
@@ -2618,7 +2618,10 @@ public class LeAudioServiceTest {
    @Test
    public void testSetVolumeForBroadcastSinks() {
        mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_WITH_SET_VOLUME);
        mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_PRIMARY_GROUP_ONLY);

        int groupId = 1;
        int groupId2 = 2;
        int volume = 100;
        int newVolume = 120;
        /* AUDIO_DIRECTION_OUTPUT_BIT = 0x01 */
@@ -2630,6 +2633,8 @@ public class LeAudioServiceTest {
        connectTestDevice(mRightDevice, groupId);
        assertThat(mService.setActiveDevice(mLeftDevice)).isFalse();

        connectTestDevice(mSingleDevice, groupId2);

        ArgumentCaptor<BluetoothProfileConnectionInfo> profileInfo =
                ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class);

@@ -2639,6 +2644,7 @@ public class LeAudioServiceTest {
        TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());

        doReturn(volume).when(mVolumeControlService).getAudioDeviceGroupVolume(groupId);
        doReturn(volume).when(mVolumeControlService).getAudioDeviceGroupVolume(groupId2);
        // Set group and device as active.
        injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE);

@@ -2648,6 +2654,7 @@ public class LeAudioServiceTest {

        // Set group to inactive, only keep them connected as broadcast sink devices.
        injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE);
        injectGroupStatusChange(groupId2, LeAudioStackEvent.GROUP_STATUS_INACTIVE);

        verify(mAudioManager, times(1))
                .handleBluetoothActiveDeviceChanged(
@@ -2657,14 +2664,18 @@ public class LeAudioServiceTest {
        // Verify setGroupVolume will not be called if no active sinks
        doReturn(new ArrayList<>()).when(mBassClientService).getActiveBroadcastSinks();
        mService.setVolume(newVolume);
        verify(mVolumeControlService, times(0)).setGroupVolume(groupId, newVolume);
        verify(mVolumeControlService, never()).setGroupVolume(groupId, newVolume);

        mService.mUnicastGroupIdDeactivatedForBroadcastTransition = groupId;
        // Verify setGroupVolume will be called if active sinks
        doReturn(List.of(mLeftDevice, mRightDevice))
        doReturn(List.of(mLeftDevice, mRightDevice, mSingleDevice))
                .when(mBassClientService)
                .getActiveBroadcastSinks();
        mService.setVolume(newVolume);

        // Verify set volume only on primary group
        verify(mVolumeControlService, times(1)).setGroupVolume(groupId, newVolume);
        verify(mVolumeControlService, never()).setGroupVolume(groupId2, newVolume);
    }

    @Test