Loading packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt +21 −42 Original line number Diff line number Diff line Loading @@ -19,21 +19,17 @@ package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel import android.bluetooth.BluetoothDevice import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.uiEventLogger import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.res.R import com.android.systemui.testKosmos import com.android.systemui.volume.data.repository.audioSharingRepository import com.android.systemui.volume.domain.interactor.audioSharingInteractor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.mock Loading @@ -43,30 +39,14 @@ import org.mockito.kotlin.mock class AudioSharingStreamSliderViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private lateinit var stream: AudioSharingStreamSliderViewModel @Before fun setUp() { stream = audioSharingStreamSliderViewModel() } private fun audioSharingStreamSliderViewModel(): AudioSharingStreamSliderViewModel { return AudioSharingStreamSliderViewModel( testScope.backgroundScope, context, kosmos.audioSharingInteractor, kosmos.uiEventLogger, kosmos.sliderHapticsViewModelFactory, ) } private val underTest: AudioSharingStreamSliderViewModel = with(kosmos) { audioSharingStreamSliderViewModelFactory.create(applicationCoroutineScope) } @Test fun slider_media_inAudioSharing() = with(kosmos) { testScope.runTest { val audioSharingSlider by collectLastValue(stream.slider) kosmos.runTest { val audioSharingSlider by collectLastValue(underTest.slider) val bluetoothDevice: BluetoothDevice = mock {} val cachedDevice: CachedBluetoothDevice = mock { Loading @@ -86,4 +66,3 @@ class AudioSharingStreamSliderViewModelTest : SysuiTestCase() { .isEqualTo(Icon.Resource(R.drawable.ic_volume_media_bt, null)) } } } packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt +15 −8 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel import android.content.Context import com.android.internal.logging.UiEventLogger import com.android.systemui.Flags import com.android.systemui.common.shared.model.Icon Loading @@ -24,6 +23,7 @@ import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel import com.android.systemui.res.R import com.android.systemui.volume.domain.interactor.AudioSharingInteractor import com.android.systemui.volume.panel.shared.VolumePanelLogger import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import dagger.assisted.Assisted import dagger.assisted.AssistedFactory Loading @@ -34,6 +34,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach Loading @@ -43,21 +44,25 @@ class AudioSharingStreamSliderViewModel @AssistedInject constructor( @Assisted private val coroutineScope: CoroutineScope, private val context: Context, private val audioSharingInteractor: AudioSharingInteractor, private val uiEventLogger: UiEventLogger, private val hapticsViewModelFactory: SliderHapticsViewModel.Factory, private val volumePanelLogger: VolumePanelLogger, ) : SliderViewModel { private val volumeChanges = MutableStateFlow<Int?>(null) override val slider: StateFlow<SliderState> = combine(audioSharingInteractor.volume, audioSharingInteractor.secondaryDevice) { volume, device -> combine( audioSharingInteractor.volume.distinctUntilChanged().onEach { it?.let(volumePanelLogger::onAudioSharingVolumeUpdateReceived) }, audioSharingInteractor.secondaryDevice, ) { volume, device -> val deviceName = device?.name ?: return@combine SliderState.Empty if (volume == null) { SliderState.Empty } else { State( value = volume.toFloat(), valueRange = Loading @@ -74,13 +79,15 @@ constructor( init { volumeChanges .filterNotNull() .onEach { audioSharingInteractor.setStreamVolume(it) } .onEach { volumePanelLogger.onSetAudioSharingVolumeRequested(it) audioSharingInteractor.setStreamVolume(it) } .launchIn(coroutineScope) } override fun onValueChanged(state: SliderState, newValue: Float) { val audioViewModel = state as? State audioViewModel ?: return if (state !is State) return volumeChanges.tryEmit(newValue.roundToInt()) } Loading packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt +9 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel import com.android.systemui.res.R import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession import com.android.systemui.volume.panel.shared.VolumePanelLogger import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject Loading @@ -44,17 +45,23 @@ constructor( private val context: Context, private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, private val hapticsViewModelFactory: SliderHapticsViewModel.Factory, private val volumePanelLogger: VolumePanelLogger, ) : SliderViewModel { override val slider: StateFlow<SliderState> = mediaDeviceSessionInteractor .playbackInfo(session) .mapNotNull { it?.getCurrentState() } .mapNotNull { volumePanelLogger.onVolumeUpdateReceived(session.sessionToken, it.currentVolume) it.getCurrentState() } .stateIn(coroutineScope, SharingStarted.Eagerly, SliderState.Empty) override fun onValueChanged(state: SliderState, newValue: Float) { coroutineScope.launch { mediaDeviceSessionInteractor.setSessionVolume(session, newValue.roundToInt()) val volume = newValue.roundToInt() volumePanelLogger.onSetVolumeRequested(session.sessionToken, volume) mediaDeviceSessionInteractor.setSessionVolume(session, volume) } } Loading packages/SystemUI/src/com/android/systemui/volume/panel/shared/VolumePanelLogger.kt +48 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.volume.panel.shared import android.media.session.MediaSession import android.media.session.MediaSession.Token import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel Loading @@ -42,7 +44,7 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo str1 = key bool1 = isAvailable }, { "$str1 isAvailable=$bool1" } { "$str1 isAvailable=$bool1" }, ) } Loading @@ -51,7 +53,7 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo TAG, LogLevel.DEBUG, { bool1 = globalState.isVisible }, { "Global state changed: isVisible=$bool1" } { "Global state changed: isVisible=$bool1" }, ) } Loading @@ -63,7 +65,7 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo str1 = audioStream.toString() int1 = volume }, { "Set volume: stream=$str1 volume=$int1" } { "Set volume: stream=$str1 volume=$int1" }, ) } Loading @@ -75,7 +77,49 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo str1 = audioStream.toString() int1 = volume }, { "Volume update received: stream=$str1 volume=$int1" } { "Volume update received: stream=$str1 volume=$int1" }, ) } fun onSetVolumeRequested(sessionToken: MediaSession.Token, volume: Int) { logBuffer.log( TAG, LogLevel.DEBUG, { str1 = sessionToken.toString() int1 = volume }, { "Set volume: token=$str1 volume=$int1" }, ) } fun onVolumeUpdateReceived(sessionToken: Token, volume: Int) { logBuffer.log( TAG, LogLevel.DEBUG, { str1 = sessionToken.toString() int1 = volume }, { "Volume update received: token=$str1 volume=$int1" }, ) } fun onSetAudioSharingVolumeRequested(volume: Int) { logBuffer.log( TAG, LogLevel.DEBUG, { int1 = volume }, { "Set volume: audio-sharing volume=$int1" }, ) } fun onAudioSharingVolumeUpdateReceived(volume: Int) { logBuffer.log( TAG, LogLevel.DEBUG, { int1 = volume }, { "Volume update received: audio-sharing volume=$int1" }, ) } } packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt +2 −2 Original line number Diff line number Diff line Loading @@ -16,11 +16,11 @@ package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel import android.content.applicationContext import com.android.internal.logging.uiEventLogger import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory import com.android.systemui.kosmos.Kosmos import com.android.systemui.volume.domain.interactor.audioSharingInteractor import com.android.systemui.volume.shared.volumePanelLogger import kotlinx.coroutines.CoroutineScope val Kosmos.audioSharingStreamSliderViewModelFactory by Loading @@ -29,10 +29,10 @@ val Kosmos.audioSharingStreamSliderViewModelFactory by override fun create(coroutineScope: CoroutineScope): AudioSharingStreamSliderViewModel { return AudioSharingStreamSliderViewModel( coroutineScope, applicationContext, audioSharingInteractor, uiEventLogger, sliderHapticsViewModelFactory, volumePanelLogger, ) } } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt +21 −42 Original line number Diff line number Diff line Loading @@ -19,21 +19,17 @@ package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel import android.bluetooth.BluetoothDevice import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.uiEventLogger import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.res.R import com.android.systemui.testKosmos import com.android.systemui.volume.data.repository.audioSharingRepository import com.android.systemui.volume.domain.interactor.audioSharingInteractor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.mock Loading @@ -43,30 +39,14 @@ import org.mockito.kotlin.mock class AudioSharingStreamSliderViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private lateinit var stream: AudioSharingStreamSliderViewModel @Before fun setUp() { stream = audioSharingStreamSliderViewModel() } private fun audioSharingStreamSliderViewModel(): AudioSharingStreamSliderViewModel { return AudioSharingStreamSliderViewModel( testScope.backgroundScope, context, kosmos.audioSharingInteractor, kosmos.uiEventLogger, kosmos.sliderHapticsViewModelFactory, ) } private val underTest: AudioSharingStreamSliderViewModel = with(kosmos) { audioSharingStreamSliderViewModelFactory.create(applicationCoroutineScope) } @Test fun slider_media_inAudioSharing() = with(kosmos) { testScope.runTest { val audioSharingSlider by collectLastValue(stream.slider) kosmos.runTest { val audioSharingSlider by collectLastValue(underTest.slider) val bluetoothDevice: BluetoothDevice = mock {} val cachedDevice: CachedBluetoothDevice = mock { Loading @@ -86,4 +66,3 @@ class AudioSharingStreamSliderViewModelTest : SysuiTestCase() { .isEqualTo(Icon.Resource(R.drawable.ic_volume_media_bt, null)) } } }
packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt +15 −8 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel import android.content.Context import com.android.internal.logging.UiEventLogger import com.android.systemui.Flags import com.android.systemui.common.shared.model.Icon Loading @@ -24,6 +23,7 @@ import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel import com.android.systemui.res.R import com.android.systemui.volume.domain.interactor.AudioSharingInteractor import com.android.systemui.volume.panel.shared.VolumePanelLogger import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import dagger.assisted.Assisted import dagger.assisted.AssistedFactory Loading @@ -34,6 +34,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach Loading @@ -43,21 +44,25 @@ class AudioSharingStreamSliderViewModel @AssistedInject constructor( @Assisted private val coroutineScope: CoroutineScope, private val context: Context, private val audioSharingInteractor: AudioSharingInteractor, private val uiEventLogger: UiEventLogger, private val hapticsViewModelFactory: SliderHapticsViewModel.Factory, private val volumePanelLogger: VolumePanelLogger, ) : SliderViewModel { private val volumeChanges = MutableStateFlow<Int?>(null) override val slider: StateFlow<SliderState> = combine(audioSharingInteractor.volume, audioSharingInteractor.secondaryDevice) { volume, device -> combine( audioSharingInteractor.volume.distinctUntilChanged().onEach { it?.let(volumePanelLogger::onAudioSharingVolumeUpdateReceived) }, audioSharingInteractor.secondaryDevice, ) { volume, device -> val deviceName = device?.name ?: return@combine SliderState.Empty if (volume == null) { SliderState.Empty } else { State( value = volume.toFloat(), valueRange = Loading @@ -74,13 +79,15 @@ constructor( init { volumeChanges .filterNotNull() .onEach { audioSharingInteractor.setStreamVolume(it) } .onEach { volumePanelLogger.onSetAudioSharingVolumeRequested(it) audioSharingInteractor.setStreamVolume(it) } .launchIn(coroutineScope) } override fun onValueChanged(state: SliderState, newValue: Float) { val audioViewModel = state as? State audioViewModel ?: return if (state !is State) return volumeChanges.tryEmit(newValue.roundToInt()) } Loading
packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt +9 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel import com.android.systemui.res.R import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession import com.android.systemui.volume.panel.shared.VolumePanelLogger import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject Loading @@ -44,17 +45,23 @@ constructor( private val context: Context, private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, private val hapticsViewModelFactory: SliderHapticsViewModel.Factory, private val volumePanelLogger: VolumePanelLogger, ) : SliderViewModel { override val slider: StateFlow<SliderState> = mediaDeviceSessionInteractor .playbackInfo(session) .mapNotNull { it?.getCurrentState() } .mapNotNull { volumePanelLogger.onVolumeUpdateReceived(session.sessionToken, it.currentVolume) it.getCurrentState() } .stateIn(coroutineScope, SharingStarted.Eagerly, SliderState.Empty) override fun onValueChanged(state: SliderState, newValue: Float) { coroutineScope.launch { mediaDeviceSessionInteractor.setSessionVolume(session, newValue.roundToInt()) val volume = newValue.roundToInt() volumePanelLogger.onSetVolumeRequested(session.sessionToken, volume) mediaDeviceSessionInteractor.setSessionVolume(session, volume) } } Loading
packages/SystemUI/src/com/android/systemui/volume/panel/shared/VolumePanelLogger.kt +48 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.volume.panel.shared import android.media.session.MediaSession import android.media.session.MediaSession.Token import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel Loading @@ -42,7 +44,7 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo str1 = key bool1 = isAvailable }, { "$str1 isAvailable=$bool1" } { "$str1 isAvailable=$bool1" }, ) } Loading @@ -51,7 +53,7 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo TAG, LogLevel.DEBUG, { bool1 = globalState.isVisible }, { "Global state changed: isVisible=$bool1" } { "Global state changed: isVisible=$bool1" }, ) } Loading @@ -63,7 +65,7 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo str1 = audioStream.toString() int1 = volume }, { "Set volume: stream=$str1 volume=$int1" } { "Set volume: stream=$str1 volume=$int1" }, ) } Loading @@ -75,7 +77,49 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo str1 = audioStream.toString() int1 = volume }, { "Volume update received: stream=$str1 volume=$int1" } { "Volume update received: stream=$str1 volume=$int1" }, ) } fun onSetVolumeRequested(sessionToken: MediaSession.Token, volume: Int) { logBuffer.log( TAG, LogLevel.DEBUG, { str1 = sessionToken.toString() int1 = volume }, { "Set volume: token=$str1 volume=$int1" }, ) } fun onVolumeUpdateReceived(sessionToken: Token, volume: Int) { logBuffer.log( TAG, LogLevel.DEBUG, { str1 = sessionToken.toString() int1 = volume }, { "Volume update received: token=$str1 volume=$int1" }, ) } fun onSetAudioSharingVolumeRequested(volume: Int) { logBuffer.log( TAG, LogLevel.DEBUG, { int1 = volume }, { "Set volume: audio-sharing volume=$int1" }, ) } fun onAudioSharingVolumeUpdateReceived(volume: Int) { logBuffer.log( TAG, LogLevel.DEBUG, { int1 = volume }, { "Volume update received: audio-sharing volume=$int1" }, ) } }
packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt +2 −2 Original line number Diff line number Diff line Loading @@ -16,11 +16,11 @@ package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel import android.content.applicationContext import com.android.internal.logging.uiEventLogger import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory import com.android.systemui.kosmos.Kosmos import com.android.systemui.volume.domain.interactor.audioSharingInteractor import com.android.systemui.volume.shared.volumePanelLogger import kotlinx.coroutines.CoroutineScope val Kosmos.audioSharingStreamSliderViewModelFactory by Loading @@ -29,10 +29,10 @@ val Kosmos.audioSharingStreamSliderViewModelFactory by override fun create(coroutineScope: CoroutineScope): AudioSharingStreamSliderViewModel { return AudioSharingStreamSliderViewModel( coroutineScope, applicationContext, audioSharingInteractor, uiEventLogger, sliderHapticsViewModelFactory, volumePanelLogger, ) } } Loading