Merge "Add logs for launcher user cache" into udc-dev
diff --git a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
index 3fddd9d..dc28c6a 100644
--- a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
+++ b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3.testing;
 
-import static com.android.launcher3.testing.shared.TestProtocol.VIEW_AND_ACTIVITY_LEAKS;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
@@ -25,10 +24,7 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.Process;
 import android.system.Os;
-import android.util.Log;
-import android.view.View;
 
 import androidx.annotation.Keep;
 import androidx.annotation.Nullable;
@@ -42,7 +38,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.LinkedList;
 import java.util.Map;
 import java.util.WeakHashMap;
 import java.util.concurrent.CountDownLatch;
@@ -52,7 +47,6 @@
  * Class to handle requests from tests, including debug ones.
  */
 public class DebugTestInformationHandler extends TestInformationHandler {
-    private static LinkedList sLeaks;
     private static Collection<String> sEvents;
     private static Application.ActivityLifecycleCallbacks sActivityLifecycleCallbacks;
     private static final Map<Activity, Boolean> sActivities =
@@ -158,19 +152,6 @@
                 return response;
             }
 
-            case TestProtocol.REQUEST_VIEW_LEAK: {
-                if (sLeaks == null) sLeaks = new LinkedList();
-                Log.d(VIEW_AND_ACTIVITY_LEAKS, "forcefully leaking 2 views");
-                sLeaks.add(new View(mContext));
-                sLeaks.add(new View(mContext));
-                return response;
-            }
-
-            case TestProtocol.PRINT_VIEW_LEAK: {
-                Log.d(VIEW_AND_ACTIVITY_LEAKS, "(pid=" + Process.myPid() + ") sLeaks=" + sLeaks);
-                return response;
-            }
-
             case TestProtocol.REQUEST_START_EVENT_LOGGING: {
                 sEvents = new ArrayList<>();
                 TestLogging.setEventConsumer(
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index 9d36c67..fcbca7e 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -113,7 +113,7 @@
     <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Брзи поставки"</string>
     <string name="taskbar_a11y_title" msgid="6432169809852243110">"Лента со задачи"</string>
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Лентата со задачи е прикажана"</string>
-    <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Лентата со задачи е сокриена"</string>
+    <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Лентата со задачи е скриена"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Лента за навигација"</string>
     <string name="always_show_taskbar" msgid="3608801276107751229">"Секогаш прикажувај „Лента“"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"Променете режим на навигација"</string>
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index e45d9fd..8a3ffb5 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -53,5 +53,5 @@
     <string name="setup_wizard_pkg" translatable="false" />
 
     <!-- This is a float because it is converted to dp later in DeviceProfile -->
-    <item name="taskbar_icon_size" type="dimen" format="float">44</item>
+    <item name="taskbar_icon_size" type="dimen" format="float">48.4</item>
 </resources>
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
index fe365f7..ca2d1f8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
@@ -34,6 +34,7 @@
 /** Helps draw the taskbar background, made up of a rectangle plus two inverted rounded corners. */
 class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
 
+    private val isInSetup: Boolean = !context.isUserSetupComplete
     private val DARK_THEME_SHADOW_ALPHA = 51f
     private val LIGHT_THEME_SHADOW_ALPHA = 25f
 
@@ -137,7 +138,7 @@
             canvas.translate(0f, leftCornerRadius)
             canvas.translate(canvas.width - rightCornerRadius, -rightCornerRadius)
             canvas.drawPath(invertedRightCornerPath, paint)
-        } else {
+        } else if (!isInSetup) {
             // backgroundHeight is a value from [0...maxBackgroundHeight], so we can use it as a
             // proxy to figure out the animation progress of the stash/unstash animation.
             val progress = backgroundHeight / maxBackgroundHeight
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
index 8e1059b..6cf63a9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
@@ -18,6 +18,8 @@
 import android.util.SparseArray;
 import android.view.View;
 
+import androidx.annotation.UiThread;
+
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.model.BgDataModel;
 import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -29,6 +31,8 @@
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LauncherBindableItemsContainer;
+import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Preconditions;
 import com.android.quickstep.RecentsModel;
 
 import java.io.PrintWriter;
@@ -37,6 +41,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Predicate;
 
 /**
@@ -250,9 +255,12 @@
         mControllers.taskbarPopupController.setDeepShortcutMap(deepShortcutMapCopy);
     }
 
+    @UiThread
     @Override
-    public void bindAllApplications(AppInfo[] apps, int flags) {
-        mControllers.taskbarAllAppsController.setApps(apps, flags);
+    public void bindAllApplications(AppInfo[] apps, int flags,
+            Map<PackageUserKey, Integer> packageUserKeytoUidMap) {
+        Preconditions.assertUIThread();
+        mControllers.taskbarAllAppsController.setApps(apps, flags, packageUserKeytoUidMap);
         mControllers.taskbarRecentAppsController.setApps(apps);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index 459a658..e0a502b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -26,7 +26,9 @@
 import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
 import com.android.launcher3.util.PackageUserKey;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Predicate;
 
 /**
@@ -53,6 +55,8 @@
     private boolean mDisallowGlobalDrag;
     private boolean mDisallowLongClick;
 
+    private Map<PackageUserKey, Integer> mPackageUserKeytoUidMap = Collections.emptyMap();
+
     /** Initialize the controller. */
     public void init(TaskbarControllers controllers, boolean allAppsVisible) {
         mControllers = controllers;
@@ -67,11 +71,12 @@
     }
 
     /** Updates the current {@link AppInfo} instances. */
-    public void setApps(AppInfo[] apps, int flags) {
+    public void setApps(AppInfo[] apps, int flags, Map<PackageUserKey, Integer> map) {
         mApps = apps;
         mAppsModelFlags = flags;
+        mPackageUserKeytoUidMap = map;
         if (mAppsView != null) {
-            mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags);
+            mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags, mPackageUserKeytoUidMap);
         }
     }
 
@@ -136,7 +141,7 @@
 
         viewController.show(animate);
         mAppsView = overlayContext.getAppsView();
-        mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags);
+        mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags, mPackageUserKeytoUidMap);
         mAppsView.getFloatingHeaderView()
                 .findFixedRowByType(PredictionRowView.class)
                 .setPredictedApps(mPredictedApps);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 95c2326..e4e8880 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -878,7 +878,9 @@
 
     private void onTISConnected(TISBinder binder) {
         mTaskbarManager = binder.getTaskbarManager();
-        mTaskbarManager.setActivity(this);
+        if (mTaskbarManager != null) {
+            mTaskbarManager.setActivity(this);
+        }
         mOverviewCommandHelper = binder.getOverviewCommandHelper();
     }
 
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index f5202b7..3a6566a 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -147,6 +147,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Consumer;
 
@@ -662,6 +663,14 @@
         } else {
             runningTasks = mGestureState.getRunningTask().getPlaceholderTasks();
         }
+
+        // Safeguard against any null tasks being sent to recents view, happens when quickswitching
+        // very quickly w/ split tasks because TopTaskTracker provides stale information compared to
+        // actual running tasks in the recents animation.
+        // TODO(b/236226779), Proper fix (ag/22237143)
+        if (Arrays.stream(runningTasks).anyMatch(Objects::isNull)) {
+            return;
+        }
         mRecentsView.onGestureAnimationStart(runningTasks, mDeviceState.getRotationTouchHelper());
     }
 
