Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +29 −9 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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)) Loading @@ -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); } Loading android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +13 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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); Loading @@ -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); Loading @@ -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( Loading @@ -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 Loading Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +29 −9 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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)) Loading @@ -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); } Loading
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +13 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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); Loading @@ -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); Loading @@ -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( Loading @@ -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 Loading