summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2019-04-26 00:10:34 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-04-26 00:10:34 +0000
commit0cc53e7f6a37cd69aefe2d1b1c093f5465d84029 (patch)
treeee9edc3d9970723b6bc47b8daeaba1131d6c5131
parent529bff9a66428ac263096d59d80b280a7d818c03 (diff)
parent5c13972e11e5eae185b141e61749415551f4857d (diff)
downloadandroid_packages_apps_Trebuchet-0cc53e7f6a37cd69aefe2d1b1c093f5465d84029.tar.gz
android_packages_apps_Trebuchet-0cc53e7f6a37cd69aefe2d1b1c093f5465d84029.tar.bz2
android_packages_apps_Trebuchet-0cc53e7f6a37cd69aefe2d1b1c093f5465d84029.zip
Merge "Decouple recents view from window while swiping up" into ub-launcher3-qt-dev
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java27
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java1
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java93
-rw-r--r--quickstep/src/com/android/quickstep/ActivityControlHelper.java15
4 files changed, 123 insertions, 13 deletions
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 35783b58a..a033402ff 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -16,14 +16,15 @@
package com.android.quickstep;
import static android.view.View.TRANSLATION_Y;
-
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_DAMPING_RATIO;
import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_STIFFNESS;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.WindowTransformSwipeHandler.RECENTS_ATTACH_DURATION;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -177,6 +178,8 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
return new AnimationFactory() {
private Animator mShelfAnim;
private ShelfAnimState mShelfState;
+ private Animator mAttachToWindowAnim;
+ private boolean mIsAttachedToWindow;
@Override
public void createActivityController(long transitionLength) {
@@ -221,6 +224,28 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
mShelfAnim.setDuration(duration);
mShelfAnim.start();
}
+
+ @Override
+ public void setRecentsAttachedToAppWindow(boolean attached, boolean animate) {
+ if (mIsAttachedToWindow == attached && animate) {
+ return;
+ }
+ mIsAttachedToWindow = attached;
+ if (mAttachToWindowAnim != null) {
+ mAttachToWindowAnim.cancel();
+ }
+ mAttachToWindowAnim = ObjectAnimator.ofFloat(activity.getOverviewPanel(),
+ RecentsView.CONTENT_ALPHA, attached ? 1 : 0);
+ mAttachToWindowAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAttachToWindowAnim = null;
+ }
+ });
+ mAttachToWindowAnim.setInterpolator(ACCEL_DEACCEL);
+ mAttachToWindowAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0);
+ mAttachToWindowAnim.start();
+ }
};
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
index bb320f2c5..5dc641fbe 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
@@ -267,6 +267,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
mMotionPauseDetector.setDisallowPause(upDist < mMotionPauseMinDisplacement
|| isLikelyToStartNewTask);
mMotionPauseDetector.addPosition(displacement, ev.getEventTime());
+ mInteractionHandler.setIsLikelyToStartNewTask(isLikelyToStartNewTask);
}
}
break;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 7ffd8d735..afc4fcb59 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -43,6 +43,7 @@ import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
@@ -111,6 +112,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
implements SwipeAnimationListener, OnApplyWindowInsetsListener {
private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
+ private static final Rect TEMP_RECT = new Rect();
+
private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null;
private static int getFlagForIndex(int index, String name) {
@@ -162,22 +165,23 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED;
enum GestureEndTarget {
- HOME(1, STATE_SCALED_CONTROLLER_HOME, true, false, ContainerType.WORKSPACE),
+ HOME(1, STATE_SCALED_CONTROLLER_HOME, true, false, ContainerType.WORKSPACE, false),
RECENTS(1, STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT
- | STATE_SCREENSHOT_VIEW_SHOWN, true, false, ContainerType.TASKSWITCHER),
+ | STATE_SCREENSHOT_VIEW_SHOWN, true, false, ContainerType.TASKSWITCHER, true),
- NEW_TASK(0, STATE_START_NEW_TASK, false, true, ContainerType.APP),
+ NEW_TASK(0, STATE_START_NEW_TASK, false, true, ContainerType.APP, true),
- LAST_TASK(0, STATE_RESUME_LAST_TASK, false, true, ContainerType.APP);
+ LAST_TASK(0, STATE_RESUME_LAST_TASK, false, true, ContainerType.APP, false);
GestureEndTarget(float endShift, int endState, boolean isLauncher, boolean canBeContinued,
- int containerType) {
+ int containerType, boolean recentsAttachedToAppWindow) {
this.endShift = endShift;
this.endState = endState;
this.isLauncher = isLauncher;
this.canBeContinued = canBeContinued;
this.containerType = containerType;
+ this.recentsAttachedToAppWindow = recentsAttachedToAppWindow;
}
/** 0 is app, 1 is overview */
@@ -190,6 +194,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
public final boolean canBeContinued;
/** Used to log where the user ended up after the gesture ends */
public final int containerType;
+ /** Whether RecentsView should be attached to the window as we animate to this target */
+ public final boolean recentsAttachedToAppWindow;
}
public static final long MAX_SWIPE_DURATION = 350;
@@ -202,6 +208,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
private static final String SCREENSHOT_CAPTURED_EVT = "ScreenshotCaptured";
private static final long SHELF_ANIM_DURATION = 120;
+ public static final long RECENTS_ATTACH_DURATION = 300;
/**
* Used as the page index for logging when we return to the last task at the end of the gesture.
@@ -254,6 +261,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
private int mLogAction = Touch.SWIPE;
private int mLogDirection = Direction.UP;
private PointF mDownPos;
+ private boolean mIsLikelyToStartNewTask;
private final RecentsAnimationWrapper mRecentsAnimationWrapper;
@@ -437,6 +445,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
mAnimationFactory = mActivityControlHelper.prepareRecentsUI(mActivity,
mWasLauncherAlreadyVisible, true,
this::onAnimatorPlaybackControllerCreated);
+ maybeUpdateRecentsAttachedState(false /* animate */);
};
if (mWasLauncherAlreadyVisible) {
// Launcher is visible, but might be about to stop. Thus, if we prepare recents
@@ -541,10 +550,65 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
setShelfState(isPaused ? PEEK : HIDE, FAST_OUT_SLOW_IN, SHELF_ANIM_DURATION);
}
+ public void maybeUpdateRecentsAttachedState() {
+ maybeUpdateRecentsAttachedState(true /* animate */);
+ }
+
+ /**
+ * Determines whether to show or hide RecentsView. The window is always
+ * synchronized with its corresponding TaskView in RecentsView, so if
+ * RecentsView is shown, it will appear to be attached to the window.
+ *
+ * Note this method has no effect unless the navigation mode is NO_BUTTON.
+ */
+ private void maybeUpdateRecentsAttachedState(boolean animate) {
+ if (mMode != Mode.NO_BUTTON || mRecentsView == null) {
+ return;
+ }
+ RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationWrapper.targetSet == null
+ ? null
+ : mRecentsAnimationWrapper.targetSet.findTask(mRunningTaskId);
+ final boolean recentsAttachedToAppWindow;
+ int runningTaskIndex = mRecentsView.getRunningTaskIndex();
+ if (mContinuingLastGesture) {
+ recentsAttachedToAppWindow = true;
+ animate = false;
+ } else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) {
+ // The window is going away so make sure recents is always visible in this case.
+ recentsAttachedToAppWindow = true;
+ animate = false;
+ } else {
+ if (mGestureEndTarget != null) {
+ recentsAttachedToAppWindow = mGestureEndTarget.recentsAttachedToAppWindow;
+ } else {
+ recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask;
+ }
+ if (animate) {
+ // Only animate if an adjacent task view is visible on screen.
+ TaskView adjacentTask1 = mRecentsView.getTaskViewAt(runningTaskIndex + 1);
+ TaskView adjacentTask2 = mRecentsView.getTaskViewAt(runningTaskIndex - 1);
+ animate = (adjacentTask1 != null && adjacentTask1.getGlobalVisibleRect(TEMP_RECT))
+ || (adjacentTask2 != null && adjacentTask2.getGlobalVisibleRect(TEMP_RECT));
+ }
+ }
+ mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
+ }
+
+ public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
+ if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) {
+ mIsLikelyToStartNewTask = isLikelyToStartNewTask;
+ maybeUpdateRecentsAttachedState();
+ }
+ }
+
@UiThread
public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator, long duration) {
mAnimationFactory.setShelfState(shelfState, interpolator, duration);
+ boolean wasShelfPeeking = mIsShelfPeeking;
mIsShelfPeeking = shelfState == PEEK;
+ if (mIsShelfPeeking != wasShelfPeeking) {
+ maybeUpdateRecentsAttachedState();
+ }
if (mRecentsView != null && shelfState.shouldPreformHaptic) {
mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
@@ -872,6 +936,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
mGestureEndTarget = target;
+ maybeUpdateRecentsAttachedState();
+
if (mGestureEndTarget == HOME) {
HomeAnimationFactory homeAnimFactory;
if (mActivity != null) {
@@ -905,8 +971,15 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
windowAnim.start(velocityPxPerMs);
mLauncherTransitionController = null;
} else {
- Animator windowAnim = mCurrentShift.animateToValue(start, end);
+ ValueAnimator windowAnim = mCurrentShift.animateToValue(start, end);
windowAnim.setDuration(duration).setInterpolator(interpolator);
+ windowAnim.addUpdateListener(valueAnimator -> {
+ if (mRecentsView != null && mRecentsView.getVisibility() != View.VISIBLE) {
+ // Views typically don't compute scroll when invisible as an optimization,
+ // but in our case we need to since the window offset depends on the scroll.
+ mRecentsView.computeScroll();
+ }
+ });
windowAnim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
@@ -1180,10 +1253,14 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
}
public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, Float expectedAlpha) {
- if (!(app.isNotInRecents
- || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME)) {
+ if (!isNotInRecents(app)) {
return 0;
}
return expectedAlpha;
}
+
+ private static boolean isNotInRecents(RemoteAnimationTargetCompat app) {
+ return app.isNotInRecents
+ || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index a71b7bb85..17f88c980 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -27,6 +27,10 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -37,10 +41,6 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
/**
* Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
*/
@@ -122,6 +122,13 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
default void setShelfState(ShelfAnimState animState, Interpolator interpolator,
long duration) { }
+
+ /**
+ * @param attached Whether to show RecentsView alongside the app window. If false, recents
+ * will be hidden by some property we can animate, e.g. alpha.
+ * @param animate Whether to animate recents to/from its new attached state.
+ */
+ default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { }
}
interface HomeAnimationFactory {