summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2019-01-29 10:52:31 -0800
committerTony Wickham <twickham@google.com>2019-01-29 17:11:12 -0800
commit023f404a12245904aec96fb9158edfca51e45434 (patch)
tree99012869e2217d1d04acd93ce868d7183de1084b
parenteefa08b8be3d146d2fbb972a7e77d5b57ec83100 (diff)
downloadandroid_packages_apps_Trebuchet-023f404a12245904aec96fb9158edfca51e45434.tar.gz
android_packages_apps_Trebuchet-023f404a12245904aec96fb9158edfca51e45434.tar.bz2
android_packages_apps_Trebuchet-023f404a12245904aec96fb9158edfca51e45434.zip
Make quick switch ("hook") more reliable
- Add max orthogonal displacement to MotionPauseDetector to avoid pausing when swiping left or right - When gesture in ambiguous between swipe up for home or swipe over for the new task, base the decision on the faster velocity component - Disable recents freescroll mode when dispatching motion from the nav bar. This way recents handles it naturally and we don't need custom logic to snap to the next page at the end of the gesture. - Fix a bug where you couldn't hook to start a new task when SWIPE_HOME was disabled Bug: 111926330 Change-Id: If63aa2bb32b57c3f401c5df8b3f6f4efec97b1fa
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java2
-rw-r--r--quickstep/res/values/dimens.xml1
-rw-r--r--quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java6
-rw-r--r--quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java39
-rw-r--r--quickstep/src/com/android/quickstep/util/MotionPauseDetector.java40
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsView.java7
-rw-r--r--src/com/android/launcher3/PagedView.java2
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;