@@ -915,7 +924,12 @@
         if (DesktopTaskView.DESKTOP_MODE_SUPPORTED && targets.hasDesktopTasks()) {
             mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets);
         } else {
+            int untrimmedAppCount = mRemoteTargetHandles.length;
             mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(targets);
+            if (mRemoteTargetHandles.length < untrimmedAppCount && mIsSwipeForSplit) {
+                updateIsGestureForSplit(mRemoteTargetHandles.length);
+                setupRecentsViewUi();
+            }
         }
         mRecentsAnimationController = controller;
         mRecentsAnimationTargets = targets;
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 253341d..39af7fd 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -144,7 +144,9 @@
 
     private void onTISConnected(TouchInteractionService.TISBinder binder) {
         mTaskbarManager = binder.getTaskbarManager();
-        mTaskbarManager.setActivity(this);
+        if (mTaskbarManager != null) {
+            mTaskbarManager.setActivity(this);
+        }
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index d9c269a..84b90b9 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -29,12 +29,15 @@
 import com.android.quickstep.views.DesktopTaskView;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * Glues together the necessary components to animate a remote target using a
  * {@link TaskViewSimulator}
  */
 public class RemoteTargetGluer {
+    private static final int DEFAULT_NUM_HANDLES = 2;
+
     private RemoteTargetHandle[] mRemoteTargetHandles;
     private SplitBounds mSplitBounds;
 
@@ -62,8 +65,9 @@
             }
         }
 
-        int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds();
-        init(context, sizingStrategy, splitIds.length == 2 ? 2 : 1, false /* forDesktop */);
+        // Assume 2 handles needed for split, scale down as needed later on when we actually
+        // get remote targets
+        init(context, sizingStrategy, DEFAULT_NUM_HANDLES, false /* forDesktop */);
     }
 
     private void init(Context context, BaseActivityInterface sizingStrategy, int numHandles,
@@ -108,6 +112,17 @@
      * the left/top task, index 1 right/bottom.
      */
     public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets) {
+        // Resize the mRemoteTargetHandles array since we started assuming split screen, but
+        // targets.apps is the ultimate source of truth here
+        long appCount = Arrays.stream(targets.apps)
+                .filter(app -> app.mode == targets.targetMode)
+                .count();
+        if (appCount < mRemoteTargetHandles.length) {
+            RemoteTargetHandle[] newHandles = new RemoteTargetHandle[(int) appCount];
+            System.arraycopy(mRemoteTargetHandles, 0/*src*/, newHandles, 0/*dst*/, (int) appCount);
+            mRemoteTargetHandles = newHandles;
+        }
+
         if (mRemoteTargetHandles.length == 1) {
             // If we're not in split screen, the splitIds count doesn't really matter since we
             // should always hit this case.
@@ -233,6 +248,14 @@
                 targets.targetMode);
     }
 
+    /**
+     * The object returned by this is may be modified in
+     * {@link #assignTargetsForSplitScreen(RemoteAnimationTargets)}, specifically the length of the
+     * array may be shortened based on the number of RemoteAnimationTargets present.
+     * <p>
+     * This can be accessed at any time, however the count will be more accurate if accessed after
+     * calling one of the respective assignTargets*() methods
+     */
     public RemoteTargetHandle[] getRemoteTargetHandles() {
         return mRemoteTargetHandles;
     }
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index 1b4fdc4..25ac47a 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -82,7 +82,8 @@
         mContext = context;
         mDeviceState = deviceState;
         mGestureState = gestureState;
-        mIsSwipeForSplit = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds().length > 1;
+        updateIsGestureForSplit(TopTaskTracker.INSTANCE.get(context)
+                .getRunningSplitTaskIds().length);
 
         mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getActivityInterface());
         mRemoteTargetHandles = mTargetGluer.getRemoteTargetHandles();
@@ -280,6 +281,10 @@
         return out;
     }
 
+    protected void updateIsGestureForSplit(int targetCount) {
+        mIsSwipeForSplit = targetCount > 1;
+    }
+
     private RectFSpringAnim getWindowAnimationToHomeInternal(
             HomeAnimationFactory homeAnimationFactory, RectF targetRect,
             TransformParams transformParams, TaskViewSimulator taskViewSimulator,
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index 2aa0be6..1744b08 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -28,7 +28,6 @@
 import android.graphics.Rect;
 import android.os.Build;
 import android.view.View;
-import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
@@ -42,6 +41,7 @@
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.util.ResourceBasedOverride;
 import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.Snackbar;
 import com.android.quickstep.util.RecentsOrientedState;
 import com.android.quickstep.views.OverviewActionsView;
 import com.android.quickstep.views.RecentsView;
@@ -272,10 +272,8 @@
             String message = activityContext.getStringCache() != null
                     ? activityContext.getStringCache().disabledByAdminMessage
                     : mThumbnailView.getContext().getString(R.string.blocked_by_policy);
-            Toast.makeText(
-                    mThumbnailView.getContext(),
-                    message,
-                    Toast.LENGTH_LONG).show();
+
+            Snackbar.show(BaseActivity.fromContext(mThumbnailView.getContext()), message, null);
         }
 
         /** Called when the snapshot has updated its full screen drawing parameters. */
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 1fbfbe6..1624eb6 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -139,8 +139,10 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
 import java.util.Arrays;
 import java.util.LinkedList;
+import java.util.function.Consumer;
 import java.util.function.Function;
 
 /**
@@ -157,15 +159,21 @@
 
     private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
 
-    private final TISBinder mTISBinder = new TISBinder();
+    private final TISBinder mTISBinder = new TISBinder(this);
 
     /**
      * Local IOverviewProxy implementation with some methods for local components
      */
-    public class TISBinder extends IOverviewProxy.Stub {
+    public static class TISBinder extends IOverviewProxy.Stub {
+
+        private final WeakReference<TouchInteractionService> mTis;
 
         @Nullable private Runnable mOnOverviewTargetChangeListener = null;
 
+        private TISBinder(TouchInteractionService tis) {
+            mTis = new WeakReference<>(tis);
+        }
+
         @BinderThread
         public void onInitialize(Bundle bundle) {
             ISystemUiProxy proxy = ISystemUiProxy.Stub.asInterface(
@@ -193,14 +201,14 @@
                     bundle.getBinder(KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER));
             IDragAndDrop dragAndDrop = IDragAndDrop.Stub.asInterface(
                     bundle.getBinder(KEY_EXTRA_SHELL_DRAG_AND_DROP));
-            MAIN_EXECUTOR.execute(() -> {
-                SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy, pip,
+            MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
+                SystemUiProxy.INSTANCE.get(tis).setProxy(proxy, pip,
                         bubbles, splitscreen, onehanded, shellTransitions, startingWindow,
                         recentTasks, launcherUnlockAnimationController, backAnimation, desktopMode,
                         unfoldTransition, dragAndDrop);
-                TouchInteractionService.this.initInputMonitor("TISBinder#onInitialize()");
-                preloadOverview(true /* fromInit */);
-            });
+                tis.initInputMonitor("TISBinder#onInitialize()");
+                tis.preloadOverview(true /* fromInit */);
+            }));
             sIsInitialized = true;
         }
 
