Merge "Import translations. DO NOT MERGE ANYWHERE"
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 357dc7b..be3f5d9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -130,6 +130,15 @@
         mPropertyHolders.add(new StatePropertyHolder(imeDownButton,
                 flags -> (flags & FLAG_IME_VISIBLE) != 0));
 
+        mPropertyHolders.add(new StatePropertyHolder(
+                mControllers.taskbarViewController.getTaskbarIconAlpha()
+                        .getProperty(ALPHA_INDEX_KEYGUARD),
+                flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0, MultiValueAlpha.VALUE, 1, 0));
+
+        mPropertyHolders.add(new StatePropertyHolder(mControllers.taskbarDragLayerController
+                .getKeyguardBgTaskbar(),
+                flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0, AnimatedFloat.VALUE, 1, 0));
+
         if (mContext.isThreeButtonNav()) {
             initButtons(mNavButtonContainer, mEndContextualContainer,
                     mControllers.navButtonController);
@@ -137,12 +146,9 @@
             // Animate taskbar background when IME shows
             mPropertyHolders.add(new StatePropertyHolder(
                     mControllers.taskbarDragLayerController.getNavbarBackgroundAlpha(),
-                    flags -> (flags & FLAG_IME_VISIBLE) == 0,
-                    AnimatedFloat.VALUE, 0, 1));
-            mPropertyHolders.add(new StatePropertyHolder(
-                    mControllers.taskbarViewController.getTaskbarIconAlpha()
-                            .getProperty(ALPHA_INDEX_KEYGUARD),
-                    flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0, MultiValueAlpha.VALUE, 1, 0));
+                    flags -> (flags & FLAG_IME_VISIBLE) != 0 ||
+                            (flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0,
+                    AnimatedFloat.VALUE, 1, 0));
 
             // Rotation button
             RotationButton rotationButton = new RotationButtonImpl(
@@ -222,7 +228,7 @@
     }
 
     /**
-     * Slightly misnamed, but should be called when only keyguard OR AOD is showing
+     * Slightly misnamed, but should be called when keyguard OR AOD is showing
      */
     public void setKeyguardVisible(boolean isKeyguardVisible) {
         updateStateForFlag(FLAG_KEYGUARD_VISIBLE, isKeyguardVisible);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index e15e9ff..df89285 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -39,6 +39,7 @@
     // Alpha properties for taskbar background.
     private final AnimatedFloat mBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
     private final AnimatedFloat mBgNavbar = new AnimatedFloat(this::updateBackgroundAlpha);
+    private final AnimatedFloat mKeyguardBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
     // Translation property for taskbar background.
     private final AnimatedFloat mBgOffset = new AnimatedFloat(this::updateBackgroundOffset);
 
@@ -56,6 +57,7 @@
     public void init(TaskbarControllers controllers) {
         mControllers = controllers;
         mTaskbarDragLayer.init(new TaskbarDragLayerCallbacks());
+        mKeyguardBgTaskbar.value = 1;
     }
 
     public void onDestroy() {
@@ -80,12 +82,18 @@
         return mBgNavbar;
     }
 
+    public AnimatedFloat getKeyguardBgTaskbar() {
+        return mKeyguardBgTaskbar;
+    }
+
     public AnimatedFloat getTaskbarBackgroundOffset() {
         return mBgOffset;
     }
 
     private void updateBackgroundAlpha() {
-        mTaskbarDragLayer.setTaskbarBackgroundAlpha(Math.max(mBgNavbar.value, mBgTaskbar.value));
+        mTaskbarDragLayer.setTaskbarBackgroundAlpha(
+                Math.max(mBgNavbar.value, mBgTaskbar.value * mKeyguardBgTaskbar.value)
+        );
     }
 
     private void updateBackgroundOffset() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
index 2936bd2..a2039b6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
@@ -57,10 +57,6 @@
         mKeyguardSysuiFlags = interestingKeyguardFlags;
 
         mBouncerShowing = bouncerShowing;
-        if (!mContext.isThreeButtonNav()) {
-            // For gesture nav we don't need to deal with bouncer or showing taskbar when locked
-            return;
-        }
 
         mNavbarButtonsViewController.setKeyguardVisible(keyguardShowing || dozing);
         updateIconsForBouncer();
diff --git a/quickstep/src/com/android/quickstep/views/AllAppsEduView.java b/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
index 04a7baa..e9d7c3c 100644
--- a/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
+++ b/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
@@ -17,6 +17,7 @@
 
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
@@ -67,6 +68,8 @@
     private int mWidthPx;
     private int mMaxHeightPx;
 
+    private boolean mCanInterceptTouch;
+
     public AllAppsEduView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mCircle = (GradientDrawable) context.getDrawable(R.drawable.all_apps_edu_circle);
@@ -116,16 +119,27 @@
         return true;
     }
 
