From ae86d22dfb6d365b52bd1465a1b3f2811d721882 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Wed, 17 Jul 2019 17:04:40 -0700 Subject: [PATCH 01/18] Guard against NPE inside BaseIconFactory Bug: 137253043 This is a bandage fix. Ideally, we should really figure out why TaskIconCache will be sending null icon drawable to BaseIconFactory. Change-Id: Ie005006baeddc9a3379283fe7139e590daad9a57 --- .../com/android/launcher3/icons/BaseIconFactory.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java index db5515b741..fc7d6b329f 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java @@ -22,6 +22,7 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Process; import android.os.UserHandle; +import androidx.annotation.NonNull; /** * This class will be moved to androidx library. There shouldn't be any dependency outside @@ -154,7 +155,7 @@ public class BaseIconFactory implements AutoCloseable { * @param scale returns the scale result from normalization * @return a bitmap suitable for disaplaying as an icon at various system UIs. */ - public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user, + public BitmapInfo createBadgedIconBitmap(@NonNull Drawable icon, UserHandle user, boolean shrinkNonAdaptiveIcons, boolean isInstantApp, float[] scale) { if (scale == null) { scale = new float[1]; @@ -207,8 +208,11 @@ public class BaseIconFactory implements AutoCloseable { mDisableColorExtractor = true; } - private Drawable normalizeAndWrapToAdaptiveIcon(Drawable icon, boolean shrinkNonAdaptiveIcons, - RectF outIconBounds, float[] outScale) { + private Drawable normalizeAndWrapToAdaptiveIcon(@NonNull Drawable icon, + boolean shrinkNonAdaptiveIcons, RectF outIconBounds, float[] outScale) { + if (icon == null) { + return null; + } float scale = 1f; if (shrinkNonAdaptiveIcons && ATLEAST_OREO) { @@ -264,7 +268,7 @@ public class BaseIconFactory implements AutoCloseable { * @param icon drawable that should be flattened to a bitmap * @param scale the scale to apply before drawing {@param icon} on the canvas */ - public Bitmap createIconBitmap(Drawable icon, float scale, int size) { + public Bitmap createIconBitmap(@NonNull Drawable icon, float scale, int size) { Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); if (icon == null) { return bitmap; From f33b6d4378c6029265742bdc19d805b73b096ffa Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Thu, 18 Jul 2019 14:38:46 -0700 Subject: [PATCH 02/18] Allow TouchControllers to override shouldDisableGestures Currently only StatusBarTouchController overrides this to always return false, so that you can swipe down for notifications during transition to home screen from an app (in gesture nav). Bug: 137161198 Change-Id: I803c37937d5294810cbe0c1bbffcd5dddcc5ca3b --- .../touchcontrollers/StatusBarTouchController.java | 6 ++++++ src/com/android/launcher3/util/TouchController.java | 4 ++++ src/com/android/launcher3/views/BaseDragLayer.java | 10 +++++----- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index f5ba3725df..18996ddb03 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -166,4 +166,10 @@ public class StatusBarTouchController implements TouchController { mSysUiProxy = RecentsModel.INSTANCE.get(mLauncher).getSystemUiProxy(); return mSysUiProxy != null; } + + @Override + public boolean allowWhenGesturesDisabled() { + // Always allow intercepting touches for this controller. + return true; + } } \ No newline at end of file diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java index fc1d819f78..2cd28bbe8d 100644 --- a/src/com/android/launcher3/util/TouchController.java +++ b/src/com/android/launcher3/util/TouchController.java @@ -32,5 +32,9 @@ public interface TouchController { */ boolean onControllerInterceptTouchEvent(MotionEvent ev); + default boolean allowWhenGesturesDisabled() { + return false; + } + default void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 8bf33bf05c..4fe3d99d1e 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -21,7 +21,6 @@ import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; -import static com.android.launcher3.Utilities.shouldDisableGestures; import android.annotation.TargetApi; import android.content.Context; @@ -30,7 +29,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; import android.util.AttributeSet; -import android.util.Log; import android.util.Property; import android.view.MotionEvent; import android.view.View; @@ -152,15 +150,17 @@ public abstract class BaseDragLayer } private TouchController findControllerToHandleTouch(MotionEvent ev) { - if (shouldDisableGestures(ev)) return null; + boolean gesturesEnabled = !Utilities.shouldDisableGestures(ev); AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); - if (topView != null && topView.onControllerInterceptTouchEvent(ev)) { + if (topView != null && (gesturesEnabled || topView.allowWhenGesturesDisabled()) + && topView.onControllerInterceptTouchEvent(ev)) { return topView; } for (TouchController controller : mControllers) { - if (controller.onControllerInterceptTouchEvent(ev)) { + if ((gesturesEnabled || controller.allowWhenGesturesDisabled()) + && controller.onControllerInterceptTouchEvent(ev)) { return controller; } } From c0a1b7046d803451d2ad754959c03488d48226ca Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 16 Jul 2019 16:33:22 -0700 Subject: [PATCH 03/18] Improving TAPL code around fallback recents Change-Id: I9cd1caa2725f1d3967447130f4e34c4cf878514b --- tests/tapl/com/android/launcher3/tapl/Background.java | 3 ++- tests/tapl/com/android/launcher3/tapl/BaseOverview.java | 2 +- .../android/launcher3/tapl/LauncherInstrumentation.java | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 060bf30202..bcce8ef579 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -54,7 +54,8 @@ public class Background extends LauncherInstrumentation.VisibleContainer { "want to switch from background to overview")) { verifyActiveContainer(); goToOverviewUnchecked(BACKGROUND_APP_STATE_ORDINAL); - return new BaseOverview(mLauncher); + return mLauncher.isFallbackOverview() ? + new BaseOverview(mLauncher) : new Overview(mLauncher); } } diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index 04a0f12714..bbd2c29e3e 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -41,7 +41,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { @Override protected LauncherInstrumentation.ContainerType getContainerType() { - return LauncherInstrumentation.ContainerType.BASE_OVERVIEW; + return LauncherInstrumentation.ContainerType.FALLBACK_OVERVIEW; } /** diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index a5b0d25671..79379e5922 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -87,7 +87,7 @@ public final class LauncherInstrumentation { // 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 { - WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, BASE_OVERVIEW + WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, FALLBACK_OVERVIEW } public enum NavigationModel {ZERO_BUTTON, TWO_BUTTON, THREE_BUTTON} @@ -451,7 +451,7 @@ public final class LauncherInstrumentation { return waitForLauncherObject(OVERVIEW_RES_ID); } - case BASE_OVERVIEW: { + case FALLBACK_OVERVIEW: { return waitForFallbackLauncherObject(OVERVIEW_RES_ID); } case BACKGROUND: { @@ -739,6 +739,10 @@ public final class LauncherInstrumentation { return mDevice.getLauncherPackageName(); } + boolean isFallbackOverview() { + return !getOverviewPackageName().equals(getLauncherPackageName()); + } + @NonNull public UiDevice getDevice() { return mDevice; From c8d496fe002b9d6e0c9ee1ddf7ce27b0a2399abe Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 18 Jul 2019 18:24:47 -0700 Subject: [PATCH 04/18] Fix waiting for launcher initialization Bug: 137836033 Change-Id: Ifc8ce867abd85eaeacd09a2b39636ecc4109c046 --- .../android/quickstep/TouchInteractionService.java | 2 +- .../quickstep/QuickstepTestInformationHandler.java | 2 +- .../android/quickstep/TouchInteractionService.java | 11 +++++------ .../launcher3/tapl/LauncherInstrumentation.java | 6 +++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java index 917800f2a6..577b175661 100644 --- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -186,7 +186,7 @@ public class TouchInteractionService extends Service { return mMyBinder; } - public static boolean isInputMonitorInitialized() { + public static boolean isInitialized() { return true; } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java index b507044e0a..4eb9df2cbd 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -38,7 +38,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, - TouchInteractionService.isInputMonitorInitialized()); + TouchInteractionService.isInitialized()); return response; } 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 debed898ef..d10e5123d5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -77,7 +77,6 @@ import com.android.launcher3.logging.EventLogArray; 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; @@ -154,6 +153,7 @@ public class TouchInteractionService extends Service implements MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor); MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet); MAIN_THREAD_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */)); + sIsInitialized = true; } @Override @@ -227,15 +227,15 @@ public class TouchInteractionService extends Service implements }; private static boolean sConnected = false; - private static boolean sInputMonitorInitialized = false; + private static boolean sIsInitialized = false; private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState(); public static boolean isConnected() { return sConnected; } - public static boolean isInputMonitorInitialized() { - return sInputMonitorInitialized; + public static boolean isInitialized() { + return sIsInitialized; } public static SwipeSharedState getSwipeSharedState() { @@ -336,7 +336,6 @@ public class TouchInteractionService extends Service implements mInputMonitorCompat.dispose(); mInputMonitorCompat = null; } - sInputMonitorInitialized = false; } private void initInputMonitor() { @@ -354,7 +353,6 @@ public class TouchInteractionService extends Service implements Log.e(TAG, "Unable to create input monitor", e); } initTouchBounds(); - sInputMonitorInitialized = true; } private int getNavbarSize(String resName) { @@ -492,6 +490,7 @@ public class TouchInteractionService extends Service implements @Override public void onDestroy() { + sIsInitialized = false; if (mIsUserUnlocked) { mInputConsumer.unregisterInputConsumer(); mOverviewComponentObserver.onDestroy(); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 79379e5922..8639ea207d 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -396,7 +396,7 @@ public final class LauncherInstrumentation { } private UiObject2 verifyContainerType(ContainerType containerType) { - //waitForTouchInteractionService(); + waitForLauncherInitialized(); assertEquals("Unexpected display rotation", mExpectedRotation, mDevice.getDisplayRotation()); @@ -468,7 +468,7 @@ public final class LauncherInstrumentation { } } - private void waitForTouchInteractionService() { + private void waitForLauncherInitialized() { for (int i = 0; i < 100; ++i) { if (getTestInfo( TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED). @@ -477,7 +477,7 @@ public final class LauncherInstrumentation { } SystemClock.sleep(100); } - fail("TouchInteractionService didn't connect"); + fail("Launcher didn't initialize"); } Parcelable executeAndWaitForEvent(Runnable command, From 76d2a6fcc37110d65a112eea7dbc25854b3270df Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 19 Jul 2019 10:40:25 -0700 Subject: [PATCH 05/18] Improving system health diags Change-Id: I207c5b9c9ad9e99646419b7a4bd77b59a067f26d --- .../android/launcher3/tapl/TestHelpers.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java index e19f91a20a..ebe5eac5f5 100644 --- a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java +++ b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java @@ -30,6 +30,7 @@ import android.os.DropBoxManager; import org.junit.Assert; +import java.util.Date; import java.util.List; public class TestHelpers { @@ -104,28 +105,21 @@ public class TestHelpers { DropBoxManager dropbox = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE); Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); - long timestamp = 0; + long timestamp = System.currentTimeMillis() - 5 * 60000; DropBoxManager.Entry entry; - int crashCount = 0; StringBuilder errorDetails = new StringBuilder(); while (null != (entry = dropbox.getNextEntry(label, timestamp))) { - String dropboxSnippet; - try { - dropboxSnippet = entry.getText(4096); - } finally { - entry.close(); - } - - crashCount++; - errorDetails.append(label); - errorDetails.append(": "); - errorDetails.append(truncateCrash(dropboxSnippet, 40)); - errorDetails.append(" ...\n"); - timestamp = entry.getTimeMillis(); + errorDetails.append(new Date(timestamp)); + errorDetails.append(": "); + errorDetails.append(entry.getTag()); + errorDetails.append(": "); + final String dropboxSnippet = entry.getText(4096); + if (dropboxSnippet != null) errorDetails.append(truncateCrash(dropboxSnippet, 40)); + errorDetails.append(" ...\n"); + entry.close(); } - Assert.assertEquals(errorDetails.toString(), 0, crashCount); - return crashCount > 0 ? errorDetails.toString() : null; + return errorDetails.length() != 0 ? errorDetails.toString() : null; } public static String getSystemHealthMessage(Context context) { @@ -133,9 +127,15 @@ public class TestHelpers { StringBuilder errors = new StringBuilder(); final String[] labels = { + "system_app_anr", + "system_app_crash", + "system_app_native_crash", + "system_app_wtf", + "system_server_anr", "system_server_crash", "system_server_native_crash", - "system_server_anr", + "system_server_watchdog", + "system_server_wtf", }; for (String label : labels) { From 21cd128141931279ac21433da4fed1f2884be4b7 Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 19 Jul 2019 12:12:49 -0700 Subject: [PATCH 06/18] Logging original exception in PortraitLandscapeRunner Change-Id: I672e563df45f1f0dcdda5b1f863919f0150e73e6 --- .../com/android/launcher3/ui/PortraitLandscapeRunner.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java index 0f36292f90..ddcb4da883 100644 --- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java +++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java @@ -1,5 +1,6 @@ package com.android.launcher3.ui; +import android.util.Log; import android.view.Surface; import com.android.launcher3.tapl.TestHelpers; @@ -9,6 +10,7 @@ import org.junit.runner.Description; import org.junit.runners.model.Statement; class PortraitLandscapeRunner implements TestRule { + private static final String TAG = "PortraitLandscapeRunner"; private AbstractLauncherUiTest mTest; public PortraitLandscapeRunner(AbstractLauncherUiTest test) { @@ -36,6 +38,9 @@ class PortraitLandscapeRunner implements TestRule { evaluateInPortrait(); evaluateInLandscape(); + } catch (Exception e) { + Log.e(TAG, "Exception", e); + throw e; } finally { mTest.mDevice.setOrientationNatural(); mTest.executeOnLauncher(launcher -> From bc4d213535f296f90ad8dabe22eea13cc8ace838 Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Thu, 18 Jul 2019 15:40:49 -0700 Subject: [PATCH 07/18] TaskView - add a getter for the bitmap data. This allows other components to get it directly from the view, rather than retaining their own copy. Bug: 137129923 Tested: Manual Change-Id: Ibab307517c31cd3cb59b4d77ff390fd97546e86d --- .../src/com/android/quickstep/views/TaskThumbnailView.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 d55a520443..7f1e8980b9 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 @@ public class TaskThumbnailView extends View { return new ColorMatrixColorFilter(COLOR_MATRIX); } + + public Bitmap getThumbnail() { + if (mThumbnailData == null) { + return null; + } + return mThumbnailData.thumbnail; + } } From 3fca6aaec2883c4bb3108fc272589d8f89b59ba0 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Fri, 19 Jul 2019 16:48:55 -0700 Subject: [PATCH 08/18] Finish recents animation when touching during animation to recents This regressed in ag/8542000, where we cancel the animation instead of ending it. We should only cancel when going to home; in other cases, we should still call end(). Bug: 137487381 Change-Id: I093954908c3ac747ec3132aa700c8be2f927631a --- .../android/quickstep/WindowTransformSwipeHandler.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index df37759cc4..cc9719b418 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -56,6 +56,9 @@ import android.view.ViewTreeObserver.OnDrawListener; import android.view.WindowInsets; import android.view.animation.Interpolator; +import androidx.annotation.NonNull; +import androidx.annotation.UiThread; + import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; @@ -88,9 +91,6 @@ import com.android.systemui.shared.system.LatencyTrackerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; -import androidx.annotation.NonNull; -import androidx.annotation.UiThread; - @TargetApi(Build.VERSION_CODES.O) public class WindowTransformSwipeHandler extends BaseSwipeUpHandler @@ -677,7 +677,7 @@ public class WindowTransformSwipeHandler @Override protected InputConsumer createNewInputProxyHandler() { - endRunningWindowAnim(true /* cancel */); + endRunningWindowAnim(mGestureEndTarget == HOME /* cancel */); endLauncherTransitionController(); if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { // Hide the task view, if not already hidden From b6841ac630fd4ca894e2638586511e3085c40baa Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Mon, 22 Jul 2019 12:39:59 -0700 Subject: [PATCH 09/18] Revert the changes that prevented touch on RecentsView during animation The original bug that was solving seems to be fixed by other changes, and this allows users to scroll, dismiss, etc on recent tasks before fully reaching overview from an app. Bug: 137487381 Change-Id: I28a708811bba3ce739ce261f19eb29558d8f0e7d --- .../android/quickstep/RecentsAnimationWrapper.java | 9 ++------- .../com/android/quickstep/views/RecentsView.java | 5 ----- .../touchcontrollers/StatusBarTouchController.java | 6 ------ src/com/android/launcher3/PagedView.java | 8 ++------ src/com/android/launcher3/Utilities.java | 14 ++------------ .../android/launcher3/util/TouchController.java | 4 ---- src/com/android/launcher3/views/BaseDragLayer.java | 8 ++------ 7 files changed, 8 insertions(+), 46 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java index ddd28a3500..ca89c33929 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java @@ -19,12 +19,12 @@ import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; -import static com.android.launcher3.Utilities.FLAG_NO_GESTURES; - import android.view.InputEvent; import android.view.KeyEvent; import android.view.MotionEvent; +import androidx.annotation.UiThread; + import com.android.launcher3.util.Preconditions; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.util.SwipeAnimationTargetSet; @@ -33,8 +33,6 @@ import com.android.systemui.shared.system.InputConsumerController; import java.util.ArrayList; import java.util.function.Supplier; -import androidx.annotation.UiThread; - /** * Wrapper around RecentsAnimationController to help with some synchronization */ @@ -184,10 +182,7 @@ public class RecentsAnimationWrapper { } } if (mInputConsumer != null) { - int flags = ev.getEdgeFlags(); - ev.setEdgeFlags(flags | FLAG_NO_GESTURES); mInputConsumer.onMotionEvent(ev); - ev.setEdgeFlags(flags); } return true; 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 b566837da6..6ff297dea3 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 @@ -473,11 +473,6 @@ public abstract class RecentsView extends PagedView impl } } - @Override - protected boolean shouldBlockGestures(MotionEvent ev) { - return Utilities.shouldDisableGestures(ev); - } - @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index 18996ddb03..f5ba3725df 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -166,10 +166,4 @@ public class StatusBarTouchController implements TouchController { mSysUiProxy = RecentsModel.INSTANCE.get(mLauncher).getSystemUiProxy(); return mSysUiProxy != null; } - - @Override - public boolean allowWhenGesturesDisabled() { - // Always allow intercepting touches for this controller. - return true; - } } \ No newline at end of file diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index bd52ffe4b2..d2b8d4e300 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -848,7 +848,7 @@ public abstract class PagedView extends ViewGrou */ // Skip touch handling if there are no pages to swipe - if (getChildCount() <= 0 || shouldBlockGestures(ev)) return false; + if (getChildCount() <= 0) return false; acquireVelocityTrackerAndAddMovement(ev); @@ -1093,14 +1093,10 @@ public abstract class PagedView extends ViewGrou mAllowOverScroll = enable; } - protected boolean shouldBlockGestures(MotionEvent ev) { - return false; - } - @Override public boolean onTouchEvent(MotionEvent ev) { // Skip touch handling if there are no pages to swipe - if (getChildCount() <= 0 || shouldBlockGestures(ev)) return false; + if (getChildCount() <= 0) return false; acquireVelocityTrackerAndAddMovement(ev); diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 65aa3a775d..fc5cd8a888 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -16,6 +16,8 @@ package com.android.launcher3; +import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED; + import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager; @@ -92,8 +94,6 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED; - /** * Various utilities shared amongst the Launcher's classes. */ @@ -127,16 +127,6 @@ public final class Utilities { */ public static final int EDGE_NAV_BAR = 1 << 8; - /** - * Set on a motion event do disallow any gestures and only handle touch. - * See {@link MotionEvent#setEdgeFlags(int)}. - */ - public static final int FLAG_NO_GESTURES = 1 << 9; - - public static boolean shouldDisableGestures(MotionEvent ev) { - return (ev.getEdgeFlags() & FLAG_NO_GESTURES) == FLAG_NO_GESTURES; - } - /** * Indicates if the device has a debug build. Should only be used to store additional info or * add extra logging and not for changing the app behavior. diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java index 2cd28bbe8d..fc1d819f78 100644 --- a/src/com/android/launcher3/util/TouchController.java +++ b/src/com/android/launcher3/util/TouchController.java @@ -32,9 +32,5 @@ public interface TouchController { */ boolean onControllerInterceptTouchEvent(MotionEvent ev); - default boolean allowWhenGesturesDisabled() { - return false; - } - default void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 7b16409d9f..f2f2f3b537 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -150,17 +150,13 @@ public abstract class BaseDragLayer } private TouchController findControllerToHandleTouch(MotionEvent ev) { - boolean gesturesEnabled = !Utilities.shouldDisableGestures(ev); - AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); - if (topView != null && (gesturesEnabled || topView.allowWhenGesturesDisabled()) - && topView.onControllerInterceptTouchEvent(ev)) { + if (topView != null && topView.onControllerInterceptTouchEvent(ev)) { return topView; } for (TouchController controller : mControllers) { - if ((gesturesEnabled || controller.allowWhenGesturesDisabled()) - && controller.onControllerInterceptTouchEvent(ev)) { + if (controller.onControllerInterceptTouchEvent(ev)) { return controller; } } From 20aa2e4f51da9d35a0f699ff864fe56ae31f2220 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 22 Jul 2019 16:54:29 -0700 Subject: [PATCH 10/18] Logging start and end of linear gesture Change-Id: Ie0756c89e3871b3f4e12849ef52c44f84a5ceeee --- .../tapl/com/android/launcher3/tapl/LauncherInstrumentation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 8639ea207d..b76a82c6e2 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -821,6 +821,7 @@ public final class LauncherInstrumentation { // 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); From 44515f42c0e532e4121f7c6019161cfbd37b3ba1 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 12:36:05 -0700 Subject: [PATCH 11/18] Allowing both normal-case and uppercase versions of widget prompt The prompt is "Add automatically" Bug: 138152531 Change-Id: I5f1a15563e1e11768579711108a28070b72b4454 --- .../android/launcher3/tapl/AddToHomeScreenPrompt.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java index 7f561a2af3..6813400b87 100644 --- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java +++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java @@ -19,7 +19,11 @@ package com.android.launcher3.tapl; 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|Add automatically"); private final LauncherInstrumentation mLauncher; private final UiObject2 mWidgetCell; @@ -33,9 +37,6 @@ public class AddToHomeScreenPrompt { public void addAutomatically() { mLauncher.waitForObjectInContainer( mWidgetCell.getParent().getParent().getParent().getParent(), - By.text(LauncherInstrumentation.isAvd() - ? "ADD AUTOMATICALLY" - : "Add automatically")). - click(); + By.text(ADD_AUTOMATICALLY)).click(); } } From d418f3c3fa17c4c4a0ae552541ca78acd42917ff Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 23 Jul 2019 13:33:53 -0700 Subject: [PATCH 12/18] Set FastBitmapDrawable scale=1 before drawing it in DragView When we draw the icon to the DragView, we draw it with the current scale, which is > 1 when animating the icon down. Instead, we should always draw the icon with scale 1 since the DragView itself is scaled. Bug: 138236583 Change-Id: I6bca5cf28c54d58476240e0e68900a8f08ffe60b --- src/com/android/launcher3/graphics/DragPreviewProvider.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java index 7eb4015bfa..9263a2ac94 100644 --- a/src/com/android/launcher3/graphics/DragPreviewProvider.java +++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java @@ -29,6 +29,7 @@ import android.os.Handler; 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 @@ public class DragPreviewProvider { 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; From 34828b1942d9442a05463ddee0c61118af70341c Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 13:54:05 -0700 Subject: [PATCH 13/18] Improving "Add automatically" recognition Bug: 138152531 Change-Id: I204233f06a80d2d17b24dd9622c7a2152b1303a0 --- .../com/android/launcher3/tapl/AddToHomeScreenPrompt.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java index 6813400b87..03d1600783 100644 --- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java +++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java @@ -16,6 +16,8 @@ package com.android.launcher3.tapl; +import static java.util.regex.Pattern.CASE_INSENSITIVE; + import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiObject2; @@ -23,7 +25,7 @@ import java.util.regex.Pattern; public class AddToHomeScreenPrompt { private static final Pattern ADD_AUTOMATICALLY = - Pattern.compile("ADD AUTOMATICALLY|Add automatically"); + Pattern.compile("^Add automatically$", CASE_INSENSITIVE); private final LauncherInstrumentation mLauncher; private final UiObject2 mWidgetCell; From a50538198079c36f3352be26e679b4067af3badc Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 15:48:02 -0700 Subject: [PATCH 14/18] TAPL: adding 1 to gesture margins to avoid accidentally triggering back Change-Id: I7152d60dffc2085313dc1466693b599e4efe0394 --- .../com/android/launcher3/tapl/LauncherInstrumentation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index b76a82c6e2..eac5de782d 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -778,7 +778,7 @@ public final class LauncherInstrumentation { 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 +794,7 @@ public final class LauncherInstrumentation { 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; From 48ba8c864cdddddad80f5566372cf98a7988aca9 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 23 Jul 2019 11:48:21 -0700 Subject: [PATCH 15/18] Fix regression in assistant window handling - Skip the assistant as the running task when handling swipe up - Also ensure that we fall into the overview input consumer if we are swiping it from the assistant over home - Skip accounting for the scroll offset when there is no running task Bug: 136282913 Change-Id: I28e45e407702d6d6aebaa0232cd96ccb10047644 --- .../quickstep/TouchInteractionService.java | 27 ++++++++++++++++--- .../android/quickstep/views/RecentsView.java | 3 +++ 2 files changed, 27 insertions(+), 3 deletions(-) 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 d10e5123d5..77563400f4 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_N 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; @@ -102,6 +104,7 @@ import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; 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; @@ -566,7 +569,7 @@ public class TouchInteractionService extends Service implements 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 +607,7 @@ public class TouchInteractionService extends Service implements } 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 +619,17 @@ public class TouchInteractionService extends Service implements 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 +639,8 @@ public class TouchInteractionService extends Service implements 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 +652,12 @@ public class TouchInteractionService extends Service implements } } + 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 b566837da6..01f922fec2 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 @@ -1697,6 +1697,9 @@ public abstract class RecentsView extends PagedView impl * @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(); From cd7b00853ba60671f6637a5f51e97bdb942bab88 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 16:49:48 -0700 Subject: [PATCH 16/18] Adding debug tracing Bug: 138251824 Change-Id: Ibe3de964aeacbf83fd46cc53fda7d15c9401fe4d --- .../quickstep/TouchInteractionService.java | 16 ++++++++++++++++ .../quickstep/NavigationModeSwitchRule.java | 2 ++ .../android/launcher3/testing/TestProtocol.java | 2 ++ .../launcher3/tapl/LauncherInstrumentation.java | 8 ++++++++ 4 files changed, 28 insertions(+) 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 d10e5123d5..86c4a06a79 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -77,6 +77,7 @@ import com.android.launcher3.logging.EventLogArray; 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; @@ -339,16 +340,25 @@ public class TouchInteractionService extends Service implements } 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 +416,9 @@ public class TouchInteractionService extends Service implements @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 +528,9 @@ public class TouchInteractionService extends Service implements } 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; diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java index 3b35c86af8..b6cd1bec3c 100644 --- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java +++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java @@ -80,6 +80,7 @@ public class NavigationModeSwitchRule implements TestRule { 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 @@ public class NavigationModeSwitchRule implements TestRule { } finally { setActiveOverlay(prevOverlayPkg, originalMode); } + mLauncher.disableDebugTracing(); } public void evaluateWithoutChangingSetting(Statement base) throws Throwable { diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 079ab6d8fe..9846a04271 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -77,4 +77,6 @@ public final class TestProtocol { 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/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index b76a82c6e2..2ed2646339 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -937,4 +937,12 @@ public final class LauncherInstrumentation { 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 From 064cba456090fe1b651f98e0e891b3b84e541b1f Mon Sep 17 00:00:00 2001 From: Anna Wasewicz Date: Tue, 23 Jul 2019 17:34:34 -0700 Subject: [PATCH 17/18] Changing ENABLE_HINTS_IN_OVERVIEW flag to be true in qt-r1-dev. It should be false in qt-dev and true in qt-r1-dev. Bug: 138252347 Change-Id: If9de47ef937ecb3da9c8d43eea8ad4b6e6885582 --- src/com/android/launcher3/config/BaseFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 45639e0a43..54efcb7868 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -105,7 +105,7 @@ abstract class BaseFlags { "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( From 0dd1c782f0cb1653f191a2ec9db72f8f26190dc8 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 17:30:04 -0700 Subject: [PATCH 18/18] Checking Launcher internal integrity from tests In particular, we check that the stable Launcher state equals its current state. This can help detect Launcher being in a corrupted state as in b/133867119. The check gets called by tests when the Launcher is not transitioning from state to state. Bug: 137307838 Change-Id: I3d36edff35e42d14be6b9a52351bd6f709be75e8 --- .../launcher3/ui/AbstractLauncherUiTest.java | 71 +++++++++++++++++++ .../tapl/LauncherInstrumentation.java | 17 ++++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 361f2fb533..8dc8cea40d 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -17,6 +17,7 @@ package com.android.launcher3.ui; 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.LauncherAppState; 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.model.AppLaunchTracker; 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 @@ public abstract class AbstractLauncherUiTest { 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 @@ public abstract class AbstractLauncherUiTest { 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/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index eac5de782d..db88202e79 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.Deque; 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 @@ public final class LauncherInstrumentation { // 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 @@ public final class LauncherInstrumentation { private final Deque mDiagnosticContext = new LinkedList<>(); private Supplier mSystemHealthSupplier; + private Consumer mOnSettledStateAction; + /** * Constructs the root of TAPL hierarchy. You get all other objects from it. */ @@ -296,6 +299,10 @@ public final class LauncherInstrumentation { this.mSystemHealthSupplier = supplier; } + public void setOnSettledStateAction(Consumer onSettledStateAction) { + mOnSettledStateAction = onSettledStateAction; + } + private String getSystemHealthMessage() { final String testPackage = getContext().getPackageName(); try { @@ -415,6 +422,14 @@ public final class LauncherInstrumentation { 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) {