@@ -208,65 +216,72 @@
         @Override
         public void onTaskbarToggled() {
             if (!FeatureFlags.ENABLE_KEYBOARD_TASKBAR_TOGGLE.get()) return;
-            MAIN_EXECUTOR.execute(() -> {
+            MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
                 TaskbarActivityContext activityContext =
-                        mTaskbarManager.getCurrentActivityContext();
+                        tis.mTaskbarManager.getCurrentActivityContext();
 
                 if (activityContext != null) {
                     activityContext.toggleTaskbarStash();
                 }
-            });
+            }));
         }
 
         @BinderThread
         public void onOverviewToggle() {
             TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onOverviewToggle");
-            // If currently screen pinning, do not enter overview
-            if (mDeviceState.isScreenPinningActive()) {
-                return;
-            }
-            TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
-            mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_TOGGLE);
+            executeForTouchInteractionService(tis -> {
+                // If currently screen pinning, do not enter overview
+                if (tis.mDeviceState.isScreenPinningActive()) {
+                    return;
+                }
+                TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+                tis.mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_TOGGLE);
+            });
         }
 
         @BinderThread
         @Override
         public void onOverviewShown(boolean triggeredFromAltTab) {
-            if (triggeredFromAltTab) {
-                TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
-                mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_KEYBOARD_INPUT);
-            } else {
-                mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_SHOW);
-            }
+            executeForTouchInteractionService(tis -> {
+                if (triggeredFromAltTab) {
+                    TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+                    tis.mOverviewCommandHelper.addCommand(
+                            OverviewCommandHelper.TYPE_KEYBOARD_INPUT);
+                } else {
+                    tis.mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_SHOW);
+                }
+            });
         }
 
         @BinderThread
         @Override
         public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
-            if (triggeredFromAltTab && !triggeredFromHomeKey) {
-                // onOverviewShownFromAltTab hides the overview and ends at the target app
-                mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_HIDE);
-            }
+            executeForTouchInteractionService(tis -> {
+                if (triggeredFromAltTab && !triggeredFromHomeKey) {
+                    // onOverviewShownFromAltTab hides the overview and ends at the target app
+                    tis.mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_HIDE);
+                }
+            });
         }
 
         @BinderThread
         @Override
         public void onAssistantAvailable(boolean available, boolean longPressHomeEnabled) {
-            MAIN_EXECUTOR.execute(() -> {
-                mDeviceState.setAssistantAvailable(available);
-                TouchInteractionService.this.onAssistantVisibilityChanged();
-                executeForTaskbarManager(() -> mTaskbarManager
+            MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
+                tis.mDeviceState.setAssistantAvailable(available);
+                tis.onAssistantVisibilityChanged();
+                executeForTaskbarManager(taskbarManager -> taskbarManager
                         .onLongPressHomeEnabled(longPressHomeEnabled));
-            });
+            }));
         }
 
         @BinderThread
         @Override
         public void onAssistantVisibilityChanged(float visibility) {
-            MAIN_EXECUTOR.execute(() -> {
-                mDeviceState.setAssistantVisibility(visibility);
-                TouchInteractionService.this.onAssistantVisibilityChanged();
-            });
+            MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
+                tis.mDeviceState.setAssistantVisibility(visibility);
+                tis.onAssistantVisibilityChanged();
+            }));
         }
 
         @Override
@@ -276,16 +291,17 @@
 
         @BinderThread
         public void onSystemUiStateChanged(int stateFlags) {
-            MAIN_EXECUTOR.execute(() -> {
-                int lastFlags = mDeviceState.getSystemUiStateFlags();
-                mDeviceState.setSystemUiFlags(stateFlags);
-                TouchInteractionService.this.onSystemUiFlagsChanged(lastFlags);
-            });
+            MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
+                int lastFlags = tis.mDeviceState.getSystemUiStateFlags();
+                tis.mDeviceState.setSystemUiFlags(stateFlags);
+                tis.onSystemUiFlagsChanged(lastFlags);
+            }));
         }
 
         @BinderThread
         public void onActiveNavBarRegionChanges(Region region) {
-            MAIN_EXECUTOR.execute(() -> mDeviceState.setDeferredGestureRegion(region));
+            MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(
+                    tis -> tis.mDeviceState.setDeferredGestureRegion(region)));
         }
 
         @BinderThread
@@ -309,75 +325,105 @@
         @BinderThread
         @Override
         public void enterStageSplitFromRunningApp(boolean leftOrTop) {
-            StatefulActivity activity =
-                    mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
-            if (activity != null) {
-                activity.enterStageSplitFromRunningApp(leftOrTop);
-            }
+            executeForTouchInteractionService(tis -> {
+                StatefulActivity activity =
+                        tis.mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
+                if (activity != null) {
+                    activity.enterStageSplitFromRunningApp(leftOrTop);
+                }
+            });
         }
 
         /**
          * Preloads the Overview activity.
-         *
+         * <p>
          * This method should only be used when the All Set page of the SUW is reached to safely
          * preload the Launcher for the SUW first reveal.
          */
         public void preloadOverviewForSUWAllSet() {
-            preloadOverview(false, true);
+            executeForTouchInteractionService(tis -> tis.preloadOverview(false, true));
         }
 
         @Override
         public void onRotationProposal(int rotation, boolean isValid) {
-            executeForTaskbarManager(() -> mTaskbarManager.onRotationProposal(rotation, isValid));
+            executeForTaskbarManager(taskbarManager ->
+                    taskbarManager.onRotationProposal(rotation, isValid));
         }
 
         @Override
         public void disable(int displayId, int state1, int state2, boolean animate) {
-            executeForTaskbarManager(() -> mTaskbarManager
-                    .disableNavBarElements(displayId, state1, state2, animate));
+            executeForTaskbarManager(taskbarManager ->
+                    taskbarManager.disableNavBarElements(displayId, state1, state2, animate));
         }
 
         @Override
         public void onSystemBarAttributesChanged(int displayId, int behavior) {
-            executeForTaskbarManager(() -> mTaskbarManager
-                    .onSystemBarAttributesChanged(displayId, behavior));
+            executeForTaskbarManager(taskbarManager ->
+                    taskbarManager.onSystemBarAttributesChanged(displayId, behavior));
         }
 
         @Override
         public void onNavButtonsDarkIntensityChanged(float darkIntensity) {
-            executeForTaskbarManager(() -> mTaskbarManager
-                    .onNavButtonsDarkIntensityChanged(darkIntensity));
+            executeForTaskbarManager(taskbarManager ->
+                    taskbarManager.onNavButtonsDarkIntensityChanged(darkIntensity));
         }
 
