summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaNavigationViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt18
3 files changed, 66 insertions, 8 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
index 8751aa31f237..17423e235af6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
@@ -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,9 +692,43 @@ private fun ContentScope.Navigation(
)
},
modifier =
- Modifier.fillMaxWidth().clearAndSetSemantics {
- contentDescription = viewModel.contentDescription
- },
+ 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
+ }
+ }
+ }
+ }
+ }
+ },
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaNavigationViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaNavigationViewModel.kt
index ca7334341c87..a3689926e937 100644
--- a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaNavigationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaNavigationViewModel.kt
@@ -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
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt
index 15951165a19e..19b08fa212db 100644
--- a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt
@@ -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)