diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.kt b/quickstep/src/com/android/quickstep/SystemUiProxy.kt index 199283bd1b..448d529c2f 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.kt +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.kt @@ -44,6 +44,7 @@ import android.window.RemoteTransition import android.window.TaskSnapshot import android.window.TransitionFilter import android.window.TransitionInfo +import android.window.WindowContainerTransaction import androidx.annotation.MainThread import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread @@ -1209,6 +1210,7 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context: options: ActivityOptions, listener: RecentsAnimationListener, useSyntheticRecentsTransition: Boolean, + wct: WindowContainerTransaction? = null, ): Boolean { executeWithErrorLog({ "Error starting recents via shell" }) { recentTasks?.startRecentsTransition( @@ -1219,6 +1221,7 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context: putBoolean("is_synthetic_recents_transition", true) } }, + wct, context.iApplicationThread, RecentsAnimationListenerStub(listener), ) diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index a80500ae41..39c468edbb 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -341,11 +341,11 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn instanceof RecentsWindowManager recentsWindowManager && RecentsWindowFlags.Companion.getEnableOverviewInWindow()) { mRecentsAnimationStartPending = getSystemUiProxy().startRecentsActivity(intent, options, - mCallbacks, gestureState.useSyntheticRecentsTransition()); + mCallbacks, gestureState.useSyntheticRecentsTransition(), null); recentsWindowManager.startRecentsWindow(mCallbacks); } else { mRecentsAnimationStartPending = getSystemUiProxy().startRecentsActivity(intent, - options, mCallbacks, false /* useSyntheticRecentsTransition */); + options, mCallbacks, false /* useSyntheticRecentsTransition */, null); } ActiveGestureProtoLogProxy.logSettingRecentsAnimationStartPending( mRecentsAnimationStartPending); diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index 0d0618cafb..74088c1f20 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -63,6 +63,7 @@ import android.window.IRemoteTransitionFinishedCallback; import android.window.RemoteTransition; import android.window.RemoteTransitionStub; import android.window.TransitionInfo; +import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -882,7 +883,8 @@ public class SplitSelectStateController { * @param taskBounds the bounds of the task, used for {@link FloatingTaskView} animation */ public void enterSplitSelect(ActivityManager.RunningTaskInfo taskInfo, - int splitPosition, Rect taskBounds) { + int splitPosition, Rect taskBounds, boolean startRecents, + @Nullable WindowContainerTransaction withRecentsWct) { mTaskInfo = taskInfo; String packageName = mTaskInfo.realActivity.getPackageName(); PackageManager pm = mLauncher.getApplicationContext().getPackageManager(); @@ -893,53 +895,72 @@ public class SplitSelectStateController { } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Package not found: " + packageName, e); } - RecentsAnimationCallbacks callbacks = new RecentsAnimationCallbacks( - SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext())); - DesktopSplitRecentsAnimationListener listener = - new DesktopSplitRecentsAnimationListener(splitPosition, taskBounds); - - callbacks.addListener(listener); - UI_HELPER_EXECUTOR.execute(() -> { - // Transition from app to enter stage split in launcher with recents animation - final ActivityOptions options = ActivityOptions.makeBasic(); - options.setPendingIntentBackgroundActivityStartMode( - ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS); - options.setTransientLaunch(); - SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()) - .startRecentsActivity( - mOverviewComponentObserver.getOverviewIntent(), options, - callbacks, false /* useSyntheticRecentsTransition */); - }); + final DesktopSplitRecentsAnimation animation = new DesktopSplitRecentsAnimation( + splitPosition, taskBounds); + final Runnable updateTaskbarRunnable = () -> { + final LauncherTaskbarUIController c = mLauncher.getTaskbarUIController(); + if (c != null) { + c.updateTaskbarLauncherStateGoingHome(); + } + }; + if (startRecents) { + RecentsAnimationCallbacks callbacks = new RecentsAnimationCallbacks( + SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext())); + callbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() { + @Override + public void onRecentsAnimationStart(RecentsAnimationController controller, + RecentsAnimationTargets targets, + @Nullable TransitionInfo transitionInfo) { + animation.start(() -> { + controller.finish( + true /* toRecents */, + updateTaskbarRunnable, + false /* sendUserLeaveHint */); + }); + } + }); + UI_HELPER_EXECUTOR.execute(() -> { + // Transition from app to enter stage split in launcher with recents animation + final ActivityOptions options = ActivityOptions.makeBasic(); + options.setPendingIntentBackgroundActivityStartMode( + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS); + options.setTransientLaunch(); + SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()) + .startRecentsActivity( + mOverviewComponentObserver.getOverviewIntent(), options, + callbacks, false /* useSyntheticRecentsTransition */, + withRecentsWct); + }); + } else { + animation.start(updateTaskbarRunnable); + } } - private class DesktopSplitRecentsAnimationListener implements - RecentsAnimationCallbacks.RecentsAnimationListener { + private class DesktopSplitRecentsAnimation { private final Rect mTempRect = new Rect(); private final RectF mTaskBounds = new RectF(); private final int mSplitPosition; - DesktopSplitRecentsAnimationListener(int splitPosition, Rect taskBounds) { + DesktopSplitRecentsAnimation(int splitPosition, Rect taskBounds) { mSplitPosition = splitPosition; mTaskBounds.set(taskBounds); } - @Override - public void onRecentsAnimationStart(RecentsAnimationController controller, - RecentsAnimationTargets targets, TransitionInfo transitionInfo) { - StatsLogManager.LauncherEvent launcherDesktopSplitEvent = + void start(@NonNull Runnable onAnimationStart) { + final StatsLogManager.LauncherEvent launcherDesktopSplitEvent = mSplitPosition == STAGE_POSITION_BOTTOM_OR_RIGHT ? - LAUNCHER_DESKTOP_MODE_SPLIT_RIGHT_BOTTOM : - LAUNCHER_DESKTOP_MODE_SPLIT_LEFT_TOP; + LAUNCHER_DESKTOP_MODE_SPLIT_RIGHT_BOTTOM : + LAUNCHER_DESKTOP_MODE_SPLIT_LEFT_TOP; setInitialTaskSelect(mTaskInfo, mSplitPosition, null, launcherDesktopSplitEvent); - RecentsView recentsView = mLauncher.getOverviewPanel(); + final RecentsView recentsView = mLauncher.getOverviewPanel(); recentsView.getPagedOrientationHandler().getInitialSplitPlaceholderBounds( mSplitPlaceholderSize, mSplitPlaceholderInset, mLauncher.getDeviceProfile(), getActiveSplitStagePosition(), mTempRect); - PendingAnimation anim = new PendingAnimation( + final PendingAnimation anim = new PendingAnimation( SplitAnimationTimings.TABLET_HOME_TO_SPLIT.getDuration()); final FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView( mLauncher, mLauncher.getDragLayer(), @@ -957,17 +978,7 @@ public class SplitSelectStateController { anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { - controller.finish( - true /* toRecents */, - () -> { - LauncherTaskbarUIController controller = - mLauncher.getTaskbarUIController(); - if (controller != null) { - controller.updateTaskbarLauncherStateGoingHome(); - } - - }, - false /* sendUserLeaveHint */); + onAnimationStart.run(); } @Override public void onAnimationEnd(Animator animation) { @@ -1010,10 +1021,12 @@ public class SplitSelectStateController { @Override public boolean onRequestSplitSelect(ActivityManager.RunningTaskInfo taskInfo, - int splitPosition, Rect taskBounds) { + int splitPosition, Rect taskBounds, boolean startRecents, + @Nullable WindowContainerTransaction withRecentsWct) { MAIN_EXECUTOR.execute(() -> { if (mController != null) { - mController.enterSplitSelect(taskInfo, splitPosition, taskBounds); + mController.enterSplitSelect(taskInfo, splitPosition, taskBounds, + startRecents, withRecentsWct); } }); return true; diff --git a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java index 0e2713981d..b30c282d18 100644 --- a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java +++ b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java @@ -94,7 +94,7 @@ public class SplitWithKeyboardShortcutController { SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()) .startRecentsActivity(mOverviewComponentObserver.getOverviewIntent(), ActivityOptions.makeBasic(), callbacks, - false /* useSyntheticRecentsTransition */); + false /* useSyntheticRecentsTransition */, null); }); }); } diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java index af578db2c8..c363b4f20d 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java @@ -85,7 +85,8 @@ public class TaskAnimationManagerTest { final ArgumentCaptor optionsCaptor = ArgumentCaptor.forClass(ActivityOptions.class); verify(mSystemUiProxy) - .startRecentsActivity(any(), optionsCaptor.capture(), any(), anyBoolean()); + .startRecentsActivity(any(), optionsCaptor.capture(), any(), anyBoolean(), + any()); assertEquals(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS, optionsCaptor.getValue().getPendingIntentBackgroundActivityStartMode()); } @@ -117,7 +118,7 @@ public class TaskAnimationManagerTest { doReturn(mock(LauncherActivityInterface.class)).when(gestureState).getContainerInterface(); when(mSystemUiProxy - .startRecentsActivity(any(), any(), listenerCaptor.capture(), anyBoolean())) + .startRecentsActivity(any(), any(), listenerCaptor.capture(), anyBoolean(), any())) .thenReturn(true); when(gestureState.getRunningTaskIds(anyBoolean())).thenReturn(new int[0]);