-        private void executeForTaskbarManager(final Runnable r) {
-            MAIN_EXECUTOR.execute(() -> {
-                if (mTaskbarManager == null) {
-                    return;
-                }
-                r.run();
-            });
+        private void executeForTouchInteractionService(
+                @NonNull Consumer<TouchInteractionService> tisConsumer) {
+            TouchInteractionService tis = mTis.get();
+            if (tis == null) return;
+            tisConsumer.accept(tis);
         }
 
+        private void executeForTaskbarManager(
+                @NonNull Consumer<TaskbarManager> taskbarManagerConsumer) {
+            MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
+                TaskbarManager taskbarManager = tis.mTaskbarManager;
+                if (taskbarManager == null) return;
+                taskbarManagerConsumer.accept(taskbarManager);
+            }));
+        }
+
+        /**
+         * Returns the {@link TaskbarManager}.
+         * <p>
+         * Returns {@code null} if TouchInteractionService is not connected
+         */
+        @Nullable
         public TaskbarManager getTaskbarManager() {
-            return mTaskbarManager;
+            TouchInteractionService tis = mTis.get();
+            if (tis == null) return null;
+            return tis.mTaskbarManager;
         }
 
+        /**
+         * Returns the {@link OverviewCommandHelper}.
+         * <p>
+         * Returns {@code null} if TouchInteractionService is not connected
+         */
+        @Nullable
         public OverviewCommandHelper getOverviewCommandHelper() {
-            return mOverviewCommandHelper;
+            TouchInteractionService tis = mTis.get();
+            if (tis == null) return null;
+            return tis.mOverviewCommandHelper;
         }
 
         /**
          * Sets a proxy to bypass swipe up behavior
          */
         public void setSwipeUpProxy(Function<GestureState, AnimatedFloat> proxy) {
-            mSwipeUpProxyProvider = proxy != null ? proxy : (i -> null);
+            TouchInteractionService tis = mTis.get();
+            if (tis == null) return;
+            tis.mSwipeUpProxyProvider = proxy != null ? proxy : (i -> null);
         }
 
         /**
          * Sets the task id where gestures should be blocked
          */
         public void setGestureBlockedTaskId(int taskId) {
-            mDeviceState.setGestureBlockingTaskId(taskId);
+            TouchInteractionService tis = mTis.get();
+            if (tis == null) return;
+            tis.mDeviceState.setGestureBlockingTaskId(taskId);
         }
 
         /** Sets a listener to be run on Overview Target updates. */
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
index 8274a51..1868463 100644
--- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -61,6 +61,7 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatedFloat;
 import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.taskbar.TaskbarManager;
 import com.android.launcher3.util.Executors;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.TouchInteractionService.TISBinder;
@@ -100,6 +101,7 @@
 
     private TISBindHelper mTISBindHelper;
     private TISBinder mBinder;
+    @Nullable private TaskbarManager mTaskbarManager = null;
 
     private final AnimatedFloat mSwipeProgress = new AnimatedFloat(this::onSwipeProgressUpdate);
     private BgDrawable mBackground;
@@ -262,19 +264,25 @@
         mAnimatedBackground.playAnimation();
     }
 
