diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 65dfe0523a..39727e16cb 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -15,6 +15,7 @@ */ package com.android.quickstep; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; @@ -24,7 +25,6 @@ import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.Flags.enableCursorHoverStates; -import static com.android.quickstep.fallback.window.RecentsWindowFlags.enableOverviewOnConnectedDisplays; import static com.android.launcher3.LauncherPrefs.backedUpItem; import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent; import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe; @@ -39,8 +39,10 @@ import static com.android.quickstep.InputConsumer.TYPE_CURSOR_HOVER; import static com.android.quickstep.InputConsumer.createNoOpInputConsumer; import static com.android.quickstep.InputConsumerUtils.newConsumer; import static com.android.quickstep.InputConsumerUtils.tryCreateAssistantInputConsumer; +import static com.android.quickstep.fallback.window.RecentsWindowFlags.enableOverviewOnConnectedDisplays; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; +import android.app.ActivityManager; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -98,6 +100,7 @@ import com.android.launcher3.util.TraceHelper; import com.android.quickstep.OverviewCommandHelper.CommandType; import com.android.quickstep.OverviewComponentObserver.OverviewChangeListener; import com.android.quickstep.actioncorner.ActionCornerHandler; +import com.android.quickstep.fallback.RecentsState; import com.android.quickstep.fallback.window.RecentsWindowFlags; import com.android.quickstep.fallback.window.RecentsWindowManager; import com.android.quickstep.fallback.window.RecentsWindowSwipeHandler; @@ -120,6 +123,8 @@ import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; +import com.android.systemui.shared.system.TaskStackChangeListener; +import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController; import com.android.systemui.unfold.progress.IUnfoldAnimation; import com.android.wm.shell.back.IBackAnimation; @@ -610,6 +615,50 @@ public class TouchInteractionService extends Service { } }; + // We should clean up the recents window on the primary display on home intent start, however we + // have no other way of listening to this event in the 3P launcher case. + private final TaskStackChangeListener mHomeIntentStartedListener = + new TaskStackChangeListener() { + @Override + public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, + boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { + TaskStackChangeListener.super.onActivityRestartAttempt(task, homeTaskVisible, + clearedTask, wasVisible); + if (task.configuration.windowConfiguration.getActivityType() + != ACTIVITY_TYPE_HOME + || task.displayId != DEFAULT_DISPLAY) { + // We only want to handle home intent starts, and only on the primary + // display. + return; + } + if (mGestureState != DEFAULT_STATE) { + // If there's an ongoing gesture, we shouldn't clean up the recents window + // since gestures will clean up the recents window when needed. + return; + } + RecentsWindowManager recentsWindowManager = + mRecentsWindowManagerRepository.get(DEFAULT_DISPLAY); + TaskAnimationManager taskAnimationManager = + mTaskAnimationManagerRepository.get(DEFAULT_DISPLAY); + if (recentsWindowManager == null || taskAnimationManager == null) { + return; + } + if (taskAnimationManager.isRecentsAnimationRunning()) { + RecentsState recentsState = + recentsWindowManager.getStateManager().getState(); + if (!recentsState.isRecentsViewVisible()) { + // If we're in a state where the recents view is visible, we can ignore + // the recents animation running check, otherwise we should wait for + // the recents animation to end. + return; + } + } + if (recentsWindowManager.isStarted()) { + recentsWindowManager.getStateManager().goToState(RecentsState.HOME, true); + } + } + }; + private OverviewCommandHelper mOverviewCommandHelper; private OverviewComponentObserver mOverviewComponentObserver; private InputConsumerController mInputConsumer; @@ -824,6 +873,17 @@ public class TouchInteractionService extends Service { mTaskbarManager.setRecentsViewContainer(newOverviewContainer); } } + if (RecentsWindowFlags.getEnableOverviewInWindow()) { + mRecentsWindowManagerRepository.forEach( + /* createIfAbsent= */ false, RecentsWindowManager::cleanupRecentsWindow); + if (isHomeAndOverviewSame) { + TaskStackChangeListeners.getInstance().unregisterTaskStackListener( + mHomeIntentStartedListener); + } else { + TaskStackChangeListeners.getInstance().registerTaskStackListener( + mHomeIntentStartedListener); + } + } } @UiThread @@ -881,6 +941,10 @@ public class TouchInteractionService extends Service { mDisplayInfoChangeListener); LockedUserState.get(this).removeOnUserUnlockedRunnable(mUserUnlockedRunnable); ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener); + if (RecentsWindowFlags.getEnableOverviewInWindow()) { + TaskStackChangeListeners.getInstance().unregisterTaskStackListener( + mHomeIntentStartedListener); + } super.onDestroy(); } diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index c9d8860b28..b7e101038a 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -23,6 +23,7 @@ import static androidx.test.InstrumentationRegistry.getInstrumentation; import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS; import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage; import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess; +import static com.android.launcher3.ui.TaplTestsLauncher3Test.getAppPackageName; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.rule.ShellCommandRule.disableHeadsUpNotification; import static com.android.launcher3.util.rule.ShellCommandRule.getLauncherCommand; @@ -30,7 +31,6 @@ import static com.android.launcher3.util.ui.AbstractLauncherUiTest.DEFAULT_BROAD import static com.android.launcher3.util.ui.AbstractLauncherUiTest.resolveSystemApp; import static com.android.launcher3.util.ui.AbstractLauncherUiTest.startAppFast; import static com.android.launcher3.util.ui.AbstractLauncherUiTest.startTestActivity; -import static com.android.launcher3.ui.TaplTestsLauncher3Test.getAppPackageName; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 512db394ac..784ffb2312 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -263,7 +263,7 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine endY = startY; } - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.linearGesture( startX, startY, endX, endY, 20, false, LauncherInstrumentation.GestureScope.EXPECT_PILFER), @@ -276,7 +276,7 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine "clicking Recents button for the first time"); mLauncher.getOverview(); mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT); - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> recentsButton.click(), "clicking Recents button for the second time"); } diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index 12d9d649af..b715a41ca4 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -168,7 +168,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.waitForObjectInContainer(verifyActiveContainer(), clearAllSelector)); if (mLauncher.is3PLauncher()) { - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( clickClearAll, "clicking 'Clear All'"); } else { @@ -507,7 +507,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_ENTER_UP); mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT); - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.assertTrue( "Failed to press enter", mLauncher.getDevice().pressKeyCode(KeyEvent.KEYCODE_ENTER)), diff --git a/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java b/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java index 7cb26142a5..bb5e3000a5 100644 --- a/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java +++ b/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java @@ -224,7 +224,7 @@ public final class KeyboardQuickSwitch { if (expectedPackageName == null || !mIsHomeState) { mLauncher.unpressKeyCode(KeyEvent.KEYCODE_ALT_LEFT, 0); } else { - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.unpressKeyCode(KeyEvent.KEYCODE_ALT_LEFT, 0), "unpressing left alt"); } diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index c40e5a93d8..2f36a50577 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -63,7 +63,7 @@ public abstract class Launchable { + mLauncher.getVisibleBounds(mObject)); if (launcherStopsAfterLaunch()) { - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.clickLauncherObject(mObject), "clicking the launchable"); } else { @@ -96,7 +96,7 @@ public abstract class Launchable { + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds( mObject)); - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.clickLauncherObject(mObject), "clicking the launchable"); diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java index 3e4cf80941..d3467ca725 100644 --- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java +++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java @@ -157,7 +157,7 @@ public final class LaunchedAppState extends Background { int endX = startX; int endY = startY - taskbarFromNavThreshold; - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.linearGesture(startX, startY, endX, endY, 10, /* slowDown= */ true, LauncherInstrumentation.GestureScope.EXPECT_PILFER), diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index e05aeb9433..3e3bdeca6f 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -1149,12 +1149,20 @@ public final class LauncherInstrumentation { } } - void executeAndWaitForLauncherStop(Runnable command, String actionName) { - executeAndWaitForLauncherEvent( - () -> command.run(), - event -> TestProtocol.LAUNCHER_ACTIVITY_STOPPED_MESSAGE - .equals(event.getClassName().toString()), - () -> "Launcher activity didn't stop", actionName); + void executeAndWaitForLauncherHidden(Runnable command, String actionName) { + // Since LAUNCHER_ACTIVITY_STOPPED_MESSAGE is only ever sent from Launcher.onStop or + // RecentsActivity.onStop, we never receive this signal on 3P launchers with recents + // window enabled. So, instead we should wait for the recent window's state manager to + // report the normal state. + if (is3PLauncher() && isRecentsWindowEnabled()) { + runToState(command, NORMAL_STATE_ORDINAL, actionName); + } else { + executeAndWaitForLauncherEvent( + () -> command.run(), + event -> TestProtocol.LAUNCHER_ACTIVITY_STOPPED_MESSAGE + .equals(event.getClassName().toString()), + () -> "Launcher activity didn't stop", actionName); + } } /** diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java index 8049ec6ebf..ceb28dd982 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java @@ -245,7 +245,7 @@ public final class OverviewTask { public LaunchedAppState open() { try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { verifyActiveContainer(); - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.clickLauncherObject(mTask), "clicking an overview task"); if (mOverview.getContainerType() diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java index 90d32f3249..b96f7c3394 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java @@ -65,7 +65,7 @@ public class OverviewTaskMenu { try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "before tapping the app info menu item")) { - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.clickLauncherObject( mLauncher.findObjectInContainer(mMenu, By.text("App info"))), "tapped app info menu item"); @@ -106,7 +106,7 @@ public class OverviewTaskMenu { try (LauncherInstrumentation.Closable ignored = mLauncher.eventsCheck(); LauncherInstrumentation.Closable ignored1 = mLauncher.addContextLayer( "before tapping the desktop menu item")) { - mLauncher.executeAndWaitForLauncherStop( + mLauncher.executeAndWaitForLauncherHidden( () -> mLauncher.clickLauncherObject( mLauncher.findObjectInContainer(mMenu, By.text("Desktop"))), "tapped desktop menu item"); diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index 68c7049a11..095fcb88bb 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -555,7 +555,7 @@ public final class Workspace extends Home { private static void dropDraggedIcon(LauncherInstrumentation launcher, Point dest, long downTime, @Nullable Runnable expectedEvents, boolean startsActivity) { if (startsActivity) { - launcher.executeAndWaitForLauncherStop( + launcher.executeAndWaitForLauncherHidden( () -> sendUp(launcher, dest, downTime), "sending UP event"); } else {