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

Commit 1e6eaea0 authored by Tony's avatar Tony
Browse files

Improve quick scrub

- Snap to the next task when quick scrub starts, but don't allow
  snapping to further pages until the transition to overview
  completes (to prevent overshooting)
- Simplify quick switch to just launch the task that was snapped
  to in onQuickScrubStart
- Cleanup some state code

Bug: 70180755
Bug: 74014237
Change-Id: I7a4a0f1a568947b1f5e56a27d7328e47b05a675d
parent 7eee62b3
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
package com.android.launcher3.uioverrides;

import com.android.launcher3.Launcher;
import com.android.quickstep.QuickScrubController;
import com.android.quickstep.RecentsView;

/**
 * Extension of overview state used for QuickScrub
@@ -28,7 +30,14 @@ public class FastOverviewState extends OverviewState {
    private static final boolean DEBUG_DIFFERENT_UI = false;

    public FastOverviewState(int id) {
        super(id, STATE_FLAGS);
        super(id, QuickScrubController.QUICK_SWITCH_START_DURATION, STATE_FLAGS);
    }

    @Override
    public void onStateTransitionEnd(Launcher launcher) {
        super.onStateTransitionEnd(launcher);
        RecentsView recentsView = launcher.getOverviewPanel();
        recentsView.getQuickScrubController().onFinishedTransitionToQuickScrub();
    }

    @Override
+3 −3
Original line number Diff line number Diff line
@@ -37,11 +37,11 @@ public class OverviewState extends LauncherState {
            | FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI;

    public OverviewState(int id) {
        this(id, STATE_FLAGS);
        this(id, OVERVIEW_TRANSITION_MS, STATE_FLAGS);
    }

    protected OverviewState(int id, int stateFlags) {
        super(id, ContainerType.TASKSWITCHER, OVERVIEW_TRANSITION_MS, stateFlags);
    protected OverviewState(int id, int transitionDuration, int stateFlags) {
        super(id, ContainerType.TASKSWITCHER, transitionDuration, stateFlags);
    }

    @Override
+40 −24
Original line number Diff line number Diff line
@@ -34,8 +34,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
 */
public class QuickScrubController implements OnAlarmListener {

    public static final int QUICK_SWITCH_START_DURATION = 133;
    public static final int QUICK_SWITCH_SNAP_DURATION = 120;
    public static final int QUICK_SWITCH_START_DURATION = 210;

