Merge "Ensure some taskbar states are initialized correctly" into sc-v2-dev
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index c5b191e..4ec16ad 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1396,7 +1396,7 @@
// Removing views sets the currentPage to 0, so we save this and restore it after
// the new set of views are added
- int previousPage = mCurrentPage;
+ int previousCurrentPage = mCurrentPage;
removeAllViews();
// Add views as children based on whether it's grouped or single task
@@ -1420,7 +1420,14 @@
if (!taskGroups.isEmpty()) {
addView(mClearAllButton);
}
- setCurrentPage(previousPage);
+
+ boolean settlingOnNewTask = mNextPage != INVALID_PAGE;
+ if (settlingOnNewTask) {
+ // Restore mCurrentPage but don't call setCurrentPage() as that clobbers the scroll.
+ mCurrentPage = previousCurrentPage;
+ } else {
+ setCurrentPage(previousCurrentPage);
+ }
// Keep same previous focused task
TaskView newFocusedTaskView = getTaskViewByTaskId(focusedTaskId);
@@ -1446,7 +1453,7 @@
}
int targetPage = -1;
- if (mNextPage == INVALID_PAGE) {
+ if (!settlingOnNewTask) {
// Set the current page to the running task, but not if settling on new task.
if (runningTaskId != -1) {
targetPage = indexOfChild(newRunningTaskView);
@@ -2254,7 +2261,7 @@
updateChildTaskOrientations();
// Reload the task list
- mTaskListChangeId = mModel.getTasks(this::applyLoadPlan);
+ reloadIfNeeded();
}
/**
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index e30829e..1e8e3ca 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -376,6 +376,7 @@
protected LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() {
LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
itemBuilder.setIsWork(!Process.myUserHandle().equals(user));
+ itemBuilder.setRank(rank);
return itemBuilder;
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 41c7c37..5b940a8 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -423,6 +423,18 @@
waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
}
+ @Test
+ @PortraitLandscape
+ public void testDeleteFromWorkspace() throws Exception {
+ // test delete both built-in apps and user-installed app from workspace
+ for (String appName : new String[] {"Gmail", "Play Store", APP_NAME}) {
+ final AppIcon appIcon = createShortcutIfNotExist(appName);
+ Workspace workspace = mLauncher.getWorkspace().deleteAppIcon(appIcon);
+ assertNull(appName + " app was found after being deleted from workspace",
+ workspace.tryGetWorkspaceAppIcon(appName));
+ }
+ }
+
public static String getAppPackageName() {
return getInstrumentation().getContext().getPackageName();
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 91b1bc7..631e8f1 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1399,14 +1399,15 @@
final Point start = new Point(startX, startY);
final Point end = new Point(endX, endY);
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
- final long endTime = movePointer(start, end, steps, downTime, slowDown, gestureScope);
+ final long endTime = movePointer(
+ start, end, steps, false, downTime, slowDown, gestureScope);
sendPointer(downTime, endTime, MotionEvent.ACTION_UP, end, gestureScope);
}
- long movePointer(Point start, Point end, int steps, long downTime, boolean slowDown,
- GestureScope gestureScope) {
- long endTime = movePointer(
- downTime, downTime, steps * GESTURE_STEP_MS, start, end, gestureScope);
+ long movePointer(Point start, Point end, int steps, boolean isDecelerating,
+ long downTime, boolean slowDown, GestureScope gestureScope) {
+ long endTime = movePointer(downTime, downTime, steps * GESTURE_STEP_MS,
+ isDecelerating, start, end, gestureScope);
if (slowDown) {
endTime = movePointer(downTime, endTime + GESTURE_STEP_MS, 5 * GESTURE_STEP_MS, end,
end, gestureScope);
@@ -1485,21 +1486,55 @@
public long movePointer(long downTime, long startTime, long duration, Point from, Point to,
GestureScope gestureScope) {
+ return movePointer(
+ downTime, startTime, duration, false, from, to, gestureScope);
+ }
+
+ public long movePointer(long downTime, long startTime, long duration, boolean isDecelerating,
+ Point from, Point to, GestureScope gestureScope) {
log("movePointer: " + from + " to " + to);
final Point point = new Point();
long steps = duration / GESTURE_STEP_MS;
+
long currentTime = startTime;
- for (long i = 0; i < steps; ++i) {
- sleep(GESTURE_STEP_MS);
- currentTime += GESTURE_STEP_MS;
- final float progress = (currentTime - startTime) / (float) duration;
+ if (isDecelerating) {
+ // formula: V = V0 - D*T, assuming V = 0 when T = duration
- point.x = from.x + (int) (progress * (to.x - from.x));
- point.y = from.y + (int) (progress * (to.y - from.y));
+ // vx0: initial speed at the x-dimension, set as twice the avg speed
+ // dx: the constant deceleration at the x-dimension
+ double vx0 = 2 * (to.x - from.x) / duration;
+ double dx = vx0 / duration;
+ // vy0: initial speed at the y-dimension, set as twice the avg speed
+ // dy: the constant deceleration at the y-dimension
+ double vy0 = 2 * (to.y - from.y) / duration;
+ double dy = vy0 / duration;
- sendPointer(downTime, currentTime, MotionEvent.ACTION_MOVE, point, gestureScope);
+ for (long i = 0; i < steps; ++i) {
+ sleep(GESTURE_STEP_MS);
+ currentTime += GESTURE_STEP_MS;
+
+ // formula: P = P0 + V0*T - (D*T^2/2)
+ final double t = (i + 1) * GESTURE_STEP_MS;
+ point.x = from.x + (int) (vx0 * t - 0.5 * dx * t * t);
+ point.y = from.y + (int) (vy0 * t - 0.5 * dy * t * t);
+
+ sendPointer(downTime, currentTime, MotionEvent.ACTION_MOVE, point, gestureScope);
+ }
+ } else {
+ for (long i = 0; i < steps; ++i) {
+ sleep(GESTURE_STEP_MS);
+ currentTime += GESTURE_STEP_MS;
+
+ final float progress = (currentTime - startTime) / (float) duration;
+ point.x = from.x + (int) (progress * (to.x - from.x));
+ point.y = from.y + (int) (progress * (to.y - from.y));
+
+ sendPointer(downTime, currentTime, MotionEvent.ACTION_MOVE, point, gestureScope);
+
+ }
}
+
return currentTime;
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index d9f5cc8..3f0d7fd 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -46,6 +46,9 @@
*/
public final class Workspace extends Home {
private static final int FLING_STEPS = 10;
+ private static final int DEFAULT_DRAG_STEPS = 10;
+ private static final String DROP_BAR_RES_ID = "drop_target_bar";
+ private static final String DELETE_TARGET_TEXT_ID = "delete_target_text";
static final Pattern EVENT_CTRL_W_DOWN = Pattern.compile(
"Key event: KeyEvent.*?action=ACTION_DOWN.*?keyCode=KEYCODE_W"
@@ -211,6 +214,40 @@
TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
+ /*
+ * Get the center point of the delete icon in the drop target bar.
+ */
+ private Point getDeleteDropPoint() {
+ return mLauncher.waitForObjectInContainer(
+ mLauncher.waitForLauncherObject(DROP_BAR_RES_ID),
+ DELETE_TARGET_TEXT_ID).getVisibleCenter();
+ }
+
+ /**
+ * Delete the appIcon from the workspace.
+ *
+ * @param appIcon to be deleted.
+ * @return validated workspace after the existing appIcon being deleted.
+ */
+ public Workspace deleteAppIcon(AppIcon appIcon) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "removing app icon from workspace")) {
+ dragIconToWorkspace(
+ mLauncher, appIcon,
+ () -> getDeleteDropPoint(),
+ true, /* decelerating */
+ appIcon.getLongPressIndicator(),
+ () -> mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT),
+ null);
+
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "dragged the app to the drop bar")) {
+ return new Workspace(mLauncher);
+ }
+ }
+ }
+
/**
* Finds folder icons in the current workspace.
*
@@ -241,8 +278,8 @@
expectLongClickEvents.run();
launcher.waitForLauncherObject(longPressIndicator);
LauncherInstrumentation.log("dragIconToSpringLoaded: indicator");
- launcher.movePointer(iconCenter, dragStartCenter, 10, downTime, true,
- LauncherInstrumentation.GestureScope.INSIDE);
+ launcher.movePointer(iconCenter, dragStartCenter, DEFAULT_DRAG_STEPS, false,
+ downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
}, SPRING_LOADED_STATE_ORDINAL, "long-pressing and triggering drag start");
return dragStartCenter;
}
@@ -270,7 +307,7 @@
expectDropEvents = () -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN,
LauncherInstrumentation.EVENT_START);
}
- dragIconToWorkspace(launcher, launchable, () -> dest, longPressIndicator,
+ dragIconToWorkspace(launcher, launchable, () -> dest, false, longPressIndicator,
expectLongClickEvents, expectDropEvents);
}
@@ -280,13 +317,13 @@
*/
static void dragIconToWorkspace(LauncherInstrumentation launcher, Launchable launchable,
Supplier<Point> destSupplier, String longPressIndicator) {
- dragIconToWorkspace(launcher, launchable, destSupplier, longPressIndicator,
+ dragIconToWorkspace(launcher, launchable, destSupplier, false, longPressIndicator,
() -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT), null);
}
static void dragIconToWorkspace(
LauncherInstrumentation launcher, Launchable launchable, Supplier<Point> dest,
- String longPressIndicator, Runnable expectLongClickEvents,
+ boolean isDecelerating, String longPressIndicator, Runnable expectLongClickEvents,
@Nullable Runnable expectDropEvents) {
try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer(
"want to drag icon to workspace")) {
@@ -301,8 +338,8 @@
while (targetDest.x > displayX || targetDest.x < 0) {
int edgeX = targetDest.x > 0 ? displayX : 0;
Point screenEdge = new Point(edgeX, targetDest.y);
- launcher.movePointer(dragStart, screenEdge, 10, downTime, true,
- LauncherInstrumentation.GestureScope.INSIDE);
+ launcher.movePointer(dragStart, screenEdge, DEFAULT_DRAG_STEPS, isDecelerating,
+ downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
launcher.waitForIdle(); // Wait for the page change to happen
targetDest.x += displayX * (targetDest.x > 0 ? -1 : 1);
dragStart = screenEdge;
@@ -310,8 +347,8 @@
// targetDest.x is now between 0 and displayX so we found the target page,
// we just have to put move the icon to the destination and drop it
- launcher.movePointer(dragStart, targetDest, 10, downTime, true,
- LauncherInstrumentation.GestureScope.INSIDE);
+ launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
+ downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
}
}