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

Commit 05a31ede authored by Winson Chung's avatar Winson Chung
Browse files

Defer launching the quickscrub task until after the page settles

- Tweak the durations to be less laggy
- Add some state logging

Bug: 67957962
Bug: 70180755
Change-Id: Ia0caa5178b3ed976705eb2d973bc00d8f1b9e3ca
parent 006239ba
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ public class QuickScrubController implements OnAlarmListener {

    private static final int NUM_QUICK_SCRUB_SECTIONS = 5;
    private static final long AUTO_ADVANCE_DELAY = 500;
    private static final int QUICKSCRUB_SNAP_DURATION_PER_PAGE = 325;
    private static final int QUICKSCRUB_END_SNAP_DURATION_PER_PAGE = 60;

    private Launcher mLauncher;
@@ -58,18 +59,22 @@ public class QuickScrubController implements OnAlarmListener {
        if (mRecentsView == null) {
        } else {
            int page = mRecentsView.getNextPage();
            // Settle on the page then launch it.
            int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen())
                    * QUICKSCRUB_END_SNAP_DURATION_PER_PAGE;
            mRecentsView.snapToPage(page, snapDuration);
            // TODO: Fix this to actually wait until page-settle
            mRecentsView.postDelayed(() -> {
            Runnable launchTaskRunnable = () -> {
                if (page < mRecentsView.getFirstTaskIndex()) {
                    mRecentsView.getPageAt(page).performClick();
                } else {
                    ((TaskView) mRecentsView.getPageAt(page)).launchTask(true);
                }
            }, snapDuration);
            };
            int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen())
                    * QUICKSCRUB_END_SNAP_DURATION_PER_PAGE;
            if (mRecentsView.snapToPage(page, snapDuration)) {
                // Settle on the page then launch it
                mRecentsView.setNextPageSwitchRunnable(launchTaskRunnable);
            } else {
                // No page move needed, just launch it
                launchTaskRunnable.run();
            }
        }
    }

