Loading packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt +49 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) Loading @@ -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 } } } } } }, ) } Loading packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaNavigationViewModel.kt +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt +15 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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(), Loading Loading @@ -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) Loading Loading
packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt +49 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) Loading @@ -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 } } } } } }, ) } Loading
packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaNavigationViewModel.kt +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading
packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt +15 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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(), Loading Loading @@ -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) Loading