Loading quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +15 −3 Original line number Diff line number Diff line Loading @@ -539,7 +539,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, @Override public void onMotionPauseDetected() { mHasMotionEverBeenPaused = true; maybeUpdateRecentsAttachedState(); maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */); performHapticFeedback(); } Loading @@ -550,18 +550,24 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, }; } public void maybeUpdateRecentsAttachedState() { private void maybeUpdateRecentsAttachedState() { maybeUpdateRecentsAttachedState(true /* animate */); } private void maybeUpdateRecentsAttachedState(boolean animate) { maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */); } /** * 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. * @param animate whether to animate when attaching RecentsView * @param moveFocusedTask whether to move focused task to front when attaching */ private void maybeUpdateRecentsAttachedState(boolean animate) { private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) { if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) { return; } Loading @@ -580,6 +586,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, } else { recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask; } if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow() && recentsAttachedToAppWindow) { // Only move focused task if RecentsView has never been attached before, to avoid // TaskView jumping to new position as we move the tasks. mRecentsView.moveFocusedTaskToFront(); } mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); // Reapply window transform throughout the attach animation, as the animation affects how Loading quickstep/src/com/android/quickstep/BaseActivityInterface.java +13 −0 Original line number Diff line number Diff line Loading @@ -400,6 +400,10 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T default boolean isRecentsAttachedToAppWindow() { return false; } default boolean hasRecentsEverAttachedToAppWindow() { return false; } } class DefaultAnimationFactory implements AnimationFactory { Loading @@ -409,6 +413,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T private final Consumer<AnimatorControllerWithResistance> mCallback; private boolean mIsAttachedToWindow; private boolean mHasEverAttachedToWindow; DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback) { mCallback = callback; Loading Loading @@ -462,6 +467,9 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T } mIsAttachedToWindow = attached; RecentsView recentsView = mActivity.getOverviewPanel(); if (attached) { mHasEverAttachedToWindow = true; } Animator fadeAnim = mActivity.getStateManager() .createStateElementAnimation(INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0); Loading Loading @@ -491,6 +499,11 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T return mIsAttachedToWindow; } @Override public boolean hasRecentsEverAttachedToAppWindow() { return mHasEverAttachedToWindow; } protected void createBackgroundToOverviewAnim(ACTIVITY_TYPE activity, PendingAnimation pa) { // Scale down recents from being full screen to being in overview. RecentsView recentsView = activity.getOverviewPanel(); Loading quickstep/src/com/android/quickstep/views/RecentsView.java +46 −3 Original line number Diff line number Diff line Loading @@ -563,6 +563,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T * removed from recentsView */ private int mSplitHiddenTaskViewIndex; /** * The task to be removed and immediately re-added. Should not be added to task pool. */ private TaskView mMovingTaskView; // Keeps track of the index where the first TaskView should be private int mTaskViewStartIndex = 0; Loading Loading @@ -826,9 +830,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T public void onViewRemoved(View child) { super.onViewRemoved(child); // Clear the task data for the removed child if it was visible unless it's the initial // taskview for entering split screen, we only pretend to dismiss the task if (child instanceof TaskView && child != mSplitHiddenTaskView) { // Clear the task data for the removed child if it was visible unless: // - It's the initial taskview for entering split screen, we only pretend to dismiss the // task // - It's the focused task to be moved to the front, we immediately re-add the task if (child instanceof TaskView && child != mSplitHiddenTaskView && child != mMovingTaskView) { TaskView taskView = (TaskView) child; mHasVisibleTaskData.delete(taskView.getTaskId()); mTaskViewPool.recycle(taskView); Loading Loading @@ -1121,6 +1128,42 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } } /** * Moves the focused task to the front of the carousel in tablets, to minimize animation * required to focus the task in grid. */ public void moveFocusedTaskToFront() { if (!(mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get())) { return; } TaskView focusedTaskView = getFocusedTaskView(); if (focusedTaskView == null) { return; } if (indexOfChild(focusedTaskView) != mCurrentPage) { return; } if (mCurrentPage == mTaskViewStartIndex) { return; } int primaryScroll = mOrientationHandler.getPrimaryScroll(this); int currentPageScroll = getScrollForPage(mCurrentPage); mCurrentPageScrollDiff = primaryScroll - currentPageScroll; mMovingTaskView = focusedTaskView; removeView(focusedTaskView); mMovingTaskView = null; focusedTaskView.onRecycle(); addView(focusedTaskView, mTaskViewStartIndex); setCurrentPage(mTaskViewStartIndex); updateGridProperties(); } protected void applyLoadPlan(ArrayList<Task> tasks) { if (mPendingAnimation != null) { mPendingAnimation.addEndListener(success -> applyLoadPlan(tasks)); Loading Loading
quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +15 −3 Original line number Diff line number Diff line Loading @@ -539,7 +539,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, @Override public void onMotionPauseDetected() { mHasMotionEverBeenPaused = true; maybeUpdateRecentsAttachedState(); maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */); performHapticFeedback(); } Loading @@ -550,18 +550,24 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, }; } public void maybeUpdateRecentsAttachedState() { private void maybeUpdateRecentsAttachedState() { maybeUpdateRecentsAttachedState(true /* animate */); } private void maybeUpdateRecentsAttachedState(boolean animate) { maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */); } /** * 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. * @param animate whether to animate when attaching RecentsView * @param moveFocusedTask whether to move focused task to front when attaching */ private void maybeUpdateRecentsAttachedState(boolean animate) { private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) { if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) { return; } Loading @@ -580,6 +586,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, } else { recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask; } if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow() && recentsAttachedToAppWindow) { // Only move focused task if RecentsView has never been attached before, to avoid // TaskView jumping to new position as we move the tasks. mRecentsView.moveFocusedTaskToFront(); } mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); // Reapply window transform throughout the attach animation, as the animation affects how Loading
quickstep/src/com/android/quickstep/BaseActivityInterface.java +13 −0 Original line number Diff line number Diff line Loading @@ -400,6 +400,10 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T default boolean isRecentsAttachedToAppWindow() { return false; } default boolean hasRecentsEverAttachedToAppWindow() { return false; } } class DefaultAnimationFactory implements AnimationFactory { Loading @@ -409,6 +413,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T private final Consumer<AnimatorControllerWithResistance> mCallback; private boolean mIsAttachedToWindow; private boolean mHasEverAttachedToWindow; DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback) { mCallback = callback; Loading Loading @@ -462,6 +467,9 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T } mIsAttachedToWindow = attached; RecentsView recentsView = mActivity.getOverviewPanel(); if (attached) { mHasEverAttachedToWindow = true; } Animator fadeAnim = mActivity.getStateManager() .createStateElementAnimation(INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0); Loading Loading @@ -491,6 +499,11 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T return mIsAttachedToWindow; } @Override public boolean hasRecentsEverAttachedToAppWindow() { return mHasEverAttachedToWindow; } protected void createBackgroundToOverviewAnim(ACTIVITY_TYPE activity, PendingAnimation pa) { // Scale down recents from being full screen to being in overview. RecentsView recentsView = activity.getOverviewPanel(); Loading
quickstep/src/com/android/quickstep/views/RecentsView.java +46 −3 Original line number Diff line number Diff line Loading @@ -563,6 +563,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T * removed from recentsView */ private int mSplitHiddenTaskViewIndex; /** * The task to be removed and immediately re-added. Should not be added to task pool. */ private TaskView mMovingTaskView; // Keeps track of the index where the first TaskView should be private int mTaskViewStartIndex = 0; Loading Loading @@ -826,9 +830,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T public void onViewRemoved(View child) { super.onViewRemoved(child); // Clear the task data for the removed child if it was visible unless it's the initial // taskview for entering split screen, we only pretend to dismiss the task if (child instanceof TaskView && child != mSplitHiddenTaskView) { // Clear the task data for the removed child if it was visible unless: // - It's the initial taskview for entering split screen, we only pretend to dismiss the // task // - It's the focused task to be moved to the front, we immediately re-add the task if (child instanceof TaskView && child != mSplitHiddenTaskView && child != mMovingTaskView) { TaskView taskView = (TaskView) child; mHasVisibleTaskData.delete(taskView.getTaskId()); mTaskViewPool.recycle(taskView); Loading Loading @@ -1121,6 +1128,42 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } } /** * Moves the focused task to the front of the carousel in tablets, to minimize animation * required to focus the task in grid. */ public void moveFocusedTaskToFront() { if (!(mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get())) { return; } TaskView focusedTaskView = getFocusedTaskView(); if (focusedTaskView == null) { return; } if (indexOfChild(focusedTaskView) != mCurrentPage) { return; } if (mCurrentPage == mTaskViewStartIndex) { return; } int primaryScroll = mOrientationHandler.getPrimaryScroll(this); int currentPageScroll = getScrollForPage(mCurrentPage); mCurrentPageScrollDiff = primaryScroll - currentPageScroll; mMovingTaskView = focusedTaskView; removeView(focusedTaskView); mMovingTaskView = null; focusedTaskView.onRecycle(); addView(focusedTaskView, mTaskViewStartIndex); setCurrentPage(mTaskViewStartIndex); updateGridProperties(); } protected void applyLoadPlan(ArrayList<Task> tasks) { if (mPendingAnimation != null) { mPendingAnimation.addEndListener(success -> applyLoadPlan(tasks)); Loading