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
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index 61684e0..7f9d3a1 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -32,6 +32,7 @@
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 @@
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 @@
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);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java
index 26fe54e..6b1f3d3 100644
--- a/quickstep/src/com/android/quickstep/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/RecentsView.java
@@ -75,6 +75,7 @@
private boolean mOverviewStateEnabled;
private boolean mTaskStackListenerRegistered;
private LayoutTransition mLayoutTransition;
+ private Runnable mNextPageSwitchRunnable;
/**
* TODO: Call reloadIdNeeded in onTaskStackChanged.
@@ -243,6 +244,19 @@
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;
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 17f0482..dd0892b 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -41,6 +41,7 @@
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.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 @@
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 @@
}
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 @@
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 @@
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 @@
// 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);
+ }
}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 0ebae81..bb137b0 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1622,7 +1622,7 @@
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 @@
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 @@
// 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 @@
}
invalidate();
+ return Math.abs(delta) > 0;
}
public void scrollLeft() {