+    private void setSetupUIVisible(boolean visible) {
+        if (mBinder == null || mTaskbarManager == null) return;
+        mTaskbarManager.setSetupUIVisible(visible);
+    }
+
     @Override
     protected void onResume() {
         super.onResume();
         maybeResumeOrPauseBackgroundAnimation();
         if (mBinder != null) {
-            mBinder.getTaskbarManager().setSetupUIVisible(true);
+            setSetupUIVisible(true);
             mBinder.setSwipeUpProxy(this::createSwipeUpProxy);
         }
     }
 
     private void onTISConnected(TISBinder binder) {
         mBinder = binder;
-        mBinder.getTaskbarManager().setSetupUIVisible(isResumed());
+        mTaskbarManager = mBinder.getTaskbarManager();
+        setSetupUIVisible(isResumed());
         mBinder.setSwipeUpProxy(isResumed() ? this::createSwipeUpProxy : null);
         mBinder.setOverviewTargetChangeListener(mBinder::preloadOverviewForSUWAllSet);
         mBinder.preloadOverviewForSUWAllSet();
@@ -293,7 +301,7 @@
 
     private void clearBinderOverride() {
         if (mBinder != null) {
-            mBinder.getTaskbarManager().setSetupUIVisible(false);
+            setSetupUIVisible(false);
             mBinder.setSwipeUpProxy(null);
             mBinder.setOverviewTargetChangeListener(null);
         }
@@ -352,9 +360,8 @@
         mContentView.setAlpha(alpha);
         mContentView.setTranslationY((alpha - 1) * mSwipeUpShift);
 
-        if (mLauncherStartAnim == null) {
-            mLauncherStartAnim = mBinder.getTaskbarManager().createLauncherStartFromSuwAnim(
-                    MAX_SWIPE_DURATION);
+        if (mLauncherStartAnim == null && mTaskbarManager != null) {
+            mLauncherStartAnim = mTaskbarManager.createLauncherStartFromSuwAnim(MAX_SWIPE_DURATION);
         }
         if (mLauncherStartAnim != null) {
             mLauncherStartAnim.setPlayFraction(Utilities.mapBoundToRange(
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index fbb8109..6288937 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -566,9 +566,10 @@
      * Helps to construct and log statsd compatible impression events.
      */
     private static class StatsCompatImpressionLogger implements StatsImpressionLogger {
-        private final IntArray mResultTypeList = new IntArray();
-        private final IntArray mResultCountList = new IntArray();
+        private int[] mResultTypeList = new int[]{};
+        private int[] mResultCountList = new int[]{};
         private final List<Boolean> mAboveKeyboardList = new ArrayList<>();
+        private int[] mUidList = new int[]{};
         private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
         private State mLauncherState = State.UNKNOWN;
         private int mQueryLength = -1;
@@ -593,28 +594,32 @@
 
         @Override
         public StatsImpressionLogger withResultType(IntArray resultType) {
-            this.mResultTypeList.clear();
-            this.mResultTypeList.addAll(resultType);
+            mResultTypeList = resultType.toArray();
             return this;
         }
 
         @Override
         public StatsImpressionLogger withResultCount(IntArray resultCount) {
-            this.mResultCountList.clear();
-            this.mResultCountList.addAll(resultCount);
+            mResultCountList = resultCount.toArray();
             return this;
         }
 
         @Override
         public StatsImpressionLogger withAboveKeyboard(List<Boolean> aboveKeyboard) {
-            this.mAboveKeyboardList.clear();
+            mAboveKeyboardList.clear();
             this.mAboveKeyboardList.addAll(aboveKeyboard);
             return this;
         }
 
         @Override
+        public StatsImpressionLogger withUids(IntArray uid) {
+            mUidList = uid.toArray();
+            return this;
+        }
+
+        @Override
         public void log(EventEnum event) {
-            boolean [] mAboveKeyboard = new boolean[mAboveKeyboardList.size()];
+            boolean[] mAboveKeyboard = new boolean[mAboveKeyboardList.size()];
             for (int i = 0; i < mAboveKeyboardList.size(); i++) {
                 mAboveKeyboard[i] = mAboveKeyboardList.get(i);
             }
@@ -626,11 +631,12 @@
                 logStringBuilder.append(String.format("ImpressionEvent:%s ", name));
                 logStringBuilder.append(String.format("LauncherState = %s ", mLauncherState));
                 logStringBuilder.append(String.format("QueryLength = %s ", mQueryLength));
-                for (int i = 0; i < mResultTypeList.size(); i++) {
+                for (int i = 0; i < mResultTypeList.length; i++) {
                     logStringBuilder.append(String.format(
-                            "\n ResultType = %s with ResultCount = %s with is_above_keyboard = %s",
-                            mResultTypeList.get(i), mResultCountList.get(i),
-                            mAboveKeyboard[i]));
+                            "\n ResultType = %s with ResultCount = %s with is_above_keyboard = %s"
+                                    + " with uid = %s",
+                            mResultTypeList[i], mResultCountList[i],
+                            mAboveKeyboard[i], mUidList[i]));
                 }
                 Log.d(IMPRESSION_TAG, logStringBuilder.toString());
             }
@@ -643,11 +649,13 @@
                     mLauncherState.getLauncherState(), // state
                     mQueryLength, // query_length
                     //result type list
-                    mResultTypeList.toArray(),
+                    mResultTypeList,
                     // result count list
-                    mResultCountList.toArray(),
+                    mResultCountList,
                     // above keyboard list
-                    mAboveKeyboard
+                    mAboveKeyboard,
+                    // uid list
+                    mUidList
             );
         }
     }
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 7b90ecb..32eadce 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -312,6 +312,7 @@
     @Test
     @ScreenRecord // b/242163205
     @PlatinumTest(focusArea = "launcher")
+    @TaskbarModeSwitch(mode = PERSISTENT)
     public void testQuickSwitchToPreviousAppForTablet() throws Exception {
         assumeTrue(mLauncher.isTablet());
         startTestActivity(2);
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 2664988..93ea28e 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -100,7 +100,7 @@
     <string name="folder_name_format_exact" msgid="8626242716117004803">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> Elemente"</string>
     <string name="folder_name_format_overflow" msgid="4270108890534995199">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> oder mehr Elemente"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Hintergründe"</string>
-    <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hintergrund &amp; Stil"</string>
+    <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hintergrund und Stil"</string>
     <string name="edit_home_screen" msgid="8947858375782098427">"Startbildschirm bearbeiten"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"Einstellungen"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Von deinem Administrator deaktiviert"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 8416815..7478968 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -50,8 +50,7 @@
     <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personnels"</string>
     <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Professionnels"</string>
     <string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
-    <!-- no translation found for widget_category_note_taking (3469689394504266039) -->
-    <skip />
+    <string name="widget_category_note_taking" msgid="3469689394504266039">"Prise de note"</string>
     <string name="widget_education_header" msgid="4874760613775913787">"Renseignements utiles à portée de main"</string>
     <string name="widget_education_content" msgid="1731667670753497052">"Pour obtenir des informations sans ouvrir d\'applications, vous pouvez ajouter des widgets à votre écran d\'accueil"</string>
     <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Touchez pour modifier les paramètres du widget"</string>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 0b75c45..37a20bf 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -133,6 +133,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.StringRes;
+import androidx.annotation.UiThread;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.launcher3.DropTarget.DragObject;
@@ -205,6 +206,7 @@
 import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.PendingRequestArgs;
+import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.util.ScreenOnTracker;
@@ -246,6 +248,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
@@ -518,11 +521,12 @@
         // TODO: move the SearchConfig to SearchState when new LauncherState is created.
         mBaseSearchConfig = new BaseSearchConfig();
 
+        setupViews();
+
         mAppWidgetManager = new WidgetManagerHelper(this);
         mAppWidgetHolder = createAppWidgetHolder();
         mAppWidgetHolder.startListening();
 
-        setupViews();
         mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots);
 
         boolean internalStateHandled = ACTIVITY_TRACKER.handleCreate(this);
@@ -2970,8 +2974,12 @@
      */
     @Override
     @TargetApi(Build.VERSION_CODES.S)
-    public void bindAllApplications(AppInfo[] apps, int flags) {
-        mAppsView.getAppsStore().setApps(apps, flags);
+    @UiThread
+    public void bindAllApplications(AppInfo[] apps, int flags,
+            Map<PackageUserKey, Integer> packageUserKeytoUidMap) {
+        Preconditions.assertUIThread();
+        AllAppsStore appsStore = mAppsView.getAppsStore();
+        appsStore.setApps(apps, flags, packageUserKeytoUidMap);
         PopupContainerWithArrow.dismissInvalidPopup(this);
         if (Utilities.ATLEAST_S) {
             Trace.endAsyncSection(DISPLAY_ALL_APPS_TRACE_METHOD_NAME,
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 21dfbe1..d4140d8 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -444,6 +444,9 @@
             // Animate to A-Z with 0 time to reset the animation with proper state management.
             animateToSearchState(false, 0);
         }
+        if (isSearching()) {
+            mWorkManager.reset();
+        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index a977b3a..06af970 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK;
 import static com.android.launcher3.testing.shared.TestProtocol.WORK_TAB_MISSING;
 
+import android.os.UserHandle;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -35,7 +36,9 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
@@ -57,8 +60,8 @@
 
     private final List<OnUpdateListener> mUpdateListeners = new CopyOnWriteArrayList<>();
     private final ArrayList<ViewGroup> mIconContainers = new ArrayList<>();
+    private Map<PackageUserKey, Integer> mPackageUserKeytoUidMap = Collections.emptyMap();
     private int mModelFlags;
-
     private int mDeferUpdatesFlags = 0;
     private boolean mUpdatePending = false;
 
@@ -67,12 +70,21 @@
     }
 
     /**
-     * Sets the current set of apps.
+     * Sets the current set of apps and sets mapping for {@link PackageUserKey} to Uid for
+     * the current set of apps.
      */
-    public void setApps(AppInfo[] apps, int flags) {
+    public void setApps(AppInfo[] apps, int flags, Map<PackageUserKey, Integer> map) {
         mApps = apps;
         mModelFlags = flags;
         notifyUpdate();
+        mPackageUserKeytoUidMap = map;
+    }
+
+    /**
+     * Look up for Uid using package name and user handle for the current set of apps.
+     */
+    public int lookUpForUid(String packageName, UserHandle user) {
+        return mPackageUserKeytoUidMap.getOrDefault(new PackageUserKey(packageName, user), -1);
     }
 
     /**
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 663fdb9..8c2fb19 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -166,7 +166,7 @@
         return super.onApplyWindowInsets(insets);
     }
 
-    private void updateTranslationY() {
+    void updateTranslationY() {
         setTranslationY(-mImeInsets.bottom);
     }
 
@@ -180,6 +180,10 @@
         rect.set(insets.left, insets.top, insets.right, insets.bottom);
     }
 
+    public Rect getImeInsets() {
+        return mImeInsets;
+    }
+
     @Override
     public void onTranslationStart() {
         setFlag(FLAG_TRANSLATION_ONGOING);
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
index 30af502..44c233f 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -136,6 +136,11 @@
     public void reset() {
         boolean isEnabled = !mAllApps.getAppsStore().hasModelFlag(FLAG_QUIET_MODE_ENABLED);
         updateCurrentState(isEnabled ? STATE_ENABLED : STATE_DISABLED);
+        if (mWorkModeSwitch != null) {
+            // reset the position of the button and clear IME insets.
+            mWorkModeSwitch.getImeInsets().setEmpty();
+            mWorkModeSwitch.updateTranslationY();
+        }
     }
 
     private void updateCurrentState(@WorkProfileState int currentState) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 621c2ab..f88ff86 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -302,7 +302,7 @@
             "Enable widget transition animation when resizing the widgets");
 
     public static final BooleanFlag PREEMPTIVE_UNFOLD_ANIMATION_START = getDebugFlag(270397209,
-            "PREEMPTIVE_UNFOLD_ANIMATION_START", ENABLED,
+            "PREEMPTIVE_UNFOLD_ANIMATION_START", DISABLED,
             "Enables starting the unfold animation preemptively when unfolding, without"
                     + "waiting for SystemUI and then merging the SystemUI progress whenever we "
                     + "start receiving the events");
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index 2ce6c78..dd82ecf 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -273,6 +273,8 @@
         // {@link #onAnimationEnd} before B reads new UI state from {@link #onAnimationStart}.
         a.addListener(new AnimatorListenerAdapter() {
             private CellLayout mCellLayout;
+
+            private boolean mFolderClipChildren;
             private boolean mFolderClipToPadding;
             private boolean mContentClipChildren;
             private boolean mContentClipToPadding;
@@ -283,12 +285,14 @@
             public void onAnimationStart(Animator animator) {
                 super.onAnimationStart(animator);
                 mCellLayout = mContent.getCurrentCellLayout();
+                mFolderClipChildren = mFolder.getClipChildren();
                 mFolderClipToPadding = mFolder.getClipToPadding();
                 mContentClipChildren = mContent.getClipChildren();
                 mContentClipToPadding = mContent.getClipToPadding();
                 mCellLayoutClipChildren = mCellLayout.getClipChildren();
                 mCellLayoutClipPadding = mCellLayout.getClipToPadding();
 
+                mFolder.setClipChildren(false);
                 mFolder.setClipToPadding(false);
                 mContent.setClipChildren(false);
                 mContent.setClipToPadding(false);
@@ -309,6 +313,7 @@
                 mFolder.mFooter.setTranslationX(0f);
                 mFolder.mFolderName.setAlpha(1f);
 
+                mFolder.setClipChildren(mFolderClipChildren);
                 mFolder.setClipToPadding(mFolderClipToPadding);
                 mContent.setClipChildren(mContentClipChildren);
                 mContent.setClipToPadding(mContentClipToPadding);
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 1e3b003..2f7f51e 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -100,6 +100,7 @@
     private final UserCache mUserManager;
     private final InstantAppResolver mInstantAppResolver;
     private final IconProvider mIconProvider;
+    private final HandlerRunnable mCancelledRunnable;
 
     private final SparseArray<BitmapInfo> mWidgetCategoryBitmapInfos;
 
@@ -117,6 +118,10 @@
         mInstantAppResolver = InstantAppResolver.newInstance(mContext);
         mIconProvider = iconProvider;
         mWidgetCategoryBitmapInfos = new SparseArray<>();
+
+        mCancelledRunnable = new HandlerRunnable(
+                mWorkerHandler, () -> null, MAIN_EXECUTOR, c -> { });
+        mCancelledRunnable.cancel();
     }
 
     @Override
@@ -172,23 +177,30 @@
     public HandlerRunnable updateIconInBackground(final ItemInfoUpdateReceiver caller,
             final ItemInfoWithIcon info) {
         Preconditions.assertUIThread();
+        Supplier<ItemInfoWithIcon> task;
+        if (info instanceof AppInfo || info instanceof WorkspaceItemInfo) {
+            task = () -> {
+                getTitleAndIcon(info, false);
+                return info;
+            };
+        } else if (info instanceof PackageItemInfo pii) {
+            task = () -> {
+                getTitleAndIconForApp(pii, false);
+                return pii;
+            };
+        } else {
+            Log.i(TAG, "Icon update not supported for "
+                    + info == null ? "null" : info.getClass().getName());
+            return mCancelledRunnable;
+        }
+
         if (mPendingIconRequestCount <= 0) {
             MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
         }
         mPendingIconRequestCount++;
 
         HandlerRunnable<ItemInfoWithIcon> request = new HandlerRunnable<>(mWorkerHandler,
-                () -> {
-                    if (info instanceof AppInfo || info instanceof WorkspaceItemInfo) {
-                        getTitleAndIcon(info, false);
-                    } else if (info instanceof PackageItemInfo) {
-                        getTitleAndIconForApp((PackageItemInfo) info, false);
-                    }
-                    return info;
-                },
-                MAIN_EXECUTOR,
-                caller::reapplyItemInfo,
-                this::onIconRequestEnd);
+                task, MAIN_EXECUTOR, caller::reapplyItemInfo, this::onIconRequestEnd);
         Utilities.postAsyncCallback(mWorkerHandler, request);
         return request;
     }
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 15f3538..66ed779 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -642,6 +642,9 @@
 
         @UiEvent(doc = "User has swiped upwards from the gesture handle to show transient taskbar.")
         LAUNCHER_TRANSIENT_TASKBAR_SHOW(1331),
+
+        @UiEvent(doc = "App launched through pending intent")
+        LAUNCHER_APP_LAUNCH_PENDING_INTENT(1394),
         ;
 
         // ADD MORE
@@ -976,6 +979,14 @@
         }
 
         /**
+         * Sets list of uid for each of {@link com.android.app.search.ResultType} that indicates
+         * package name for the impression event.
+         */
+        default StatsImpressionLogger withUids(IntArray uid) {
+            return this;
+        }
+
+        /**
          * Builds the final message and logs it as {@link EventEnum}.
          */
         default void log(EventEnum event) {
diff --git a/src/com/android/launcher3/model/BaseLauncherBinder.java b/src/com/android/launcher3/model/BaseLauncherBinder.java
index 85def73..dcd61a8 100644
--- a/src/com/android/launcher3/model/BaseLauncherBinder.java
+++ b/src/com/android/launcher3/model/BaseLauncherBinder.java
@@ -23,6 +23,8 @@
 import android.os.Process;
 import android.util.Log;
 
+import androidx.annotation.WorkerThread;
+
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel.CallbackTask;
@@ -39,15 +41,20 @@
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.util.LooperIdleLock;
+import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.RunnableList;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
 
 /**
  * Binds the results of {@link com.android.launcher3.model.LoaderTask} to the Callbacks objects.
@@ -143,11 +150,18 @@
     /**
      * Binds the all apps results from LoaderTask to the callbacks UX.
      */
+    @WorkerThread
     public void bindAllApps() {
+        Preconditions.assertWorkerThread();
         // shallow copy
         AppInfo[] apps = mBgAllAppsList.copyData();
         int flags = mBgAllAppsList.getFlags();
-        executeCallbacksTask(c -> c.bindAllApplications(apps, flags), mUiExecutor);
+        Map<PackageUserKey, Integer> packageUserKeytoUidMap = Arrays.stream(apps).collect(
+                Collectors.toMap(
+                        appInfo -> new PackageUserKey(appInfo.componentName.getPackageName(),
+                                appInfo.user), appInfo -> appInfo.uid, (a, b) -> a));
+        executeCallbacksTask(c -> c.bindAllApplications(apps, flags, packageUserKeytoUidMap),
+                mUiExecutor);
     }
 
     /**
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index 44d32d9..1ba015a 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -22,6 +22,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel;
@@ -35,11 +36,15 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.Executor;
 import java.util.function.Predicate;
@@ -153,7 +158,9 @@
         scheduleCallbackTask(c -> c.bindWorkspaceComponentsRemoved(matcher));
     }
 
+    @WorkerThread
     public void bindApplicationsIfNeeded() {
+        Preconditions.assertWorkerThread();
         boolean changeFlag = mAllAppsList.getAndResetChangeFlag();
         if (TestProtocol.sDebugTracing) {
             Log.d(WORK_TAB_MISSING, "bindApplicationsIfNeeded changeFlag? " +
@@ -162,7 +169,11 @@
         if (changeFlag) {
             AppInfo[] apps = mAllAppsList.copyData();
             int flags = mAllAppsList.getFlags();
-            scheduleCallbackTask(c -> c.bindAllApplications(apps, flags));
+            Map<PackageUserKey, Integer> packageUserKeytoUidMap = Arrays.stream(apps).collect(
+                    Collectors.toMap(
+                            appInfo -> new PackageUserKey(appInfo.componentName.getPackageName(),
+                                    appInfo.user), appInfo -> appInfo.uid, (a, b) -> a));
+            scheduleCallbackTask(c -> c.bindAllApplications(apps, flags, packageUserKeytoUidMap));
         }
     }
 }
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 0861e9d..d94df51 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -51,6 +51,7 @@
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.IntSparseArrayMap;
+import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 
@@ -497,7 +498,9 @@
          */
         default void bindExtraContainerItems(FixedContainerItems item) { }
 
-        default void bindAllApplications(AppInfo[] apps, int flags) { }
+        default void bindAllApplications(AppInfo[] apps, int flags,
+                Map<PackageUserKey, Integer> packageUserKeytoUidMap) {
+        }
 
         /**
          * Binds the cache of string resources
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index 34972e7..7e6cbef 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -61,6 +61,13 @@
     // Section name used for indexing.
     public String sectionName = "";
 
+    /**
+     * The uid of the application.
+     * The kernel user-ID that has been assigned to this application. Currently this is not a unique
+     * ID (multiple applications can have the same uid).
+     */
+    public int uid = -1;
+
     public AppInfo() {
         itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
     }
@@ -87,6 +94,7 @@
         if (quietModeEnabled) {
             runtimeStatusFlags |= FLAG_DISABLED_QUIET_USER;
         }
+        uid = info.getApplicationInfo().uid;
         updateRuntimeFlagsForActivityTarget(this, info);
     }
 
@@ -95,6 +103,7 @@
         componentName = info.componentName;
         title = Utilities.trim(info.title);
         intent = new Intent(info.intent);
+        uid = info.uid;
     }
 
     @VisibleForTesting
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index fcc62a7..458f137 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -26,6 +26,8 @@
 import android.view.ViewAnimationUtils;
 import android.view.inputmethod.InputMethodManager;
 
+import androidx.annotation.UiThread;
+
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.BubbleTextView;
@@ -38,6 +40,7 @@
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.ActivityAllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsStore;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.dragndrop.DraggableView;
@@ -54,10 +57,13 @@
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.OnboardingPrefs;
+import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.BaseDragLayer;
 
 import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Launcher activity for secondary displays
@@ -291,9 +297,13 @@
         mPopupDataProvider.setDeepShortcutMap(deepShortcutMap);
     }
 
+    @UiThread
     @Override
-    public void bindAllApplications(AppInfo[] apps, int flags) {
-        mAppsView.getAppsStore().setApps(apps, flags);
+    public void bindAllApplications(AppInfo[] apps, int flags,
+            Map<PackageUserKey, Integer> packageUserKeytoUidMap) {
+        Preconditions.assertUIThread();
+        AllAppsStore appsStore = mAppsView.getAppsStore();
+        appsStore.setApps(apps, flags, packageUserKeytoUidMap);
         PopupContainerWithArrow.dismissInvalidPopup(this);
     }
 
diff --git a/src/com/android/launcher3/util/ContentWriter.java b/src/com/android/launcher3/util/ContentWriter.java
index 7c5ef4d..9910dc2 100644
--- a/src/com/android/launcher3/util/ContentWriter.java
+++ b/src/com/android/launcher3/util/ContentWriter.java
@@ -106,7 +106,7 @@
 
     public int commit() {
         if (mCommitParams != null) {
-            mCommitParams.mDbController.update(
+            return mCommitParams.mDbController.update(
                     Favorites.TABLE_NAME, getValues(mContext),
                     mCommitParams.mWhere, mCommitParams.mSelectionArgs);
         }
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index c2767be..fada4a3 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -59,6 +59,7 @@
     private void attachObserver() {
         if (!mCompleted) {
             mAttachedView.getViewTreeObserver().addOnDrawListener(this);
+            mAttachedView.getRootView().invalidate();
         }
     }
 
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 515a2d8..4b319e5 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.LauncherSettings.Animation.DEFAULT_NO_ICON;
 import static com.android.launcher3.logging.KeyboardStateManager.KeyboardState.HIDE;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_KEYBOARD_CLOSED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_PENDING_INTENT;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
 import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -305,6 +306,11 @@
         ActivityOptionsWrapper options = getActivityLaunchOptions(v, item);
         try {
             intent.send(null, 0, null, null, null, null, options.toBundle());
+            if (item != null) {
+                InstanceId instanceId = new InstanceIdSequence().newInstanceId();
+                getStatsLogManager().logger().withItemInfo(item).withInstanceId(instanceId)
+                        .log(LAUNCHER_APP_LAUNCH_PENDING_INTENT);
+            }
             return options.onEndCallback;
         } catch (PendingIntent.CanceledException e) {
             Toast.makeText(v.getContext(),
diff --git a/src/com/android/launcher3/views/Snackbar.java b/src/com/android/launcher3/views/Snackbar.java
index 8d5838e..2460be1 100644
--- a/src/com/android/launcher3/views/Snackbar.java
+++ b/src/com/android/launcher3/views/Snackbar.java
@@ -65,9 +65,26 @@
         show(activity, labelStringRedId, NO_ID, onDismissed, null);
     }
 
+    /** Show a snackbar with just a label. */
+    public static <T extends Context & ActivityContext> void show(T activity, String labelString,
+            Runnable onDismissed) {
+        show(activity, labelString, NO_ID, onDismissed, null);
+    }
+
     /** Show a snackbar with a label and action. */
     public static <T extends Context & ActivityContext> void show(T activity, int labelStringResId,
             int actionStringResId, Runnable onDismissed, @Nullable Runnable onActionClicked) {
+        show(
+                activity,
+                activity.getResources().getString(labelStringResId),
+                actionStringResId,
+                onDismissed,
+                onActionClicked);
+    }
+
+    /** Show a snackbar with a label and action. */
+    public static <T extends Context & ActivityContext> void show(T activity, String labelString,
+            int actionStringResId, Runnable onDismissed, @Nullable Runnable onActionClicked) {
         closeOpenViews(activity, true, TYPE_SNACKBAR);
         Snackbar snackbar = new Snackbar(activity, null);
         // Set some properties here since inflated xml only contains the children.
@@ -105,8 +122,7 @@
                 : insets.bottom));
 
         TextView labelView = snackbar.findViewById(R.id.label);
-        String labelText = res.getString(labelStringResId);
-        labelView.setText(labelText);
+        labelView.setText(labelString);
 
         TextView actionView = snackbar.findViewById(R.id.action);
         float actionWidth;
@@ -127,7 +143,7 @@
             actionView.setVisibility(GONE);
         }
 
-        int totalContentWidth = (int) (labelView.getPaint().measureText(labelText) + actionWidth)
+        int totalContentWidth = (int) (labelView.getPaint().measureText(labelString) + actionWidth)
                 + labelView.getPaddingRight() + labelView.getPaddingLeft()
                 + padding * 2;
         if (totalContentWidth > params.width) {
diff --git a/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java
index 2742882..580b4f1 100644
--- a/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java
@@ -105,6 +105,7 @@
                 mEnforcedRectangle);
         setOutlineProvider(mCornerRadiusEnforcementOutline);
         setClipToOutline(true);
+        invalidateOutline();
     }
 
     /** Returns the corner radius currently enforced, in pixels. */
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index 723ea17..8dd1de4 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -42,7 +42,6 @@
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
 import com.android.launcher3.R;
-import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.recyclerview.ViewHolderBinder;
 import com.android.launcher3.util.LabelComparator;
 import com.android.launcher3.util.PackageUserKey;
@@ -58,7 +57,6 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-import java.util.Map;
 import java.util.OptionalInt;
 import java.util.function.IntSupplier;
 import java.util.function.Predicate;
@@ -174,9 +172,6 @@
         mAllEntries.clear();
         mAllEntries.add(new WidgetListSpaceEntry());
         tempEntries.stream().sorted(mRowComparator).forEach(mAllEntries::add);
-        if (shouldClearVisibleEntries()) {
-            mVisibleEntries.clear();
-        }
         updateVisibleEntries();
     }
 
@@ -426,29 +421,6 @@
         updateVisibleEntries();
     }
 
-    /**
-     * Returns {@code true} if there is a change in {@link #mAllEntries} that results in an
-     * invalidation of {@link #mVisibleEntries}. e.g. there is change in the device language.
-     */
-    private boolean shouldClearVisibleEntries() {
-        Map<PackageUserKey, PackageItemInfo> packagesInfo =
-                mAllEntries.stream()
-                        .filter(entry -> entry instanceof WidgetsListHeaderEntry)
-                        .map(entry -> entry.mPkgItem)
-                        .collect(Collectors.toMap(
-                                entry -> PackageUserKey.fromPackageItemInfo(entry),
-                                entry -> entry));
-        for (WidgetsListBaseEntry visibleEntry: mVisibleEntries) {
-            PackageUserKey key = PackageUserKey.fromPackageItemInfo(visibleEntry.mPkgItem);
-            PackageItemInfo packageItemInfo = packagesInfo.get(key);
-            if (packageItemInfo != null
-                    && !visibleEntry.mPkgItem.title.equals(packageItemInfo.title)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     /** Comparator for sorting WidgetListRowEntry based on package title. */
     public static class WidgetListBaseRowEntryComparator implements
             Comparator<WidgetsListBaseEntry> {
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index b7c3aca..cbc537c 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -105,8 +105,6 @@
     public static final String REQUEST_WINDOW_INSETS = "window-insets";
     public static final String REQUEST_PID = "pid";
     public static final String REQUEST_FORCE_GC = "gc";
-    public static final String REQUEST_VIEW_LEAK = "view-leak";
-    public static final String PRINT_VIEW_LEAK = "print-leak";
     public static final String REQUEST_RECENT_TASKS_LIST = "recent-tasks-list";
     public static final String REQUEST_START_EVENT_LOGGING = "start-event-logging";
     public static final String REQUEST_GET_TEST_EVENTS = "get-test-events";
@@ -154,7 +152,6 @@
     public static final String REQUEST_MOCK_SENSOR_ROTATION = "mock-sensor-rotation";
 
     public static final String PERMANENT_DIAG_TAG = "TaplTarget";
-    public static final String VIEW_AND_ACTIVITY_LEAKS = "b/260260325";
     public static final String WORK_TAB_MISSING = "b/243688989";
     public static final String TWO_TASKBAR_LONG_CLICKS = "b/262282528";
     public static final String WORKSPACE_LOADS_FOREVER = "b/267200150";
diff --git a/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java b/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
index b9da16a..3dfd6b4 100644
--- a/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
+++ b/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
@@ -37,6 +37,7 @@
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.LauncherLayoutBuilder;
 import com.android.launcher3.util.LauncherModelHelper;
+import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.TestUtil;
 
@@ -48,6 +49,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -192,7 +194,8 @@
         }
 
         @Override
-        public void bindAllApplications(AppInfo[] apps, int flags) {
+        public void bindAllApplications(AppInfo[] apps, int flags,
+                Map<PackageUserKey, Integer> packageUserKeytoUidMap) {
             mAppInfos = apps;
         }
 
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index d7c4ae3..604fe42 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -242,17 +242,7 @@
     public void setUp() throws Exception {
         mLauncher.onTestStart();
 
-        final boolean keyguardAlreadyVisible = sSeenKeygard;
-
-        sSeenKeygard = sSeenKeygard
-                || !TestHelpers.wait(
-                Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000);
-
-        Assert.assertFalse(
-                "Keyguard is visible, which is likely caused by a crash in SysUI, seeing keyguard"
-                        + " for the first time = "
-                        + !keyguardAlreadyVisible,
-                sSeenKeygard);
+        verifyKeyguardInvisible();
 
         final String launcherPackageName = mDevice.getLauncherPackageName();
         try {
@@ -285,6 +275,20 @@
         }
     }
 
+    private static void verifyKeyguardInvisible() {
+        final boolean keyguardAlreadyVisible = sSeenKeygard;
+
+        sSeenKeygard = sSeenKeygard
+                || !TestHelpers.wait(
+                Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000);
+
+        Assert.assertFalse(
+                "Keyguard is visible, which is likely caused by a crash in SysUI, seeing keyguard"
+                        + " for the first time = "
+                        + !keyguardAlreadyVisible,
+                sSeenKeygard);
+    }
+
     @After
     public void verifyLauncherState() {
         try {
@@ -402,6 +406,7 @@
     // flakiness.
     protected void waitForLauncherCondition(
             String message, Function<Launcher, Boolean> condition, long timeout) {
+        verifyKeyguardInvisible();
         if (!TestHelpers.isInLauncherProcess()) return;
         Wait.atMost(message, () -> getFromLauncher(condition), timeout, mLauncher);
     }
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 2adfc98..c4f5da5 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1841,14 +1841,6 @@
         return testInfo != null ? testInfo.getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD) : null;
     }
 
-    public void produceViewLeak() {
-        getTestInfo(TestProtocol.REQUEST_VIEW_LEAK);
-    }
-
-    public void printViewLeak() {
-        getTestInfo(TestProtocol.PRINT_VIEW_LEAK);
-    }
-
     public ArrayList<ComponentName> getRecentTasks() {
         ArrayList<ComponentName> tasks = new ArrayList<>();
         ArrayList<String> components = getTestInfo(TestProtocol.REQUEST_RECENT_TASKS_LIST)