Loading packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt +16 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,9 @@ interface AudioSharingRepository { /** Whether the device is in audio sharing. */ val inAudioSharing: Flow<Boolean> /** The primary headset groupId in audio sharing. */ val primaryGroupId: StateFlow<Int> /** The secondary headset groupId in audio sharing. */ val secondaryGroupId: StateFlow<Int> Loading Loading @@ -109,6 +112,16 @@ class AudioSharingRepositoryImpl( awaitClose { contentResolver.unregisterContentObserver(callback) } } override val primaryGroupId: StateFlow<Int> = primaryChange .map { BluetoothUtils.getPrimaryGroupIdForBroadcast(contentResolver) } .onStart { emit(BluetoothUtils.getPrimaryGroupIdForBroadcast(contentResolver)) } .flowOn(backgroundCoroutineContext) .stateIn( coroutineScope, SharingStarted.WhileSubscribed(), BluetoothUtils.getPrimaryGroupIdForBroadcast(contentResolver)) override val secondaryGroupId: StateFlow<Int> = merge( btManager.profileManager.leAudioBroadcastAssistantProfile Loading @@ -121,7 +134,7 @@ class AudioSharingRepositoryImpl( BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT } .map { getSecondaryGroupId() }, primaryChange.map { getSecondaryGroupId() }) primaryGroupId.map { getSecondaryGroupId() }) .onStart { emit(getSecondaryGroupId()) } .flowOn(backgroundCoroutineContext) .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), getSecondaryGroupId()) Loading Loading @@ -193,6 +206,8 @@ class AudioSharingRepositoryImpl( class AudioSharingRepositoryEmptyImpl : AudioSharingRepository { override val inAudioSharing: Flow<Boolean> = flowOf(false) override val primaryGroupId: StateFlow<Int> = MutableStateFlow(BluetoothCsipSetCoordinator.GROUP_ID_INVALID) override val secondaryGroupId: StateFlow<Int> = MutableStateFlow(BluetoothCsipSetCoordinator.GROUP_ID_INVALID) override val volumeMap: StateFlow<GroupIdToVolumes> = MutableStateFlow(emptyMap()) Loading packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt +25 −5 Original line number Diff line number Diff line Loading @@ -131,6 +131,10 @@ class AudioSharingRepositoryTest { `when`(deviceManager.findDevice(device2)).thenReturn(cachedDevice2) `when`(receiveState.bisSyncState).thenReturn(arrayListOf(TEST_RECEIVE_STATE_CONTENT)) `when`(assistant.getAllSources(any())).thenReturn(listOf(receiveState)) Settings.Secure.putInt( contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID_INVALID) underTest = AudioSharingRepositoryImpl( contentResolver, Loading @@ -155,6 +159,22 @@ class AudioSharingRepositoryTest { } } @Test fun primaryGroupIdChange_emitValues() { testScope.runTest { val groupIds = mutableListOf<Int?>() underTest.primaryGroupId.onEach { groupIds.add(it) }.launchIn(backgroundScope) runCurrent() triggerContentObserverChange() runCurrent() Truth.assertThat(groupIds) .containsExactly( TEST_GROUP_ID_INVALID, TEST_GROUP_ID2) } } @Test fun secondaryGroupIdChange_emitValues() { testScope.runTest { Loading Loading @@ -217,7 +237,7 @@ class AudioSharingRepositoryTest { fun setSecondaryVolume_setValue() { testScope.runTest { Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID2) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) Loading Loading @@ -248,7 +268,7 @@ class AudioSharingRepositoryTest { private fun triggerSourceAdded() { verify(assistant).registerServiceCallBack(any(), assistantCallbackCaptor.capture()) Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID1) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) Loading @@ -259,7 +279,7 @@ class AudioSharingRepositoryTest { verify(assistant).registerServiceCallBack(any(), assistantCallbackCaptor.capture()) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1)) Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID1) assistantCallbackCaptor.value.sourceRemoved(device2) Loading @@ -269,7 +289,7 @@ class AudioSharingRepositoryTest { verify(eventManager).registerCallback(btCallbackCaptor.capture()) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1)) Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID1) btCallbackCaptor.value.onProfileConnectionStateChanged(cachedDevice2, state, profile) Loading @@ -283,7 +303,7 @@ class AudioSharingRepositoryTest { contentObserverCaptor.capture()) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID2) contentObserverCaptor.value.primaryChanged() Loading packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt +53 −13 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.systemui.volume.domain.interactor import android.media.AudioManager.STREAM_MUSIC import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope Loading @@ -40,17 +42,57 @@ class AudioSharingInteractorTest : SysuiTestCase() { @Before fun setUp() { with(kosmos) { underTest = audioSharingInteractor } with(kosmos) { with(audioSharingRepository) { setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME)) } underTest = audioSharingInteractor } } @Test fun volumeChanges_returnVolume() { fun handlePrimaryGroupChange_nullVolume() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { setSecondaryGroupId(TEST_GROUP_ID) setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME)) with(audioSharingRepository) { setPrimaryGroupId(TEST_GROUP_ID_INVALID) } val preMusicStream by collectLastValue( audioVolumeInteractor.getAudioStream(AudioStream(STREAM_MUSIC)) ) val preVolume = preMusicStream?.volume runCurrent() underTest.handlePrimaryGroupChange() val musicStream by collectLastValue( audioVolumeInteractor.getAudioStream(AudioStream(STREAM_MUSIC)) ) runCurrent() Truth.assertThat(musicStream?.volume).isEqualTo(preVolume) } } } @Test fun handlePrimaryGroupChange_setStreamVolume() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { setPrimaryGroupId(TEST_GROUP_ID) } underTest.handlePrimaryGroupChange() val musicStream by collectLastValue( audioVolumeInteractor.getAudioStream(AudioStream(STREAM_MUSIC)) ) runCurrent() Truth.assertThat(musicStream?.volume).isEqualTo(TEST_MUSIC_VOLUME) } } } @Test fun secondaryGroupVolumeChanges_returnVolume() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { setSecondaryGroupId(TEST_GROUP_ID) } val volume by collectLastValue(underTest.volume) runCurrent() Loading @@ -60,13 +102,10 @@ class AudioSharingInteractorTest : SysuiTestCase() { } @Test fun volumeChanges_returnNull() { fun secondaryGroupVolumeChanges_returnNull() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { setSecondaryGroupId(TEST_GROUP_ID_INVALID) setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME)) } with(audioSharingRepository) { setSecondaryGroupId(TEST_GROUP_ID_INVALID) } val volume by collectLastValue(underTest.volume) runCurrent() Loading @@ -76,7 +115,7 @@ class AudioSharingInteractorTest : SysuiTestCase() { } @Test fun volumeChanges_returnDefaultVolume() { fun secondaryGroupVolumeChanges_returnDefaultVolume() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { Loading @@ -94,7 +133,8 @@ class AudioSharingInteractorTest : SysuiTestCase() { private companion object { const val TEST_GROUP_ID = 1 const val TEST_GROUP_ID_INVALID = -1 const val TEST_VOLUME = 10 const val TEST_MUSIC_VOLUME = 10 const val TEST_VOLUME = 255 const val TEST_VOLUME_DEFAULT = 20 } } packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java +11 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.volume; import static com.android.settingslib.flags.Flags.volumeDialogAudioSharingFix; import android.content.Context; import android.content.res.Configuration; import android.os.Handler; Loading @@ -26,6 +28,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.res.R; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.volume.domain.interactor.AudioSharingInteractor; import java.io.PrintWriter; Loading @@ -41,11 +44,14 @@ public class VolumeUI implements CoreStartable, ConfigurationController.Configur private boolean mEnabled; private final Context mContext; private VolumeDialogComponent mVolumeComponent; private AudioSharingInteractor mAudioSharingInteractor; @Inject public VolumeUI(Context context, VolumeDialogComponent volumeDialogComponent) { public VolumeUI(Context context, VolumeDialogComponent volumeDialogComponent, AudioSharingInteractor audioSharingInteractor) { mContext = context; mVolumeComponent = volumeDialogComponent; mAudioSharingInteractor = audioSharingInteractor; } @Override Loading @@ -58,6 +64,9 @@ public class VolumeUI implements CoreStartable, ConfigurationController.Configur mVolumeComponent.setEnableDialogs(enableVolumeUi, enableSafetyWarning); setDefaultVolumeController(); if (volumeDialogAudioSharingFix()) { mAudioSharingInteractor.handlePrimaryGroupChange(); } } @Override Loading packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt +0 −1 Original line number Diff line number Diff line Loading @@ -75,7 +75,6 @@ interface AudioModule { @Provides @SysUISingleton fun provideAudioSharingRepository( @Application context: Context, contentResolver: ContentResolver, localBluetoothManager: LocalBluetoothManager?, @Application coroutineScope: CoroutineScope, Loading Loading
packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt +16 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,9 @@ interface AudioSharingRepository { /** Whether the device is in audio sharing. */ val inAudioSharing: Flow<Boolean> /** The primary headset groupId in audio sharing. */ val primaryGroupId: StateFlow<Int> /** The secondary headset groupId in audio sharing. */ val secondaryGroupId: StateFlow<Int> Loading Loading @@ -109,6 +112,16 @@ class AudioSharingRepositoryImpl( awaitClose { contentResolver.unregisterContentObserver(callback) } } override val primaryGroupId: StateFlow<Int> = primaryChange .map { BluetoothUtils.getPrimaryGroupIdForBroadcast(contentResolver) } .onStart { emit(BluetoothUtils.getPrimaryGroupIdForBroadcast(contentResolver)) } .flowOn(backgroundCoroutineContext) .stateIn( coroutineScope, SharingStarted.WhileSubscribed(), BluetoothUtils.getPrimaryGroupIdForBroadcast(contentResolver)) override val secondaryGroupId: StateFlow<Int> = merge( btManager.profileManager.leAudioBroadcastAssistantProfile Loading @@ -121,7 +134,7 @@ class AudioSharingRepositoryImpl( BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT } .map { getSecondaryGroupId() }, primaryChange.map { getSecondaryGroupId() }) primaryGroupId.map { getSecondaryGroupId() }) .onStart { emit(getSecondaryGroupId()) } .flowOn(backgroundCoroutineContext) .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), getSecondaryGroupId()) Loading Loading @@ -193,6 +206,8 @@ class AudioSharingRepositoryImpl( class AudioSharingRepositoryEmptyImpl : AudioSharingRepository { override val inAudioSharing: Flow<Boolean> = flowOf(false) override val primaryGroupId: StateFlow<Int> = MutableStateFlow(BluetoothCsipSetCoordinator.GROUP_ID_INVALID) override val secondaryGroupId: StateFlow<Int> = MutableStateFlow(BluetoothCsipSetCoordinator.GROUP_ID_INVALID) override val volumeMap: StateFlow<GroupIdToVolumes> = MutableStateFlow(emptyMap()) Loading
packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt +25 −5 Original line number Diff line number Diff line Loading @@ -131,6 +131,10 @@ class AudioSharingRepositoryTest { `when`(deviceManager.findDevice(device2)).thenReturn(cachedDevice2) `when`(receiveState.bisSyncState).thenReturn(arrayListOf(TEST_RECEIVE_STATE_CONTENT)) `when`(assistant.getAllSources(any())).thenReturn(listOf(receiveState)) Settings.Secure.putInt( contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID_INVALID) underTest = AudioSharingRepositoryImpl( contentResolver, Loading @@ -155,6 +159,22 @@ class AudioSharingRepositoryTest { } } @Test fun primaryGroupIdChange_emitValues() { testScope.runTest { val groupIds = mutableListOf<Int?>() underTest.primaryGroupId.onEach { groupIds.add(it) }.launchIn(backgroundScope) runCurrent() triggerContentObserverChange() runCurrent() Truth.assertThat(groupIds) .containsExactly( TEST_GROUP_ID_INVALID, TEST_GROUP_ID2) } } @Test fun secondaryGroupIdChange_emitValues() { testScope.runTest { Loading Loading @@ -217,7 +237,7 @@ class AudioSharingRepositoryTest { fun setSecondaryVolume_setValue() { testScope.runTest { Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID2) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) Loading Loading @@ -248,7 +268,7 @@ class AudioSharingRepositoryTest { private fun triggerSourceAdded() { verify(assistant).registerServiceCallBack(any(), assistantCallbackCaptor.capture()) Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID1) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) Loading @@ -259,7 +279,7 @@ class AudioSharingRepositoryTest { verify(assistant).registerServiceCallBack(any(), assistantCallbackCaptor.capture()) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1)) Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID1) assistantCallbackCaptor.value.sourceRemoved(device2) Loading @@ -269,7 +289,7 @@ class AudioSharingRepositoryTest { verify(eventManager).registerCallback(btCallbackCaptor.capture()) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1)) Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID1) btCallbackCaptor.value.onProfileConnectionStateChanged(cachedDevice2, state, profile) Loading @@ -283,7 +303,7 @@ class AudioSharingRepositoryTest { contentObserverCaptor.capture()) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) Settings.Secure.putInt( context.contentResolver, contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), TEST_GROUP_ID2) contentObserverCaptor.value.primaryChanged() Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt +53 −13 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.systemui.volume.domain.interactor import android.media.AudioManager.STREAM_MUSIC import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope Loading @@ -40,17 +42,57 @@ class AudioSharingInteractorTest : SysuiTestCase() { @Before fun setUp() { with(kosmos) { underTest = audioSharingInteractor } with(kosmos) { with(audioSharingRepository) { setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME)) } underTest = audioSharingInteractor } } @Test fun volumeChanges_returnVolume() { fun handlePrimaryGroupChange_nullVolume() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { setSecondaryGroupId(TEST_GROUP_ID) setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME)) with(audioSharingRepository) { setPrimaryGroupId(TEST_GROUP_ID_INVALID) } val preMusicStream by collectLastValue( audioVolumeInteractor.getAudioStream(AudioStream(STREAM_MUSIC)) ) val preVolume = preMusicStream?.volume runCurrent() underTest.handlePrimaryGroupChange() val musicStream by collectLastValue( audioVolumeInteractor.getAudioStream(AudioStream(STREAM_MUSIC)) ) runCurrent() Truth.assertThat(musicStream?.volume).isEqualTo(preVolume) } } } @Test fun handlePrimaryGroupChange_setStreamVolume() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { setPrimaryGroupId(TEST_GROUP_ID) } underTest.handlePrimaryGroupChange() val musicStream by collectLastValue( audioVolumeInteractor.getAudioStream(AudioStream(STREAM_MUSIC)) ) runCurrent() Truth.assertThat(musicStream?.volume).isEqualTo(TEST_MUSIC_VOLUME) } } } @Test fun secondaryGroupVolumeChanges_returnVolume() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { setSecondaryGroupId(TEST_GROUP_ID) } val volume by collectLastValue(underTest.volume) runCurrent() Loading @@ -60,13 +102,10 @@ class AudioSharingInteractorTest : SysuiTestCase() { } @Test fun volumeChanges_returnNull() { fun secondaryGroupVolumeChanges_returnNull() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { setSecondaryGroupId(TEST_GROUP_ID_INVALID) setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME)) } with(audioSharingRepository) { setSecondaryGroupId(TEST_GROUP_ID_INVALID) } val volume by collectLastValue(underTest.volume) runCurrent() Loading @@ -76,7 +115,7 @@ class AudioSharingInteractorTest : SysuiTestCase() { } @Test fun volumeChanges_returnDefaultVolume() { fun secondaryGroupVolumeChanges_returnDefaultVolume() { with(kosmos) { testScope.runTest { with(audioSharingRepository) { Loading @@ -94,7 +133,8 @@ class AudioSharingInteractorTest : SysuiTestCase() { private companion object { const val TEST_GROUP_ID = 1 const val TEST_GROUP_ID_INVALID = -1 const val TEST_VOLUME = 10 const val TEST_MUSIC_VOLUME = 10 const val TEST_VOLUME = 255 const val TEST_VOLUME_DEFAULT = 20 } }
packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java +11 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.volume; import static com.android.settingslib.flags.Flags.volumeDialogAudioSharingFix; import android.content.Context; import android.content.res.Configuration; import android.os.Handler; Loading @@ -26,6 +28,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.res.R; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.volume.domain.interactor.AudioSharingInteractor; import java.io.PrintWriter; Loading @@ -41,11 +44,14 @@ public class VolumeUI implements CoreStartable, ConfigurationController.Configur private boolean mEnabled; private final Context mContext; private VolumeDialogComponent mVolumeComponent; private AudioSharingInteractor mAudioSharingInteractor; @Inject public VolumeUI(Context context, VolumeDialogComponent volumeDialogComponent) { public VolumeUI(Context context, VolumeDialogComponent volumeDialogComponent, AudioSharingInteractor audioSharingInteractor) { mContext = context; mVolumeComponent = volumeDialogComponent; mAudioSharingInteractor = audioSharingInteractor; } @Override Loading @@ -58,6 +64,9 @@ public class VolumeUI implements CoreStartable, ConfigurationController.Configur mVolumeComponent.setEnableDialogs(enableVolumeUi, enableSafetyWarning); setDefaultVolumeController(); if (volumeDialogAudioSharingFix()) { mAudioSharingInteractor.handlePrimaryGroupChange(); } } @Override Loading
packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt +0 −1 Original line number Diff line number Diff line Loading @@ -75,7 +75,6 @@ interface AudioModule { @Provides @SysUISingleton fun provideAudioSharingRepository( @Application context: Context, contentResolver: ContentResolver, localBluetoothManager: LocalBluetoothManager?, @Application coroutineScope: CoroutineScope, Loading