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

Commit 532a703c authored by Juan Sebastian Martinez's avatar Juan Sebastian Martinez Committed by Android (Google) Code Review
Browse files

Merge changes from topic "HAPTIC_VOLUME_SLIDER" into main

* changes:
  Extending the SeekableSliderTracker to support Select & Arrow operations
  Adding support for external stimulus release event in the SeekableSliderEventProducer.
parents d649dcaf 10254b56
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -65,4 +65,11 @@ class SeekableSliderEventProducer : SliderEventProducer, OnSeekBarChangeListener
            SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, previousEvent.currentProgress)
        }
    }

    /** The arrow navigation that was operating the slider has stopped. */
    fun onArrowUp() {
        _currentEvent.update { previousEvent ->
            SliderEvent(SliderEventType.ARROW_UP, previousEvent.currentProgress)
        }
    }
}
+55 −2
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ class SeekableSliderTracker(

    override suspend fun iterateState(event: SliderEvent) {
        when (currentState) {
            SliderState.IDLE -> handleIdle(event.type)
            SliderState.IDLE -> handleIdle(event.type, event.currentProgress)
            SliderState.WAIT -> handleWait(event.type, event.currentProgress)
            SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH -> handleAcquired(event.type)
            SliderState.DRAG_HANDLE_DRAGGING -> handleDragging(event.type, event.currentProgress)
@@ -67,17 +67,26 @@ class SeekableSliderTracker(
            SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH -> setState(SliderState.IDLE)
            SliderState.JUMP_TRACK_LOCATION_SELECTED -> handleJumpToTrack(event.type)
            SliderState.JUMP_BOOKEND_SELECTED -> handleJumpToBookend(event.type)
            SliderState.ARROW_HANDLE_MOVED_ONCE -> handleArrowOnce(event.type)
            SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY ->
                handleArrowContinuous(event.type, event.currentProgress)
            SliderState.ARROW_HANDLE_REACHED_BOOKEND -> handleArrowBookend()
        }
        latestProgress = event.currentProgress
    }

    private fun handleIdle(newEventType: SliderEventType) {
    private fun handleIdle(newEventType: SliderEventType, currentProgress: Float) {
        if (newEventType == SliderEventType.STARTED_TRACKING_TOUCH) {
            timerJob = launchTimer()
            // The WAIT state will wait for the timer to complete or a slider progress to occur.
            // This will disambiguate between an imprecise touch that acquires the slider handle,
            // and a select and jump operation in the slider track.
            setState(SliderState.WAIT)
        } else if (newEventType == SliderEventType.PROGRESS_CHANGE_BY_PROGRAM) {
            val state =
                if (bookendReached(currentProgress)) SliderState.ARROW_HANDLE_REACHED_BOOKEND
                else SliderState.ARROW_HANDLE_MOVED_ONCE
            setState(state)
        }
    }

@@ -176,6 +185,13 @@ class SeekableSliderTracker(
            SliderState.DRAG_HANDLE_REACHED_BOOKEND -> executeOnBookend()
            SliderState.JUMP_TRACK_LOCATION_SELECTED ->
                sliderListener.onProgressJump(latestProgress)
            SliderState.ARROW_HANDLE_MOVED_ONCE -> sliderListener.onSelectAndArrow(latestProgress)
            SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY -> sliderListener.onProgress(latestProgress)
            SliderState.ARROW_HANDLE_REACHED_BOOKEND -> {
                executeOnBookend()
                // This transitory execution must also reset the state
                resetState()
            }
            else -> {}
        }
    }
@@ -204,6 +220,43 @@ class SeekableSliderTracker(
            currentProgress <= config.lowerBookendThreshold
    }

    private fun handleArrowOnce(newEventType: SliderEventType) {
        val nextState =
            when (newEventType) {
                SliderEventType.STARTED_TRACKING_TOUCH -> {
                    // Launching the timer and going to WAIT
                    timerJob = launchTimer()
                    SliderState.WAIT
                }
                SliderEventType.PROGRESS_CHANGE_BY_PROGRAM ->
                    SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY
                SliderEventType.ARROW_UP -> SliderState.IDLE
                else -> SliderState.ARROW_HANDLE_MOVED_ONCE
            }
        setState(nextState)
    }

    private fun handleArrowContinuous(newEventType: SliderEventType, currentProgress: Float) {
        val reachedBookend = bookendReached(currentProgress)
        val nextState =
            when (newEventType) {
                SliderEventType.ARROW_UP -> SliderState.IDLE
                SliderEventType.STARTED_TRACKING_TOUCH -> {
                    // Launching the timer and going to WAIT
                    timerJob = launchTimer()
                    SliderState.WAIT
                }
                SliderEventType.PROGRESS_CHANGE_BY_PROGRAM -> {
                    if (reachedBookend) SliderState.ARROW_HANDLE_REACHED_BOOKEND
                    else SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY
                }
                else -> SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY
            }
        setState(nextState)
    }

    private fun handleArrowBookend() = setState(SliderState.IDLE)

    @VisibleForTesting
    fun setState(state: SliderState) {
        currentState = state
+1 −1
Original line number Diff line number Diff line
@@ -29,5 +29,5 @@ enum class SliderEventType {
    /* The slider has stopped tracking touch events. */
    STOPPED_TRACKING_TOUCH,
    /* The external (not touch) stimulus that was modifying the slider progress has stopped. */
    EXTERNAL_STIMULUS_RELEASE,
    ARROW_UP,
}
+7 −1
Original line number Diff line number Diff line
@@ -32,6 +32,12 @@ enum class SliderState {
    DRAG_HANDLE_REACHED_BOOKEND,
    /* A location in the slider track has been selected. */
    JUMP_TRACK_LOCATION_SELECTED,
    /* The slider handled moved to a bookend after it was selected. */
    /* The slider handle moved to a bookend after it was selected. */
    JUMP_BOOKEND_SELECTED,
    /** The slider handle moved due to single select-and-arrow operation */
    ARROW_HANDLE_MOVED_ONCE,
    /** The slider handle moves continuously due to constant select-and-arrow operations */
    ARROW_HANDLE_MOVES_CONTINUOUSLY,
    /** The slider handle reached a bookend due to a select-and-arrow operation */
    ARROW_HANDLE_REACHED_BOOKEND,
}
+1 −1
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
                mListener.onChanged(mTracking, progress, false);
                SeekableSliderEventProducer eventProducer =
                        mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer();
                if (eventProducer != null) {
                if (eventProducer != null && fromUser) {
                    eventProducer.onProgressChanged(seekBar, progress, fromUser);
                }
            }
Loading