Merge "Add OverviewDesktop test to verify carousel behavior on swipe up" into main
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index 949acc1..5101851 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -506,3 +506,10 @@
description: "Enable launcher app contrast tiles."
bug: "341217082"
}
+
+flag {
+ name: "msdl_feedback"
+ namespace: "launcher"
+ description: "Enable MSDL feedback for Launcher interactions"
+ bug: "377496684"
+}
\ No newline at end of file
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 3ae2b89..5c80575 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -34,7 +34,6 @@
<string name="taskbar_view_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarViewCallbacksFactory</string>
<string name="launcher_restore_event_logger_class" translatable="false">com.android.quickstep.LauncherRestoreEventLoggerImpl</string>
<string name="taskbar_edu_tooltip_controller_class" translatable="false">com.android.launcher3.taskbar.TaskbarEduTooltipController</string>
- <string name="contextual_edu_manager_class" translatable="false">com.android.quickstep.contextualeducation.SystemContextualEduStatsManager</string>
<string name="nav_handle_long_press_handler_class" translatable="false"></string>
<string name="contextual_search_invoker_class" translatable="false"></string>
<string name="contextual_search_state_manager_class" translatable="false"></string>
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index a5cc32a..714838a 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -20,9 +20,9 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher;
-import static com.android.wm.shell.shared.GroupedRecentTaskInfo.TYPE_FREEFORM;
+import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM;
-import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
import android.app.KeyguardManager;
import android.app.TaskInfo;
import android.content.ComponentName;
@@ -40,7 +40,7 @@
import com.android.quickstep.util.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.wm.shell.recents.IRecentTasksListener;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import java.io.PrintWriter;
@@ -76,7 +76,7 @@
private @Nullable RecentsModel.RunningTasksListener mRunningTasksListener;
private @Nullable RecentsModel.RecentTasksChangedListener mRecentTasksChangedListener;
// Tasks are stored in order of least recently launched to most recently launched.
- private ArrayList<ActivityManager.RunningTaskInfo> mRunningTasks;
+ private ArrayList<RunningTaskInfo> mRunningTasks;
public RecentTasksList(Context context, LooperExecutor mainThreadExecutor,
KeyguardManager keyguardManager, SystemUiProxy sysUiProxy,
@@ -93,35 +93,38 @@
}
@Override
- public void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onRunningTaskAppeared(RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> {
RecentTasksList.this.onRunningTaskAppeared(taskInfo);
});
}
@Override
- public void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onRunningTaskVanished(RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> {
RecentTasksList.this.onRunningTaskVanished(taskInfo);
});
}
@Override
- public void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onRunningTaskChanged(RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> {
RecentTasksList.this.onRunningTaskChanged(taskInfo);
});
}
@Override
- public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onTaskMovedToFront(GroupedTaskInfo[] visibleTasks) {
mMainThreadExecutor.execute(() -> {
- topTaskTracker.onTaskMovedToFront(taskInfo);
+ // TODO(b/346588978): We currently are only sending a single task, but this will
+ // be updated once we send the full set of visible tasks
+ final TaskInfo info = visibleTasks[0].getTaskInfo1();
+ topTaskTracker.handleTaskMovedToFront(info);
});
}
@Override
- public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> topTaskTracker.onTaskChanged(taskInfo));
}
});
@@ -250,7 +253,7 @@
mRecentTasksChangedListener = null;
}
- private void initRunningTasks(ArrayList<ActivityManager.RunningTaskInfo> runningTasks) {
+ private void initRunningTasks(ArrayList<RunningTaskInfo> runningTasks) {
// Tasks are retrieved in order of most recently launched/used to least recently launched.
mRunningTasks = new ArrayList<>(runningTasks);
Collections.reverse(mRunningTasks);
@@ -259,13 +262,13 @@
/**
* Gets the set of running tasks.
*/
- public ArrayList<ActivityManager.RunningTaskInfo> getRunningTasks() {
+ public ArrayList<RunningTaskInfo> getRunningTasks() {
return mRunningTasks;
}
- private void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+ private void onRunningTaskAppeared(RunningTaskInfo taskInfo) {
// Make sure this task is not already in the list
- for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
+ for (RunningTaskInfo existingTask : mRunningTasks) {
if (taskInfo.taskId == existingTask.taskId) {
return;
}
@@ -276,9 +279,9 @@
}
}
- private void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ private void onRunningTaskVanished(RunningTaskInfo taskInfo) {
// Find the task from the list of running tasks, if it exists
- for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
+ for (RunningTaskInfo existingTask : mRunningTasks) {
if (existingTask.taskId != taskInfo.taskId) continue;
mRunningTasks.remove(existingTask);
@@ -289,9 +292,9 @@
}
}
- private void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ private void onRunningTaskChanged(RunningTaskInfo taskInfo) {
// Find the task from the list of running tasks, if it exists
- for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
+ for (RunningTaskInfo existingTask : mRunningTasks) {
if (existingTask.taskId != taskInfo.taskId) continue;
mRunningTasks.remove(existingTask);
@@ -309,7 +312,7 @@
@VisibleForTesting
TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
int currentUserId = Process.myUserHandle().getIdentifier();
- ArrayList<GroupedRecentTaskInfo> rawTasks;
+ ArrayList<GroupedTaskInfo> rawTasks;
try {
rawTasks = mSysUiProxy.getRecentTasks(numTasks, currentUserId);
} catch (SystemUiProxy.GetRecentTasksException e) {
@@ -332,7 +335,7 @@
TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());
int numVisibleTasks = 0;
- for (GroupedRecentTaskInfo rawTask : rawTasks) {
+ for (GroupedTaskInfo rawTask : rawTasks) {
if (rawTask.getType() == TYPE_FREEFORM) {
// TYPE_FREEFORM tasks is only created when desktop mode can be entered,
// leftover TYPE_FREEFORM tasks created when flag was on should be ignored.
@@ -344,14 +347,13 @@
}
continue;
}
- ActivityManager.RecentTaskInfo taskInfo1 = rawTask.getTaskInfo1();
- ActivityManager.RecentTaskInfo taskInfo2 = rawTask.getTaskInfo2();
+ TaskInfo taskInfo1 = rawTask.getTaskInfo1();
+ TaskInfo taskInfo2 = rawTask.getTaskInfo2();
Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
Task task1 = loadKeysOnly
? new Task(task1Key)
: Task.from(task1Key, taskInfo1,
tmpLockedUsers.get(task1Key.userId) /* isLocked */);
- task1.setLastSnapshotData(taskInfo1);
Task task2 = null;
if (taskInfo2 != null) {
// Is split task
@@ -360,7 +362,6 @@
? new Task(task2Key)
: Task.from(task2Key, taskInfo2,
tmpLockedUsers.get(task2Key.userId) /* isLocked */);
- task2.setLastSnapshotData(taskInfo2);
} else {
// Is fullscreen task
if (numVisibleTasks > 0) {
@@ -384,17 +385,16 @@
return allTasks;
}
- private @Nullable DesktopTask createDesktopTask(GroupedRecentTaskInfo recentTaskInfo) {
+ 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 (ActivityManager.RecentTaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) {
+ for (TaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) {
Task.TaskKey key = new Task.TaskKey(taskInfo);
Task task = Task.from(key, taskInfo, false);
- task.setLastSnapshotData(taskInfo);
task.positionInParent = taskInfo.positionInParent;
task.appBounds = taskInfo.configuration.windowConfiguration.getAppBounds();
task.isVisible = taskInfo.isVisible;
@@ -429,14 +429,14 @@
}
writer.println(prefix + " ]");
int currentUserId = Process.myUserHandle().getIdentifier();
- ArrayList<GroupedRecentTaskInfo> rawTasks;
+ ArrayList<GroupedTaskInfo> rawTasks;
try {
rawTasks = mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId);
} catch (SystemUiProxy.GetRecentTasksException e) {
rawTasks = new ArrayList<>();
}
writer.println(prefix + " rawTasks=[");
- for (GroupedRecentTaskInfo task : rawTasks) {
+ for (GroupedTaskInfo task : rawTasks) {
TaskInfo taskInfo1 = task.getTaskInfo1();
TaskInfo taskInfo2 = task.getTaskInfo2();
ComponentName cn1 = taskInfo1.topActivity;
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index cd39c09..73e22bb 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -91,7 +91,7 @@
import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.recents.IRecentsAnimationController;
import com.android.wm.shell.recents.IRecentsAnimationRunner;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.IShellTransitions;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -1358,15 +1358,15 @@
* @throws GetRecentTasksException if IRecentTasks is not initialized, or when we get
* RemoteException from server side
*/
- public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId)
- throws GetRecentTasksException {
+ public ArrayList<GroupedTaskInfo> getRecentTasks(int numTasks,
+ int userId) throws GetRecentTasksException {
if (mRecentTasks == null) {
Log.e(TAG, "getRecentTasks() failed due to null mRecentTasks");
throw new GetRecentTasksException("null mRecentTasks");
}
try {
- final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
- RECENT_IGNORE_UNAVAILABLE, userId);
+ final GroupedTaskInfo[] rawTasks =
+ mRecentTasks.getRecentTasks(numTasks, RECENT_IGNORE_UNAVAILABLE, userId);
if (rawTasks == null) {
return new ArrayList<>();
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 0b6794c..0ea128a 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -201,8 +201,7 @@
// Only finish if the end target is RECENTS. Otherwise, if the target is
// NEW_TASK, startActivityFromRecents will be skipped.
if (mLastGestureState.getEndTarget() == RECENTS) {
- finishRunningRecentsAnimation(false /* toHome */,
- true /* forceFinish */, null /* forceFinishCb */);
+ finishRunningRecentsAnimation(false /* toHome */);
}
});
}
diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java
index 71b6573..c9dfe6d 100644
--- a/quickstep/src/com/android/quickstep/TopTaskTracker.java
+++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java
@@ -27,6 +27,7 @@
import android.annotation.UserIdInt;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.TaskInfo;
import android.content.Context;
import androidx.annotation.NonNull;
@@ -67,7 +68,7 @@
private static final int HISTORY_SIZE = 5;
// Ordered list with first item being the most recent task.
- private final LinkedList<RunningTaskInfo> mOrderedTaskList = new LinkedList<>();
+ private final LinkedList<TaskInfo> mOrderedTaskList = new LinkedList<>();
private final Context mContext;
private final SplitStageInfo mMainStagePosition = new SplitStageInfo();
@@ -96,6 +97,10 @@
@Override
public void onTaskMovedToFront(RunningTaskInfo taskInfo) {
+ handleTaskMovedToFront(taskInfo);
+ }
+
+ public void handleTaskMovedToFront(TaskInfo taskInfo) {
mOrderedTaskList.removeIf(rto -> rto.taskId == taskInfo.taskId);
mOrderedTaskList.addFirst(taskInfo);
@@ -103,7 +108,7 @@
// display's task to the list, to avoid showing non-home display's task upon going to
// Recents animation.
if (taskInfo.displayId != DEFAULT_DISPLAY) {
- final RunningTaskInfo topTaskOnHomeDisplay = mOrderedTaskList.stream()
+ final TaskInfo topTaskOnHomeDisplay = mOrderedTaskList.stream()
.filter(rto -> rto.displayId == DEFAULT_DISPLAY).findFirst().orElse(null);
if (topTaskOnHomeDisplay != null) {
mOrderedTaskList.removeIf(rto -> rto.taskId == topTaskOnHomeDisplay.taskId);
@@ -113,9 +118,9 @@
if (mOrderedTaskList.size() >= HISTORY_SIZE) {
// If we grow in size, remove the last taskInfo which is not part of the split task.
- Iterator<RunningTaskInfo> itr = mOrderedTaskList.descendingIterator();
+ Iterator<TaskInfo> itr = mOrderedTaskList.descendingIterator();
while (itr.hasNext()) {
- RunningTaskInfo info = itr.next();
+ TaskInfo info = itr.next();
if (info.taskId != taskInfo.taskId
&& info.taskId != mMainStagePosition.taskId
&& info.taskId != mSideStagePosition.taskId) {
@@ -215,13 +220,13 @@
Collections.addAll(mOrderedTaskList, tasks);
}
- ArrayList<RunningTaskInfo> tasks = new ArrayList<>(mOrderedTaskList);
+ ArrayList<TaskInfo> tasks = new ArrayList<>(mOrderedTaskList);
// Strip the pinned task and recents task
tasks.removeIf(t -> t.taskId == mPinnedTaskId || isRecentsTask(t));
return new CachedTaskInfo(tasks);
}
- private static boolean isRecentsTask(RunningTaskInfo task) {
+ private static boolean isRecentsTask(TaskInfo task) {
return task != null && task.configuration.windowConfiguration
.getActivityType() == ACTIVITY_TYPE_RECENTS;
}
@@ -233,10 +238,10 @@
public static class CachedTaskInfo {
@Nullable
- private final RunningTaskInfo mTopTask;
- public final List<RunningTaskInfo> mAllCachedTasks;
+ private final TaskInfo mTopTask;
+ public final List<TaskInfo> mAllCachedTasks;
- CachedTaskInfo(List<RunningTaskInfo> allCachedTasks) {
+ CachedTaskInfo(List<TaskInfo> allCachedTasks) {
mAllCachedTasks = allCachedTasks;
mTopTask = allCachedTasks.isEmpty() ? null : allCachedTasks.get(0);
}
@@ -262,7 +267,7 @@
// Not an excluded task.
return null;
}
- List<RunningTaskInfo> visibleNonExcludedTasks = mAllCachedTasks.stream()
+ List<TaskInfo> visibleNonExcludedTasks = mAllCachedTasks.stream()
.filter(t -> t.isVisible
&& (t.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0
&& t.getActivityType() != ACTIVITY_TYPE_HOME
diff --git a/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java b/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java
index d470b88..6a72537 100644
--- a/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java
+++ b/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java
@@ -16,29 +16,28 @@
package com.android.quickstep.contextualeducation;
-import android.content.Context;
-
import com.android.launcher3.contextualeducation.ContextualEduStatsManager;
+import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.quickstep.SystemUiProxy;
import com.android.systemui.contextualeducation.GestureType;
+import javax.inject.Inject;
+
/**
* A class to update contextual education data via {@link SystemUiProxy}
*/
+@LauncherAppSingleton
public class SystemContextualEduStatsManager extends ContextualEduStatsManager {
- private Context mContext;
+ private final SystemUiProxy mSystemUiProxy;
- public SystemContextualEduStatsManager(Context context) {
- mContext = context;
+ @Inject
+ public SystemContextualEduStatsManager(SystemUiProxy systemUiProxy) {
+ mSystemUiProxy = systemUiProxy;
}
@Override
public void updateEduStats(boolean isTrackpadGesture, GestureType gestureType) {
- SystemUiProxy.INSTANCE.get(mContext).updateContextualEduStats(isTrackpadGesture,
+ mSystemUiProxy.updateContextualEduStats(isTrackpadGesture,
gestureType.name());
}
-
- @Override
- public void close() {
- }
}
diff --git a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
index 3870b9b..9f6360b 100644
--- a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
+++ b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
@@ -15,10 +15,12 @@
*/
package com.android.quickstep.dagger;
+import com.android.launcher3.contextualeducation.ContextualEduStatsManager;
import com.android.launcher3.uioverrides.SystemApiWrapper;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl;
import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.PluginManagerWrapper;
+import com.android.quickstep.contextualeducation.SystemContextualEduStatsManager;
import dagger.Binds;
import dagger.Module;
@@ -28,4 +30,6 @@
@Binds abstract PluginManagerWrapper bindPluginManagerWrapper(PluginManagerWrapperImpl impl);
@Binds abstract ApiWrapper bindApiWrapper(SystemApiWrapper systemApiWrapper);
+ @Binds abstract ContextualEduStatsManager bindContextualEduStatsManager(
+ SystemContextualEduStatsManager manager);
}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
index 78224ae..843ef6c 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
@@ -218,6 +218,11 @@
)
}
+ private val onBackInvokedCallback: () -> Unit = {
+ // If we are in live tile mode, launch the live task, otherwise return home
+ recentsView?.runningTaskView?.launchWithAnimation() ?: startHome()
+ }
+
private fun cleanupRecentsWindow() {
RecentsWindowProtoLogProxy.logCleanup(isShowing())
if (isShowing()) {
@@ -241,6 +246,10 @@
}
windowManager.addView(windowView, windowLayoutParams)
+ windowView
+ ?.findOnBackInvokedDispatcher()
+ ?.registerSystemOnBackInvokedCallback(onBackInvokedCallback)
+
windowView?.systemUiVisibility =
(View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
diff --git a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
index 4f38ec7..275af00 100644
--- a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
+++ b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
@@ -73,13 +73,17 @@
getTaskDataById(taskId).map { it?.thumbnail }.distinctUntilChangedBy { it?.snapshotId }
override fun setVisibleTasks(visibleTaskIdList: Set<Int>) {
- Log.d(TAG, "setVisibleTasks: $visibleTaskIdList")
-
// Remove tasks are no longer visible
val tasksNoLongerVisible = taskRequests.keys.subtract(visibleTaskIdList)
removeTasks(tasksNoLongerVisible)
// Add new tasks to be requested
- visibleTaskIdList.subtract(taskRequests.keys).forEach { taskId -> requestTaskData(taskId) }
+ val newlyVisibleTasks = visibleTaskIdList.subtract(taskRequests.keys)
+ newlyVisibleTasks.forEach { taskId -> requestTaskData(taskId) }
+
+ if (tasksNoLongerVisible.isNotEmpty() || newlyVisibleTasks.isNotEmpty()) {
+ Log.d(TAG, "setVisibleTasks to: $visibleTaskIdList, " +
+ "removed: $tasksNoLongerVisible, added: $newlyVisibleTasks")
+ }
}
private fun requestTaskData(taskId: Int) {
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
index c3d865f..32b5b85 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
@@ -23,6 +23,7 @@
import com.android.launcher3.dagger.LauncherAppComponent
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.util.LauncherModelHelper
+import com.android.quickstep.dagger.QuickStepModule
import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.shared.system.InputConsumerController
import dagger.BindsInstance
@@ -105,7 +106,7 @@
}
@LauncherAppSingleton
-@Component
+@Component(modules = [QuickStepModule::class])
interface TestComponent : LauncherAppComponent {
@Component.Builder
interface Builder : LauncherAppComponent.Builder {
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
index 244b897..b3c486c 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
@@ -28,7 +28,9 @@
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
import android.app.KeyguardManager;
+import android.app.TaskInfo;
import android.content.Context;
import android.content.res.Resources;
@@ -39,7 +41,7 @@
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.views.TaskViewType;
import com.android.systemui.shared.recents.model.Task;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import org.junit.Before;
import org.junit.Test;
@@ -91,8 +93,8 @@
@Test
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() throws Exception {
- GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(
- new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo(), null);
+ GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forSplitTasks(
+ new RecentTaskInfo(), new RecentTaskInfo(), null);
when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -119,12 +121,11 @@
@Test
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() throws Exception {
String taskDescription = "Wheeee!";
- ActivityManager.RecentTaskInfo task1 = new ActivityManager.RecentTaskInfo();
+ RecentTaskInfo task1 = new RecentTaskInfo();
task1.taskDescription = new ActivityManager.TaskDescription(taskDescription);
- ActivityManager.RecentTaskInfo task2 = new ActivityManager.RecentTaskInfo();
+ RecentTaskInfo task2 = new RecentTaskInfo();
task2.taskDescription = new ActivityManager.TaskDescription();
- GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(task1, task2,
- null);
+ GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forSplitTasks(task1, task2, null);
when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -138,11 +139,11 @@
@Test
public void loadTasksInBackground_freeformTask_createsDesktopTask() throws Exception {
- ActivityManager.RecentTaskInfo[] tasks = {
+ List<TaskInfo> tasks = Arrays.asList(
createRecentTaskInfo(1 /* taskId */),
createRecentTaskInfo(4 /* taskId */),
- createRecentTaskInfo(5 /* taskId */)};
- GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forFreeformTasks(
+ createRecentTaskInfo(5 /* taskId */));
+ GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forFreeformTasks(
tasks, Collections.emptySet() /* minimizedTaskIds */);
when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -162,14 +163,13 @@
@Test
public void loadTasksInBackground_freeformTask_onlyMinimizedTasks_doesNotCreateDesktopTask()
throws Exception {
- ActivityManager.RecentTaskInfo[] tasks = {
+ List<TaskInfo> tasks = Arrays.asList(
createRecentTaskInfo(1 /* taskId */),
createRecentTaskInfo(4 /* taskId */),
- createRecentTaskInfo(5 /* taskId */)};
+ createRecentTaskInfo(5 /* taskId */));
Set<Integer> minimizedTaskIds =
Arrays.stream(new Integer[]{1, 4, 5}).collect(Collectors.toSet());
- GroupedRecentTaskInfo recentTaskInfos =
- GroupedRecentTaskInfo.forFreeformTasks(tasks, minimizedTaskIds);
+ GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forFreeformTasks(tasks, minimizedTaskIds);
when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -179,8 +179,8 @@
assertEquals(0, taskList.size());
}
- private ActivityManager.RecentTaskInfo createRecentTaskInfo(int taskId) {
- ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
+ private TaskInfo createRecentTaskInfo(int taskId) {
+ RecentTaskInfo recentTaskInfo = new RecentTaskInfo();
recentTaskInfo.taskId = taskId;
return recentTaskInfo;
}
diff --git a/res/values/config.xml b/res/values/config.xml
index a1ccb67..f6f3c95 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -76,7 +76,6 @@
<string name="taskbar_view_callbacks_factory_class" translatable="false"></string>
<string name="launcher_restore_event_logger_class" translatable="false"></string>
<string name="taskbar_edu_tooltip_controller_class" translatable="false"></string>
- <string name="contextual_edu_manager_class" translatable="false"></string>
<!-- Used for determining category of a widget presented in widget recommendations. -->
<string name="widget_recommendation_category_provider_class" translatable="false"></string>
diff --git a/res/xml/backupscheme.xml b/res/xml/backupscheme.xml
index 27fddc8..58916a8 100644
--- a/res/xml/backupscheme.xml
+++ b/res/xml/backupscheme.xml
@@ -2,6 +2,7 @@
<full-backup-content xmlns:android="http://schemas.android.com/apk/res/android">
<include domain="database" path="launcher.db" />
+ <include domain="database" path="launcher_5_by_8.db" />
<include domain="database" path="launcher_6_by_5.db" />
<include domain="database" path="launcher_5_by_6.db" />
<include domain="database" path="launcher_4_by_6.db" />
diff --git a/res/xml/default_workspace_5x8.xml b/res/xml/default_workspace_5x8.xml
new file mode 100644
index 0000000..b078cfd
--- /dev/null
+++ b/res/xml/default_workspace_5x8.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+
+ <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+ <!-- Mail Calendar Gallery Store Internet Camera -->
+ <resolve
+ launcher:container="-101"
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
+ <favorite launcher:uri="mailto:" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="1"
+ launcher:x="1"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_CALENDAR;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="2"
+ launcher:x="2"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+ <favorite launcher:uri="#Intent;type=images/*;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="3"
+ launcher:x="3"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
+ <favorite launcher:uri="market://details?id=com.android.launcher" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="4"
+ launcher:x="4"
+ launcher:y="0" >
+ <favorite
+ launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+ <favorite launcher:uri="http://www.example.com/" />
+ </resolve>
+
+ <!-- Resolve camera intent if GoogleCamera is not available e.g. on emulator -->
+ <resolve
+ launcher:container="-101"
+ launcher:screen="5"
+ launcher:x="5"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+ </resolve>
+
+</favorites>
diff --git a/res/xml/paddings_5x8.xml b/res/xml/paddings_5x8.xml
new file mode 100644
index 0000000..afa70c5
--- /dev/null
+++ b/res/xml/paddings_5x8.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+ <device-padding
+ launcher:maxEmptySpace="100dp">
+ <workspaceTopPadding
+ launcher:a="0.31"
+ launcher:b="0"/>
+ <workspaceBottomPadding
+ launcher:a="0.69"
+ launcher:b="0"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="0"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="9999dp">
+ <workspaceTopPadding
+ launcher:a="0.48"
+ launcher:b="0"/>
+ <workspaceBottomPadding
+ launcher:a="0.52"
+ launcher:b="0"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="0"/>
+ </device-padding>
+</device-paddings>
\ No newline at end of file
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 7acba75..1b38695 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -52,7 +52,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.DotRenderer;
-import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.DeviceGridState;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.testing.shared.ResourceUtils;
@@ -303,35 +302,6 @@
DisplayController.INSTANCE.executeIfCreated(dc -> dc.setPriorityListener(null));
}
- /**
- * Reinitialize the current grid after a restore, where some grids might now be disabled.
- */
- public void reinitializeAfterRestore(Context context) {
- String currentGridName = getCurrentGridName(context);
- String currentDbFile = dbFile;
- String newGridName = initGrid(context, currentGridName);
- String newDbFile = dbFile;
- FileLog.d(TAG, "Reinitializing grid after restore."
- + " currentGridName=" + currentGridName
- + ", currentDbFile=" + currentDbFile
- + ", newGridName=" + newGridName
- + ", newDbFile=" + newDbFile);
- if (!newDbFile.equals(currentDbFile)) {
- FileLog.d(TAG, "Restored grid is disabled : " + currentGridName
- + ", migrating to: " + newGridName
- + ", removing all other grid db files");
- for (String gridDbFile : LauncherFiles.GRID_DB_FILES) {
- if (gridDbFile.equals(currentDbFile)) {
- continue;
- }
- if (context.getDatabasePath(gridDbFile).delete()) {
- FileLog.d(TAG, "Removed old grid db file: " + gridDbFile);
- }
- }
- setCurrentGrid(context, newGridName);
- }
- }
-
public static String getCurrentGridName(Context context) {
return LauncherPrefs.get(context).get(GRID_NAME);
}
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
index 1148f79..95c0ee8 100644
--- a/src/com/android/launcher3/LauncherFiles.java
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -16,6 +16,7 @@
private static final String XML = ".xml";
public static final String LAUNCHER_DB = "launcher.db";
+ public static final String LAUNCHER_5_BY_8_DB = "launcher_5_by_8.db";
public static final String LAUNCHER_6_BY_5_DB = "launcher_6_by_5.db";
public static final String LAUNCHER_4_BY_5_DB = "launcher_4_by_5.db";
public static final String LAUNCHER_4_BY_6_DB = "launcher_4_by_6.db";
@@ -35,6 +36,7 @@
public static final List<String> GRID_DB_FILES = Collections.unmodifiableList(Arrays.asList(
LAUNCHER_DB,
+ LAUNCHER_5_BY_8_DB,
LAUNCHER_6_BY_5_DB,
LAUNCHER_4_BY_5_DB,
LAUNCHER_4_BY_6_DB,
diff --git a/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java b/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java
index da13546..5664174 100644
--- a/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java
+++ b/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java
@@ -16,22 +16,25 @@
package com.android.launcher3.contextualeducation;
-import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
-
-import com.android.launcher3.R;
-import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.ResourceBasedOverride;
-import com.android.launcher3.util.SafeCloseable;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+import com.android.launcher3.dagger.LauncherBaseAppComponent;
+import com.android.launcher3.util.DaggerSingletonObject;
import com.android.systemui.contextualeducation.GestureType;
+import javax.inject.Inject;
+
/**
* A class to update contextual education data. It is a no-op implementation and could be
- * overridden by changing the resource value [R.string.contextual_edu_manager_class] to provide
- * a real implementation.
+ * overridden through dagger modules to provide a real implementation.
*/
-public class ContextualEduStatsManager implements ResourceBasedOverride, SafeCloseable {
- public static final MainThreadInitializedObject<ContextualEduStatsManager> INSTANCE =
- forOverride(ContextualEduStatsManager.class, R.string.contextual_edu_manager_class);
+@LauncherAppSingleton
+public class ContextualEduStatsManager {
+ public static final DaggerSingletonObject<ContextualEduStatsManager> INSTANCE =
+ new DaggerSingletonObject<>(LauncherBaseAppComponent::getContextualEduStatsManager);
+
+ @Inject
+ public ContextualEduStatsManager() { }
+
/**
* Updates contextual education stats when a gesture is triggered
@@ -40,8 +43,4 @@
*/
public void updateEduStats(boolean isTrackpadGesture, GestureType gestureType) {
}
-
- @Override
- public void close() {
- }
}
diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
index e89671e..8fe0409 100644
--- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
+++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
@@ -18,6 +18,7 @@
import android.content.Context;
+import com.android.launcher3.contextualeducation.ContextualEduStatsManager;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.util.ApiWrapper;
@@ -43,6 +44,7 @@
public interface LauncherBaseAppComponent {
DaggerSingletonTracker getDaggerSingletonTracker();
ApiWrapper getApiWrapper();
+ ContextualEduStatsManager getContextualEduStatsManager();
CustomWidgetManager getCustomWidgetManager();
IconShape getIconShape();
InstallSessionHelper getInstallSessionHelper();
diff --git a/src/com/android/launcher3/model/GridSizeMigrationDBController.java b/src/com/android/launcher3/model/GridSizeMigrationDBController.java
index bad7577..2d6be7e 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationDBController.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationDBController.java
@@ -38,7 +38,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.Flags;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
@@ -86,6 +85,9 @@
if (needsToMigrate) {
Log.i(TAG, "Migration is needed. destDeviceState: " + destDeviceState
+ ", srcDeviceState: " + srcDeviceState);
+ } else {
+ Log.i(TAG, "Migration is not needed. destDeviceState: " + destDeviceState
+ + ", srcDeviceState: " + srcDeviceState);
}
return needsToMigrate;
}
@@ -118,21 +120,13 @@
@NonNull DatabaseHelper target,
@NonNull SQLiteDatabase source) {
- Log.i("b/360462379", "Going from " + srcDeviceState.getColumns() + "x"
- + srcDeviceState.getRows());
- Log.i("b/360462379", "Going to " + destDeviceState.getColumns() + "x"
- + destDeviceState.getRows());
-
if (!needsToMigrate(srcDeviceState, destDeviceState)) {
- Log.i("b/360462379", "Does not need to migrate.");
return true;
}
if (LauncherPrefs.get(context).get(IS_FIRST_LOAD_AFTER_RESTORE)
- && Flags.enableGridMigrationFix()
&& srcDeviceState.getColumns().equals(destDeviceState.getColumns())
&& srcDeviceState.getRows() < destDeviceState.getRows()) {
- Log.i("b/360462379", "Grid migration fix entry point.");
// Only use this strategy when comparing the previous grid to the new grid and the
// columns are the same and the destination has more rows
copyTable(source, TABLE_NAME, target.getWritableDatabase(), TABLE_NAME, context);
diff --git a/src/com/android/launcher3/model/GridSizeMigrationLogic.kt b/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
index 9470abf..07316ef 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
+++ b/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
@@ -339,7 +339,7 @@
srcDeviceState: DeviceGridState,
destDeviceState: DeviceGridState,
): Boolean {
- return (isFirstLoad && Flags.enableGridMigrationFix()) &&
+ return isFirstLoad &&
srcDeviceState.columns == destDeviceState.columns &&
srcDeviceState.rows < destDeviceState.rows
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 59c27af..8db981f 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -51,7 +51,6 @@
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
-import com.android.launcher3.Flags;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherFiles;
@@ -124,18 +123,14 @@
// executed again.
LauncherPrefs.get(context).removeSync(RESTORE_DEVICE);
- if (Flags.enableNarrowGridRestore()) {
- DeviceGridState deviceGridState = new DeviceGridState(context);
- String oldPhoneFileName = deviceGridState.getDbFile();
- List<String> previousDbs = existingDbs(context);
- removeOldDBs(context, oldPhoneFileName);
- // The idp before this contains data about the old phone, after this it becomes the idp
- // of the current phone.
- idp.reset(context);
- trySettingPreviousGridAsCurrent(context, idp, oldPhoneFileName, previousDbs);
- } else {
- idp.reinitializeAfterRestore(context);
- }
+ DeviceGridState deviceGridState = new DeviceGridState(context);
+ String oldPhoneFileName = deviceGridState.getDbFile();
+ List<String> previousDbs = existingDbs(context);
+ removeOldDBs(context, oldPhoneFileName);
+ // The idp before this contains data about the old phone, after this it becomes the idp
+ // of the current phone.
+ idp.reset(context);
+ trySettingPreviousGridAsCurrent(context, idp, oldPhoneFileName, previousDbs);
}