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

Commit b12fb720 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I43acab2f,Ib9ba0a6b into main

* changes:
  Fix turbulence noise logic
  Fix unwanted reserved spaces for semantic buttons
parents 8d6962ab d43ebf95
Loading
Loading
Loading
Loading
+0 −16
Original line number Diff line number Diff line
@@ -21,9 +21,7 @@ import android.app.BroadcastOptions
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.session.MediaController
import android.media.session.MediaSession
import android.media.session.PlaybackState
import android.provider.Settings
import android.util.Log
import com.android.internal.jank.Cuj
@@ -42,7 +40,6 @@ import com.android.systemui.media.dialog.MediaOutputDialogManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.kotlin.pairwiseBy
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.Flow
@@ -70,19 +67,6 @@ constructor(
            .map { entries -> entries[instanceId]?.let { toMediaControlModel(it) } }
            .distinctUntilChanged()

    val isStartedPlaying: Flow<Boolean> =
        mediaControl
            .map { mediaControl ->
                mediaControl?.token?.let { token ->
                    MediaController(applicationContext, token).playbackState?.let {
                        it.state == PlaybackState.STATE_PLAYING
                    }
                }
                    ?: false
            }
            .pairwiseBy(initialValue = false) { wasPlaying, isPlaying -> !wasPlaying && isPlaying }
            .distinctUntilChanged()

    val onAnyMediaConfigurationChange: Flow<Unit> = repository.onAnyMediaConfigurationChange

    fun removeMediaControl(
+44 −44
Original line number Diff line number Diff line
@@ -260,45 +260,51 @@ object MediaControlViewBinder {
            }

            SEMANTIC_ACTIONS_ALL.forEachIndexed { index, id ->
                val button = viewHolder.getAction(id)
                val actionViewModel = viewModel.actionButtons[index]
                if (button.id == R.id.actionPrev) {
                    actionViewModel?.let {
                        viewController.setUpPrevButtonInfo(true, it.notVisibleValue)
                    }
                } else if (button.id == R.id.actionNext) {
                    actionViewModel?.let {
                        viewController.setUpNextButtonInfo(true, it.notVisibleValue)
                    }
                val buttonView = viewHolder.getAction(id)
                val buttonModel = viewModel.actionButtons[index]
                if (buttonView.id == R.id.actionPrev) {
                    viewController.setUpPrevButtonInfo(
                        buttonModel.isEnabled,
                        buttonModel.notVisibleValue
                    )
                } else if (buttonView.id == R.id.actionNext) {
                    viewController.setUpNextButtonInfo(
                        buttonModel.isEnabled,
                        buttonModel.notVisibleValue
                    )
                }
                actionViewModel?.let { action ->
                    val animHandler = (button.tag ?: AnimationBindHandler()) as AnimationBindHandler
                val animHandler = (buttonView.tag ?: AnimationBindHandler()) as AnimationBindHandler
                animHandler.tryExecute {
                        if (animHandler.updateRebindId(action.rebindId)) {
                    if (buttonModel.isEnabled) {
                        if (animHandler.updateRebindId(buttonModel.rebindId)) {
                            animHandler.unregisterAll()
                            animHandler.tryRegister(action.icon)
                            animHandler.tryRegister(action.background)
                            animHandler.tryRegister(buttonModel.icon)
                            animHandler.tryRegister(buttonModel.background)
                            bindButtonCommon(
                                button,
                                buttonView,
                                viewHolder.multiRippleView,
                                action,
                                buttonModel,
                                viewController,
                                falsingManager,
                            )
                        }
                        val visible = action.isVisibleWhenScrubbing || !viewController.isScrubbing
                    } else {
                        animHandler.unregisterAll()
                        clearButton(buttonView)
                    }
                    val visible =
                        buttonModel.isEnabled &&
                            (buttonModel.isVisibleWhenScrubbing || !viewController.isScrubbing)
                    setSemanticButtonVisibleAndAlpha(
                        viewHolder.getAction(id),
                        viewController.expandedLayout,
                        viewController.collapsedLayout,
                        visible,
                            action.notVisibleValue,
                            action.showInCollapsed
                        buttonModel.notVisibleValue,
                        buttonModel.showInCollapsed
                    )
                }
            }
                    ?: clearButton(button)
            }
        } else {
            // Hide buttons that only appear for semantic actions
            SEMANTIC_ACTIONS_COMPACT.forEach { buttonId ->
@@ -309,7 +315,7 @@ object MediaControlViewBinder {
            // Set all generic buttons
            genericButtons.forEachIndexed { index, button ->
                if (index < viewModel.actionButtons.size) {
                    viewModel.actionButtons[index]?.let { action ->
                    val action = viewModel.actionButtons[index]
                    bindButtonCommon(
                        button,
                        viewHolder.multiRippleView,
@@ -318,13 +324,7 @@ object MediaControlViewBinder {
                        falsingManager,
                    )
                    setVisibleAndAlpha(expandedSet, button.id, visible = true)
                        setVisibleAndAlpha(
                            collapsedSet,
                            button.id,
                            visible = action.showInCollapsed
                        )
                    }
                        ?: clearButton(button)
                    setVisibleAndAlpha(collapsedSet, button.id, visible = action.showInCollapsed)
                } else {
                    // Hide any unused buttons
                    clearButton(button)
+8 −6
Original line number Diff line number Diff line
@@ -709,12 +709,6 @@ constructor(

        // For Turbulence noise.
        val loadingEffectView = mediaViewHolder.loadingEffectView
        turbulenceNoiseAnimationConfig =
            createTurbulenceNoiseConfig(
                loadingEffectView,
                turbulenceNoiseView,
                colorSchemeTransition
            )
        noiseDrawCallback =
            object : PaintDrawCallback {
                override fun onDraw(paint: Paint) {
@@ -809,6 +803,14 @@ constructor(

    fun setUpTurbulenceNoise() {
        if (!mediaFlags.isMediaControlsRefactorEnabled()) return
        if (!this::turbulenceNoiseAnimationConfig.isInitialized) {
            turbulenceNoiseAnimationConfig =
                createTurbulenceNoiseConfig(
                    mediaViewHolder.loadingEffectView,
                    mediaViewHolder.turbulenceNoiseView,
                    colorSchemeTransition
                )
        }
        if (Flags.shaderlibLoadingEffectRefactor()) {
            if (!this::loadingEffect.isInitialized) {
                loadingEffect =
+35 −44
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context
import android.content.pm.PackageManager
import android.media.session.MediaController
import android.media.session.MediaSession.Token
import android.media.session.PlaybackState
import android.text.TextUtils
import android.util.Log
import androidx.constraintlayout.widget.ConstraintSet
@@ -40,16 +41,14 @@ import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.monet.ColorScheme
import com.android.systemui.monet.Style
import com.android.systemui.res.R
import com.android.systemui.util.kotlin.sample
import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map

/** Models UI state and handles user input for a media control. */
class MediaControlViewModel(
@@ -60,31 +59,20 @@ class MediaControlViewModel(
    private val logger: MediaUiEventLogger,
) {

    private val isAnyButtonClicked: MutableStateFlow<Boolean> = MutableStateFlow(false)

    private val playTurbulenceNoise: Flow<Boolean> =
        interactor.mediaControl.sample(
            combine(isAnyButtonClicked, interactor.isStartedPlaying) {
                    isButtonClicked,
                    isStartedPlaying ->
                    isButtonClicked && isStartedPlaying
                }
                .distinctUntilChanged()
        )

    @OptIn(ExperimentalCoroutinesApi::class)
    val player: Flow<MediaPlayerViewModel?> =
        interactor.onAnyMediaConfigurationChange
            .flatMapLatest {
                combine(playTurbulenceNoise, interactor.mediaControl) {
                    playTurbulenceNoise,
                    mediaControl ->
                    mediaControl?.let { toViewModel(it, playTurbulenceNoise) }
                interactor.mediaControl.map { mediaControl ->
                    mediaControl?.let { toViewModel(it) }
                }
            }
            .distinctUntilChanged()
            .flowOn(backgroundDispatcher)

    private var isPlaying = false
    private var isAnyButtonClicked = false

    private fun onDismissMediaData(
        token: Token?,
        uid: Int,
@@ -95,10 +83,8 @@ class MediaControlViewModel(
        interactor.removeMediaControl(token, instanceId, MEDIA_PLAYER_ANIMATION_DELAY)
    }

    private suspend fun toViewModel(
        model: MediaControlModel,
        playTurbulenceNoise: Boolean
    ): MediaPlayerViewModel? {
    private suspend fun toViewModel(model: MediaControlModel): MediaPlayerViewModel? {
        val mediaController = model.token?.let { MediaController(applicationContext, it) }
        val wallpaperColors =
            MediaArtworkHelper.getWallpaperColor(
                applicationContext,
@@ -118,8 +104,14 @@ class MediaControlViewModel(

        val gutsViewModel = toGutsViewModel(model, scheme)

        // Set playing state
        val wasPlaying = isPlaying
        isPlaying =
            mediaController?.playbackState?.let { it.state == PlaybackState.STATE_PLAYING } ?: false

        // Resetting button clicks state.
        isAnyButtonClicked.value = false
        val wasButtonClicked = isAnyButtonClicked
        isAnyButtonClicked = false

        return MediaPlayerViewModel(
            contentDescription = { gutsVisible ->
@@ -144,7 +136,7 @@ class MediaControlViewModel(
            shouldAddGradient = wallpaperColors != null,
            colorScheme = scheme,
            canShowTime = canShowScrubbingTimeViews(model.semanticActionButtons),
            playTurbulenceNoise = playTurbulenceNoise,
            playTurbulenceNoise = isPlaying && !wasPlaying && wasButtonClicked,
            useSemanticActions = model.semanticActionButtons != null,
            actionButtons = toActionViewModels(model),
            outputSwitcher = toOutputSwitcherViewModel(model),
@@ -168,9 +160,7 @@ class MediaControlViewModel(
                    seekBarViewModel.updateStaticProgress(model.resumeProgress)
                } else {
                    backgroundExecutor.execute {
                        seekBarViewModel.updateController(
                            model.token?.let { MediaController(applicationContext, it) }
                        )
                        seekBarViewModel.updateController(mediaController)
                    }
                }
            }
@@ -283,16 +273,17 @@ class MediaControlViewModel(
        )
    }

    private fun toActionViewModels(model: MediaControlModel): List<MediaActionViewModel?> {
    private fun toActionViewModels(model: MediaControlModel): List<MediaActionViewModel> {
        val semanticActionButtons =
            model.semanticActionButtons?.let { mediaButton ->
                with(mediaButton) {
                val isScrubbingTimeEnabled = canShowScrubbingTimeViews(mediaButton)
                SEMANTIC_ACTIONS_ALL.map { buttonId ->
                        getActionById(buttonId)?.let {
                            toSemanticActionViewModel(model, it, buttonId, isScrubbingTimeEnabled)
                        }
                    }
                    toSemanticActionViewModel(
                        model,
                        mediaButton.getActionById(buttonId),
                        buttonId,
                        isScrubbingTimeEnabled
                    )
                }
            }
        val notifActionButtons =
@@ -304,7 +295,7 @@ class MediaControlViewModel(

    private fun toSemanticActionViewModel(
        model: MediaControlModel,
        mediaAction: MediaAction,
        mediaAction: MediaAction?,
        buttonId: Int,
        canShowScrubbingTimeViews: Boolean
    ): MediaActionViewModel {
@@ -312,9 +303,9 @@ class MediaControlViewModel(
        val hideWhenScrubbing = SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.contains(buttonId)
        val shouldHideWhenScrubbing = canShowScrubbingTimeViews && hideWhenScrubbing
        return MediaActionViewModel(
            icon = mediaAction.icon,
            contentDescription = mediaAction.contentDescription,
            background = mediaAction.background,
            icon = mediaAction?.icon,
            contentDescription = mediaAction?.contentDescription,
            background = mediaAction?.background,
            isVisibleWhenScrubbing = !shouldHideWhenScrubbing,
            notVisibleValue =
                if (
@@ -326,11 +317,11 @@ class MediaControlViewModel(
                    ConstraintSet.GONE
                },
            showInCollapsed = showInCollapsed,
            rebindId = mediaAction.rebindId,
            rebindId = mediaAction?.rebindId,
            buttonId = buttonId,
            isEnabled = mediaAction.action != null,
            isEnabled = mediaAction?.action != null,
            onClicked = { id ->
                mediaAction.action?.let {
                mediaAction?.action?.let {
                    onButtonClicked(id, model.uid, model.packageName, model.instanceId, it)
                }
            },
@@ -366,7 +357,7 @@ class MediaControlViewModel(
    ) {
        logger.logTapAction(id, uid, packageName, instanceId)
        // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_CLICK_EVENT)
        isAnyButtonClicked.value = true
        isAnyButtonClicked = true
        action.run()
    }

+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ data class MediaPlayerViewModel(
    val canShowTime: Boolean,
    val playTurbulenceNoise: Boolean,
    val useSemanticActions: Boolean,
    val actionButtons: List<MediaActionViewModel?>,
    val actionButtons: List<MediaActionViewModel>,
    val outputSwitcher: MediaOutputSwitcherViewModel,
    val gutsMenu: GutsViewModel,
    val onClicked: (Expandable) -> Unit,