+
+    private boolean shouldInterceptTouch(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mCanInterceptTouch = (ev.getEdgeFlags() & EDGE_NAV_BAR) == 0;
+        }
+        return mCanInterceptTouch;
+    }
+
     @Override
     public boolean onControllerTouchEvent(MotionEvent ev) {
-        mTouchController.onControllerTouchEvent(ev);
-        if (mAnimation != null) {
+        if (shouldInterceptTouch(ev)) {
+            mTouchController.onControllerTouchEvent(ev);
             updateAnimationOnTouchEvent(ev);
         }
-        return super.onControllerTouchEvent(ev);
+        return true;
     }
 
     private void updateAnimationOnTouchEvent(MotionEvent ev) {
+        if (mAnimation == null) {
+            return;
+        }
         switch (ev.getActionMasked()) {
             case MotionEvent.ACTION_DOWN:
                 mAnimation.pause();
@@ -144,7 +158,10 @@
 
     @Override
     public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
-        mTouchController.onControllerInterceptTouchEvent(ev);
+        if (shouldInterceptTouch(ev)) {
+            mTouchController.onControllerInterceptTouchEvent(ev);
+            updateAnimationOnTouchEvent(ev);
+        }
         return true;
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index be6e3ff..6ea4a0d 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3756,8 +3756,8 @@
             TaskView taskView = getTaskViewAt(i);
             float scrollDiff = taskView.getScrollAdjustment(showAsFullscreen, showAsGrid);
             int pageScroll = newPageScrolls[i + mTaskViewStartIndex] + (int) scrollDiff;
-            if ((mIsRtl && pageScroll < clearAllScroll)
-                    || (!mIsRtl && pageScroll > clearAllScroll)) {
+            if ((mIsRtl && pageScroll < clearAllScroll + clearAllWidth)
+                    || (!mIsRtl && pageScroll > clearAllScroll - clearAllWidth)) {
                 pageScroll = clearAllScroll + (mIsRtl ? clearAllWidth : -clearAllWidth);
             }
             if (outPageScrolls[i] != pageScroll) {
diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
index 3e84a76..fef9304 100644
--- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
@@ -16,6 +16,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.launcher3.Launcher;
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 import com.android.quickstep.views.DigitalWellBeingToast;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
@@ -32,6 +33,7 @@
             resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
 
     @Test
+    @ScreenRecord //b/193440212
     public void testToast() throws Exception {
         startAppFast(CALCULATOR_PACKAGE);
 
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index a683d01..20b4715 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -59,6 +59,7 @@
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.util.Wait;
 import com.android.launcher3.util.rule.FailureWatcher;
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 import com.android.quickstep.views.RecentsView;
 
 import org.junit.After;
@@ -213,6 +214,7 @@
     // b/143488140
     //@NavigationModeSwitch
     @Test
+    @ScreenRecord // b/194484556
     public void testOverview() {
         startAppFast(getAppPackageName());
         startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index c14a590..ea69b94 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -93,7 +93,7 @@
 
     @Test
     @PortraitLandscape
-    @ScreenRecord //b/191344757
+    @ScreenRecord //b/193440212
     public void testOverview() throws Exception {
         startTestAppsWithCheck();
         // mLauncher.pressHome() also tests an important case of pressing home while in background.
@@ -159,7 +159,6 @@
     @Test
     @NavigationModeSwitch
     @PortraitLandscape
-    @ScreenRecord //b/191344757
     public void testOverviewActions() throws Exception {
         // Experimenting for b/165029151:
         final Overview overview = mLauncher.pressHome().switchToOverview();
@@ -185,7 +184,6 @@
     @Test
     @NavigationModeSwitch
     @PortraitLandscape
-    @ScreenRecord //b/191344757
     public void testSwitchToOverview() throws Exception {
         assertNotNull("Workspace.switchToOverview() returned null",
                 mLauncher.pressHome().switchToOverview());
@@ -196,7 +194,6 @@
     @Test
     @NavigationModeSwitch
     @PortraitLandscape
-    @ScreenRecord //b/191344757
     public void testBackground() throws Exception {
         startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
         final Background background = getAndAssertBackground();
@@ -218,7 +215,6 @@
 
     @Test
     @PortraitLandscape
-    @ScreenRecord //b/191344757
     public void testAllAppsFromHome() throws Exception {
         // Test opening all apps
         assertNotNull("switchToAllApps() returned null",
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index 15131f1..11eea60 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -44,7 +44,6 @@
             style="@style/TextHeadline"
             android:layout_weight="1"
             android:background="@android:color/transparent"
-            android:textStyle="bold"
             android:gravity="center_horizontal"
             android:hint="@string/folder_hint_text"
             android:imeOptions="flagNoExtractUi"
diff --git a/res/xml/size_limits_80x104.xml b/res/xml/size_limits_80x104.xml
index f5ca757..4178664 100644
--- a/res/xml/size_limits_80x104.xml
+++ b/res/xml/size_limits_80x104.xml
@@ -31,32 +31,72 @@
     </device-padding>
 
     <device-padding
-        launcher:maxEmptySpace="97dp">
+        launcher:maxEmptySpace="100dp">
         <workspaceTopPadding
             launcher:a="0"
-            launcher:b="16dp"/>
+            launcher:b="9dp"/>
         <workspaceBottomPadding
-            launcher:a="0.56"
+            launcher:a="0.40"
             launcher:b="0"
-            launcher:c="16dp"/>
+            launcher:c="9dp"/>
         <hotseatBottomPadding
-            launcher:a="0.44"
+            launcher:a="0.60"
             launcher:b="0"
-            launcher:c="16dp"/>
+            launcher:c="9dp"/>
+    </device-padding>
+
+    <device-padding
+        launcher:maxEmptySpace="103dp">
+        <workspaceTopPadding
+            launcher:a="0"
+            launcher:b="26dp"/>
+        <workspaceBottomPadding
+            launcher:a="0"
+            launcher:b="20dp"/>
+        <hotseatBottomPadding
+            launcher:a="1"
+            launcher:b="0"
+            launcher:c="46dp"/>
     </device-padding>
 
     <device-padding
         launcher:maxEmptySpace="107dp">
         <workspaceTopPadding
             launcher:a="0"
-            launcher:b="16dp"/>
+            launcher:b="9dp"/>
         <workspaceBottomPadding
             launcher:a="0"
-            launcher:b="36dp"/>
+            launcher:b="34dp"/>
         <hotseatBottomPadding
             launcher:a="1"
             launcher:b="0"
-            launcher:c="52dp"/>
+            launcher:c="43dp"/>
+    </device-padding>
+
+    <device-padding
+        launcher:maxEmptySpace="120dp">
+        <workspaceTopPadding
+            launcher:a="0"
+            launcher:b="16dp"/>
+        <workspaceBottomPadding
+            launcher:a="1"
+            launcher:c="72dp"/>
+        <hotseatBottomPadding
+            launcher:a="0"
+            launcher:b="56dp"/>
+    </device-padding>
+
+    <device-padding
+        launcher:maxEmptySpace="135dp">
+        <workspaceTopPadding
+            launcher:a="0"
+            launcher:b="39dp"/>
+        <workspaceBottomPadding
+            launcher:a="1"
+            launcher:c="95dp"/>
+        <hotseatBottomPadding
+            launcher:a="0"
+            launcher:b="56dp"/>
     </device-padding>
 
     <device-padding
@@ -71,5 +111,4 @@
             launcher:a="0"
             launcher:b="36dp"/>
     </device-padding>
-
 </device-paddings>
\ No newline at end of file
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 222c7d6..94e98db 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -93,6 +93,7 @@
     private static final float MAX_HORIZONTAL_PADDING_PERCENT = 0.14f;
 
     private static final float TALL_DEVICE_ASPECT_RATIO_THRESHOLD = 2.0f;
+    private static final float TALLER_DEVICE_ASPECT_RATIO_THRESHOLD = 2.15f;
 
     // To evenly space the icons, increase the left/right margins for tablets in portrait mode.
     private static final int PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER = 4;
@@ -152,12 +153,13 @@
     public int folderChildDrawablePaddingPx;
 
     // Hotseat
+    public int hotseatBarSizeExtraSpacePx;
     public final int numShownHotseatIcons;
     public int hotseatCellHeightPx;
     private final int hotseatExtraVerticalSize;
     // In portrait: size = height, in landscape: size = width
     public int hotseatBarSizePx;
-    public final int hotseatBarTopPaddingPx;
+    public int hotseatBarTopPaddingPx;
     public final int hotseatBarBottomPaddingPx;
     // Start is the side next to the nav bar, end is the side next to the workspace
     public final int hotseatBarSidePaddingStartPx;
@@ -328,6 +330,7 @@
                 isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
         numShownAllAppsColumns =
                 isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
+        hotseatBarSizeExtraSpacePx = 0;
         hotseatBarTopPaddingPx =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
         hotseatBarBottomPaddingPx = (isTallDevice ? 0
@@ -358,6 +361,7 @@
 
         // Calculate all of the remaining variables.
         extraSpace = updateAvailableDimensions(res);
+
         // Now that we have all of the variables calculated, we can tune certain sizes.
         if (isScalableGrid && inv.devicePaddings != null) {
             // Paddings were created assuming no scaling, so we first unscale the extra space.
@@ -377,12 +381,25 @@
             qsbBottomMarginPx = Math.round(qsbBottomMarginOriginalPx * cellScaleToFit);
         } else if (!isVerticalBarLayout() && isPhone && isTallDevice) {
             // We increase the hotseat size when there is extra space.
-            // ie. For a display with a large aspect ratio, we can keep the icons on the workspace
-            // in portrait mode closer together by adding more height to the hotseat.
-            // Note: This calculation was created after noticing a pattern in the design spec.
-            int extraSpace = getCellSize().y - iconSizePx - iconDrawablePaddingPx * 2
-                    - workspacePageIndicatorHeight;
-            hotseatBarSizePx += extraSpace;
+
+            if (Float.compare(aspectRatio, TALLER_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0) {
+                // For taller devices, we will take a third of the extra space from each row,
+                // and add it to the space above and below the hotseat.
+                int extraSpace = ((getCellSize().y - iconSizePx - iconDrawablePaddingPx * 2)
+                        * inv.numRows) / 3;
+
+                int halfExtraSpace = extraSpace / 2;
+                hotseatBarTopPaddingPx += halfExtraSpace;
+                hotseatBarSizeExtraSpacePx = halfExtraSpace;
+            } else {
+                // ie. For a display with a large aspect ratio, we can keep the icons on the
+                // workspace in portrait mode closer together by adding more height to the hotseat.
+                // Note: This calculation was created after noticing a pattern in the design spec.
+                hotseatBarSizeExtraSpacePx = getCellSize().y - iconSizePx
+                        - iconDrawablePaddingPx * 2 - workspacePageIndicatorHeight;
+            }
+
+            updateHotseatIconSize(iconSizePx);
 
             // Recalculate the available dimensions using the new hotseat size.
             updateAvailableDimensions(res);
@@ -407,7 +424,8 @@
                     + hotseatBarSidePaddingEndPx;
         } else {
             hotseatBarSizePx = hotseatIconSizePx + hotseatBarTopPaddingPx
-                    + hotseatBarBottomPaddingPx + (isScalableGrid ? 0 : hotseatExtraVerticalSize);
+                    + hotseatBarBottomPaddingPx + (isScalableGrid ? 0 : hotseatExtraVerticalSize)
+                    + hotseatBarSizeExtraSpacePx;
         }
     }
 
@@ -657,8 +675,11 @@
         int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
 
         if (isScalableGrid) {
-            folderCellWidthPx = (int) (cellWidthPx * scale);
-            folderCellHeightPx = (int) (cellHeightPx * scale);
+            int minWidth = folderChildIconSizePx + iconDrawablePaddingPx * 2;
+            int minHeight = folderChildIconSizePx + iconDrawablePaddingPx * 2 + textHeight;
+
+            folderCellWidthPx = (int) Math.max(minWidth, cellWidthPx * scale);
+            folderCellHeightPx = (int) Math.max(minHeight, cellHeightPx * scale);
 
             int borderSpacing = (int) (cellLayoutBorderSpacingOriginalPx * scale);
             folderCellLayoutBorderSpacingPx = borderSpacing;
@@ -827,11 +848,11 @@
                 ? workspacePadding.bottom
                 : hotseatBarSizePx - hotseatCellHeightPx - hotseatQsbHeight;
 
-        if (isScalableGrid) {
+        if (isScalableGrid && qsbBottomMarginPx > mInsets.bottom) {
             return Math.min(qsbBottomMarginPx, freeSpace);
-        }  else {
+        } else {
             return (int) (freeSpace * QSB_CENTER_FACTOR)
-                + (isTaskbarPresent ? taskbarSize : getInsets().bottom);
+                + (isTaskbarPresent ? taskbarSize : mInsets.bottom);
         }
     }
 
diff --git a/src/com/android/launcher3/touch/BaseSwipeDetector.java b/src/com/android/launcher3/touch/BaseSwipeDetector.java
index cfd3153..1276ece 100644
--- a/src/com/android/launcher3/touch/BaseSwipeDetector.java
+++ b/src/com/android/launcher3/touch/BaseSwipeDetector.java
@@ -17,8 +17,6 @@
 
 import static android.view.MotionEvent.INVALID_POINTER_ID;
 
-import static com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS;
-
 import android.graphics.PointF;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -43,8 +41,7 @@
  */
 public abstract class BaseSwipeDetector {
 
-    // b/193440212: Debug swipe gesture in tests.
-    private static final boolean DBG = IS_RUNNING_IN_TEST_HARNESS;
+    private static final boolean DBG = false;
     private static final String TAG = "BaseSwipeDetector";
     private static final float ANIMATION_DURATION = 1200;
     /** The minimum release velocity in pixels per millisecond that triggers fling.*/
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index dc59bdd..5fbf847 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -61,13 +61,23 @@
             out.putNextEntry(new ZipEntry("visible_windows.zip"));
             dumpCommand("cmd window dump-visible-window-views", out);
             out.closeEntry();
-        } catch (IOException ex) { }
+        } catch (IOException ex) {
+        }
 
         Log.e(TAG, "Failed test " + description.getMethodName()
                 + ",\nscreenshot will be saved to " + sceenshot
                 + ",\nUI dump at: " + hierarchy
                 + " (use go/web-hv to open the dump file)", e);
         device.takeScreenshot(sceenshot);
+
+        // Dump accessibility hierarchy
+        final File accessibilityHierarchyFile = new File(parentFile,
+                "AccessibilityHierarchy-" + description.getMethodName() + ".uix");
+        try {
+            device.dumpWindowHierarchy(accessibilityHierarchyFile);
+        } catch (IOException ex) {
+            Log.e(TAG, "Failed to save accessibility hierarchy", ex);
+        }
     }
 
     private static void dumpStringCommand(String cmd, OutputStream out) throws IOException {
diff --git a/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java b/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
index 0e27b61..32dd21c 100644
--- a/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
+++ b/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
@@ -56,7 +56,7 @@
     public static final int PLATFORM_PRESUBMIT = 0x8;
     public static final int PLATFORM_POSTSUBMIT = 0x10;
 
-    private static int sRunFlavor;
+    private static int sRunFlavor = PLATFORM_PRESUBMIT; // b/194528425
 
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.METHOD)
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index a15131d..7ec5208 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -56,24 +56,29 @@
     protected abstract String launchableType();
 
     private Background launch(BySelector selector) {
-        LauncherInstrumentation.log("Launchable.launch before click "
-                + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
-        final String label = mObject.getText();
+        try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+                "want to launch an app from " + launchableType())) {
+            LauncherInstrumentation.log("Launchable.launch before click "
+                    + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
+            final String label = mObject.getText();
 
-        mLauncher.executeAndWaitForEvent(
-                () -> {
-                    mLauncher.clickLauncherObject(mObject);
-                    expectActivityStartEvents();
-                },
-                event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
-                () -> "Launching an app didn't open a new window: " + label,
-                "clicking " + launchableType());
+            mLauncher.executeAndWaitForEvent(
+                    () -> {
+                        mLauncher.clickLauncherObject(mObject);
+                        expectActivityStartEvents();
+                    },
+                    event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+                    () -> "Launching an app didn't open a new window: " + label,
+                    "clicking " + launchableType());
 
-        mLauncher.assertTrue(
-                "App didn't start: " + label + " (" + selector + ")",
-                TestHelpers.wait(Until.hasObject(selector),
-                        LauncherInstrumentation.WAIT_TIME_MS));
-        return new Background(mLauncher);
+            try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("clicked")) {
+                mLauncher.assertTrue(
+                        "App didn't start: " + label + " (" + selector + ")",
+                        TestHelpers.wait(Until.hasObject(selector),
+                                LauncherInstrumentation.WAIT_TIME_MS));
+                return new Background(mLauncher);
+            }
+        }
     }
 
     /**
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 1f64131..93c921e 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -383,6 +383,14 @@
 
             if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked";
 
+            final String visibleApps = mDevice.findObjects(getAnyObjectSelector())
+                    .stream()
+                    .map(LauncherInstrumentation::getApplicationPackageSafe)
+                    .distinct()
+                    .filter(pkg -> pkg != null)
+                    .collect(Collectors.joining(","));
+            if (SYSTEMUI_PACKAGE.equals(visibleApps)) return "Only System UI views are visible";
+
             if (!mDevice.wait(Until.hasObject(getAnyObjectSelector()), WAIT_TIME_MS)) {
                 return "Screen is empty";
             }
@@ -406,12 +414,15 @@
     }
 
     private String getVisiblePackages() {
-        return mDevice.findObjects(getAnyObjectSelector())
+        final String apps = mDevice.findObjects(getAnyObjectSelector())
                 .stream()
                 .map(LauncherInstrumentation::getApplicationPackageSafe)
                 .distinct()
-                .filter(pkg -> pkg != null && !"com.android.systemui".equals(pkg))
+                .filter(pkg -> pkg != null && !SYSTEMUI_PACKAGE.equals(pkg))
                 .collect(Collectors.joining(", "));
+        return !apps.isEmpty()
+                ? "active app: " + apps
+                : "the test doesn't see views from any app, including Launcher";
     }
 
     private static String getApplicationPackageSafe(UiObject2 object) {