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

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

Merge "[Media] Reject seek bar scrubbing if too vertical." into main

parents d464624f 93780a19
Loading
Loading
Loading
Loading
+49 −4
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ import androidx.compose.ui.graphics.drawscope.clipRect
import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.PointerInputChange
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.Layout
@@ -663,11 +665,20 @@ private fun ContentScope.Navigation(
                if (isSeekBarVisible) {
                    // To allow the seek bar slider to fade in and out, it's tagged as an element.
                    Element(key = Media.Elements.SeekBarSlider, modifier = Modifier.weight(1f)) {
                        val sliderDragDelta = remember {
                            // Not a mutableStateOf - this is never accessed in composition and
                            // using an anonymous object avoids generics boxing of inline Offset.
                            object {
                                var value = Offset.Zero
                            }
                        }
                        Slider(
                            interactionSource = interactionSource,
                            value = viewModel.progress,
                            onValueChange = { progress -> viewModel.onScrubChange(progress) },
                            onValueChangeFinished = { viewModel.onScrubFinished() },
                            onValueChangeFinished = {
                                viewModel.onScrubFinished(sliderDragDelta.value)
                            },
                            colors = colors,
                            thumb = {
                                SeekBarThumb(interactionSource = interactionSource, colors = colors)
@@ -681,8 +692,42 @@ private fun ContentScope.Navigation(
                                )
                            },
                            modifier =
                                Modifier.fillMaxWidth().clearAndSetSemantics {
                                Modifier.fillMaxWidth()
                                    .clearAndSetSemantics {
                                        contentDescription = viewModel.contentDescription
                                    }
                                    .pointerInput(Unit) {
                                        // Track and report the drag delta to the view-model so it
                                        // can
                                        // decide whether to accept the next onValueChangeFinished
                                        // or
                                        // reject it if the drag was overly vertical.
                                        awaitPointerEventScope {
                                            var down: PointerInputChange? = null
                                            while (true) {
                                                val event =
                                                    awaitPointerEvent(PointerEventPass.Initial)
                                                when (event.type) {
                                                    PointerEventType.Press -> {
                                                        // A new gesture has begun. Record the
                                                        // initial
                                                        // down input change.
                                                        down = event.changes.last()
                                                    }

                                                    PointerEventType.Move -> {
                                                        // The pointer has moved. If it's the same
                                                        // pointer as the latest down, calculate and
                                                        // report the drag delta.
                                                        val change = event.changes.last()
                                                        if (change.id == down?.id) {
                                                            sliderDragDelta.value =
                                                                change.position - down.position
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    },
                        )
                    }
+2 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.media.remedia.ui.viewmodel

import androidx.annotation.FloatRange
import androidx.compose.ui.geometry.Offset

/**
 * Models UI state for the navigation component of the UI (potentially containing the seek bar and
@@ -58,7 +59,7 @@ sealed interface MediaNavigationViewModel {
         * A callback to invoke once the user finishes "scrubbing" (e.g. stopped moving the thumb of
         * the seek bar). The position/progress should be committed.
         */
        val onScrubFinished: () -> Unit,
        val onScrubFinished: (delta: Offset) -> Unit,
        /** Accessibility string to attach to the seekbar UI element. */
        val contentDescription: String,
    ) : MediaNavigationViewModel
+15 −3
Original line number Diff line number Diff line
@@ -26,9 +26,9 @@ import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.ImageBitmap
import com.android.systemui.classifier.Classifier
import com.android.systemui.classifier.domain.interactor.runIfNotFalseTap
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.lifecycle.ExclusiveActivatable
@@ -42,6 +42,7 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.util.Locale
import kotlin.math.abs
import kotlin.math.roundToLong
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.awaitCancellation
@@ -114,8 +115,11 @@ constructor(
                                    isScrubbing = true
                                    seekProgress = progress
                                },
                                onScrubFinished = {
                                    if (!falsingSystem.isFalseTouch(Classifier.MEDIA_SEEKBAR)) {
                                onScrubFinished = { dragDelta ->
                                    if (
                                        dragDelta.isHorizontal() &&
                                            !falsingSystem.isFalseTouch(Classifier.MEDIA_SEEKBAR)
                                    ) {
                                        interactor.seek(
                                            sessionKey = session.key,
                                            to = (seekProgress * session.durationMs).roundToLong(),
@@ -346,6 +350,14 @@ constructor(
            .formatMeasures(*measures.toTypedArray())
    }

    /**
     * Returns `true` if this [Offset] is the same or larger on the horizontal axis than the
     * vertical axis.
     */
    private fun Offset.isHorizontal(): Boolean {
        return abs(x) >= abs(y)
    }

    interface FalsingSystem {
        fun runIfNotFalseTap(@FalsingManager.Penalty penalty: Int, block: () -> Unit)