Merge "delete appIcon from workspace via TAPL" into sc-v2-dev

This commit is contained in:
Ling Wo 2021-12-14 02:10:59 +00:00 committed by Android (Google) Code Review
commit 361d8286cc
3 changed files with 105 additions and 21 deletions

View File

@ -423,6 +423,18 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); 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() { public static String getAppPackageName() {
return getInstrumentation().getContext().getPackageName(); return getInstrumentation().getContext().getPackageName();
} }

View File

@ -1399,14 +1399,15 @@ public final class LauncherInstrumentation {
final Point start = new Point(startX, startY); final Point start = new Point(startX, startY);
final Point end = new Point(endX, endY); final Point end = new Point(endX, endY);
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope); 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); sendPointer(downTime, endTime, MotionEvent.ACTION_UP, end, gestureScope);
} }
long movePointer(Point start, Point end, int steps, long downTime, boolean slowDown, long movePointer(Point start, Point end, int steps, boolean isDecelerating,
GestureScope gestureScope) { long downTime, boolean slowDown, GestureScope gestureScope) {
long endTime = movePointer( long endTime = movePointer(downTime, downTime, steps * GESTURE_STEP_MS,
downTime, downTime, steps * GESTURE_STEP_MS, start, end, gestureScope); isDecelerating, start, end, gestureScope);
if (slowDown) { if (slowDown) {
endTime = movePointer(downTime, endTime + GESTURE_STEP_MS, 5 * GESTURE_STEP_MS, end, endTime = movePointer(downTime, endTime + GESTURE_STEP_MS, 5 * GESTURE_STEP_MS, end,
end, gestureScope); end, gestureScope);
@ -1485,21 +1486,55 @@ public final class LauncherInstrumentation {
public long movePointer(long downTime, long startTime, long duration, Point from, Point to, public long movePointer(long downTime, long startTime, long duration, Point from, Point to,
GestureScope gestureScope) { 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); log("movePointer: " + from + " to " + to);
final Point point = new Point(); final Point point = new Point();
long steps = duration / GESTURE_STEP_MS; long steps = duration / GESTURE_STEP_MS;
long currentTime = startTime; long currentTime = startTime;
for (long i = 0; i < steps; ++i) {
sleep(GESTURE_STEP_MS);
currentTime += GESTURE_STEP_MS; if (isDecelerating) {
final float progress = (currentTime - startTime) / (float) duration; // formula: V = V0 - D*T, assuming V = 0 when T = duration
point.x = from.x + (int) (progress * (to.x - from.x)); // vx0: initial speed at the x-dimension, set as twice the avg speed
point.y = from.y + (int) (progress * (to.y - from.y)); // 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; return currentTime;
} }

View File

@ -46,6 +46,9 @@ import java.util.stream.Collectors;
*/ */
public final class Workspace extends Home { public final class Workspace extends Home {
private static final int FLING_STEPS = 10; 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( static final Pattern EVENT_CTRL_W_DOWN = Pattern.compile(
"Key event: KeyEvent.*?action=ACTION_DOWN.*?keyCode=KEYCODE_W" "Key event: KeyEvent.*?action=ACTION_DOWN.*?keyCode=KEYCODE_W"
@ -211,6 +214,40 @@ public final class Workspace extends Home {
TestProtocol.TEST_INFO_RESPONSE_FIELD); 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. * Finds folder icons in the current workspace.
* *
@ -241,8 +278,8 @@ public final class Workspace extends Home {
expectLongClickEvents.run(); expectLongClickEvents.run();
launcher.waitForLauncherObject(longPressIndicator); launcher.waitForLauncherObject(longPressIndicator);
LauncherInstrumentation.log("dragIconToSpringLoaded: indicator"); LauncherInstrumentation.log("dragIconToSpringLoaded: indicator");
launcher.movePointer(iconCenter, dragStartCenter, 10, downTime, true, launcher.movePointer(iconCenter, dragStartCenter, DEFAULT_DRAG_STEPS, false,
LauncherInstrumentation.GestureScope.INSIDE); downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
}, SPRING_LOADED_STATE_ORDINAL, "long-pressing and triggering drag start"); }, SPRING_LOADED_STATE_ORDINAL, "long-pressing and triggering drag start");
return dragStartCenter; return dragStartCenter;
} }
@ -270,7 +307,7 @@ public final class Workspace extends Home {
expectDropEvents = () -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, expectDropEvents = () -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN,
LauncherInstrumentation.EVENT_START); LauncherInstrumentation.EVENT_START);
} }
dragIconToWorkspace(launcher, launchable, () -> dest, longPressIndicator, dragIconToWorkspace(launcher, launchable, () -> dest, false, longPressIndicator,
expectLongClickEvents, expectDropEvents); expectLongClickEvents, expectDropEvents);
} }
@ -280,13 +317,13 @@ public final class Workspace extends Home {
*/ */
static void dragIconToWorkspace(LauncherInstrumentation launcher, Launchable launchable, static void dragIconToWorkspace(LauncherInstrumentation launcher, Launchable launchable,
Supplier<Point> destSupplier, String longPressIndicator) { 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); () -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT), null);
} }
static void dragIconToWorkspace( static void dragIconToWorkspace(
LauncherInstrumentation launcher, Launchable launchable, Supplier<Point> dest, LauncherInstrumentation launcher, Launchable launchable, Supplier<Point> dest,
String longPressIndicator, Runnable expectLongClickEvents, boolean isDecelerating, String longPressIndicator, Runnable expectLongClickEvents,
@Nullable Runnable expectDropEvents) { @Nullable Runnable expectDropEvents) {
try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer( try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer(
"want to drag icon to workspace")) { "want to drag icon to workspace")) {
@ -301,8 +338,8 @@ public final class Workspace extends Home {
while (targetDest.x > displayX || targetDest.x < 0) { while (targetDest.x > displayX || targetDest.x < 0) {
int edgeX = targetDest.x > 0 ? displayX : 0; int edgeX = targetDest.x > 0 ? displayX : 0;
Point screenEdge = new Point(edgeX, targetDest.y); Point screenEdge = new Point(edgeX, targetDest.y);
launcher.movePointer(dragStart, screenEdge, 10, downTime, true, launcher.movePointer(dragStart, screenEdge, DEFAULT_DRAG_STEPS, isDecelerating,
LauncherInstrumentation.GestureScope.INSIDE); downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
launcher.waitForIdle(); // Wait for the page change to happen launcher.waitForIdle(); // Wait for the page change to happen
targetDest.x += displayX * (targetDest.x > 0 ? -1 : 1); targetDest.x += displayX * (targetDest.x > 0 ? -1 : 1);
dragStart = screenEdge; dragStart = screenEdge;
@ -310,8 +347,8 @@ public final class Workspace extends Home {
// targetDest.x is now between 0 and displayX so we found the target page, // 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 // we just have to put move the icon to the destination and drop it
launcher.movePointer(dragStart, targetDest, 10, downTime, true, launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
LauncherInstrumentation.GestureScope.INSIDE); downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents); dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
} }
} }