Merge "Using the first frame delay based on the display refresh rate instead of hardcoding it to 16ms" into ub-launcher3-qt-r1-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index d10e512..6f36b05 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -33,11 +33,13 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
+import android.app.TaskInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -77,6 +79,7 @@
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.provider.RestoreDbTask;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.SysUINavigationMode.Mode;
@@ -102,6 +105,7 @@
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
+import com.android.systemui.shared.system.TaskInfoCompat;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -339,16 +343,25 @@
}
private void initInputMonitor() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 1");
+ }
if (!mMode.hasGestures || mISystemUiProxy == null) {
return;
}
disposeEventHandlers();
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 2");
+ }
try {
mInputMonitorCompat = InputMonitorCompat.fromBundle(mISystemUiProxy
.monitorGestureInput("swipe-up", mDefaultDisplayId), KEY_EXTRA_INPUT_MONITOR);
mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
mMainChoreographer, this::onInputEvent);
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 3");
+ }
} catch (RemoteException e) {
Log.e(TAG, "Unable to create input monitor", e);
}
@@ -406,6 +419,9 @@
@Override
public void onNavigationModeChanged(Mode newMode) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onNavigationModeChanged " + newMode);
+ }
if (mMode.hasGestures != newMode.hasGestures) {
if (newMode.hasGestures) {
getSystemService(DisplayManager.class).registerDisplayListener(
@@ -515,6 +531,9 @@
}
private void onInputEvent(InputEvent ev) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onInputEvent " + ev);
+ }
if (!(ev instanceof MotionEvent)) {
Log.e(TAG, "Unknown event " + ev);
return;
@@ -566,7 +585,7 @@
if (isInValidSystemUiState) {
// This handles apps launched in direct boot mode (e.g. dialer) as well as apps
// launched while device is locked even after exiting direct boot mode (e.g. camera).
- return createDeviceLockedInputConsumer(mAM.getRunningTask(0));
+ return createDeviceLockedInputConsumer(mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT));
} else {
return mResetGestureInputConsumer;
}
@@ -604,7 +623,7 @@
}
private InputConsumer newBaseConsumer(boolean useSharedState, MotionEvent event) {
- final RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
+ RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
if (!useSharedState) {
sSwipeSharedState.clearAllState(false /* finishAnimation */);
}
@@ -616,6 +635,17 @@
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
+ boolean forceOverviewInputConsumer = false;
+ if (isExcludedAssistant(runningTaskInfo)) {
+ // In the case where we are in the excluded assistant state, ignore it and treat the
+ // running activity as the task behind the assistant
+ runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT);
+ final ComponentName homeComponent =
+ mOverviewComponentObserver.getHomeIntent().getComponent();
+ forceOverviewInputConsumer =
+ runningTaskInfo.baseIntent.getComponent().equals(homeComponent);
+ }
+
if (runningTaskInfo == null && !sSwipeSharedState.goingToLauncher
&& !sSwipeSharedState.recentsAnimationFinishInterrupted) {
return mResetGestureInputConsumer;
@@ -625,7 +655,8 @@
RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
info.id = sSwipeSharedState.nextRunningTaskId;
return createOtherActivityInputConsumer(event, info);
- } else if (sSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
+ } else if (sSwipeSharedState.goingToLauncher || activityControl.isResumed()
+ || forceOverviewInputConsumer) {
return createOverviewInputConsumer(event);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
return createOverviewInputConsumer(event);
@@ -637,6 +668,12 @@
}
}
+ private boolean isExcludedAssistant(TaskInfo info) {
+ return info != null
+ && TaskInfoCompat.getActivityType(info) == ACTIVITY_TYPE_ASSISTANT
+ && (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
+ }
+
private boolean disableHorizontalSwipe(MotionEvent event) {
// mExclusionRegion can change on binder thread, use a local instance here.
Region exclusionRegion = mExclusionRegion;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 6ff297d..9b157d1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -1692,6 +1692,9 @@
* @return How many pixels the running task is offset on the x-axis due to the current scrollX.
*/
public float getScrollOffset() {
+ if (getRunningTaskIndex() == -1) {
+ return 0;
+ }
int startScroll = getScrollForPage(getRunningTaskIndex());
int offsetX = startScroll - getScrollX();
offsetX *= getScaleX();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index d55a520..7f1e898 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -410,4 +410,11 @@
return new ColorMatrixColorFilter(COLOR_MATRIX);
}
+
+ public Bitmap getThumbnail() {
+ if (mThumbnailData == null) {
+ return null;
+ }
+ return mThumbnailData.thumbnail;
+ }
}
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index 3b35c86..b6cd1be 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -80,6 +80,7 @@
return new Statement() {
@Override
public void evaluate() throws Throwable {
+ mLauncher.enableDebugTracing();
final Context context = getInstrumentation().getContext();
final int currentInteractionMode =
LauncherInstrumentation.getCurrentInteractionMode(context);
@@ -104,6 +105,7 @@
} finally {
setActiveOverlay(prevOverlayPkg, originalMode);
}
+ mLauncher.disableDebugTracing();
}
public void evaluateWithoutChangingSetting(Statement base) throws Throwable {
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index 45639e0..54efcb7 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -105,7 +105,7 @@
"ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview");
public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag(
- "ENABLE_HINTS_IN_OVERVIEW", false,
+ "ENABLE_HINTS_IN_OVERVIEW", true,
"Show chip hints and gleams on the overview screen");
public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag(
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index 7eb4015..9263a2a 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -29,6 +29,7 @@
import android.view.View;
import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
@@ -87,6 +88,9 @@
Rect bounds = getDrawableBounds(d);
destCanvas.translate(blurSizeOutline / 2 - bounds.left,
blurSizeOutline / 2 - bounds.top);
+ if (d instanceof FastBitmapDrawable) {
+ ((FastBitmapDrawable) d).setScale(1);
+ }
d.draw(destCanvas);
} else {
final Rect clipRect = mTempRect;
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 079ab6d..9846a04 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -77,4 +77,6 @@
public static boolean sDebugTracing = false;
public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing";
+
+ public static final String NO_BACKGROUND_TO_OVERVIEW_TAG = "b/138251824";
}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 361f2fb..8dc8cea 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -17,6 +17,7 @@
import static androidx.test.InstrumentationRegistry.getInstrumentation;
+import static com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static org.junit.Assert.assertTrue;
@@ -45,6 +46,7 @@
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.LauncherAppsCompat;
@@ -52,6 +54,7 @@
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.testcomponent.TestCommandReceiver;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.FailureWatcher;
@@ -103,6 +106,10 @@
Utilities.enableRunningInTestHarnessForTests();
mLauncher.setSystemHealthSupplier(() -> TestCommandReceiver.callCommand(
TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE).getString("result"));
+ mLauncher.setOnSettledStateAction(
+ containerType -> executeOnLauncher(
+ launcher ->
+ checkLauncherIntegrity(launcher, containerType)));
}
}
@@ -379,4 +386,68 @@
protected int getAllAppsScroll(Launcher launcher) {
return launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
}
+
+ private static void checkLauncherIntegrity(
+ Launcher launcher, ContainerType expectedContainerType) {
+ if (launcher != null) {
+ final LauncherStateManager stateManager = launcher.getStateManager();
+ final LauncherState stableState = stateManager.getCurrentStableState();
+
+ assertTrue("Stable state != state: " + stableState.getClass().getSimpleName() + ", "
+ + stateManager.getState().getClass().getSimpleName(),
+ stableState == stateManager.getState());
+
+ final boolean isResumed = launcher.hasBeenResumed();
+ assertTrue("hasBeenResumed() != isStarted(), hasBeenResumed(): " + isResumed,
+ isResumed == launcher.isStarted());
+ assertTrue("hasBeenResumed() != isUserActive(), hasBeenResumed(): " + isResumed,
+ isResumed == launcher.isUserActive());
+
+ final int ordinal = stableState.ordinal;
+
+ switch (expectedContainerType) {
+ case WORKSPACE:
+ case WIDGETS: {
+ assertTrue(
+ "Launcher is not resumed in state: " + expectedContainerType,
+ isResumed);
+ assertTrue(TestProtocol.stateOrdinalToString(ordinal),
+ ordinal == TestProtocol.NORMAL_STATE_ORDINAL);
+ break;
+ }
+ case ALL_APPS: {
+ assertTrue(
+ "Launcher is not resumed in state: " + expectedContainerType,
+ isResumed);
+ assertTrue(TestProtocol.stateOrdinalToString(ordinal),
+ ordinal == TestProtocol.ALL_APPS_STATE_ORDINAL);
+ break;
+ }
+ case OVERVIEW: {
+ assertTrue(
+ "Launcher is not resumed in state: " + expectedContainerType,
+ isResumed);
+ assertTrue(TestProtocol.stateOrdinalToString(ordinal),
+ ordinal == TestProtocol.OVERVIEW_STATE_ORDINAL);
+ break;
+ }
+ case BACKGROUND: {
+ assertTrue("Launcher is resumed in state: " + expectedContainerType,
+ !isResumed);
+ assertTrue(TestProtocol.stateOrdinalToString(ordinal),
+ ordinal == TestProtocol.NORMAL_STATE_ORDINAL);
+ break;
+ }
+ default:
+ throw new IllegalArgumentException(
+ "Illegal container: " + expectedContainerType);
+ }
+ } else {
+ assertTrue(
+ "Container type is not BACKGROUND or FALLBACK_OVERVIEW: "
+ + expectedContainerType,
+ expectedContainerType == ContainerType.BACKGROUND ||
+ expectedContainerType == ContainerType.FALLBACK_OVERVIEW);
+ }
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
index 7f561a2..03d1600 100644
--- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
+++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
@@ -16,10 +16,16 @@
package com.android.launcher3.tapl;
+import static java.util.regex.Pattern.CASE_INSENSITIVE;
+
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiObject2;
+import java.util.regex.Pattern;
+
public class AddToHomeScreenPrompt {
+ private static final Pattern ADD_AUTOMATICALLY =
+ Pattern.compile("^Add automatically$", CASE_INSENSITIVE);
private final LauncherInstrumentation mLauncher;
private final UiObject2 mWidgetCell;
@@ -33,9 +39,6 @@
public void addAutomatically() {
mLauncher.waitForObjectInContainer(
mWidgetCell.getParent().getParent().getParent().getParent(),
- By.text(LauncherInstrumentation.isAvd()
- ? "ADD AUTOMATICALLY"
- : "Add automatically")).
- click();
+ By.text(ADD_AUTOMATICALLY)).click();
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 8639ea2..f91e2ad 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -72,6 +72,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -86,7 +87,7 @@
// Types for launcher containers that the user is interacting with. "Background" is a
// pseudo-container corresponding to inactive launcher covered by another app.
- enum ContainerType {
+ public enum ContainerType {
WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, FALLBACK_OVERVIEW
}
@@ -135,6 +136,8 @@
private final Deque<String> mDiagnosticContext = new LinkedList<>();
private Supplier<String> mSystemHealthSupplier;
+ private Consumer<ContainerType> mOnSettledStateAction;
+
/**
* Constructs the root of TAPL hierarchy. You get all other objects from it.
*/
@@ -296,6 +299,10 @@
this.mSystemHealthSupplier = supplier;
}
+ public void setOnSettledStateAction(Consumer<ContainerType> onSettledStateAction) {
+ mOnSettledStateAction = onSettledStateAction;
+ }
+
private String getSystemHealthMessage() {
final String testPackage = getContext().getPackageName();
try {
@@ -415,6 +422,14 @@
assertTrue(error, error == null);
log("verifyContainerType: " + containerType);
+ final UiObject2 container = verifyVisibleObjects(containerType);
+
+ if (mOnSettledStateAction != null) mOnSettledStateAction.accept(containerType);
+
+ return container;
+ }
+
+ private UiObject2 verifyVisibleObjects(ContainerType containerType) {
try (Closable c = addContextLayer(
"but the current state is not " + containerType.name())) {
switch (containerType) {
@@ -778,7 +793,7 @@
startX = endX = rect.centerX();
final int vertCenter = rect.centerY();
final float halfGestureHeight = rect.height() * percent / 2.0f;
- startY = (int) (vertCenter - halfGestureHeight);
+ startY = (int) (vertCenter - halfGestureHeight) + 1;
endY = (int) (vertCenter + halfGestureHeight);
}
break;
@@ -794,7 +809,7 @@
startY = endY = rect.centerY();
final int horizCenter = rect.centerX();
final float halfGestureWidth = rect.width() * percent / 2.0f;
- startX = (int) (horizCenter - halfGestureWidth);
+ startX = (int) (horizCenter - halfGestureWidth) + 1;
endX = (int) (horizCenter + halfGestureWidth);
}
break;
@@ -821,6 +836,7 @@
// Inject a swipe gesture. Inject exactly 'steps' motion points, incrementing event time by a
// fixed interval each time.
void linearGesture(int startX, int startY, int endX, int endY, int steps) {
+ log("linearGesture: " + startX + ", " + startY + " -> " + endX + ", " + endY);
final long downTime = SystemClock.uptimeMillis();
final Point start = new Point(startX, startY);
final Point end = new Point(endX, endY);
@@ -936,4 +952,12 @@
getContext().getSystemService(WindowManager.class).getDefaultDisplay().getRealSize(size);
return size;
}
+
+ public void enableDebugTracing() {
+ getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING);
+ }
+
+ public void disableDebugTracing() {
+ getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING);
+ }
}
\ No newline at end of file