Merge "Using model-time scrolling in all apps" into ub-launcher3-qt-dev

This commit is contained in:
TreeHugger Robot
2019-05-14 20:34:15 +00:00
committed by Android (Google) Code Review
7 changed files with 95 additions and 32 deletions
@@ -19,7 +19,6 @@ package com.android.launcher3.appprediction;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.quickstep.logging.UserEventDispatcherExtension.ALL_APPS_PREDICTION_TIPS;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
@@ -39,6 +38,7 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.FloatingHeaderView;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.compat.UserManagerCompat;
@@ -152,7 +152,7 @@ public class AllAppsTipView extends AbstractFloatingView {
|| !launcher.isInState(ALL_APPS)
|| hasSeenAllAppsTip(launcher)
|| UserManagerCompat.getInstance(launcher).isDemoUser()
|| ActivityManager.isRunningInTestHarness()) {
|| Utilities.IS_RUNNING_IN_TEST_HARNESS) {
return false;
}
@@ -24,6 +24,7 @@ public final class TestProtocol {
public static final String SCROLL_Y_FIELD = "scrollY";
public static final String STATE_FIELD = "state";
public static final String SWITCHED_TO_STATE_MESSAGE = "TAPL_SWITCHED_TO_STATE";
public static final String SCROLL_FINISHED_MESSAGE = "TAPL_SCROLL_FINISHED";
public static final String RESPONSE_MESSAGE_POSTFIX = "_RESPONSE";
public static final int NORMAL_STATE_ORDINAL = 0;
public static final int SPRING_LOADED_STATE_ORDINAL = 1;
@@ -32,7 +32,8 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.graphics.DrawableFactory;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -419,4 +420,13 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
public boolean hasOverlappingRendering() {
return false;
}
@Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
if (state == SCROLL_STATE_IDLE && Utilities.IS_RUNNING_IN_TEST_HARNESS) {
AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
}
}
}
@@ -24,7 +24,6 @@ import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerTyp
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.app.ActivityManager;
import android.content.SharedPreferences;
import android.os.Handler;
import android.view.MotionEvent;
@@ -32,6 +31,7 @@ import android.view.MotionEvent;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.states.InternalStateHandler;
@@ -134,7 +134,7 @@ public class DiscoveryBounce extends AbstractFloatingView {
&& !shouldShowForWorkProfile(launcher))
|| AbstractFloatingView.getTopOpenView(launcher) != null
|| UserManagerCompat.getInstance(launcher).isDemoUser()
|| ActivityManager.isRunningInTestHarness()) {
|| Utilities.IS_RUNNING_IN_TEST_HARNESS) {
return;
}
@@ -159,7 +159,7 @@ public class DiscoveryBounce extends AbstractFloatingView {
|| (launcher.getSharedPrefs().getBoolean(SHELF_BOUNCE_SEEN, false)
&& !shouldShowForWorkProfile(launcher))
|| UserManagerCompat.getInstance(launcher).isDemoUser()
|| ActivityManager.isRunningInTestHarness()) {
|| Utilities.IS_RUNNING_IN_TEST_HARNESS) {
return;
}
@@ -62,6 +62,13 @@ public class AccessibilityManagerCompat {
sendEventToTest(accessibilityManager, TestProtocol.SWITCHED_TO_STATE_MESSAGE, parcel);
}
public static void sendScrollFinishedEventToTest(Context context) {
final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
if (accessibilityManager == null) return;
sendEventToTest(accessibilityManager, TestProtocol.SCROLL_FINISHED_MESSAGE, null);
}
private static void sendEventToTest(
AccessibilityManager accessibilityManager, String eventTag, Bundle data) {
final AccessibilityEvent e = AccessibilityEvent.obtain(
@@ -18,6 +18,8 @@ package com.android.launcher3.tapl;
import static com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel.ZERO_BUTTON;
import android.graphics.Rect;
import androidx.annotation.NonNull;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.Direction;
@@ -32,7 +34,6 @@ import com.android.launcher3.TestProtocol;
public class AllApps extends LauncherInstrumentation.VisibleContainer {
private static final int MAX_SCROLL_ATTEMPTS = 40;
private static final int MIN_INTERACT_SIZE = 100;
private static final int FLING_SPEED = LauncherInstrumentation.needSlowGestures() ? 1000 : 3000;
private final int mHeight;
@@ -102,7 +103,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer {
"search_container_all_apps");
int attempts = 0;
allAppsContainer.setGestureMargins(0, searchBox.getVisibleBounds().bottom + 1, 0, 5);
final Rect margins = new Rect(0, searchBox.getVisibleBounds().bottom + 1, 0, 5);
for (int scroll = getScroll(allAppsContainer);
scroll != 0;
@@ -113,7 +114,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer {
"Exceeded max scroll attempts: " + MAX_SCROLL_ATTEMPTS,
++attempts <= MAX_SCROLL_ATTEMPTS);
allAppsContainer.scroll(Direction.UP, 1);
mLauncher.scrollWithModelTime(allAppsContainer, Direction.UP, 1, margins, 50);
}
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("scrolled up")) {
@@ -133,7 +134,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer {
// Try to figure out how much percentage of the container needs to be scrolled in order
// to reveal the app icon to have the MIN_INTERACT_SIZE
final float pct = Math.max(((float) (MIN_INTERACT_SIZE - appHeight)) / mHeight, 0.2f);
allAppsContainer.scroll(Direction.DOWN, pct);
mLauncher.scrollWithModelTime(allAppsContainer, Direction.DOWN, pct, null, 10);
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"scrolled an icon in all apps to make it visible - and then")) {
mLauncher.waitForIdle();
@@ -150,9 +151,8 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer {
mLauncher.addContextLayer("want to fling forward in all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Start the gesture in the center to avoid starting at elements near the top.
allAppsContainer.setGestureMargins(0, 0, 0, mHeight / 2);
allAppsContainer.fling(Direction.DOWN,
(int) (FLING_SPEED * mLauncher.getDisplayDensity()));
mLauncher.scrollWithModelTime(
allAppsContainer, Direction.DOWN, 1, new Rect(0, 0, 0, mHeight / 2), 10);
verifyActiveContainer();
}
}
@@ -165,9 +165,8 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer {
mLauncher.addContextLayer("want to fling backward in all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Start the gesture in the center, for symmetry with forward.
allAppsContainer.setGestureMargins(0, mHeight / 2, 0, 0);
allAppsContainer.fling(Direction.UP,
(int) (FLING_SPEED * mLauncher.getDisplayDensity()));
mLauncher.scrollWithModelTime(
allAppsContainer, Direction.UP, 1, new Rect(0, mHeight / 2, 0, 0), 10);
verifyActiveContainer();
}
}
@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -47,6 +48,7 @@ import androidx.annotation.Nullable;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.Configurator;
import androidx.test.uiautomator.Direction;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
@@ -363,7 +365,7 @@ public final class LauncherInstrumentation {
? NORMAL_STATE_ORDINAL : BACKGROUND_APP_STATE_ORDINAL;
final Point displaySize = getRealDisplaySize();
swipeViaMovePointer(
swipeWithModelTime(
displaySize.x / 2, displaySize.y - 1,
displaySize.x / 2, 0,
finalState, ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME);
@@ -563,18 +565,65 @@ public final class LauncherInstrumentation {
() -> mDevice.swipe(startX, startY, endX, endY, steps));
}
void swipeViaMovePointer(
void swipeWithModelTime(
int startX, int startY, int endX, int endY, int expectedState, int steps) {
changeStateViaGesture(startX, startY, endX, endY, expectedState, () -> {
final long downTime = SystemClock.uptimeMillis();
final Point start = new Point(startX, startY);
final Point end = new Point(endX, endY);
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start);
final long endTime = movePointer(downTime, downTime, steps * GESTURE_STEP_MS, start,
end);
sendPointer(
downTime, endTime, MotionEvent.ACTION_UP, end);
});
changeStateViaGesture(startX, startY, endX, endY, expectedState,
() -> swipeWithModelTime(startX, startY, endX, endY, steps));
}
void scrollWithModelTime(
UiObject2 container, Direction direction, float percent, Rect margins, int steps) {
final Rect rect = container.getVisibleBounds();
if (margins != null) {
rect.left += margins.left;
rect.top += margins.top;
rect.right -= margins.right;
rect.bottom -= margins.bottom;
}
final int startX;
final int startY;
final int endX;
final int endY;
switch (direction) {
case UP: {
startX = endX = rect.centerX();
final int vertCenter = rect.centerY();
final float halfGestureHeight = rect.height() * percent / 2.0f;
startY = (int) (vertCenter - halfGestureHeight);
endY = (int) (vertCenter + halfGestureHeight);
}
break;
case DOWN: {
startX = endX = rect.centerX();
final int vertCenter = rect.centerY();
final float halfGestureHeight = rect.height() * percent / 2.0f;
startY = (int) (vertCenter + halfGestureHeight);
endY = (int) (vertCenter - halfGestureHeight);
}
break;
default:
fail("Unsupported direction");
return;
}
executeAndWaitForEvent(
() -> swipeWithModelTime(startX, startY, endX, endY, steps),
event -> TestProtocol.SCROLL_FINISHED_MESSAGE.equals(event.getClassName()),
"Didn't receive a scroll end message: " + startX + ", " + startY
+ ", " + endX + ", " + endY);
}
// Inject a swipe gesture. Inject exactly 'steps' motion points, incrementing event time by a
// fixed interval each time.
private void swipeWithModelTime(int startX, int startY, int endX, int endY, int steps) {
final long downTime = SystemClock.uptimeMillis();
final Point start = new Point(startX, startY);
final Point end = new Point(endX, endY);
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start);
final long endTime = movePointer(downTime, downTime, steps * GESTURE_STEP_MS, start, end);
sendPointer(downTime, endTime, MotionEvent.ACTION_UP, end);
}
private void changeStateViaGesture(int startX, int startY, int endX, int endY,
@@ -688,10 +737,7 @@ public final class LauncherInstrumentation {
}
static void sleep(int duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
}
SystemClock.sleep(duration);
}
int getEdgeSensitivityWidth() {