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

Commit 6a0a213f authored by Anton Potapov's avatar Anton Potapov
Browse files

Update volume panel in-call behaviour:

1) Show call slider on top;
2) Move isExpanded updates to be behind the `StateFlow`. This fixes the case when the media session is updated, the playback doesn't change and mutableIsExpanded is overridden by that update;

Flag: EXEMPT bugfix
Fixes: 353589592
Fixes: 346891818
Test: manual on foldable
Test: atest VolumePanelScreenshotTest
Change-Id: Id0591da61484fb416b6eda4aaf74c49e447cf0aa
parent 8f065bd9
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.volume.panel.component.volume.domain.interactor
import android.media.AudioDeviceInfo
import android.media.AudioManager
import com.android.settingslib.volume.data.repository.AudioRepository
import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession
@@ -42,6 +43,7 @@ constructor(
    @VolumePanelScope scope: CoroutineScope,
    mediaOutputInteractor: MediaOutputInteractor,
    audioRepository: AudioRepository,
    audioModeInteractor: AudioModeInteractor,
) {

    val volumePanelSliders: StateFlow<List<SliderType>> =
@@ -49,9 +51,14 @@ constructor(
                mediaOutputInteractor.activeMediaDeviceSessions,
                mediaOutputInteractor.defaultActiveMediaSession.filterData(),
                audioRepository.communicationDevice,
            ) { activeSessions, defaultSession, communicationDevice ->
                audioModeInteractor.isOngoingCall,
            ) { activeSessions, defaultSession, communicationDevice, isOngoingCall ->
                coroutineScope {
                    val viewModels = buildList {
                        if (isOngoingCall) {
                            addCall(communicationDevice?.type)
                        }

                        if (defaultSession?.isTheSameSession(activeSessions.remote) == true) {
                            addSession(activeSessions.remote)
                            addStream(AudioManager.STREAM_MUSIC)
@@ -60,11 +67,10 @@ constructor(
                            addSession(activeSessions.remote)
                        }

                        if (communicationDevice?.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
                            addStream(AudioManager.STREAM_BLUETOOTH_SCO)
                        } else {
                            addStream(AudioManager.STREAM_VOICE_CALL)
                        if (!isOngoingCall) {
                            addCall(communicationDevice?.type)
                        }

                        addStream(AudioManager.STREAM_RING)
                        addStream(AudioManager.STREAM_NOTIFICATION)
                        addStream(AudioManager.STREAM_ALARM)
@@ -74,6 +80,14 @@ constructor(
            }
            .stateIn(scope, SharingStarted.Eagerly, emptyList())

    private fun MutableList<SliderType>.addCall(communicationDeviceType: Int?) {
        if (communicationDeviceType == AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
            addStream(AudioManager.STREAM_BLUETOOTH_SCO)
        } else {
            addStream(AudioManager.STREAM_VOICE_CALL)
        }
    }

    private fun MutableList<SliderType>.addSession(remoteMediaDeviceSession: MediaDeviceSession?) {
        if (remoteMediaDeviceSession?.canAdjustVolume == true) {
            add(SliderType.MediaDeviceCast(remoteMediaDeviceSession))
+25 −11
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.volume.panel.component.volume.ui.viewmodel

import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor
import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
@@ -35,9 +36,11 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
@@ -58,24 +61,31 @@ constructor(
    mediaDeviceSessionInteractor: MediaDeviceSessionInteractor,
    private val streamSliderViewModelFactory: AudioStreamSliderViewModel.Factory,
    private val castVolumeSliderViewModelFactory: CastVolumeSliderViewModel.Factory,
    audioModeInteractor: AudioModeInteractor,
    streamsInteractor: AudioSlidersInteractor,
) {

    private val mutableIsExpanded = MutableStateFlow<Boolean?>(null)
    private val isPlaybackActive: Flow<Boolean?> =
        mediaOutputInteractor.defaultActiveMediaSession
            .filterData()
            .flatMapLatest { session ->
    private val isActive: Flow<Boolean?> =
        combine(
                audioModeInteractor.isOngoingCall,
                mediaOutputInteractor.defaultActiveMediaSession.filterData().flatMapLatest { session
                    ->
                    if (session == null) {
                        flowOf(false)
                    } else {
                    mediaDeviceSessionInteractor.playbackState(session).map { it?.isActive == true }
                        mediaDeviceSessionInteractor.playbackState(session).map {
                            it?.isActive == true
                        }
                    }
            .onEach { isPlaybackActive -> mutableIsExpanded.value = !isPlaybackActive }
                },
            ) { isOngoingCall, isPlaybackActive ->
                isOngoingCall || isPlaybackActive
            }
            .stateIn(scope, SharingStarted.Eagerly, null)

    private val portraitExpandable: Flow<SlidersExpandableViewModel> =
        isPlaybackActive
        isActive
            .filterNotNull()
            .flatMapLatest { isActive ->
                if (isActive) {
@@ -105,6 +115,10 @@ constructor(
            }
            .stateIn(scope, SharingStarted.Eagerly, emptyList())

    init {
        isActive.filterNotNull().onEach { mutableIsExpanded.value = !it }.launchIn(scope)
    }

    fun isExpandable(isPortrait: Boolean): Flow<SlidersExpandableViewModel> {
        return if (isPortrait) {
            portraitExpandable
+4 −2
Original line number Diff line number Diff line
@@ -17,15 +17,17 @@
package com.android.systemui.volume.panel.component.volume.domain.interactor

import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.volume.data.repository.audioRepository
import com.android.systemui.volume.domain.interactor.audioModeInteractor
import com.android.systemui.volume.mediaOutputInteractor

val Kosmos.audioSlidersInteractor by
    Kosmos.Fixture {
        AudioSlidersInteractor(
            testScope.backgroundScope,
            applicationCoroutineScope,
            mediaOutputInteractor,
            audioRepository,
            audioModeInteractor,
        )
    }
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.volume.panel.component.volume.ui.viewmodel

import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.volume.domain.interactor.audioModeInteractor
import com.android.systemui.volume.mediaDeviceSessionInteractor
import com.android.systemui.volume.mediaOutputInteractor
import com.android.systemui.volume.panel.component.volume.domain.interactor.audioSlidersInteractor
@@ -32,6 +33,7 @@ val Kosmos.audioVolumeComponentViewModel by
            mediaDeviceSessionInteractor,
            audioStreamSliderViewModelFactory,
            castVolumeSliderViewModelFactory,
            audioModeInteractor,
            audioSlidersInteractor,
        )
    }