From 005df0ba69e38aa94a9f55eb43819a426c0cd3cc Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 13 Feb 2018 11:28:12 -0800 Subject: [PATCH] Animate launcher when launching recent tasks - Scale up adjacent recent tasks and translate away from center - Workspace card instead recenters in the screen - Translate hotseat offscreen Clicking on one of the adjacent tasks will scale it up to the center of the screen while the center and other adjacent task parallax to the right beneath it. Change-Id: If96eec987c100458b8444a6cd698ec7bf6e6ba6b --- quickstep/res/values/dimens.xml | 3 + .../LauncherAppTransitionManagerImpl.java | 133 ++++++++++++++++-- .../RecentsViewStateController.java | 7 + .../RecentsAnimationInterpolator.java | 24 ++-- .../com/android/quickstep/RecentsView.java | 14 +- .../src/com/android/quickstep/TaskView.java | 37 ++--- .../WindowTransformSwipeHandler.java | 8 +- src/com/android/launcher3/Launcher.java | 12 +- .../LauncherAppTransitionManager.java | 15 +- .../launcher3/popup/SystemShortcut.java | 2 +- .../launcher3/uioverrides/OverviewPanel.java | 2 +- 11 files changed, 184 insertions(+), 73 deletions(-) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index d8504f19bc..0956048429 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -37,4 +37,7 @@ 25dp 80dp + 120dp + 80dp + 150% diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index adea1f2477..8f498d27fe 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -16,6 +16,7 @@ package com.android.launcher3; +import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS; import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber; import static com.android.systemui.shared.recents.utilities.Utilities.getSurface; @@ -28,13 +29,13 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.TargetApi; +import android.app.ActivityOptions; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Matrix; import android.graphics.Rect; import android.os.Build; -import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Surface; @@ -46,6 +47,7 @@ import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.InsettableFrameLayout.LayoutParams; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.anim.PropertyListBuilder; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.graphics.DrawableFactory; import com.android.quickstep.RecentsAnimationInterpolator; @@ -80,8 +82,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag private static final int CLOSING_TRANSITION_DURATION_MS = 350; // Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down. - private static final float ALL_APPS_PROGRESS_START = 1.3059858f; - private static final float ALL_APPS_PROGRESS_SLIDE_END = 0.99581414f; + private static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f; + private static final float ALL_APPS_PROGRESS_OVERSHOOT = 0.99581414f; private final DragLayer mDragLayer; private final Launcher mLauncher; @@ -89,6 +91,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag private final float mContentTransY; private final float mWorkspaceTransY; + private final float mRecentsTransX; + private final float mRecentsTransY; + private final float mRecentsScale; private View mFloatingView; private boolean mIsRtl; @@ -105,6 +110,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag Resources res = mLauncher.getResources(); mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y); mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y); + mRecentsTransX = res.getDimensionPixelSize(R.dimen.recents_adjacent_trans_x); + mRecentsTransY = res.getDimensionPixelSize(R.dimen.recents_adjacent_trans_y); + mRecentsScale = res.getFraction(R.fraction.recents_adjacent_scale, 1, 1); mLauncher.addOnDeviceProfileChangeListener(this); registerRemoteAnimations(); @@ -116,7 +124,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag } private void setCurrentAnimator(LauncherTransitionAnimator animator) { - if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) { + if (isAnimating()) { mCurrentAnimator.cancel(); } mCurrentAnimator = animator; @@ -124,18 +132,23 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag @Override public void finishLauncherAnimation() { - if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) { + if (isAnimating()) { mCurrentAnimator.finishLauncherAnimation(); } mCurrentAnimator = null; } + @Override + public boolean isAnimating() { + return mCurrentAnimator != null && mCurrentAnimator.isRunning(); + } + /** - * @return A Bundle with remote animations that controls how the window of the opening + * @return ActivityOptions with remote animations that controls how the window of the opening * targets are displayed. */ @Override - public Bundle getActivityLaunchOptions(Launcher launcher, View v) { + public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) { if (hasControlRemoteAppTransitionPermission()) { try { RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mLauncher) { @@ -188,7 +201,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag }; return ActivityOptionsCompat.makeRemoteAnimation( - new RemoteAnimationAdapterCompat(runner, 500, 380)).toBundle(); + new RemoteAnimationAdapterCompat(runner, 500, 380)); } catch (NoClassDefFoundError e) { // Gracefully fall back to default launch options if the user's platform doesn't // have the latest changes. @@ -230,7 +243,93 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag } // Found a visible recents task that matches the opening app, lets launch the app from there - return new LauncherTransitionAnimator(null, getRecentsWindowAnimator(taskView, targets)); + return new LauncherTransitionAnimator(getRecentsLauncherAnimator(recentsView, taskView), + getRecentsWindowAnimator(taskView, targets)); + } + + /** + * Animate adjacent tasks off screen while scaling up, and translate hotseat off screen as well. + * + * If launching one of the adjacent tasks, parallax the center task and other adjacent task + * to the right. + */ + private Animator getRecentsLauncherAnimator(RecentsView recentsView, TaskView v) { + AnimatorSet launcherAnimator = new AnimatorSet(); + + int launchedTaskIndex = recentsView.indexOfChild(v); + int centerTaskIndex = recentsView.getCurrentPage(); + boolean launchingCenterTask = launchedTaskIndex == centerTaskIndex; + if (launchingCenterTask) { + if (launchedTaskIndex - 1 >= recentsView.getFirstTaskIndex()) { + TaskView adjacentPage1 = (TaskView) recentsView.getPageAt(launchedTaskIndex - 1); + ObjectAnimator adjacentTask1ScaleAndTranslate = + LauncherAnimUtils.ofPropertyValuesHolder(adjacentPage1, + new PropertyListBuilder() + .scale(adjacentPage1.getScaleX() * mRecentsScale) + .translationY(mRecentsTransY) + .translationX(mIsRtl ? mRecentsTransX : -mRecentsTransX) + .build()); + launcherAnimator.play(adjacentTask1ScaleAndTranslate); + } + if (launchedTaskIndex + 1 < recentsView.getPageCount()) { + TaskView adjacentTask2 = (TaskView) recentsView.getPageAt(launchedTaskIndex + 1); + ObjectAnimator adjacentTask2ScaleAndTranslate = + LauncherAnimUtils.ofPropertyValuesHolder(adjacentTask2, + new PropertyListBuilder() + .scale(adjacentTask2.getScaleX() * mRecentsScale) + .translationY(mRecentsTransY) + .translationX(mIsRtl ? -mRecentsTransX : mRecentsTransX) + .build()); + launcherAnimator.play(adjacentTask2ScaleAndTranslate); + } + } else if (centerTaskIndex >= recentsView.getFirstTaskIndex()) { + // We are launching an adjacent task, so parallax the center and other adjacent task. + TaskView centerTask = (TaskView) recentsView.getPageAt(centerTaskIndex); + float translationX = Math.abs(v.getTranslationX()); + ObjectAnimator centerTaskParallaxToRight = + LauncherAnimUtils.ofPropertyValuesHolder(centerTask, + new PropertyListBuilder() + .scale(v.getScaleX()) + .translationX(mIsRtl ? -translationX : translationX) + .build()); + launcherAnimator.play(centerTaskParallaxToRight); + int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - launchedTaskIndex); + if (otherAdjacentTaskIndex >= recentsView.getFirstTaskIndex() + && otherAdjacentTaskIndex < recentsView.getPageCount()) { + TaskView otherAdjacentTask = (TaskView) recentsView.getPageAt( + otherAdjacentTaskIndex); + ObjectAnimator otherAdjacentTaskParallaxToRight = + LauncherAnimUtils.ofPropertyValuesHolder(otherAdjacentTask, + new PropertyListBuilder() + .translationX(otherAdjacentTask.getTranslationX() + + (mIsRtl ? -translationX : translationX)) + .build()); + launcherAnimator.play(otherAdjacentTaskParallaxToRight); + } + } + + Animator allAppsSlideOut = ObjectAnimator.ofFloat(mLauncher.getAllAppsController(), + ALL_APPS_PROGRESS, ALL_APPS_PROGRESS_OFF_SCREEN); + launcherAnimator.play(allAppsSlideOut); + + Workspace workspace = mLauncher.getWorkspace(); + float[] workspaceScaleAndTranslation = LauncherState.NORMAL + .getWorkspaceScaleAndTranslation(mLauncher); + Animator recenterWorkspace = LauncherAnimUtils.ofPropertyValuesHolder( + workspace, new PropertyListBuilder() + .translationX(workspaceScaleAndTranslation[1]) + .translationY(workspaceScaleAndTranslation[2]) + .build()); + launcherAnimator.play(recenterWorkspace); + CellLayout currentWorkspacePage = (CellLayout) workspace.getPageAt( + workspace.getCurrentPage()); + Animator hideWorkspaceScrim = ObjectAnimator.ofInt( + currentWorkspacePage.getScrimBackground(), DRAWABLE_ALPHA, 0); + launcherAnimator.play(hideWorkspaceScrim); + + launcherAnimator.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR); + launcherAnimator.setDuration(RECENTS_LAUNCH_DURATION); + return launcherAnimator; } /** @@ -247,7 +346,10 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag RecentsAnimationInterpolator recentsInterpolator = new RecentsAnimationInterpolator( new Rect(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx), v.getThumbnail().getInsets(), - taskViewBounds, new Rect(0, v.getThumbnail().getTop(), 0, 0)); + taskViewBounds, + new Rect(0, v.getThumbnail().getTop(), 0, 0), + v.getScaleX(), + v.getTranslationX()); Rect crop = new Rect(); Matrix matrix = new Matrix(); @@ -310,6 +412,13 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag isFirstFrame = false; } }); + appAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + // Make sure recents gets fixed up by resetting task alphas and scales, etc. + mLauncher.getStateManager().reapplyState(); + } + }); return appAnimator; } @@ -708,9 +817,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag // Animate the shelf in two parts: slide in, and overeshoot. AllAppsTransitionController allAppsController = mLauncher.getAllAppsController(); // The shelf will start offscreen - final float startY = ALL_APPS_PROGRESS_START; + final float startY = ALL_APPS_PROGRESS_OFF_SCREEN; // And will end slightly pulled up, so that there is something to overshoot back to 1f. - final float slideEnd = ALL_APPS_PROGRESS_SLIDE_END; + final float slideEnd = ALL_APPS_PROGRESS_OVERSHOOT; allAppsController.setProgress(startY); diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 57e588bd39..7d371e96bf 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -34,6 +34,7 @@ import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.Interpolators; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.RecentsView; +import com.android.quickstep.TaskView; public class RecentsViewStateController implements StateHandler { @@ -62,6 +63,12 @@ public class RecentsViewStateController implements StateHandler { mWorkspaceCard.setWorkspaceScrollingEnabled(state == OVERVIEW); setVisibility(state == OVERVIEW); setTransitionProgress(state == OVERVIEW ? 1 : 0); + if (state == OVERVIEW) { + for (int i = mRecentsView.getFirstTaskIndex(); i < mRecentsView.getPageCount(); i++) { + ((TaskView) mRecentsView.getPageAt(i)).resetVisualProperties(); + } + mRecentsView.updateCurveProperties(); + } } @Override diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationInterpolator.java b/quickstep/src/com/android/quickstep/RecentsAnimationInterpolator.java index 9cc038f0ef..1f9c7281fe 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationInterpolator.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationInterpolator.java @@ -53,12 +53,15 @@ public class RecentsAnimationInterpolator { private Rect mTaskInsets; private Rect mThumbnail; - private float mTaskScale; + private float mInitialTaskScale; + private float mInitialTaskTranslationX; + private float mFinalTaskScale; private Rect mScaledTask; private Rect mTargetTask; private Rect mSrcWindow; - public RecentsAnimationInterpolator(Rect window, Rect insets, Rect task, Rect taskInsets) { + public RecentsAnimationInterpolator(Rect window, Rect insets, Rect task, Rect taskInsets, + float taskScale, float taskTranslationX) { mWindow = window; mInsets = insets; mTask = task; @@ -68,16 +71,18 @@ public class RecentsAnimationInterpolator { mThumbnail = new Rect(task); Utilities.insetRect(mThumbnail, taskInsets); - mTaskScale = (float) mInsetWindow.width() / mThumbnail.width(); + mInitialTaskScale = taskScale; + mInitialTaskTranslationX = taskTranslationX; + mFinalTaskScale = (float) mInsetWindow.width() / mThumbnail.width(); mScaledTask = new Rect(task); - Utilities.scaleRectAboutCenter(mScaledTask, mTaskScale); + Utilities.scaleRectAboutCenter(mScaledTask, mFinalTaskScale); Rect finalScaledTaskInsets = new Rect(taskInsets); - Utilities.scaleRect(finalScaledTaskInsets, mTaskScale); + Utilities.scaleRect(finalScaledTaskInsets, mFinalTaskScale); mTargetTask = new Rect(mInsetWindow); mTargetTask.offsetTo(window.top + insets.top - finalScaledTaskInsets.top, window.left + insets.left - finalScaledTaskInsets.left); - float initialWinScale = 1f / mTaskScale; + float initialWinScale = 1f / mFinalTaskScale; Rect scaledWindow = new Rect(mInsetWindow); Utilities.scaleRectAboutCenter(scaledWindow, initialWinScale); Rect scaledInsets = new Rect(insets); @@ -89,13 +94,14 @@ public class RecentsAnimationInterpolator { public TaskWindowBounds interpolate(float t) { mTmpTaskWindowBounds.taskScale = Utilities.mapRange(t, - 1, (float) mInsetWindow.width() / mThumbnail.width()); + mInitialTaskScale, mFinalTaskScale); mTmpTaskWindowBounds.taskX = Utilities.mapRange(t, - 0, mTargetTask.left - mScaledTask.left); + mInitialTaskTranslationX, mTargetTask.left - mScaledTask.left); mTmpTaskWindowBounds.taskY = Utilities.mapRange(t, 0, mTargetTask.top - mScaledTask.top); - mTmpTaskWindowBounds.winScale = mTmpTaskWindowBounds.taskScale / mTaskScale; + float taskScale = Utilities.mapRange(t, 1, mFinalTaskScale); + mTmpTaskWindowBounds.winScale = taskScale / mFinalTaskScale; mTmpTaskWindowBounds.winX = Utilities.mapRange(t, mSrcWindow.left, 0); mTmpTaskWindowBounds.winY = Utilities.mapRange(t, diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java index c8122d21ee..ec0716c49c 100644 --- a/quickstep/src/com/android/quickstep/RecentsView.java +++ b/quickstep/src/com/android/quickstep/RecentsView.java @@ -17,6 +17,7 @@ package com.android.quickstep; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.quickstep.TaskView.CURVE_FACTOR; import static com.android.quickstep.TaskView.CURVE_INTERPOLATOR; @@ -221,8 +222,8 @@ public class RecentsView extends PagedView implements Insettable { } public boolean isTaskViewVisible(TaskView tv) { - // For now, just check if it's the active task - return indexOfChild(tv) == getNextPage(); + // For now, just check if it's the active task or an adjacent task + return Math.abs(indexOfChild(tv) - getNextPage()) <= 1; } public TaskView getTaskView(int taskId) { @@ -294,13 +295,10 @@ public class RecentsView extends PagedView implements Insettable { final Task task = tasks.get(i); final TaskView taskView = (TaskView) getChildAt(tasks.size() - i - 1 + mFirstTaskIndex); taskView.bind(task); - taskView.setScaleX(1f); - taskView.setScaleY(1f); - taskView.setTranslationX(0f); - taskView.setTranslationY(0f); - taskView.setAlpha(1f); + taskView.resetVisualProperties(); loader.loadTaskData(task); } + updateCurveProperties(); applyIconScale(false /* animate */); if (oldChildCount != getChildCount()) { @@ -402,7 +400,7 @@ public class RecentsView extends PagedView implements Insettable { /** * Scales and adjusts translation of adjacent pages as if on a curved carousel. */ - private void updateCurveProperties() { + public void updateCurveProperties() { if (getPageCount() == 0 || getPageAt(0).getMeasuredWidth() == 0) { return; } diff --git a/quickstep/src/com/android/quickstep/TaskView.java b/quickstep/src/com/android/quickstep/TaskView.java index f21742aa59..b407f75ffa 100644 --- a/quickstep/src/com/android/quickstep/TaskView.java +++ b/quickstep/src/com/android/quickstep/TaskView.java @@ -24,7 +24,6 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.res.Resources; import android.graphics.Outline; -import android.graphics.Rect; import android.os.Handler; import android.util.AttributeSet; import android.view.View; @@ -32,19 +31,15 @@ import android.view.ViewOutlineProvider; import android.widget.FrameLayout; import android.widget.ImageView; +import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.quickstep.RecentsView.PageCallbacks; import com.android.quickstep.RecentsView.ScrollState; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.Task.TaskCallbacks; import com.android.systemui.shared.recents.model.ThumbnailData; -import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat; -import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture; -import com.android.systemui.shared.recents.view.RecentsTransition; import com.android.systemui.shared.system.ActivityManagerWrapper; -import java.util.ArrayList; -import java.util.List; import java.util.function.Consumer; /** @@ -120,26 +115,7 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback if (mTask != null) { final ActivityOptions opts; if (animate) { - // Calculate the bounds of the thumbnail to animate from - final Rect bounds = new Rect(); - final int[] pos = new int[2]; - mSnapshotView.getLocationInWindow(pos); - bounds.set(pos[0], pos[1], - pos[0] + mSnapshotView.getWidth(), - pos[1] + mSnapshotView.getHeight()); - AppTransitionAnimationSpecsFuture animFuture = - new AppTransitionAnimationSpecsFuture(getHandler()) { - @Override - public List composeSpecs() { - ArrayList specs = - new ArrayList<>(); - specs.add(new AppTransitionAnimationSpecCompat(mTask.key.id, null, - bounds)); - return specs; - } - }; - opts = RecentsTransition.createAspectScaleAnimation( - getContext(), getHandler(), true /* scaleUp */, animFuture, null); + opts = Launcher.getLauncher(getContext()).getActivityLaunchOptions(this, false); } else { opts = ActivityOptions.makeCustomAnimation(getContext(), 0, 0); } @@ -178,6 +154,14 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback mIconView.setScaleY(iconScale); } + public void resetVisualProperties() { + setScaleX(1f); + setScaleY(1f); + setTranslationX(0f); + setTranslationY(0f); + setAlpha(1f); + } + @Override public int onPageScroll(ScrollState scrollState) { float curveInterpolation = @@ -209,7 +193,6 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback return SCROLL_TYPE_TASK; } - private static final class TaskOutlineProvider extends ViewOutlineProvider { private final int mMarginTop; diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java index 528fd72679..11b4e5aa83 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -46,9 +46,7 @@ import android.support.annotation.UiThread; import android.support.annotation.WorkerThread; import android.util.Log; import android.view.View; -import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnDrawListener; -import android.view.ViewTreeObserver.OnPreDrawListener; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; @@ -62,11 +60,9 @@ import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; - import com.android.launcher3.logging.UserEventDispatcher; -import com.android.launcher3.userevent.nano.LauncherLogProto; -import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; +import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.TraceHelper; import com.android.launcher3.util.ViewOnDrawExecutor; @@ -359,7 +355,7 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler { AbstractFloatingView.closeAllOpenViews(mLauncher, mWasLauncherAlreadyVisible); - if (mWasLauncherAlreadyVisible) { + if (mWasLauncherAlreadyVisible && !mLauncher.getAppTransitionManager().isAnimating()) { DeviceProfile dp = mLauncher.getDeviceProfile(); long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx); mLauncherTransitionController = mLauncher.getStateManager() diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index b87511af9d..ed8d39cc3b 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -39,6 +39,7 @@ import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.annotation.TargetApi; +import android.app.ActivityOptions; import android.app.AlertDialog; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; @@ -1924,7 +1925,7 @@ public class Launcher extends BaseActivity intent.setSourceBounds(getViewBounds(v)); // If there is no target package, use the default intent chooser animation launchOptions = hasTargetPackage - ? getActivityLaunchOptions(v, isInMultiWindowModeCompat()) + ? getActivityLaunchOptionsAsBundle(v, isInMultiWindowModeCompat()) : null; } else { launchOptions = null; @@ -1979,8 +1980,13 @@ public class Launcher extends BaseActivity } } + public Bundle getActivityLaunchOptionsAsBundle(View v, boolean useDefaultLaunchOptions) { + ActivityOptions activityOptions = getActivityLaunchOptions(v, useDefaultLaunchOptions); + return activityOptions == null ? null : activityOptions.toBundle(); + } + @TargetApi(Build.VERSION_CODES.M) - public Bundle getActivityLaunchOptions(View v, boolean useDefaultLaunchOptions) { + public ActivityOptions getActivityLaunchOptions(View v, boolean useDefaultLaunchOptions) { return useDefaultLaunchOptions ? mAppTransitionManager.getDefaultActivityLaunchOptions(this, v) : mAppTransitionManager.getActivityLaunchOptions(this, v); @@ -2004,7 +2010,7 @@ public class Launcher extends BaseActivity boolean useLaunchAnimation = (v != null) && !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION); Bundle optsBundle = useLaunchAnimation - ? getActivityLaunchOptions(v, isInMultiWindowModeCompat()) + ? getActivityLaunchOptionsAsBundle(v, isInMultiWindowModeCompat()) : null; UserHandle user = item == null ? null : item.user; diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java index 43d5e623dc..19fa3d4452 100644 --- a/src/com/android/launcher3/LauncherAppTransitionManager.java +++ b/src/com/android/launcher3/LauncherAppTransitionManager.java @@ -21,7 +21,6 @@ import android.app.ActivityOptions; import android.content.Context; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.os.Bundle; import android.view.View; /** @@ -34,7 +33,7 @@ public class LauncherAppTransitionManager { context, R.string.app_transition_manager_class); } - public Bundle getDefaultActivityLaunchOptions(Launcher launcher, View v) { + public ActivityOptions getDefaultActivityLaunchOptions(Launcher launcher, View v) { if (Utilities.ATLEAST_MARSHMALLOW) { int left = 0, top = 0; int width = v.getMeasuredWidth(), height = v.getMeasuredHeight(); @@ -49,23 +48,27 @@ public class LauncherAppTransitionManager { height = bounds.height(); } } - return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height) - .toBundle(); + return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height); } else if (Utilities.ATLEAST_LOLLIPOP_MR1) { // On L devices, we use the device default slide-up transition. // On L MR1 devices, we use a custom version of the slide-up transition which // doesn't have the delay present in the device default. return ActivityOptions.makeCustomAnimation(launcher, R.anim.task_open_enter, - R.anim.no_anim).toBundle(); + R.anim.no_anim); } return null; } - public Bundle getActivityLaunchOptions(Launcher launcher, View v) { + public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) { return getDefaultActivityLaunchOptions(launcher, v); } /** Cancels the current Launcher transition animation */ public void finishLauncherAnimation() { } + + public boolean isAnimating() { + // We don't know when the activity options are being used. + return false; + } } diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java index d2bcd18521..32fd0633c5 100644 --- a/src/com/android/launcher3/popup/SystemShortcut.java +++ b/src/com/android/launcher3/popup/SystemShortcut.java @@ -82,7 +82,7 @@ public abstract class SystemShortcut extends ItemInfo { @Override public void onClick(View view) { Rect sourceBounds = launcher.getViewBounds(view); - Bundle opts = launcher.getActivityLaunchOptions(view, false); + Bundle opts = launcher.getActivityLaunchOptionsAsBundle(view, false); InfoDropTarget.startDetailsActivityForInfo(itemInfo, launcher, sourceBounds, opts); launcher.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP, ControlType.APPINFO_TARGET, view); diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/OverviewPanel.java b/src_ui_overrides/com/android/launcher3/uioverrides/OverviewPanel.java index 2d39505b11..4168e11603 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/OverviewPanel.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/OverviewPanel.java @@ -159,7 +159,7 @@ public class OverviewPanel extends LinearLayout implements Insettable, View.OnCl .setPackage(getContext().getPackageName()); intent.setSourceBounds(mLauncher.getViewBounds(v)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getContext().startActivity(intent, mLauncher.getActivityLaunchOptions(v, false)); + getContext().startActivity(intent, mLauncher.getActivityLaunchOptionsAsBundle(v, false)); } @Override