Merge "Tearing down the test safely." into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index e6dfe0f..1c7d7e0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -337,7 +337,7 @@
     }
 
     public boolean isBubbleBarEnabled() {
-        return BubbleBarController.BUBBLE_BAR_ENABLED;
+        return BubbleBarController.isBubbleBarEnabled();
     }
 
     /** Whether the bubble bar has any bubbles. */
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 0aa02f2..9f8f82a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -218,7 +218,8 @@
 
         // If Bubble bar is present, TaskbarControllers depends on it so build it first.
         Optional<BubbleControllers> bubbleControllersOptional = Optional.empty();
-        if (BubbleBarController.BUBBLE_BAR_ENABLED && bubbleBarView != null) {
+        BubbleBarController.onTaskbarRecreated();
+        if (BubbleBarController.isBubbleBarEnabled() && bubbleBarView != null) {
             bubbleControllersOptional = Optional.of(new BubbleControllers(
                     new BubbleBarController(this, bubbleBarView),
                     new BubbleBarViewController(this, bubbleBarView),
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
index a0ce976..712374d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
@@ -17,7 +17,7 @@
 
 import static android.view.View.VISIBLE;
 
-import static com.android.launcher3.taskbar.bubbles.BubbleBarController.BUBBLE_BAR_ENABLED;
+import static com.android.launcher3.taskbar.bubbles.BubbleBarController.isBubbleBarEnabled;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
 import static com.android.wm.shell.common.bubbles.BubbleConstants.BUBBLE_EXPANDED_SCRIM_ALPHA;
@@ -83,7 +83,7 @@
      * Updates the scrim state based on the flags.
      */
     public void updateStateForSysuiFlags(int stateFlags, boolean skipAnim) {
-        if (BUBBLE_BAR_ENABLED && DisplayController.isTransientTaskbar(mActivity)) {
+        if (isBubbleBarEnabled() && DisplayController.isTransientTaskbar(mActivity)) {
             // These scrims aren't used if bubble bar & transient taskbar are active.
             return;
         }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index bd11efd..3fb7247 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -85,17 +85,31 @@
  * information to render each of the bubbles & dispatches changes to
  * {@link BubbleBarViewController} which will then update {@link BubbleBarView} as needed.
  *
- * For details around the behavior of the bubble bar, see {@link BubbleBarView}.
+ * <p>For details around the behavior of the bubble bar, see {@link BubbleBarView}.
  */
 public class BubbleBarController extends IBubblesListener.Stub {
 
     private static final String TAG = BubbleBarController.class.getSimpleName();
     private static final boolean DEBUG = false;
 
-    // Whether bubbles are showing in the bubble bar from launcher
-    public static final boolean BUBBLE_BAR_ENABLED =
+    /**
+     * Determines whether bubbles can be shown in the bubble bar. This value updates when the
+     * taskbar is recreated.
+     *
+     * @see #onTaskbarRecreated()
+     */
+    private static boolean sBubbleBarEnabled =
             SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false);
 
+    /** Whether showing bubbles in the launcher bubble bar is enabled. */
+    public static boolean isBubbleBarEnabled() {
+        return sBubbleBarEnabled;
+    }
+
+    /** Re-reads the value of the flag from SystemProperties when taskbar is recreated. */
+    public static void onTaskbarRecreated() {
+        sBubbleBarEnabled = SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false);
+    }
     private static final int MASK_HIDE_BUBBLE_BAR = SYSUI_STATE_BOUNCER_SHOWING
             | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
             | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
@@ -167,7 +181,7 @@
 
         mSystemUiProxy = SystemUiProxy.INSTANCE.get(context);
 
-        if (BUBBLE_BAR_ENABLED) {
+        if (sBubbleBarEnabled) {
             mSystemUiProxy.setBubblesListener(this);
         }
         mMainExecutor = MAIN_EXECUTOR;
@@ -191,9 +205,9 @@
 
         bubbleControllers.runAfterInit(() -> {
             mBubbleBarViewController.setHiddenForBubbles(
-                    !BUBBLE_BAR_ENABLED || mBubbles.isEmpty());
+                    !sBubbleBarEnabled || mBubbles.isEmpty());
             mBubbleStashedHandleViewController.setHiddenForBubbles(
-                    !BUBBLE_BAR_ENABLED || mBubbles.isEmpty());
+                    !sBubbleBarEnabled || mBubbles.isEmpty());
             mBubbleBarViewController.setUpdateSelectedBubbleAfterCollapse(
                     key -> setSelectedBubble(mBubbles.get(key)));
         });
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 57d20f8..99c79b3 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -144,7 +144,7 @@
                 .around(new NavigationModeSwitchRule(mLauncher))
                 .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
                 .around(viewCaptureRule)
-                .around(new TestIsolationRule(mLauncher))
+                .around(new TestIsolationRule(mLauncher, false))
                 .around(setLauncherCommand);
 
         mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index b5e4012..aa96397 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -60,7 +60,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Laai tans programme …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string>
     <string name="label_application" msgid="8531721983832654978">"Program"</string>
-    <string name="all_apps_label" msgid="5015784846527570951">"Alle programme"</string>
+    <string name="all_apps_label" msgid="5015784846527570951">"Alle apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string>
     <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Raak en hou om \'n kortpad te skuif."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dubbeltik en hou om \'n kortpad te skuif of gebruik gepasmaakte handelinge."</string>
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index ab9836f..879000a 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -17,7 +17,6 @@
 package com.android.launcher3;
 
 import static android.text.Layout.Alignment.ALIGN_NORMAL;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V2;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_ICON_LABEL_AUTO_SCALING;
 import static com.android.launcher3.config.FeatureFlags.enableCursorHoverStates;
 import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
@@ -878,7 +877,7 @@
             if ((info.runtimeStatusFlags & FLAG_INCREMENTAL_DOWNLOAD_ACTIVE) != 0
                     || info.hasPromiseIconUi()
                     || (info.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0
-                    || (ENABLE_DOWNLOAD_APP_UX_V2.get() && icon != null)) {
+                    || (icon != null)) {
                 updateProgressBarUi(info.getProgressLevel() == 100 ? icon : null);
             }
         }
@@ -915,9 +914,7 @@
             if (mIcon instanceof PreloadIconDrawable) {
                 preloadIconDrawable = (PreloadIconDrawable) mIcon;
                 preloadIconDrawable.setLevel(progressLevel);
-                preloadIconDrawable.setIsDisabled(ENABLE_DOWNLOAD_APP_UX_V2.get()
-                        ? info.getProgressLevel() == 0
-                        : !info.isAppStartable());
+                preloadIconDrawable.setIsDisabled(info.getProgressLevel() == 0);
             } else {
                 preloadIconDrawable = makePreloadIcon();
                 setIcon(preloadIconDrawable);
@@ -942,9 +939,7 @@
         final PreloadIconDrawable preloadDrawable = newPendingIcon(getContext(), info);
 
         preloadDrawable.setLevel(progressLevel);
-        preloadDrawable.setIsDisabled(ENABLE_DOWNLOAD_APP_UX_V2.get()
-                ? info.getProgressLevel() == 0
-                : !info.isAppStartable());
+        preloadDrawable.setIsDisabled(info.getProgressLevel() == 0);
         return preloadDrawable;
     }
 
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index a3c434a..a3e68ba 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -151,21 +151,9 @@
     // TODO(Block 8): Clean up flags
 
     // TODO(Block 9): Clean up flags
-    public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V2 = getReleaseFlag(270395134,
-            "ENABLE_DOWNLOAD_APP_UX_V2", ENABLED, "Updates the download app UX"
-                    + " to have better visuals");
-
-    public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V3 = getDebugFlag(270395186,
-            "ENABLE_DOWNLOAD_APP_UX_V3", ENABLED, "Updates the download app UX"
-                    + " to have better visuals, improve contrast, and color");
 
     public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag(270395278,
             "SHOW_DOT_PAGINATION", ENABLED, "Enable showing dot pagination in workspace");
-
-    public static final BooleanFlag LARGE_SCREEN_WIDGET_PICKER = getDebugFlag(270395809,
-            "LARGE_SCREEN_WIDGET_PICKER", ENABLED, "Enable new widget picker that takes "
-                    + "advantage of large screen format");
-
     public static final BooleanFlag UNFOLDED_WIDGET_PICKER = getDebugFlag(301918659,
             "UNFOLDED_WIDGET_PICKER", DISABLED, "Enable new widget picker that takes "
                     + "advantage of the unfolded foldable format");
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index 307052a..3e77c78 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -19,8 +19,6 @@
 
 import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V2;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V3;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -76,10 +74,8 @@
     // Duration = COMPLETE_ANIM_FRACTION * DURATION_SCALE
     private static final float COMPLETE_ANIM_FRACTION = 1f;
 
-    private static final float SMALL_SCALE = ENABLE_DOWNLOAD_APP_UX_V3.get() ? 0.8f : 0.7f;
-    private static final float PROGRESS_STROKE_SCALE = ENABLE_DOWNLOAD_APP_UX_V2.get()
-            ? 0.055f
-            : 0.075f;
+    private static final float SMALL_SCALE = 0.8f;
+    private static final float PROGRESS_STROKE_SCALE = 0.055f;
     private static final float PROGRESS_BOUNDS_SCALE = 0.075f;
     private static final int PRELOAD_ACCENT_COLOR_INDEX = 0;
     private static final int PRELOAD_BACKGROUND_COLOR_INDEX = 1;
@@ -119,8 +115,6 @@
 
     private ObjectAnimator mCurrentAnim;
 
-    private boolean mIsStartable;
-
     public PreloadIconDrawable(ItemInfoWithIcon info, Context context) {
         this(
                 info,
@@ -144,9 +138,7 @@
 
         mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
         mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
-        if (ENABLE_DOWNLOAD_APP_UX_V3.get()) {
-            mProgressPaint.setAlpha(MAX_PAINT_ALPHA);
-        }
+        mProgressPaint.setAlpha(MAX_PAINT_ALPHA);
         mIndicatorColor = indicatorColor;
 
         // This is the color
@@ -181,9 +173,6 @@
         mIconScaleMultiplier.updateValue(info.getProgressLevel() == 0 ? 0 : 1);
 
         setLevel(info.getProgressLevel());
-        if (!ENABLE_DOWNLOAD_APP_UX_V2.get()) {
-            setIsStartable(info.isAppStartable());
-        }
     }
 
     @Override
@@ -212,54 +201,31 @@
             return;
         }
 
-        if (mInternalStateProgress > 0
-                && (ENABLE_DOWNLOAD_APP_UX_V3.get() || !ENABLE_DOWNLOAD_APP_UX_V2.get())) {
+        if (mInternalStateProgress > 0) {
             // Draw background.
-            mProgressPaint.setStyle(ENABLE_DOWNLOAD_APP_UX_V3.get()
-                    ? Paint.Style.FILL
-                    : Paint.Style.FILL_AND_STROKE);
-            mProgressPaint.setColor(ENABLE_DOWNLOAD_APP_UX_V3.get()
-                    ? mPlateColor
-                    : mSystemBackgroundColor);
+            mProgressPaint.setStyle(Paint.Style.FILL);
+            mProgressPaint.setColor(mPlateColor);
             canvas.drawPath(mScaledTrackPath, mProgressPaint);
         }
 
-        if (!ENABLE_DOWNLOAD_APP_UX_V2.get() || mInternalStateProgress > 0) {
+        if (mInternalStateProgress > 0) {
             // Draw track and progress.
             mProgressPaint.setStyle(Paint.Style.STROKE);
-            mProgressPaint.setColor(ENABLE_DOWNLOAD_APP_UX_V3.get()
-                    ? mTrackColor
-                    : mSystemAccentColor);
-            if (!ENABLE_DOWNLOAD_APP_UX_V3.get()) {
-                mProgressPaint.setAlpha(TRACK_ALPHA);
-            }
+            mProgressPaint.setColor(mTrackColor);
             canvas.drawPath(mScaledTrackPath, mProgressPaint);
             mProgressPaint.setAlpha(MAX_PAINT_ALPHA);
-            if (ENABLE_DOWNLOAD_APP_UX_V3.get()) {
-                mProgressPaint.setColor(mProgressColor);
-            }
+            mProgressPaint.setColor(mProgressColor);
             canvas.drawPath(mScaledProgressPath, mProgressPaint);
         }
 
         int saveCount = canvas.save();
-        float scale = ENABLE_DOWNLOAD_APP_UX_V2.get()
-                ? 1 - mIconScaleMultiplier.value * (1 - SMALL_SCALE)
-                : SMALL_SCALE;
+        float scale = 1 - mIconScaleMultiplier.value * (1 - SMALL_SCALE);
         canvas.scale(scale, scale, bounds.exactCenterX(), bounds.exactCenterY());
 
         super.drawInternal(canvas, bounds);
         canvas.restoreToCount(saveCount);
     }
 
-    @Override
-    protected void updateFilter() {
-        if (!ENABLE_DOWNLOAD_APP_UX_V2.get()) {
-            setAlpha(mIsDisabled ? DISABLED_ICON_ALPHA : MAX_PAINT_ALPHA);
-        } else {
-            super.updateFilter();
-        }
-    }
-
     /**
      * Updates the install progress based on the level
      */
@@ -296,14 +262,6 @@
         return !mRanFinishAnimation;
     }
 
-    /** Sets whether this icon should display the startable app UI. */
-    public void setIsStartable(boolean isStartable) {
-        if (mIsStartable != isStartable) {
-            mIsStartable = isStartable;
-            setIsDisabled(!isStartable);
-        }
-    }
-
     private void updateInternalState(
             float finalProgress, boolean isFinish, Runnable onFinishCallback) {
         if (mCurrentAnim != null) {
@@ -355,7 +313,7 @@
      */
     private void setInternalProgress(float progress) {
         // Animate scale and alpha from pending to downloading state.
-        if (ENABLE_DOWNLOAD_APP_UX_V2.get() && progress > 0 && mInternalStateProgress == 0) {
+        if (progress > 0 && mInternalStateProgress == 0) {
             // Progress is changing for the first time, animate the icon scale
             Animator iconScaleAnimator = mIconScaleMultiplier.animateToValue(1);
             iconScaleAnimator.setDuration(SCALE_AND_ALPHA_ANIM_DURATION);
@@ -365,14 +323,11 @@
 
         mInternalStateProgress = progress;
         if (progress <= 0) {
-            if (!ENABLE_DOWNLOAD_APP_UX_V2.get()) {
-                mScaledTrackPath.reset();
-            }
             mIconScaleMultiplier.updateValue(0);
         } else {
             mPathMeasure.getSegment(
                     0, Math.min(progress, 1) * mTrackLength, mScaledProgressPath, true);
-            if (progress > 1 && ENABLE_DOWNLOAD_APP_UX_V2.get()) {
+            if (progress > 1) {
                 // map the scale back to original value
                 mIconScaleMultiplier.updateValue(Utilities.mapBoundToRange(
                         progress - 1, 0, COMPLETE_ANIM_FRACTION, 1, 0, EMPHASIZED));
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index dcc86a1..742d2dc 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -16,7 +16,6 @@
 package com.android.launcher3.widget;
 
 import static com.android.app.animation.Interpolators.EMPHASIZED;
-import static com.android.launcher3.config.FeatureFlags.LARGE_SCREEN_WIDGET_PICKER;
 
 import android.content.Context;
 import android.graphics.Canvas;
@@ -194,9 +193,7 @@
         int widthUsed;
         if (deviceProfile.isTablet) {
             int margin = deviceProfile.allAppsLeftRightMargin;
-            if (deviceProfile.isLandscape
-                    && LARGE_SCREEN_WIDGET_PICKER.get()
-                    && !deviceProfile.isTwoPanels) {
+            if (deviceProfile.isLandscape && !deviceProfile.isTwoPanels) {
                 margin = getResources().getDimensionPixelSize(
                         R.dimen.widget_picker_landscape_tablet_left_right_margin);
             }
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 4105a9a..2c094f2 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -18,7 +18,6 @@
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.config.FeatureFlags.LARGE_SCREEN_WIDGET_PICKER;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_SEARCHED;
 import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL;
 
@@ -679,8 +678,7 @@
 
     /** Shows the {@link WidgetsFullSheet} on the launcher. */
     public static WidgetsFullSheet show(Launcher launcher, boolean animate) {
-        boolean isTwoPane = LARGE_SCREEN_WIDGET_PICKER.get()
-                && launcher.getDeviceProfile().isTablet
+        boolean isTwoPane = launcher.getDeviceProfile().isTablet
                 && launcher.getDeviceProfile().isLandscape
                 && (!launcher.getDeviceProfile().isTwoPanels
                     || FeatureFlags.UNFOLDED_WIDGET_PICKER.get());
@@ -798,8 +796,7 @@
         // Checks the orientation of the screen
         if (mOrientation != newConfig.orientation) {
             mOrientation = newConfig.orientation;
-            if (LARGE_SCREEN_WIDGET_PICKER.get()
-                    && mDeviceProfile.isTablet && !mDeviceProfile.isTwoPanels) {
+            if (mDeviceProfile.isTablet && !mDeviceProfile.isTwoPanels) {
                 handleClose(false);
                 show(Launcher.getLauncher(getContext()), false);
             } else {
diff --git a/tests/Android.bp b/tests/Android.bp
index d828fdf..62d232c 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -49,6 +49,7 @@
       "src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
       "src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
       "src/com/android/launcher3/ui/TaplTestsLauncher3.java",
+      "src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java",
       "src/com/android/launcher3/util/LauncherLayoutBuilder.java",
       "src/com/android/launcher3/util/TestUtil.java",
       "src/com/android/launcher3/util/Wait.java",
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 3f763c3..e837b8b 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -111,15 +111,22 @@
     protected String mTargetPackage;
     private int mLauncherPid;
 
+    /** Detects activity leaks and throws an exception if a leak is found. */
     public static void checkDetectedLeaks(LauncherInstrumentation launcher) {
+        checkDetectedLeaks(launcher, false);
+    }
+
+    /** Detects activity leaks and throws an exception if a leak is found. */
+    public static void checkDetectedLeaks(LauncherInstrumentation launcher,
+            boolean requireOneActiveActivity) {
         if (sActivityLeakReported) return;
 
         // Check whether activity leak detector has found leaked activities.
-        Wait.atMost(() -> getActivityLeakErrorMessage(launcher),
+        Wait.atMost(() -> getActivityLeakErrorMessage(launcher, requireOneActiveActivity),
                 () -> {
                     launcher.forceGc();
                     return MAIN_EXECUTOR.submit(
-                            () -> launcher.noLeakedActivities()).get();
+                            () -> launcher.noLeakedActivities(requireOneActiveActivity)).get();
                 }, DEFAULT_UI_TIMEOUT, launcher);
     }
 
@@ -127,13 +134,16 @@
         return getInstrumentation().getContext().getPackageName();
     }
 
-    private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher) {
+    private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher,
+            boolean requireOneActiveActivity) {
         sActivityLeakReported = true;
-        return "Activity leak detector has found leaked activities, "
-                + dumpHprofData(launcher, false) + ".";
+        return "Activity leak detector has found leaked activities, requirining 1 activity: "
+                + requireOneActiveActivity + "; "
+                + dumpHprofData(launcher, false, requireOneActiveActivity) + ".";
     }
 
-    public static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak) {
+    private static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak,
+            boolean requireOneActiveActivity) {
         if (intentionalLeak) return "intentional leak; not generating dump";
 
         String result;
@@ -152,7 +162,7 @@
                             "am dumpheap " + device.getLauncherPackageName() + " " + fileName);
                 }
                 Log.d(TAG, "Saved leak dump, the leak is still present: "
-                        + !launcher.noLeakedActivities());
+                        + !launcher.noLeakedActivities(requireOneActiveActivity));
                 sDumpWasGenerated = true;
                 result = "saved memory dump as an artifact";
             } catch (Throwable e) {
@@ -211,7 +221,7 @@
                 .outerRule(new PortraitLandscapeRunner(this))
                 .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
                 .around(viewCaptureRule)
-                .around(new TestIsolationRule(mLauncher));
+                .around(new TestIsolationRule(mLauncher, true));
 
         return TestHelpers.isInLauncherProcess()
                 ? RuleChain.outerRule(ShellCommandRule.setDefaultLauncher()).around(inner)
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index bc53d6d..9aaca54 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -16,9 +16,6 @@
 
 package com.android.launcher3.ui;
 
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -40,16 +37,11 @@
 import com.android.launcher3.tapl.AppIcon;
 import com.android.launcher3.tapl.HomeAllApps;
 import com.android.launcher3.tapl.HomeAppIcon;
-import com.android.launcher3.tapl.Widgets;
 import com.android.launcher3.tapl.Workspace;
 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
 import com.android.launcher3.util.LauncherLayoutBuilder;
 import com.android.launcher3.util.TestUtil;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 import com.android.launcher3.util.rule.TISBindRule;
-import com.android.launcher3.util.rule.TestStabilityRule.Stability;
-import com.android.launcher3.widget.picker.WidgetsFullSheet;
-import com.android.launcher3.widget.picker.WidgetsRecyclerView;
 
 import org.junit.After;
 import org.junit.Before;
@@ -93,7 +85,7 @@
         test.waitForResumed("Launcher internal state is still Background");
         // Check that we switched to home.
         test.mLauncher.getWorkspace();
-        AbstractLauncherUiTest.checkDetectedLeaks(test.mLauncher);
+        AbstractLauncherUiTest.checkDetectedLeaks(test.mLauncher, true);
     }
 
     @After
@@ -122,10 +114,6 @@
         return launcher.getWorkspace().getCurrentPage();
     }
 
-    private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
-        return WidgetsFullSheet.getWidgetsView(launcher);
-    }
-
     @Test
     public void testDevicePressMenu() throws Exception {
         mDevice.pressMenu();
@@ -208,42 +196,6 @@
         runIconLaunchFromAllAppsTest(this, allApps);
     }
 
-    @Test
-    @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/293191790
-    @ScreenRecord
-    @PortraitLandscape
-    public void testWidgets() throws Exception {
-        // Test opening widgets.
-        executeOnLauncher(launcher ->
-                assertTrue("Widgets is initially opened", getWidgetsView(launcher) == null));
-        Widgets widgets = mLauncher.getWorkspace().openAllWidgets();
-        assertNotNull("openAllWidgets() returned null", widgets);
-        widgets = mLauncher.getAllWidgets();
-        assertNotNull("getAllWidgets() returned null", widgets);
-        executeOnLauncher(launcher ->
-                assertTrue("Widgets is not shown", getWidgetsView(launcher).isShown()));
-        executeOnLauncher(launcher -> assertEquals("Widgets is scrolled upon opening",
-                0, getWidgetsScroll(launcher)));
-
-        // Test flinging widgets.
-        widgets.flingForward();
-        Integer flingForwardY = getFromLauncher(launcher -> getWidgetsScroll(launcher));
-        executeOnLauncher(launcher -> assertTrue("Flinging forward didn't scroll widgets",
-                flingForwardY > 0));
-
-        widgets.flingBackward();
-        executeOnLauncher(launcher -> assertTrue("Flinging backward didn't scroll widgets",
-                getWidgetsScroll(launcher) < flingForwardY));
-
-        mLauncher.goHome();
-        waitForLauncherCondition("Widgets were not closed",
-                launcher -> getWidgetsView(launcher) == null);
-    }
-
-    private int getWidgetsScroll(Launcher launcher) {
-        return getWidgetsView(launcher).computeVerticalScrollOffset();
-    }
-
     @FlakyTest(bugId = 256615483)
     @Test
     @PortraitLandscape
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java b/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
new file mode 100644
index 0000000..a5e9868
--- /dev/null
+++ b/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.ui.widget;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.tapl.Widgets;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+import com.android.launcher3.util.rule.TestStabilityRule.Stability;
+import com.android.launcher3.widget.picker.WidgetsFullSheet;
+import com.android.launcher3.widget.picker.WidgetsRecyclerView;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This test run in both Out of process (Oop) and in-process (Ipc).
+ * Make sure the basic interactions with the WidgetPicker works.
+ */
+public class TaplWidgetPickerTest extends AbstractLauncherUiTest {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        initialize(this);
+    }
+
+    private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
+        return WidgetsFullSheet.getWidgetsView(launcher);
+    }
+
+    private int getWidgetsScroll(Launcher launcher) {
+        return getWidgetsView(launcher).computeVerticalScrollOffset();
+    }
+
+    /**
+     * Open Widget picker, make sure the widget picker can scroll and then go to home screen.
+     */
+    @Test
+    @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/293191790
+    @ScreenRecord
+    @PortraitLandscape
+    public void testWidgets() {
+        // Test opening widgets.
+        executeOnLauncher(launcher ->
+                assertTrue("Widgets is initially opened", getWidgetsView(launcher) == null));
+        Widgets widgets = mLauncher.getWorkspace().openAllWidgets();
+        assertNotNull("openAllWidgets() returned null", widgets);
+        widgets = mLauncher.getAllWidgets();
+        assertNotNull("getAllWidgets() returned null", widgets);
+        executeOnLauncher(launcher ->
+                assertTrue("Widgets is not shown", getWidgetsView(launcher).isShown()));
+        executeOnLauncher(launcher -> assertEquals("Widgets is scrolled upon opening",
+                0, getWidgetsScroll(launcher)));
+
+        // Test flinging widgets.
+        widgets.flingForward();
+        Integer flingForwardY = getFromLauncher(launcher -> getWidgetsScroll(launcher));
+        executeOnLauncher(launcher -> assertTrue("Flinging forward didn't scroll widgets",
+                flingForwardY > 0));
+
+        widgets.flingBackward();
+        executeOnLauncher(launcher -> assertTrue("Flinging backward didn't scroll widgets",
+                getWidgetsScroll(launcher) < flingForwardY));
+
+        mLauncher.goHome();
+        waitForLauncherCondition("Widgets were not closed",
+                launcher -> getWidgetsView(launcher) == null);
+    }
+}
diff --git a/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java b/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
index c1f9d40..2b45902 100644
--- a/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
+++ b/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
@@ -30,10 +30,12 @@
  * Isolates tests from some of the state created by the previous test.
  */
 public class TestIsolationRule implements TestRule {
-    final LauncherInstrumentation mLauncher;
+    private final LauncherInstrumentation mLauncher;
+    private final boolean mRequireOneActiveActivity;
 
-    public TestIsolationRule(LauncherInstrumentation launcher) {
+    public TestIsolationRule(LauncherInstrumentation launcher, boolean requireOneActiveActivity) {
         mLauncher = launcher;
+        mRequireOneActiveActivity = requireOneActiveActivity;
     }
 
     @NonNull
@@ -46,7 +48,7 @@
                 // Make sure that Launcher workspace looks correct.
 
                 UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).pressHome();
-                AbstractLauncherUiTest.checkDetectedLeaks(mLauncher);
+                AbstractLauncherUiTest.checkDetectedLeaks(mLauncher, mRequireOneActiveActivity);
             }
         };
     }
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 2dec880..d7f9c78 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -704,6 +704,7 @@
 
     /**
      * Set the trackpad gesture type of the interaction.
+     *
      * @param trackpadGestureType whether it's not from trackpad, two-finger, three-finger, or
      *                            four-finger gesture.
      */
@@ -1821,8 +1822,8 @@
 
         final MotionEvent event = isTrackpadGesture
                 ? getTrackpadMotionEvent(
-                        downTime, currentTime, action, point.x, point.y, pointerCount,
-                        mTrackpadGestureType)
+                downTime, currentTime, action, point.x, point.y, pointerCount,
+                mTrackpadGestureType)
                 : getMotionEvent(downTime, currentTime, action, point.x, point.y, source);
         if (action == MotionEvent.ACTION_BUTTON_PRESS
                 || action == MotionEvent.ACTION_BUTTON_RELEASE) {
@@ -2072,14 +2073,16 @@
         return String.join(", ", getActivities());
     }
 
-    public boolean noLeakedActivities() {
+    /** Returns whether no leaked activities are detected. */
+    public boolean noLeakedActivities(boolean requireOneActiveActivity) {
         final String[] activities = getActivities();
+
         for (String activity : activities) {
             if (activity.contains("(destroyed)")) {
                 return false;
             }
         }
-        return activities.length <= 2;
+        return activities.length <= (requireOneActiveActivity ? 1 : 2);
     }
 
     public int getActivitiesCreated() {