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

Commit c17db621 authored by Anton Potapov's avatar Anton Potapov
Browse files

Add remote media and audio sharing volume adjustements logs

Flag: EXEMPT BUGFIX
Bug: 395633463
Test: manual on device. Check the logs when adjusting certain volume
streams

Change-Id: Ibfeccb580c39dd9f166e26b4b0c8e24058a110a5
parent ca75ea98
Loading
Loading
Loading
Loading
+21 −42
Original line number Diff line number Diff line
@@ -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
@@ -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 {
@@ -86,4 +66,3 @@ class AudioSharingStreamSliderViewModelTest : SysuiTestCase() {
                .isEqualTo(Icon.Resource(R.drawable.ic_volume_media_bt, null))
        }
}
}
+15 −8
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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
@@ -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 =
@@ -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())
    }

+9 −2
Original line number Diff line number Diff line
@@ -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
@@ -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)
        }
    }

+48 −4
Original line number Diff line number Diff line
@@ -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
@@ -42,7 +44,7 @@ class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: Lo
                str1 = key
                bool1 = isAvailable
            },
            { "$str1 isAvailable=$bool1" }
            { "$str1 isAvailable=$bool1" },
        )
    }

@@ -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" },
        )
    }

@@ -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" },
        )
    }

@@ -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" },
        )
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -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
@@ -29,10 +29,10 @@ val Kosmos.audioSharingStreamSliderViewModelFactory by
            override fun create(coroutineScope: CoroutineScope): AudioSharingStreamSliderViewModel {
                return AudioSharingStreamSliderViewModel(
                    coroutineScope,
                    applicationContext,
                    audioSharingInteractor,
                    uiEventLogger,
                    sliderHapticsViewModelFactory,
                    volumePanelLogger,
                )
            }
        }
Loading