Merge "Set remote animations duration based on animation being run" into ub-launcher3-master
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 6fc1447..3b75001 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -32,6 +32,7 @@
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityOptions;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@@ -60,6 +61,7 @@
import com.android.quickstep.RecentsAnimationInterpolator.TaskWindowBounds;
import com.android.quickstep.RecentsView;
import com.android.quickstep.TaskView;
+import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityCompat;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
@@ -79,10 +81,14 @@
private static final String TAG = "LauncherTransition";
private static final int REFRESH_RATE_MS = 16;
+ private static final int STATUS_BAR_TRANSITION_DURATION = 120;
private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
"android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
+ private static final int APP_LAUNCH_DURATION = 500;
+ // Use a shorter duration for x or y translation to create a curve effect
+ private static final int APP_LAUNCH_CURVED_DURATION = 233;
private static final int RECENTS_LAUNCH_DURATION = 336;
private static final int LAUNCHER_RESUME_START_DELAY = 100;
private static final int CLOSING_TRANSITION_DURATION_MS = 350;
@@ -156,6 +162,7 @@
@Override
public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) {
if (hasControlRemoteAppTransitionPermission()) {
+ TaskView taskView = findTaskViewToLaunch(launcher, v);
try {
RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mLauncher) {
@Override
@@ -165,8 +172,8 @@
// processed before the next frame.
postAtFrontOfQueueAsynchronously(v.getHandler(), () -> {
final boolean removeTrackingView;
- LauncherTransitionAnimator animator =
- composeRecentsLaunchAnimator(v, targets);
+ LauncherTransitionAnimator animator = composeRecentsLaunchAnimator(
+ taskView == null ? v : taskView, targets);
if (animator != null) {
// We are animating the task view directly, do not remove it after
removeTrackingView = false;
@@ -206,8 +213,10 @@
}
};
- return ActivityOptionsCompat.makeRemoteAnimation(
- new RemoteAnimationAdapterCompat(runner, 500, 380));
+ int duration = taskView != null ? RECENTS_LAUNCH_DURATION : APP_LAUNCH_DURATION;
+ int statusBarTransitionDelay = duration - STATUS_BAR_TRANSITION_DURATION;
+ return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
+ runner, duration, statusBarTransitionDelay));
} catch (NoClassDefFoundError e) {
// Gracefully fall back to default launch options if the user's platform doesn't
// have the latest changes.
@@ -217,10 +226,56 @@
}
/**
+ * Try to find a TaskView that corresponds with the component of the launched view.
+ *
+ * If this method returns a non-null TaskView, it will be used in composeRecentsLaunchAnimation.
+ * Otherwise, we will assume we are using a normal app transition, but it's possible that the
+ * opening remote target (which we don't get until onAnimationStart) will resolve to a TaskView.
+ */
+ private TaskView findTaskViewToLaunch(Launcher launcher, View v) {
+ if (v instanceof TaskView) {
+ return (TaskView) v;
+ }
+ if (!launcher.isInState(LauncherState.OVERVIEW)) {
+ return null;
+ }
+ if (v.getTag() instanceof ItemInfo) {
+ ItemInfo itemInfo = (ItemInfo) v.getTag();
+ ComponentName componentName = itemInfo.getTargetComponent();
+ if (componentName != null) {
+ RecentsView recentsView = launcher.getOverviewPanel();
+ for (int i = 0; i < recentsView.getChildCount(); i++) {
+ TaskView taskView = (TaskView) recentsView.getPageAt(i);
+ if (recentsView.isTaskViewVisible(taskView)) {
+ Task task = taskView.getTask();
+ if (componentName.equals(task.key.getComponent())) {
+ return taskView;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
* Composes the animations for a launch from the recents list if possible.
*/
private LauncherTransitionAnimator composeRecentsLaunchAnimator(View v,
RemoteAnimationTargetCompat[] targets) {
+ RecentsView recentsView = mLauncher.getOverviewPanel();
+ boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
+ MutableBoolean skipLauncherChanges = new MutableBoolean(!launcherClosing);
+ if (v instanceof TaskView) {
+ // We already found a task view to launch, so use that for the animation.
+ TaskView taskView = (TaskView) v;
+ return new LauncherTransitionAnimator(getRecentsLauncherAnimator(recentsView, taskView),
+ getRecentsWindowAnimator(taskView, skipLauncherChanges, targets));
+ }
+
+ // It's possible that the launched view can still be resolved to a visible task view, check
+ // the task id of the opening task and see if we can find a match.
+
// Ensure recents is actually visible
if (!mLauncher.getStateManager().getState().overviewUi) {
return null;
@@ -242,7 +297,6 @@
// If the opening task id is not currently visible in overview, then fall back to normal app
// icon launch animation
- RecentsView recentsView = mLauncher.getOverviewPanel();
TaskView taskView = recentsView.getTaskView(openingTaskId);
if (taskView == null || !recentsView.isTaskViewVisible(taskView)) {
return null;
@@ -251,7 +305,6 @@
// Found a visible recents task that matches the opening app, lets launch the app from there
Animator launcherAnim;
AnimatorListenerAdapter windowAnimEndListener;
- boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
if (launcherClosing) {
launcherAnim = getRecentsLauncherAnimator(recentsView, taskView);
windowAnimEndListener = new AnimatorListenerAdapter() {
@@ -275,7 +328,6 @@
};
}
- MutableBoolean skipLauncherChanges = new MutableBoolean(!launcherClosing);
Animator windowAnim = getRecentsWindowAnimator(taskView, skipLauncherChanges, targets);
windowAnim.addListener(windowAnimEndListener);
return new LauncherTransitionAnimator(launcherAnim, windowAnim, skipLauncherChanges);
@@ -587,8 +639,8 @@
// Adjust the duration to change the "curve" of the app icon to the center.
boolean isBelowCenterY = lp.topMargin < centerY;
- x.setDuration(isBelowCenterY ? 500 : 233);
- y.setDuration(isBelowCenterY ? 233 : 500);
+ x.setDuration(isBelowCenterY ? APP_LAUNCH_DURATION : APP_LAUNCH_CURVED_DURATION);
+ y.setDuration(isBelowCenterY ? APP_LAUNCH_CURVED_DURATION : APP_LAUNCH_DURATION);
x.setInterpolator(Interpolators.AGGRESSIVE_EASE);
y.setInterpolator(Interpolators.AGGRESSIVE_EASE);
appIconAnimatorSet.play(x);
@@ -601,7 +653,7 @@
float scale = Math.max(maxScaleX, maxScaleY);
ObjectAnimator scaleAnim = ObjectAnimator
.ofFloat(mFloatingView, SCALE_PROPERTY, startScale, scale);
- scaleAnim.setDuration(500).setInterpolator(Interpolators.EXAGGERATED_EASE);
+ scaleAnim.setDuration(APP_LAUNCH_DURATION).setInterpolator(Interpolators.EXAGGERATED_EASE);
appIconAnimatorSet.play(scaleAnim);
// Fade out the app icon.
@@ -636,7 +688,7 @@
Matrix matrix = new Matrix();
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
- appAnimator.setDuration(500);
+ appAnimator.setDuration(APP_LAUNCH_DURATION);
appAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
boolean isFirstFrame = true;