    private static final boolean ENABLE_AUTO_ADVANCE = true;
    private static final int NUM_QUICK_SCRUB_SECTIONS = 3;
@@ -52,6 +51,8 @@ public class QuickScrubController implements OnAlarmListener {
    private int mQuickScrubSection;
    private boolean mStartedFromHome;
    private boolean mHasAlarmRun;
    private boolean mQuickSwitched;
    private boolean mFinishedTransitionToQuickScrub;

    public QuickScrubController(Launcher launcher, RecentsView recentsView) {
        mLauncher = launcher;
@@ -67,6 +68,10 @@ public class QuickScrubController implements OnAlarmListener {
        mStartedFromHome = startingFromHome;
        mQuickScrubSection = 0;
        mHasAlarmRun = false;
        mQuickSwitched = false;
        mFinishedTransitionToQuickScrub = false;

        snapToNextTaskIfAvailable();
        mLauncher.getUserEventDispatcher().resetActionDurationMillis();
    }

@@ -97,7 +102,9 @@ public class QuickScrubController implements OnAlarmListener {
        int quickScrubSection = Math.round(progress * NUM_QUICK_SCRUB_SECTIONS);
        if (quickScrubSection != mQuickScrubSection) {
            int pageToGoTo = mRecentsView.getNextPage() + quickScrubSection - mQuickScrubSection;
            if (mFinishedTransitionToQuickScrub) {
                goToPageWithHaptic(pageToGoTo);
            }
            if (ENABLE_AUTO_ADVANCE) {
                if (quickScrubSection == NUM_QUICK_SCRUB_SECTIONS || quickScrubSection == 0) {
                    mAutoAdvanceAlarm.setAlarm(mHasAlarmRun
@@ -111,35 +118,44 @@ public class QuickScrubController implements OnAlarmListener {
    }

    public void onQuickSwitch() {
        for (int i = 0; i < mRecentsView.getPageCount(); i++) {
            TaskView taskView = (TaskView) mRecentsView.getPageAt(i);
            if (taskView.getTask().key.id != mRecentsView.getRunningTaskId()) {
                Runnable launchTaskRunnable = () -> taskView.launchTask(true);
                if (mRecentsView.snapToPage(i, QUICK_SWITCH_SNAP_DURATION)) {
                    // Snap to the new page then launch it
                    mRecentsView.setNextPageSwitchRunnable(launchTaskRunnable);
                } else {
                    // No need to move page, just launch task directly
                    launchTaskRunnable.run();
                }
                break;
        mQuickSwitched = true;
        quickSwitchIfReady();
    }

    public void onFinishedTransitionToQuickScrub() {
        mFinishedTransitionToQuickScrub = true;
        quickSwitchIfReady();
    }

    /**
     * Immediately launches the current task (which we snapped to in onQuickScrubStart) if we've
     * gotten the onQuickSwitch callback and the transition to quick scrub has completed.
     */
    private void quickSwitchIfReady() {
        if (mQuickSwitched && mFinishedTransitionToQuickScrub) {
            onQuickScrubEnd();
            mLauncher.getUserEventDispatcher().logActionOnControl(Touch.FLING,
                    ControlType.QUICK_SCRUB_BUTTON, null, mStartedFromHome ?
                            ContainerType.WORKSPACE : ContainerType.APP);
        }
    }

    public void snapToPageForCurrentQuickScrubSection() {
        if (mInQuickScrub) {
            goToPageWithHaptic(mQuickScrubSection);
    public void snapToNextTaskIfAvailable() {
        if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
            int toPage = mStartedFromHome ? 0 : mRecentsView.getNextPage() + 1;
            goToPageWithHaptic(toPage, QUICK_SWITCH_START_DURATION);
        }
    }

    private void goToPageWithHaptic(int pageToGoTo) {
        goToPageWithHaptic(pageToGoTo, -1);
    }

    private void goToPageWithHaptic(int pageToGoTo, int overrideDuration) {
        pageToGoTo = Utilities.boundToRange(pageToGoTo, 0, mRecentsView.getPageCount() - 1);
        if (pageToGoTo != mRecentsView.getNextPage()) {
            int duration = Math.abs(pageToGoTo - mRecentsView.getNextPage())
            int duration = overrideDuration > -1 ? overrideDuration
                    : Math.abs(pageToGoTo - mRecentsView.getNextPage())
                            * QUICKSCRUB_SNAP_DURATION_PER_PAGE;
            mRecentsView.snapToPage(pageToGoTo, duration);
            mRecentsView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP,
+1 −1
Original line number Diff line number Diff line
@@ -339,7 +339,7 @@ public class RecentsView extends PagedView implements Insettable, OnSharedPrefer
        applyIconScale(false /* animate */);

        if (oldChildCount != getChildCount()) {
            mQuickScrubController.snapToPageForCurrentQuickScrubSection();
            mQuickScrubController.snapToNextTaskIfAvailable();
        }
    }

+6 −7
Original line number Diff line number Diff line
@@ -21,9 +21,8 @@ import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;

import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.quickstep.QuickScrubController.QUICK_SWITCH_START_DURATION;
import static com.android.launcher3.LauncherState.NORMAL;

import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
@@ -45,6 +44,7 @@ import android.view.ViewConfiguration;

import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherState;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.uioverrides.UiFactory;
@@ -316,13 +316,12 @@ public class TouchInteractionService extends Service {
            if (TouchConsumer.isInteractionQuick(interactionType)) {
                Runnable action = () -> {
                    Runnable onComplete = null;
                    if (interactionType == INTERACTION_QUICK_SCRUB) {
                        mQuickScrubController.onQuickScrubStart(true);
                    } else if (interactionType == INTERACTION_QUICK_SWITCH) {
                    if (interactionType == INTERACTION_QUICK_SWITCH) {
                        onComplete = mQuickScrubController::onQuickSwitch;
                    }
                    mLauncher.getStateManager().goToState(FAST_OVERVIEW, true, 0,
                            QUICK_SWITCH_START_DURATION, onComplete);
                    LauncherState fromState = mLauncher.getStateManager().getState();
                    mLauncher.getStateManager().goToState(FAST_OVERVIEW, true, onComplete);
                    mQuickScrubController.onQuickScrubStart(fromState == NORMAL);
                };

                if (mLauncher.getWorkspace().runOnOverlayHidden(action)) {
Loading