diff options
author | Tony Wickham <twickham@google.com> | 2019-01-30 19:56:23 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-01-30 19:56:23 +0000 |
commit | 42dec18638fdfc602e8b22ba5aa0f5c8a9bf159a (patch) | |
tree | fdb910fa02bf6c7e00bbb3f6684cf19361225c00 | |
parent | c5e0fb94e2e3179287d9d2337f8f23dc72fb7aae (diff) | |
parent | 023f404a12245904aec96fb9158edfca51e45434 (diff) | |
download | android_packages_apps_Trebuchet-42dec18638fdfc602e8b22ba5aa0f5c8a9bf159a.tar.gz android_packages_apps_Trebuchet-42dec18638fdfc602e8b22ba5aa0f5c8a9bf159a.tar.bz2 android_packages_apps_Trebuchet-42dec18638fdfc602e8b22ba5aa0f5c8a9bf159a.zip |
Merge "Make quick switch ("hook") more reliable" into ub-launcher3-master
7 files changed, 70 insertions, 27 deletions
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java index fb83cd32e..b37c2e09d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java @@ -57,7 +57,7 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController { @Override public boolean onDrag(float displacement) { - mMotionPauseDetector.addPosition(displacement); + mMotionPauseDetector.addPosition(displacement, 0); return super.onDrag(displacement); } diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 04fd59ce0..2626481c3 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -39,6 +39,7 @@ <dimen name="motion_pause_detector_speed_somewhat_fast">0.285dp</dimen> <dimen name="motion_pause_detector_speed_fast">0.5dp</dimen> <dimen name="motion_pause_detector_min_displacement">48dp</dimen> + <dimen name="motion_pause_detector_max_orthogonal_displacement">48dp</dimen> <!-- Launcher app transition --> <dimen name="content_trans_y">50dp</dimen> diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java index 5755205ea..a7f5f0b93 100644 --- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java +++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java @@ -201,7 +201,11 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC dispatchMotion(ev, displacement - mStartDisplacement, null); if (FeatureFlags.SWIPE_HOME.get()) { - mMotionPauseDetector.addPosition(displacement); + boolean isLandscape = isNavBarOnLeft() || isNavBarOnRight(); + float orthogonalDisplacement = !isLandscape + ? ev.getX() - mDownPos.x + : ev.getY() - mDownPos.y; + mMotionPauseDetector.addPosition(displacement, orthogonalDisplacement); } } break; diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java index 86a8081be..a99fc0f91 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -478,6 +478,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, (applier) -> { mSyncTransactionApplier = applier; }); + mRecentsView.setEnableFreeScroll(false); mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { if (!mBgLongSwipeMode && !mIsGoingToHome) { updateFinalShift(); @@ -910,7 +911,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { Interpolator interpolator = DEACCEL; final int nextPage = mRecentsView != null ? mRecentsView.getNextPage() : -1; final int runningTaskIndex = mRecentsView != null ? mRecentsView.getRunningTaskIndex() : -1; - boolean goingToNewTask = mRecentsView != null && nextPage != runningTaskIndex; + boolean goingToNewTask = mRecentsView != null && nextPage != runningTaskIndex + && mRecentsView.getTaskViewAt(nextPage) != null; final boolean reachedOverviewThreshold = currentShift >= MIN_PROGRESS_FOR_OVERVIEW; if (!isFling) { if (SWIPE_HOME.get()) { @@ -922,7 +924,11 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { endTarget = currentShift < MIN_PROGRESS_FOR_OVERVIEW ? LAST_TASK : HOME; } } else { - endTarget = reachedOverviewThreshold && mGestureStarted ? RECENTS : LAST_TASK; + endTarget = reachedOverviewThreshold && mGestureStarted + ? RECENTS + : goingToNewTask + ? NEW_TASK + : LAST_TASK; } endShift = endTarget.endShift; long expectedDuration = Math.abs(Math.round((endShift - currentShift) @@ -932,7 +938,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { interpolator = endTarget == RECENTS ? OVERSHOOT_1_2 : DEACCEL; } else { if (SWIPE_HOME.get() && endVelocity < 0 && !mIsShelfPeeking) { - endTarget = HOME; + // If swiping at a diagonal, base end target on the faster velocity. + endTarget = goingToNewTask && Math.abs(velocityX) > Math.abs(endVelocity) + ? NEW_TASK : HOME; } else if (endVelocity < 0 && (!goingToNewTask || reachedOverviewThreshold)) { // If user scrolled to a new task, only go to recents if they already passed // the overview threshold. Otherwise, we'll snap to the new task and launch it. @@ -970,27 +978,21 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { duration = Math.max(MIN_OVERSHOOT_DURATION, duration); } else if (endTarget == RECENTS) { mRecentsAnimationWrapper.enableTouchProxy(); + if (mRecentsView != null) { + duration = Math.max(duration, mRecentsView.getScroller().getDuration()); + } if (SWIPE_HOME.get()) { setShelfState(ShelfAnimState.OVERVIEW, interpolator, duration); } } else if (endTarget == NEW_TASK) { - // We aren't goingToRecents, and user scrolled/flung to a new task; snap to the closest - // task in that direction and launch it (in startNewTask()). - int taskToLaunch = runningTaskIndex + (nextPage > runningTaskIndex ? 1 : -1); - if (taskToLaunch >= mRecentsView.getTaskViewCount()) { + // Let RecentsView handle the scrolling to the task, which we launch in startNewTask(). + if (mRecentsView != null) { + duration = Math.max(duration, mRecentsView.getScroller().getDuration()); + } + } else if (endTarget == LAST_TASK) { + if (mRecentsView != null && nextPage != runningTaskIndex) { // Scrolled to Clear all button, snap back to current task and resume it. mRecentsView.snapToPage(runningTaskIndex, Math.toIntExact(duration)); - goingToNewTask = false; - } else { - float distance = Math.abs(mRecentsView.getScrollForPage(taskToLaunch) - - mRecentsView.getScrollX()); - int durationX = (int) Math.abs(distance / velocityXPxPerMs); - if (durationX > MAX_SWIPE_DURATION) { - durationX = Math.toIntExact(MAX_SWIPE_DURATION); - } - interpolator = Interpolators.scrollInterpolatorForVelocity(velocityXPxPerMs); - mRecentsView.snapToPage(taskToLaunch, durationX, interpolator); - duration = Math.max(duration, durationX); } } animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocityPxPerMs); @@ -1195,6 +1197,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { mLayoutListener.finish(); mActivityControlHelper.getAlphaProperty(mActivity).setValue(1); + mRecentsView.setEnableFreeScroll(true); mRecentsView.setRunningTaskIconScaledDown(false); mRecentsView.setOnScrollChangeListener(null); mQuickScrubController.cancelActiveQuickscrub(); diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java index 7969eec7c..1156b87b3 100644 --- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java +++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java @@ -36,12 +36,15 @@ public class MotionPauseDetector { private final float mSpeedSomewhatFast; private final float mSpeedFast; private final float mMinDisplacementForPause; + private final float mMaxOrthogonalDisplacementForPause; private Long mPreviousTime = null; private Float mPreviousPosition = null; private Float mPreviousVelocity = null; + private TotalDisplacement mTotalDisplacement = new TotalDisplacement(); private Float mFirstPosition = null; + private Float mFirstOrthogonalPosition = null; private OnMotionPauseListener mOnMotionPauseListener; private boolean mIsPaused; @@ -54,6 +57,8 @@ public class MotionPauseDetector { mSpeedSomewhatFast = res.getDimension(R.dimen.motion_pause_detector_speed_somewhat_fast); mSpeedFast = res.getDimension(R.dimen.motion_pause_detector_speed_fast); mMinDisplacementForPause = res.getDimension(R.dimen.motion_pause_detector_min_displacement); + mMaxOrthogonalDisplacementForPause = res.getDimension( + R.dimen.motion_pause_detector_max_orthogonal_displacement); } /** @@ -70,20 +75,26 @@ public class MotionPauseDetector { /** * Computes velocity and acceleration to determine whether the motion is paused. * @param position The x or y component of the motion being tracked. + * @param orthogonalPosition The x or y component (opposite of {@param position}) of the motion. * * TODO: Use historical positions as well, e.g. {@link MotionEvent#getHistoricalY(int, int)}. */ - public void addPosition(float position) { + public void addPosition(float position, float orthogonalPosition) { if (mFirstPosition == null) { mFirstPosition = position; } + if (mFirstOrthogonalPosition == null) { + mFirstOrthogonalPosition = orthogonalPosition; + } long time = SystemClock.uptimeMillis(); if (mPreviousTime != null && mPreviousPosition != null) { long changeInTime = Math.max(1, time - mPreviousTime); float changeInPosition = position - mPreviousPosition; float velocity = changeInPosition / changeInTime; if (mPreviousVelocity != null) { - checkMotionPaused(velocity, mPreviousVelocity, Math.abs(position - mFirstPosition)); + mTotalDisplacement.set(Math.abs(position - mFirstPosition), + Math.abs(orthogonalPosition - mFirstOrthogonalPosition)); + checkMotionPaused(velocity, mPreviousVelocity, mTotalDisplacement); } mPreviousVelocity = velocity; } @@ -91,7 +102,8 @@ public class MotionPauseDetector { mPreviousPosition = position; } - private void checkMotionPaused(float velocity, float prevVelocity, float totalDisplacement) { + private void checkMotionPaused(float velocity, float prevVelocity, + TotalDisplacement totalDisplacement) { float speed = Math.abs(velocity); float previousSpeed = Math.abs(prevVelocity); boolean isPaused; @@ -113,8 +125,10 @@ public class MotionPauseDetector { } } } - boolean passedMinDisplacement = totalDisplacement >= mMinDisplacementForPause; - isPaused &= passedMinDisplacement; + boolean passedMinDisplacement = totalDisplacement.primary >= mMinDisplacementForPause; + boolean passedMaxOrthogonalDisplacement = + totalDisplacement.orthogonal >= mMaxOrthogonalDisplacementForPause; + isPaused &= passedMinDisplacement && !passedMaxOrthogonalDisplacement; if (mIsPaused != isPaused) { mIsPaused = isPaused; if (mIsPaused) { @@ -131,6 +145,8 @@ public class MotionPauseDetector { mPreviousPosition = null; mPreviousVelocity = null; mFirstPosition = null; + mFirstOrthogonalPosition = null; + mTotalDisplacement.set(0, 0); setOnMotionPauseListener(null); mIsPaused = mHasEverBeenPaused = false; } @@ -142,4 +158,18 @@ public class MotionPauseDetector { public interface OnMotionPauseListener { void onMotionPauseChanged(boolean isPaused); } + + /** + * Contains the displacement from the first tracked position, + * along both the primary and orthogonal axes. + */ + private class TotalDisplacement { + public float primary; + public float orthogonal; + + public void set(float primaryDisplacement, float orthogonalDisplacement) { + this.primary = primaryDisplacement; + this.orthogonal = orthogonalDisplacement; + } + } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index c6f293d2b..5b84d2327 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -83,6 +83,7 @@ import com.android.launcher3.anim.SpringObjectAnimator; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; +import com.android.launcher3.util.OverScroller; import com.android.launcher3.util.PendingAnimation; import com.android.launcher3.util.Themes; import com.android.launcher3.util.ViewPool; @@ -339,6 +340,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl updateEmptyMessage(); } + public OverScroller getScroller() { + return mScroller; + } + public boolean isRtl() { return mIsRtl; } @@ -412,7 +417,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl public TaskView getTaskView(int taskId) { for (int i = 0; i < getTaskViewCount(); i++) { TaskView tv = (TaskView) getChildAt(i); - if (tv.getTask().key != null && tv.getTask().key.id == taskId) { + if (tv.getTask() != null && tv.getTask().key != null && tv.getTask().key.id == taskId) { return tv; } } diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 8f9e7c821..018ec5f17 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -1053,7 +1053,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou } - protected void setEnableFreeScroll(boolean freeScroll) { + public void setEnableFreeScroll(boolean freeScroll) { boolean wasFreeScroll = mFreeScroll; mFreeScroll = freeScroll; |