Merge "Show desktop tasks when taskbar is pinned on home" into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
index cb16345..b928de0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
@@ -28,6 +28,7 @@
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayDragLayer;
import com.android.launcher3.util.TouchController;
+import com.android.quickstep.RecentsFilterState;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.GroupTask;
@@ -153,6 +154,8 @@
// Skip the task reload if the list is not changed.
if (!mModel.isTaskListValid(mTaskListChangeId) || !taskIdsToExclude.equals(
mExcludedTaskIds)) {
+ final boolean shouldShowDesktopTasks = mControllers.taskbarDesktopModeController
+ .shouldShowDesktopTasksInTaskbar();
mExcludedTaskIds = taskIdsToExclude;
mTaskListChangeId = mModel.getTasks((tasks) -> {
processLoadedTasks(tasks, taskIdsToExclude);
@@ -162,7 +165,8 @@
currentFocusIndexOverride,
mHasDesktopTask,
mWasDesktopTaskFilteredOut);
- });
+ }, shouldShowDesktopTasks ? RecentsFilterState.EMPTY_FILTER
+ : RecentsFilterState.getEmptyDesktopTaskFilter());
}
mQuickSwitchViewController.updateLayoutForSurface(wasOpenedFromTaskbar,
@@ -188,8 +192,8 @@
mQuickSwitchViewController = new KeyboardQuickSwitchViewController(
mControllers, mOverlayContext, keyboardQuickSwitchView, mControllerCallbacks);
- final boolean onDesktop = mControllers.taskbarDesktopModeController
- .getAreDesktopTasksVisibleAndNotInOverview();
+ final boolean shouldShowDesktopTasks = mControllers.taskbarDesktopModeController
+ .shouldShowDesktopTasksInTaskbar();
if (mModel.isTaskListValid(mTaskListChangeId)
&& taskIdsToExclude.equals(mExcludedTaskIds)) {
@@ -201,7 +205,7 @@
/* updateTasks= */ false,
currentFocusedIndex == -1 && !mControllerCallbacks.isFirstTaskRunning()
? 0 : currentFocusedIndex,
- onDesktop,
+ shouldShowDesktopTasks,
mHasDesktopTask,
mWasDesktopTaskFilteredOut,
wasOpenedFromTaskbar);
@@ -219,11 +223,12 @@
/* updateTasks= */ true,
currentFocusedIndex == -1 && !mControllerCallbacks.isFirstTaskRunning()
? 0 : currentFocusedIndex,
- onDesktop,
+ shouldShowDesktopTasks,
mHasDesktopTask,
mWasDesktopTaskFilteredOut,
wasOpenedFromTaskbar);
- });
+ }, shouldShowDesktopTasks ? RecentsFilterState.EMPTY_FILTER
+ : RecentsFilterState.getEmptyDesktopTaskFilter());
}
private boolean shouldExcludeTask(GroupTask task, Set<Integer> taskIdsToExclude) {
@@ -233,7 +238,7 @@
private void processLoadedTasks(List<GroupTask> tasks, Set<Integer> taskIdsToExclude) {
mHasDesktopTask = false;
mWasDesktopTaskFilteredOut = false;
- if (mControllers.taskbarDesktopModeController.getAreDesktopTasksVisibleAndNotInOverview()) {
+ if (mControllers.taskbarDesktopModeController.shouldShowDesktopTasksInTaskbar()) {
processLoadedTasksOnDesktop(tasks, taskIdsToExclude);
} else {
processLoadedTasksOutsideDesktop(tasks, taskIdsToExclude);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index e28e488..4b7fe38 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -368,7 +368,8 @@
new KeyboardQuickSwitchController(),
new TaskbarPinningController(this),
bubbleControllersOptional,
- new TaskbarDesktopModeController(DesktopVisibilityController.INSTANCE.get(this)));
+ new TaskbarDesktopModeController(this,
+ DesktopVisibilityController.INSTANCE.get(this)));
mLauncherPrefs = LauncherPrefs.get(this);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDesktopModeController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDesktopModeController.kt
index a7c7381..8806bc6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDesktopModeController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDesktopModeController.kt
@@ -16,13 +16,16 @@
package com.android.launcher3.taskbar
+import android.content.Context
import com.android.launcher3.statehandlers.DesktopVisibilityController
import com.android.launcher3.statehandlers.DesktopVisibilityController.TaskbarDesktopModeListener
import com.android.launcher3.taskbar.TaskbarBackgroundRenderer.Companion.MAX_ROUNDNESS
+import com.android.launcher3.util.DisplayController
/** Handles Taskbar in Desktop Windowing mode. */
class TaskbarDesktopModeController(
- private val desktopVisibilityController: DesktopVisibilityController
+ private val context: Context,
+ private val desktopVisibilityController: DesktopVisibilityController,
) : TaskbarDesktopModeListener {
private lateinit var taskbarControllers: TaskbarControllers
private lateinit var taskbarSharedState: TaskbarSharedState
@@ -45,6 +48,12 @@
taskbarControllers.taskbarCornerRoundness.animateToValue(cornerRadius).start()
}
+ fun shouldShowDesktopTasksInTaskbar(): Boolean {
+ return desktopVisibilityController.areDesktopTasksVisible() ||
+ DisplayController.showLockedTaskbarOnHome(context) &&
+ taskbarControllers.taskbarStashController.isOnHome
+ }
+
fun getTaskbarCornerRoundness(doesAnyTaskRequireTaskbarRounding: Boolean): Float {
return if (doesAnyTaskRequireTaskbarRounding) {
MAX_ROUNDNESS
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
index 4afabde..cba2af5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
@@ -26,6 +26,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
import com.android.launcher3.util.CancellableTask
+import com.android.quickstep.RecentsFilterState
import com.android.quickstep.RecentsModel
import com.android.quickstep.util.DesktopTask
import com.android.quickstep.util.GroupTask
@@ -119,7 +120,7 @@
get() {
if (
!canShowRunningApps ||
- !controllers.taskbarDesktopModeController.areDesktopTasksVisible
+ !controllers.taskbarDesktopModeController.shouldShowDesktopTasksInTaskbar()
) {
return emptySet()
}
@@ -135,7 +136,7 @@
get() {
if (
!canShowRunningApps ||
- !controllers.taskbarDesktopModeController.areDesktopTasksVisible
+ !controllers.taskbarDesktopModeController.shouldShowDesktopTasksInTaskbar()
) {
return emptySet()
}
@@ -171,10 +172,10 @@
/** Called to update hotseatItems, in order to de-dupe them from Recent/Running tasks later. */
fun updateHotseatItemInfos(hotseatItems: Array<ItemInfo?>): Array<ItemInfo?> {
// Ignore predicted apps - we show running or recent apps instead.
- val areDesktopTasksVisible = controllers.taskbarDesktopModeController.areDesktopTasksVisible
+ val showDesktopTasks =
+ controllers.taskbarDesktopModeController.shouldShowDesktopTasksInTaskbar()
val removePredictions =
- (areDesktopTasksVisible && canShowRunningApps) ||
- (!areDesktopTasksVisible && canShowRecentApps)
+ (showDesktopTasks && canShowRunningApps) || (!showDesktopTasks && canShowRecentApps)
if (!removePredictions) {
shownHotseatItems = hotseatItems.filterNotNull()
onRecentsOrHotseatChanged()
@@ -186,7 +187,7 @@
.filter { itemInfo -> !itemInfo.isPredictedItem }
.toMutableList()
- if (areDesktopTasksVisible && canShowRunningApps) {
+ if (showDesktopTasks && canShowRunningApps) {
shownHotseatItems =
updateHotseatItemsFromRunningTasks(
getOrderedAndWrappedDesktopTasks(),
@@ -210,19 +211,24 @@
private fun reloadRecentTasksIfNeeded() {
if (!recentsModel.isTaskListValid(taskListChangeId)) {
taskListChangeId =
- recentsModel.getTasks { tasks ->
- allRecentTasks = tasks
- val oldRunningTaskdIds = runningTaskIds
- val oldMinimizedTaskIds = minimizedTaskIds
- desktopTask = allRecentTasks.filterIsInstance<DesktopTask>().firstOrNull()
- val runningTasksChanged = oldRunningTaskdIds != runningTaskIds
- val minimizedTasksChanged = oldMinimizedTaskIds != minimizedTaskIds
- if (
- onRecentsOrHotseatChanged() || runningTasksChanged || minimizedTasksChanged
- ) {
- controllers.taskbarViewController.commitRunningAppsToUI()
- }
- }
+ recentsModel.getTasks(
+ { tasks ->
+ allRecentTasks = tasks
+ val oldRunningTaskdIds = runningTaskIds
+ val oldMinimizedTaskIds = minimizedTaskIds
+ desktopTask = allRecentTasks.filterIsInstance<DesktopTask>().firstOrNull()
+ val runningTasksChanged = oldRunningTaskdIds != runningTaskIds
+ val minimizedTasksChanged = oldMinimizedTaskIds != minimizedTaskIds
+ if (
+ onRecentsOrHotseatChanged() ||
+ runningTasksChanged ||
+ minimizedTasksChanged
+ ) {
+ controllers.taskbarViewController.commitRunningAppsToUI()
+ }
+ },
+ RecentsFilterState.EMPTY_FILTER,
+ )
}
}
@@ -235,7 +241,7 @@
val oldShownTasks = shownTasks
orderedRunningTaskIds = updateOrderedRunningTaskIds()
shownTasks =
- if (controllers.taskbarDesktopModeController.areDesktopTasksVisible) {
+ if (controllers.taskbarDesktopModeController.shouldShowDesktopTasksInTaskbar()) {
computeShownRunningTasks()
} else {
computeShownRecentTasks()
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 502c001..025ad87 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -269,6 +269,8 @@
private final long mTaskbarBackgroundDuration;
private boolean mUserIsNotGoingHome = false;
+ private final boolean mInAppStateAffectsDesktopTasksVisibilityInTaskbar;
+
// Evaluate whether the handle should be stashed
private final LongPredicate mIsStashedPredicate = flags -> {
boolean inApp = hasAnyFlag(flags, FLAGS_IN_APP);
@@ -293,8 +295,17 @@
mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity);
mAccessibilityManager = mActivity.getSystemService(AccessibilityManager.class);
- mTaskbarBackgroundDuration =
- activity.getResources().getInteger(R.integer.taskbar_background_duration);
+ // Taskbar, via `TaskbarDesktopModeController`, depends on `TaskbarStashController` state to
+ // determine whether desktop tasks should be shown because taskbar is pinned on the home
+ // screen for freeform windowing displays. In this case, list of items shown in the taskbar
+ // needs to be updated when in-app state changes.
+ // TODO(b/390665752): Feature to "lock" pinned taskbar to home screen will be superseded by
+ // pinning, in other launcher states, at which point this variable can be removed.
+ mInAppStateAffectsDesktopTasksVisibilityInTaskbar =
+ DisplayController.showLockedTaskbarOnHome(mActivity);
+
+ mTaskbarBackgroundDuration = activity.getResources().getInteger(
+ R.integer.taskbar_background_duration);
if (mActivity.isPhoneMode()) {
mUnstashedHeight = mActivity.getResources().getDimensionPixelSize(
R.dimen.taskbar_phone_size);
@@ -1237,6 +1248,10 @@
if (hasAnyFlag(changedFlags, FLAG_IN_OVERVIEW | FLAG_IN_APP)) {
mControllers.runAfterInit(() -> mControllers.taskbarInsetsController
.onTaskbarOrBubblebarWindowHeightOrInsetsChanged());
+ if (mInAppStateAffectsDesktopTasksVisibilityInTaskbar) {
+ mControllers.runAfterInit(
+ () -> mControllers.taskbarViewController.commitRunningAppsToUI());
+ }
}
mActivity.applyForciblyShownFlagWhileTransientTaskbarUnstashed(!isStashedInApp());
}
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index ee4ee38..379d71b4 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -419,10 +419,6 @@
private @Nullable DesktopTask createDesktopTask(GroupedTaskInfo recentTaskInfo) {
ArrayList<Task> tasks = new ArrayList<>(recentTaskInfo.getTaskInfoList().size());
int[] minimizedTaskIds = recentTaskInfo.getMinimizedTaskIds();
- if (minimizedTaskIds.length == recentTaskInfo.getTaskInfoList().size()) {
- // All Tasks are minimized -> don't create a DesktopTask
- return null;
- }
for (TaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) {
Task.TaskKey key = new Task.TaskKey(taskInfo);
Task task = Task.from(key, taskInfo, false);
diff --git a/quickstep/src/com/android/quickstep/RecentsFilterState.java b/quickstep/src/com/android/quickstep/RecentsFilterState.java
index 70d5696..c4b0f25 100644
--- a/quickstep/src/com/android/quickstep/RecentsFilterState.java
+++ b/quickstep/src/com/android/quickstep/RecentsFilterState.java
@@ -19,6 +19,7 @@
import androidx.annotation.Nullable;
import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.views.TaskViewType;
import com.android.systemui.shared.recents.model.Task;
import java.util.HashMap;
@@ -38,7 +39,7 @@
public static final int MIN_FILTERING_TASK_COUNT = 2;
// default filter that returns true for any input
- public static final Predicate<GroupTask> DEFAULT_FILTER = (groupTask -> true);
+ public static final Predicate<GroupTask> EMPTY_FILTER = (groupTask -> true);
// the package name to filter recent tasks by
@Nullable
@@ -116,14 +117,37 @@
* Returns a predicate for filtering out GroupTasks by package name.
*
* @param packageName package name to filter GroupTasks by
- * if null, Predicate always returns true.
+ * if null, Predicate filters out desktop tasks with no non-minimized tasks.
*/
public static Predicate<GroupTask> getFilter(@Nullable String packageName) {
if (packageName == null) {
- return DEFAULT_FILTER;
+ return getEmptyDesktopTaskFilter();
}
- return (groupTask) -> (groupTask.containsPackage(packageName));
+ return (groupTask) -> (groupTask.containsPackage(packageName)
+ && !isDestopTaskWithMinimizedTasksOnly(groupTask));
+ }
+
+ /**
+ * Returns a predicate that filters out desk tasks that contain no non-minimized desktop tasks.
+ */
+ public static Predicate<GroupTask> getEmptyDesktopTaskFilter() {
+ return (groupTask -> !isDestopTaskWithMinimizedTasksOnly(groupTask));
+ }
+
+ /**
+ * Whether the provided task is a desktop task with no non-minimized tasks - returns true if the
+ * desktop task has no tasks at all.
+ *
+ * @param groupTask The group task to check.
+ */
+ static boolean isDestopTaskWithMinimizedTasksOnly(GroupTask groupTask) {
+ if (groupTask.taskViewType != TaskViewType.DESKTOP) {
+ return false;
+ }
+ return groupTask.getTasks().stream()
+ .filter(task -> !task.isMinimized)
+ .toList().isEmpty();
}
/**
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 6498b7a..dc5d59f 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -154,7 +154,7 @@
/**
* Fetches the list of recent tasks. Tasks are ordered by recency, with the latest active tasks
- * at the end of the list.
+ * at the end of the list. Filters out desktop tasks that contain no non-minimized tasks.
*
* @param callback The callback to receive the task plan once its complete or null. This is
* always called on the UI thread.
@@ -163,7 +163,7 @@
@Override
public int getTasks(@Nullable Consumer<List<GroupTask>> callback) {
return mTaskList.getTasks(false /* loadKeysOnly */, callback,
- RecentsFilterState.DEFAULT_FILTER);
+ RecentsFilterState.getEmptyDesktopTaskFilter());
}
/**
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
index 8d8e62e..8805cb1 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
@@ -147,7 +147,7 @@
@Test
fun canShowRunningAndRecentAppsIsFalseAfterInit_getTasksOnlyCalledInInit() {
// getTasks() should have been called once from init().
- verify(mockRecentsModel, times(1)).getTasks(any<Consumer<List<GroupTask>>>())
+ verify(mockRecentsModel, times(1)).getTasks(any<Consumer<List<GroupTask>>>(), any())
recentAppsController.canShowRunningApps = false
recentAppsController.canShowRecentApps = false
prepareHotseatAndRunningAndRecentApps(
@@ -156,7 +156,7 @@
recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
// Verify that getTasks() was not called again after the init().
- verify(mockRecentsModel, times(1)).getTasks(any<Consumer<List<GroupTask>>>())
+ verify(mockRecentsModel, times(1)).getTasks(any<Consumer<List<GroupTask>>>(), any())
}
@Test
@@ -881,7 +881,7 @@
taskListChangeId
}
.whenever(mockRecentsModel)
- .getTasks(any<Consumer<List<GroupTask>>>())
+ .getTasks(any<Consumer<List<GroupTask>>>(), any())
recentTasksChangedListener?.onRecentTasksChanged()
}
@@ -945,7 +945,7 @@
}
private fun setInDesktopMode(inDesktopMode: Boolean) {
- whenever(taskbarControllers.taskbarDesktopModeController.areDesktopTasksVisible)
+ whenever(taskbarControllers.taskbarDesktopModeController.shouldShowDesktopTasksInTaskbar())
.thenReturn(inDesktopMode)
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentTasksListTest.java
index ccfe36d..4a7c537 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentTasksListTest.java
@@ -21,6 +21,8 @@
import static junit.framework.TestCase.assertNull;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -160,12 +162,15 @@
List<Task> actualFreeformTasks = taskList.get(0).getTasks();
assertEquals(3, actualFreeformTasks.size());
assertEquals(1, actualFreeformTasks.get(0).key.id);
+ assertFalse(actualFreeformTasks.get(0).isMinimized);
assertEquals(4, actualFreeformTasks.get(1).key.id);
+ assertFalse(actualFreeformTasks.get(1).isMinimized);
assertEquals(5, actualFreeformTasks.get(2).key.id);
+ assertFalse(actualFreeformTasks.get(2).isMinimized);
}
@Test
- public void loadTasksInBackground_freeformTask_onlyMinimizedTasks_doesNotCreateDesktopTask()
+ public void loadTasksInBackground_freeformTask_onlyMinimizedTasks_createDesktopTask()
throws Exception {
List<TaskInfo> tasks = Arrays.asList(
createRecentTaskInfo(1 /* taskId */),
@@ -180,7 +185,16 @@
List<GroupTask> taskList = mRecentTasksList.loadTasksInBackground(
Integer.MAX_VALUE /* numTasks */, -1 /* requestId */, false /* loadKeysOnly */);
- assertEquals(0, taskList.size());
+ assertEquals(1, taskList.size());
+ assertEquals(TaskViewType.DESKTOP, taskList.get(0).taskViewType);
+ List<Task> actualFreeformTasks = taskList.get(0).getTasks();
+ assertEquals(3, actualFreeformTasks.size());
+ assertEquals(1, actualFreeformTasks.get(0).key.id);
+ assertTrue(actualFreeformTasks.get(0).isMinimized);
+ assertEquals(4, actualFreeformTasks.get(1).key.id);
+ assertTrue(actualFreeformTasks.get(1).isMinimized);
+ assertEquals(5, actualFreeformTasks.get(2).key.id);
+ assertTrue(actualFreeformTasks.get(2).isMinimized);
}
private TaskInfo createRecentTaskInfo(int taskId) {