From 501562f09a4fce6350da8096d72da93c61561452 Mon Sep 17 00:00:00 2001 From: Toni Barzic Date: Thu, 19 Dec 2024 03:06:35 +0000 Subject: [PATCH] More test for taskbar overflow Adds tests to TaskbarOverflowTests to verify that: * tapping overflow view toggles keyboard quick switch view * tasks associated with a hotseat item don't get added to recents taskbar section / overflow view * keyboard quick switch view shown from taskbar contains running tasks, excluding tasks associated with a hotseat item Bug: 379774843 Flag: com.android.launcher3.taskbar_overflow Test: atest TaskbarOverflowTest Change-Id: Iee6316c33cef6322d567e853f9fa358b7af9e172 --- .../KeyboardQuickSwitchController.java | 30 +++- .../launcher3/taskbar/TaskbarOverflowTest.kt | 132 +++++++++++++++++- .../taskbar/rules/MockedRecentsModelHelper.kt | 7 +- 3 files changed, 162 insertions(+), 7 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java index 5afc5eda6d..8555376fd6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java @@ -17,6 +17,7 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.Flags.enableAltTabKqsOnConnectedDisplays; +import android.app.ActivityManager; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.view.MotionEvent; @@ -354,6 +355,27 @@ public final class KeyboardQuickSwitchController implements } } + @VisibleForTesting + boolean isShownFromTaskbar() { + return isShown() && mQuickSwitchViewController.wasOpenedFromTaskbar(); + } + + @VisibleForTesting + boolean isShown() { + return mQuickSwitchViewController != null + && !mQuickSwitchViewController.isCloseAnimationRunning(); + } + + @VisibleForTesting + List shownTaskIds() { + if (!isShown()) { + return Collections.emptyList(); + } + + return mTasks.stream().flatMap( + groupTask -> groupTask.getTasks().stream().map(task -> task.key.id)).toList(); + } + @Override public void dumpLogs(String prefix, PrintWriter pw) { pw.println(prefix + "KeyboardQuickSwitchController:"); @@ -423,7 +445,13 @@ public final class KeyboardQuickSwitchController implements if (task == null) { return false; } - int runningTaskId = ActivityManagerWrapper.getInstance().getRunningTask().taskId; + ActivityManager.RunningTaskInfo runningTaskInfo = + ActivityManagerWrapper.getInstance().getRunningTask(); + if (runningTaskInfo == null) { + return false; + } + + int runningTaskId = runningTaskInfo.taskId; return task.containsTask(runningTaskId); } diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarOverflowTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarOverflowTest.kt index 3a27bb1683..37610444b5 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarOverflowTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarOverflowTest.kt @@ -19,6 +19,7 @@ package com.android.launcher3.taskbar import android.animation.AnimatorTestRule import android.content.ComponentName import android.content.Intent +import android.os.Process import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.SetFlagsRule @@ -27,6 +28,7 @@ import com.android.launcher3.Flags.FLAG_ENABLE_MULTI_INSTANCE_MENU_TASKBAR import com.android.launcher3.Flags.FLAG_TASKBAR_OVERFLOW import com.android.launcher3.R import com.android.launcher3.dagger.LauncherAppSingleton +import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.taskbar.TaskbarControllerTestUtil.runOnMainSync import com.android.launcher3.taskbar.TaskbarViewTestUtil.createHotseatItems import com.android.launcher3.taskbar.bubbles.BubbleBarViewController @@ -111,6 +113,7 @@ class TaskbarOverflowTest { @InjectController lateinit var recentAppsController: TaskbarRecentAppsController @InjectController lateinit var bubbleBarViewController: BubbleBarViewController @InjectController lateinit var bubbleStashController: BubbleStashController + @InjectController lateinit var keyboardQuickSwitchController: KeyboardQuickSwitchController private var desktopTaskListener: IDesktopTaskListener? = null @@ -209,8 +212,10 @@ class TaskbarOverflowTest { runOnMainSync { val taskbarView: TaskbarView = taskbarUnitTestRule.activityContext.dragLayer.findViewById(R.id.taskbar_view) + val hotseatItems = createHotseatItems(maxNumberOfTaskbarIcons - initialIconCount) + taskbarView.updateItems( - createHotseatItems(maxNumberOfTaskbarIcons - initialIconCount), + recentAppsController.updateHotseatItemInfos(hotseatItems as Array), recentAppsController.shownTasks, ) } @@ -327,13 +332,122 @@ class TaskbarOverflowTest { assertThat(taskbarIconsCentered).isTrue() } + @Test + @TaskbarMode(PINNED) + fun testPressingOverflowButtonOpensKeyboardQuickSwitch() { + val maxNumIconViews = maxNumberOfTaskbarIcons + // Assume there are at least all apps and divider icon, as they would appear once running + // apps are added, even if not present initially. + val initialIconCount = currentNumberOfTaskbarIcons.coerceAtLeast(2) + + val targetOverflowSize = 5 + val createdTasks = maxNumIconViews - initialIconCount + targetOverflowSize + createDesktopTask(createdTasks) + + assertThat(taskbarOverflowIconIndex).isEqualTo(initialIconCount) + tapOverflowIcon() + // Keyboard quick switch view is shown only after list of recent task is asynchronously + // retrieved from the recents model. + runOnMainSync { recentsModel.resolvePendingTaskRequests() } + + assertThat(getOnUiThread { keyboardQuickSwitchController.isShownFromTaskbar }).isTrue() + assertThat(getOnUiThread { keyboardQuickSwitchController.shownTaskIds() }) + .containsExactlyElementsIn(0..), + recentAppsController.shownTasks, + ) + } + + assertThat(maxNumberOfTaskbarIcons).isEqualTo(maxNumIconViews) + assertThat(currentNumberOfTaskbarIcons).isEqualTo(maxNumIconViews) + assertThat(taskbarOverflowIconIndex).isEqualTo(initialIconCount + hotseatItems.size) + assertThat(overflowItems) + .containsExactlyElementsIn(listOf(0) + (2..targetOverflowSize + 1).toList()) + } + + @Test + @TaskbarMode(PINNED) + fun testHotseatItemTasksNotShownInKQS() { + val maxNumIconViews = maxNumberOfTaskbarIcons + // Assume there are at least all apps and divider icon, as they would appear once running + // apps are added, even if not present initially. + val initialIconCount = currentNumberOfTaskbarIcons.coerceAtLeast(2) + val hotseatItems = createHotseatItems(1) + + val targetOverflowSize = 5 + val createdTasks = maxNumIconViews - initialIconCount + targetOverflowSize + createDesktopTaskWithTasksFromPackages( + listOf("fake") + + listOf(hotseatItems[0]?.targetPackage ?: "") + + List(createdTasks - 2) { "fake" } + ) + + runOnMainSync { + val taskbarView: TaskbarView = + taskbarUnitTestRule.activityContext.dragLayer.findViewById(R.id.taskbar_view) + taskbarView.updateItems( + recentAppsController.updateHotseatItemInfos(hotseatItems as Array), + recentAppsController.shownTasks, + ) + } + + tapOverflowIcon() + // Keyboard quick switch view is shown only after list of recent task is asynchronously + // retrieved from the recents model. + runOnMainSync { recentsModel.resolvePendingTaskRequests() } + + assertThat(getOnUiThread { keyboardQuickSwitchController.isShownFromTaskbar }).isTrue() + assertThat(getOnUiThread { keyboardQuickSwitchController.shownTaskIds() }) + .containsExactlyElementsIn(listOf(0) + (2..) { val tasks = - (0.. + Task( + Task.TaskKey( + index, + 0, + Intent().apply { `package` = p }, + ComponentName(p, ""), + Process.myUserHandle().identifier, + 2000, + ) + ) + }) + recentsModel.updateRecentTasks(listOf(DesktopTask(deskId = 0, tasks))) - for (task in 1..tasksToAdd) { + for (task in 1..tasks.size) { desktopTaskListener?.onTasksVisibilityChanged( context.virtualDisplay.display.displayId, task, @@ -394,6 +508,14 @@ class TaskbarOverflowTest { } } + private fun tapOverflowIcon() { + runOnMainSync { + val overflowIcon = + taskbarViewController.iconViews.firstOrNull { it is TaskbarOverflowView } + assertThat(overflowIcon?.callOnClick()).isTrue() + } + } + /** * Adds enough running apps for taskbar to enter overflow of `targetOverflowSize`, and verifies * * max number of icons in the taskbar remains unchanged diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/MockedRecentsModelHelper.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/MockedRecentsModelHelper.kt index a7bfa9a5b0..5f7b360bdf 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/MockedRecentsModelHelper.kt +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/MockedRecentsModelHelper.kt @@ -19,6 +19,7 @@ package com.android.launcher3.taskbar.rules import com.android.quickstep.RecentsModel import com.android.quickstep.RecentsModel.RecentTasksChangedListener import com.android.quickstep.TaskIconCache +import com.android.quickstep.TaskThumbnailCache import com.android.quickstep.util.GroupTask import java.util.function.Consumer import org.mockito.kotlin.any @@ -27,9 +28,11 @@ import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock -/** Helper class to mock the {@link RecentsModel} object in test */ +/** Helper class to mock the [RecentsModel] object in test */ class MockedRecentsModelHelper { private val mockIconCache: TaskIconCache = mock() + private val mockThumbnailCache: TaskThumbnailCache = mock() + var taskListId = 0 var recentTasksChangedListener: RecentTasksChangedListener? = null var taskRequests: MutableList<(List) -> Unit> = mutableListOf() @@ -37,6 +40,8 @@ class MockedRecentsModelHelper { val mockRecentsModel: RecentsModel = mock { on { iconCache } doReturn mockIconCache + on { thumbnailCache } doReturn mockThumbnailCache + on { unregisterRecentTasksChangedListener() } doAnswer { recentTasksChangedListener = null } on { registerRecentTasksChangedListener(any()) } doAnswer