@@ -93,7 +98,9 @@ public class QuickScrubController implements OnAlarmListener {

    private void goToPageWithHaptic(int pageToGoTo) {
        if (pageToGoTo != mRecentsView.getNextPage()) {
            mRecentsView.snapToPage(pageToGoTo);
            int duration = Math.abs(pageToGoTo - mRecentsView.getNextPage())
                    * QUICKSCRUB_SNAP_DURATION_PER_PAGE;
            mRecentsView.snapToPage(pageToGoTo, duration);
            mRecentsView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP,
                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
        }
+14 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ public class RecentsView extends PagedView implements Insettable {
    private boolean mOverviewStateEnabled;
    private boolean mTaskStackListenerRegistered;
    private LayoutTransition mLayoutTransition;
    private Runnable mNextPageSwitchRunnable;

    /**
     * TODO: Call reloadIdNeeded in onTaskStackChanged.
@@ -243,6 +244,19 @@ public class RecentsView extends PagedView implements Insettable {
        updateTaskStackListenerState();
    }

    public void setNextPageSwitchRunnable(Runnable r) {
        mNextPageSwitchRunnable = r;
    }

    @Override
    protected void onPageEndTransition() {
        super.onPageEndTransition();
        if (mNextPageSwitchRunnable != null) {
            mNextPageSwitchRunnable.run();
            mNextPageSwitchRunnable = null;
        }
    }

    private void applyLoadPlan(RecentsTaskLoadPlan loadPlan) {
        final RecentsTaskLoader loader = mModel.getRecentsTaskLoader();
        TaskStack stack = loadPlan != null ? loadPlan.getTaskStack() : null;
+54 −5
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.os.Handler;
import android.os.Looper;
import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver.OnDrawListener;

@@ -65,8 +66,12 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.TransactionCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;

import java.util.StringJoiner;

@TargetApi(Build.VERSION_CODES.O)
public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
    private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
    private static final boolean DEBUG_STATES = false;

    // Launcher UI related states
    private static final int STATE_LAUNCHER_PRESENT = 1 << 0;
@@ -86,8 +91,21 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
    private static final int LAUNCHER_UI_STATES =
            STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE;

    // For debugging, keep in sync with above states
    private static final String[] STATES = new String[] {
            "STATE_LAUNCHER_PRESENT",
            "STATE_LAUNCHER_DRAWN",
            "STATE_ACTIVITY_MULTIPLIER_COMPLETE",
            "STATE_APP_CONTROLLER_RECEIVED",
            "STATE_SCALED_CONTROLLER_RECENTS",
            "STATE_SCALED_CONTROLLER_APP",
            "STATE_HANDLER_INVALIDATED",
            "STATE_GESTURE_STARTED"
    };

    private static final long MAX_SWIPE_DURATION = 200;
    private static final long MIN_SWIPE_DURATION = 80;
    private static final int QUICK_SWITCH_START_DURATION = 133;
    private static final int QUICK_SWITCH_SNAP_DURATION = 120;

    private static final float MIN_PROGRESS_FOR_OVERVIEW = 0.5f;
@@ -154,7 +172,13 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
    }

    private void initStateCallbacks() {
        mStateCallback = new MultiStateCallback();
        mStateCallback = new MultiStateCallback() {
            @Override
            public void setState(int stateFlag) {
                debugNewState(stateFlag);
                super.setState(stateFlag);
            }
        };
        mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED,
                this::initializeLauncherAnimationController);
        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN,
@@ -356,7 +380,7 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
        mDeferredQuickScrubEnd = false;
        mQuickScrubController = mRecentsView.getQuickScrubController();
        mQuickScrubController.onQuickScrubStart(mStartedQuickScrubFromHome);
        animateToProgress(1f, MAX_SWIPE_DURATION);
        animateToProgress(1f, QUICK_SWITCH_START_DURATION);
        if (mStartedQuickScrubFromHome) {
            mLauncherLayoutListener.setVisibility(View.INVISIBLE);
        }
@@ -599,9 +623,14 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
            for (int i = mRecentsView.getFirstTaskIndex(); i < mRecentsView.getPageCount(); i++) {
                TaskView taskView = (TaskView) mRecentsView.getPageAt(i);
                if (taskView.getTask().key.id != mRunningTaskId) {
                    mRecentsView.snapToPage(i, QUICK_SWITCH_SNAP_DURATION);
                    taskView.postDelayed(() -> {taskView.launchTask(true);},
                            QUICK_SWITCH_SNAP_DURATION);
                    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;
                }
            }
@@ -655,4 +684,24 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
            // TODO:
        }
    }

    private synchronized void debugNewState(int stateFlag) {
        if (!DEBUG_STATES) {
            return;
        }

        int state = mStateCallback.getState();
        StringJoiner currentStateStr = new StringJoiner(", ", "[", "]");
        String stateFlagStr = "Unknown-" + stateFlag;
        for (int i = 0; i < STATES.length; i++) {
            if ((state & (i << i)) != 0) {
                currentStateStr.add(STATES[i]);
            }
            if (stateFlag == (1 << i)) {
                stateFlagStr = STATES[i] + " (" + stateFlag + ")";
            }
        }
        Log.d(TAG, "[" + System.identityHashCode(this) + "] Adding " + stateFlagStr + " to "
                + currentStateStr);
    }
}
+17 −17
Original line number Diff line number Diff line
@@ -1622,7 +1622,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
        return (float) Math.sin(f);
    }

    protected void snapToPageWithVelocity(int whichPage, int velocity) {
    protected boolean snapToPageWithVelocity(int whichPage, int velocity) {
        whichPage = validateNewPage(whichPage);
        int halfScreenSize = getMeasuredWidth() / 2;

@@ -1633,8 +1633,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
        if (Math.abs(velocity) < mMinFlingVelocity) {
            // If the velocity is low enough, then treat this more as an automatic page advance
            // as opposed to an apparent physical response to flinging
            snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
            return;
            return snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
        }

        // Here we compute a "distance" that will be used in the computation of the overall
@@ -1653,39 +1652,39 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
        // interpolator at zero, ie. 5. We use 4 to make it a little slower.
        duration = 4 * Math.round(1000 * Math.abs(distance / velocity));

        snapToPage(whichPage, delta, duration);
        return snapToPage(whichPage, delta, duration);
    }

    public void snapToPage(int whichPage) {
        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
    public boolean snapToPage(int whichPage) {
        return snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
    }

    public void snapToPageImmediately(int whichPage) {
        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true, null);
    public boolean snapToPageImmediately(int whichPage) {
        return snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true, null);
    }

    public void snapToPage(int whichPage, int duration) {
        snapToPage(whichPage, duration, false, null);
    public boolean snapToPage(int whichPage, int duration) {
        return snapToPage(whichPage, duration, false, null);
    }

    protected void snapToPage(int whichPage, int duration, TimeInterpolator interpolator) {
        snapToPage(whichPage, duration, false, interpolator);
    protected boolean snapToPage(int whichPage, int duration, TimeInterpolator interpolator) {
        return snapToPage(whichPage, duration, false, interpolator);
    }

    protected void snapToPage(int whichPage, int duration, boolean immediate,
    protected boolean snapToPage(int whichPage, int duration, boolean immediate,
            TimeInterpolator interpolator) {
        whichPage = validateNewPage(whichPage);

        int newX = getScrollForPage(whichPage);
        final int delta = newX - getUnboundedScrollX();
        snapToPage(whichPage, delta, duration, immediate, interpolator);
        return snapToPage(whichPage, delta, duration, immediate, interpolator);
    }

    protected void snapToPage(int whichPage, int delta, int duration) {
        snapToPage(whichPage, delta, duration, false, null);
    protected boolean snapToPage(int whichPage, int delta, int duration) {
        return snapToPage(whichPage, delta, duration, false, null);
    }

    protected void snapToPage(int whichPage, int delta, int duration, boolean immediate,
    protected boolean snapToPage(int whichPage, int delta, int duration, boolean immediate,
            TimeInterpolator interpolator) {
        whichPage = validateNewPage(whichPage);

@@ -1723,6 +1722,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
        }

        invalidate();
        return Math.abs(delta) > 0;
    }

    public void scrollLeft() {