diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 5abeae4653..f81c56fc34 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -212,36 +212,23 @@ public abstract class BaseSwipeUpHandler { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_FROM_RECENTS, "onFinishComplete1"); + if (!mCanceled) { + TaskView nextTask = mRecentsView.getTaskView(taskId); + if (nextTask != null) { + nextTask.launchTask(false /* animate */, true /* freezeTaskList */, + success -> { + resultCallback.accept(success); + if (!success) { + mActivityInterface.onLaunchTaskFailed(); + nextTask.notifyTaskLaunchFailed(TAG); + } else { + mActivityInterface.onLaunchTaskSuccess(); + } + }, MAIN_EXECUTOR.getHandler()); } - if (!mCanceled) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_FROM_RECENTS, "onFinishComplete2"); - } - TaskView nextTask = mRecentsView.getTaskView(taskId); - if (nextTask != null) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_FROM_RECENTS, "onFinishComplete3"); - } - nextTask.launchTask(false /* animate */, true /* freezeTaskList */, - success -> { - resultCallback.accept(success); - if (!success) { - mActivityInterface.onLaunchTaskFailed(); - nextTask.notifyTaskLaunchFailed(TAG); - } else { - mActivityInterface.onLaunchTaskSuccess(); - } - }, MAIN_EXECUTOR.getHandler()); - } - mStateCallback.setStateOnUiThread(successStateFlag); - } - mCanceled = false; - mFinishingRecentsAnimationForNewTaskId = -1; - }); + mStateCallback.setStateOnUiThread(successStateFlag); + } + mCanceled = false; } ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java index 1bd03330fe..4cfa6f1617 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java @@ -30,6 +30,7 @@ import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK; import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS; import static com.android.quickstep.GestureState.STATE_END_TARGET_ANIMATION_FINISHED; import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED; +import static com.android.quickstep.GestureState.STATE_TASK_APPEARED_DURING_SWITCH; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS; import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE; @@ -253,6 +254,8 @@ public class LauncherSwipeHandler | STATE_RECENTS_SCROLLING_FINISHED, this::onSettledOnEndTarget); + mGestureState.runOnceAtState(STATE_TASK_APPEARED_DURING_SWITCH, this::onTaskAppeared); + mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED, this::invalidateHandler); mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED, this::invalidateHandlerWithLauncher); @@ -727,6 +730,22 @@ public class LauncherSwipeHandler } } + private void onTaskAppeared() { + RemoteAnimationTargetCompat app = mGestureState.getAnimationTarget(); + if (mRecentsAnimationController != null && app != null) { + + // TODO(b/152480470): Update Task target animation after onTaskAppeared holistically. + /* android.util.Log.d("LauncherSwipeHandler", "onTaskAppeared"); + + final boolean result = mRecentsAnimationController.removeTaskTarget(app); + mGestureState.setAnimationTarget(null); + android.util.Log.d("LauncherSwipeHandler", "removeTask, result=" + result); */ + + mRecentsAnimationController.finish(false /* toRecents */, + null /* onFinishComplete */); + } + } + private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling, boolean isCancel) { final GestureEndTarget endTarget; diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index 5118906b28..544f420811 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -23,6 +23,7 @@ import android.content.Intent; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.io.PrintWriter; import java.util.ArrayList; @@ -109,6 +110,9 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL public static final int STATE_RECENTS_SCROLLING_FINISHED = getFlagForIndex("STATE_RECENTS_SCROLLING_FINISHED"); + // Called when the new task appeared from quick switching. + public static final int STATE_TASK_APPEARED_DURING_SWITCH = + getFlagForIndex("STATE_TASK_APPEARED_DURING_SWITCH"); // Needed to interact with the current activity private final Intent mHomeIntent; @@ -119,6 +123,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL private ActivityManager.RunningTaskInfo mRunningTask; private GestureEndTarget mEndTarget; + private RemoteAnimationTargetCompat mAnimationTarget; // TODO: This can be removed once we stop finishing the animation when starting a new task private int mFinishingRecentsAnimationTaskId = -1; @@ -227,6 +232,14 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL return mEndTarget; } + public void setAnimationTarget(RemoteAnimationTargetCompat target) { + mAnimationTarget = target; + } + + public RemoteAnimationTargetCompat getAnimationTarget() { + return mAnimationTarget; + } + /** * Sets the end target of this gesture and immediately notifies the state changes. */ @@ -301,6 +314,12 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED); } + @Override + public void onTaskAppeared(RemoteAnimationTargetCompat app) { + mAnimationTarget = app; + mStateCallback.setState(STATE_TASK_APPEARED_DURING_SWITCH); + } + public void dump(PrintWriter pw) { pw.println("GestureState:"); pw.println(" gestureID=" + mGestureId); diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java index 783978d6a8..566a701985 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java @@ -121,6 +121,16 @@ public class RecentsAnimationCallbacks implements }); } + @BinderThread + @Override + public void onTaskAppeared(RemoteAnimationTargetCompat app) { + Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { + for (RecentsAnimationListener listener : getListeners()) { + listener.onTaskAppeared(app); + } + }); + } + private final void onAnimationFinished(RecentsAnimationController controller) { Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { for (RecentsAnimationListener listener : getListeners()) { @@ -150,5 +160,10 @@ public class RecentsAnimationCallbacks implements * Callback made whenever the recents animation is finished. */ default void onRecentsAnimationFinished(RecentsAnimationController controller) {} + + /** + * Callback made when a task started from the recents is ready for an app transition. + */ + default void onTaskAppeared(RemoteAnimationTargetCompat app) {} } } diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java index 8dd4aa4cab..268e5645bd 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java @@ -22,6 +22,7 @@ import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; +import android.annotation.NonNull; import android.os.SystemClock; import android.util.Log; import android.view.InputEvent; @@ -34,6 +35,7 @@ import com.android.launcher3.util.Preconditions; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.RecentsAnimationControllerCompat; +import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.function.Consumer; import java.util.function.Supplier; @@ -107,6 +109,15 @@ public class RecentsAnimationController { UI_HELPER_EXECUTOR.execute(() -> mController.cleanupScreenshot()); } + /** + * Remove task remote animation target from + * {@link RecentsAnimationCallbacks#onTaskAppeared(RemoteAnimationTargetCompat)}}. + */ + @UiThread + public boolean removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) { + return mController.removeTask(target.taskId); + } + @UiThread public void finishAnimationToHome() { finishAndClear(true /* toRecents */, null, false /* sendUserLeaveHint */);