Merge "Multi-line titles supporting RTL" into udc-dev
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/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/src/com/android/quickstep/util/SplitSelectDataHolder.kt b/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
index 8e6415b..0631537 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
@@ -62,7 +62,8 @@
     companion object {
         @IntDef(SPLIT_TASK_TASK, SPLIT_TASK_PENDINGINTENT, SPLIT_TASK_SHORTCUT,
                 SPLIT_PENDINGINTENT_TASK, SPLIT_PENDINGINTENT_PENDINGINTENT, SPLIT_SHORTCUT_TASK,
-                SPLIT_SINGLE_TASK_FULLSCREEN, SPLIT_SINGLE_INTENT_FULLSCREEN)
+                SPLIT_SINGLE_TASK_FULLSCREEN, SPLIT_SINGLE_INTENT_FULLSCREEN,
+                SPLIT_SINGLE_SHORTCUT_FULLSCREEN)
         @Retention(AnnotationRetention.SOURCE)
         annotation class SplitLaunchType
 
@@ -76,6 +77,7 @@
         // Non-split edge case of launching the initial selected task as a fullscreen task
         const val SPLIT_SINGLE_TASK_FULLSCREEN = 6
         const val SPLIT_SINGLE_INTENT_FULLSCREEN = 7
+        const val SPLIT_SINGLE_SHORTCUT_FULLSCREEN = 8
     }
 
 
@@ -217,8 +219,7 @@
     fun getFullscreenLaunchData() : SplitLaunchData {
         // Convert all intents to shortcut infos to see if determine if we launch shortcut or intent
         convertIntentsToFinalTypes()
-        val splitLaunchType = if (initialTaskId != INVALID_TASK_ID) SPLIT_SINGLE_TASK_FULLSCREEN
-        else SPLIT_SINGLE_INTENT_FULLSCREEN
+        val splitLaunchType = getFullscreenLaunchType()
 
         return generateSplitLaunchData(splitLaunchType)
     }
@@ -309,6 +310,22 @@
         throw IllegalStateException("Unidentified split launch type")
     }
 
+    @SplitLaunchType
+    private fun getFullscreenLaunchType(): Int {
+        if (initialTaskId != INVALID_TASK_ID) {
+            return SPLIT_SINGLE_TASK_FULLSCREEN
+        }
+
+        if (initialShortcut != null) {
+            return SPLIT_SINGLE_SHORTCUT_FULLSCREEN
+        }
+
+        if (initialIntent != null) {
+            return SPLIT_SINGLE_INTENT_FULLSCREEN
+        }
+        throw IllegalStateException("Unidentified fullscreen launch type")
+    }
+
     data class SplitLaunchData(
             @SplitLaunchType
             val splitLaunchType: Int,
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index ec8be89..45df831 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -28,6 +28,7 @@
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_PENDINGINTENT_TASK;
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_SHORTCUT_TASK;
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_SINGLE_INTENT_FULLSCREEN;
+import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_SINGLE_SHORTCUT_FULLSCREEN;
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_SINGLE_TASK_FULLSCREEN;
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_PENDINGINTENT;
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_SHORTCUT;
@@ -524,6 +525,7 @@
         PendingIntent firstPI = launchData.getInitialPendingIntent();
         int firstUserId = launchData.getInitialUserId();
         int initialStagePosition = launchData.getInitialStagePosition();
+        ShortcutInfo initialShortcut = launchData.getInitialShortcut();
         Bundle optionsBundle = options1.toBundle();
 
         final RemoteSplitLaunchTransitionRunner animationRunner =
@@ -531,17 +533,19 @@
         final RemoteTransition remoteTransition = new RemoteTransition(animationRunner,
                 ActivityThread.currentActivityThread().getApplicationThread(),
                 "LaunchSplitPair");
-        Pair<InstanceId, com.android.launcher3.logging.InstanceId> instanceIds =
-                LogUtils.getShellShareableInstanceId();
+        InstanceId instanceId = LogUtils.getShellShareableInstanceId().first;
         if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
             switch (launchData.getSplitLaunchType()) {
                 case SPLIT_SINGLE_TASK_FULLSCREEN -> mSystemUiProxy.startTasks(firstTaskId,
                         optionsBundle, secondTaskId, null /* options2 */, initialStagePosition,
-                        DEFAULT_SPLIT_RATIO, remoteTransition, instanceIds.first);
+                        DEFAULT_SPLIT_RATIO, remoteTransition, instanceId);
                 case SPLIT_SINGLE_INTENT_FULLSCREEN -> mSystemUiProxy.startIntentAndTask(firstPI,
                         firstUserId, optionsBundle, secondTaskId, null /*options2*/,
                         initialStagePosition, DEFAULT_SPLIT_RATIO, remoteTransition,
-                        instanceIds.first);
+                        instanceId);
+                case SPLIT_SINGLE_SHORTCUT_FULLSCREEN -> mSystemUiProxy.startShortcutAndTask(
+                        initialShortcut, optionsBundle, firstTaskId, null /* options2 */,
+                        initialStagePosition, DEFAULT_SPLIT_RATIO, remoteTransition, instanceId);
             }
         } else {
             final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(firstTaskId,
@@ -549,12 +553,16 @@
             switch (launchData.getSplitLaunchType()) {
                 case SPLIT_SINGLE_TASK_FULLSCREEN -> mSystemUiProxy.startTasksWithLegacyTransition(
                         firstTaskId, optionsBundle, secondTaskId, null /* options2 */,
-                        initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, instanceIds.first);
+                        initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, instanceId);
                 case SPLIT_SINGLE_INTENT_FULLSCREEN ->
                         mSystemUiProxy.startIntentAndTaskWithLegacyTransition(firstPI, firstUserId,
                                 optionsBundle, secondTaskId, null /*options2*/,
                                 initialStagePosition, DEFAULT_SPLIT_RATIO, adapter,
-                                instanceIds.first);
+                                instanceId);
+                case SPLIT_SINGLE_SHORTCUT_FULLSCREEN ->
+                        mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(
+                                initialShortcut, optionsBundle, firstTaskId, null /* options2 */,
+                                initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, instanceId);
             }
         }
     }
diff --git a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
index a34888f..9808b28 100644
--- a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
+++ b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
@@ -24,6 +24,7 @@
 import android.view.WindowMetrics;
 
 import com.android.internal.policy.SystemBarUtils;
+import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.util.WindowBounds;
 import com.android.launcher3.util.window.CachedDisplayInfo;
 import com.android.launcher3.util.window.WindowManagerProxy;
@@ -59,6 +60,7 @@
         WindowManager windowManager = displayInfoContext.getSystemService(WindowManager.class);
         Set<WindowMetrics> possibleMaximumWindowMetrics =
                 windowManager.getPossibleMaximumWindowMetrics(DEFAULT_DISPLAY);
+        FileLog.d("b/283944974", "possibleMaximumWindowMetrics: " + possibleMaximumWindowMetrics);
         for (WindowMetrics windowMetrics : possibleMaximumWindowMetrics) {
             CachedDisplayInfo info = getDisplayInfo(windowMetrics, Surface.ROTATION_0);
             WindowBounds[] bounds = estimateWindowBounds(displayInfoContext, info);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 28f378d..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;
@@ -2971,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/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index c20494d..4e066b0 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -21,6 +21,7 @@
 import static com.android.launcher3.LauncherAppState.ACTION_FORCE_ROLOAD;
 import static com.android.launcher3.config.FeatureFlags.IS_STUDIO_BUILD;
 import static com.android.launcher3.testing.shared.TestProtocol.WORK_TAB_MISSING;
+import static com.android.launcher3.testing.shared.TestProtocol.sDebugTracing;
 import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -295,7 +296,7 @@
     }
 
     public void onBroadcastIntent(@NonNull final Intent intent) {
-        if (DEBUG_RECEIVER) Log.d(TAG, "onReceive intent=" + intent);
+        if (DEBUG_RECEIVER || sDebugTracing) Log.d(TAG, "onReceive intent=" + intent);
         final String action = intent.getAction();
         if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
             // If we have changed locale we need to clear out the labels in all apps/workspace.
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/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 17d3302..66ed779 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -979,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..6935353 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;
@@ -34,20 +36,24 @@
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.IntArray;
 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 +149,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);
     }
 
     /**
@@ -268,33 +281,18 @@
             sortWorkspaceItemsSpatially(idp, currentWorkspaceItems);
             sortWorkspaceItemsSpatially(idp, otherWorkspaceItems);
 
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "Before posting startBinding");
-            }
             // Tell the workspace that we're about to start binding items
             executeCallbacksTask(c -> {
                 c.clearPendingBinds();
                 c.startBinding();
             }, mUiExecutor);
 
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "1");
-            }
             // Bind workspace screens
             executeCallbacksTask(c -> c.bindScreens(mOrderedScreenIds), mUiExecutor);
 
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "2");
-            }
             // Load items on the current page.
             bindWorkspaceItems(currentWorkspaceItems, mUiExecutor);
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "3");
-            }
             bindAppWidgets(currentAppWidgets, mUiExecutor);
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "4");
-            }
             if (!FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
                 mExtraItems.forEach(item ->
                         executeCallbacksTask(c -> c.bindExtraContainerItems(item), mUiExecutor));
@@ -303,18 +301,8 @@
             RunnableList pendingTasks = new RunnableList();
             Executor pendingExecutor = pendingTasks::add;
             bindWorkspaceItems(otherWorkspaceItems, pendingExecutor);
-
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "5");
-            }
             bindAppWidgets(otherAppWidgets, pendingExecutor);
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "6");
-            }
             executeCallbacksTask(c -> c.finishBindingItems(currentScreenIds), pendingExecutor);
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "After posting finishBindingItems");
-            }
             pendingExecutor.execute(
                     () -> {
                         MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
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/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 1a8cf24..ca356b0 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -24,6 +24,8 @@
 import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
 import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
 import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
+import static com.android.launcher3.testing.shared.TestProtocol.WORK_TAB_MISSING;
+import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
 import static com.android.launcher3.util.PackageManagerHelper.isSystemApp;
@@ -949,6 +951,7 @@
     }
 
     private List<LauncherActivityInfo> loadAllApps() {
+        testLogD(WORK_TAB_MISSING, "loadingAllApps");
         final List<UserHandle> profiles = mUserCache.getUserProfiles();
         List<LauncherActivityInfo> allActivityList = new ArrayList<>();
         // Clear the list of apps
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/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index 5aab41a..5ebcf42 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -16,6 +16,9 @@
 
 package com.android.launcher3.pm;
 
+import static com.android.launcher3.testing.shared.TestProtocol.WORK_TAB_MISSING;
+import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
+
 import android.content.Context;
 import android.content.Intent;
 import android.os.UserHandle;
@@ -56,6 +59,7 @@
     }
 
     private void onUsersChanged(Intent intent) {
+        testLogD(WORK_TAB_MISSING, "onUsersChanged intent: " + intent);
         enableAndResetCache();
         mUserChangeListeners.forEach(Runnable::run);
     }
@@ -84,6 +88,7 @@
             List<UserHandle> users = mUserManager.getUserProfiles();
             if (users != null) {
                 for (UserHandle user : users) {
+                    testLogD(WORK_TAB_MISSING, "caching user: " + user);
                     long serial = mUserManager.getSerialNumberForUser(user);
                     mUsers.put(serial, user);
                     mUserToSerialMap.put(user, serial);
@@ -134,13 +139,24 @@
      * @see UserManager#getUserProfiles()
      */
     public List<UserHandle> getUserProfiles() {
+        StringBuilder usersToReturn = new StringBuilder();
         synchronized (this) {
             if (mUsers != null) {
+                for (UserHandle u : mUserToSerialMap.keySet()) {
+                    usersToReturn.append(u).append(" && ");
+                }
+                testLogD(WORK_TAB_MISSING, "users from cache: " + usersToReturn);
                 return new ArrayList<>(mUserToSerialMap.keySet());
+            } else {
+                testLogD(WORK_TAB_MISSING, "users from cache null");
             }
         }
 
         List<UserHandle> users = mUserManager.getUserProfiles();
+        for (UserHandle u : users) {
+            usersToReturn.append(u).append(" && ");
+        }
+        testLogD(WORK_TAB_MISSING, "users from userManager: " + usersToReturn);
         return users == null ? Collections.emptyList() : users;
     }
 }
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/ItemInfoMatcher.java b/src/com/android/launcher3/util/ItemInfoMatcher.java
index 8a27381..b6af314 100644
--- a/src/com/android/launcher3/util/ItemInfoMatcher.java
+++ b/src/com/android/launcher3/util/ItemInfoMatcher.java
@@ -18,7 +18,6 @@
 
 import android.content.ComponentName;
 import android.os.UserHandle;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 
@@ -26,7 +25,6 @@
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.testing.shared.TestProtocol;
 
 import java.util.Collection;
 import java.util.HashSet;
@@ -44,14 +42,7 @@
     private static final ComponentName EMPTY_COMPONENT = new ComponentName("", "");
 
     public static Predicate<ItemInfo> ofUser(UserHandle user) {
-        return info -> {
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.WORK_TAB_MISSING, "userHandle: " + user
-                        + ", itemUserHandle: " + info.user
-                        + " package: " + info.getTargetPackage());
-            }
-            return info != null && info.user.equals(user);
-        };
+        return info -> info != null && info.user.equals(user);
     }
 
     public static Predicate<ItemInfo> ofComponents(
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index cbc537c..8a25812 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -154,7 +154,6 @@
     public static final String PERMANENT_DIAG_TAG = "TaplTarget";
     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";
 
     public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
     public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index c4aa42b..243edc3 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -28,7 +28,6 @@
 import com.android.launcher3.celllayout.testcases.MultipleCellLayoutsSimpleReorder;
 import com.android.launcher3.tapl.Widget;
 import com.android.launcher3.tapl.WidgetResizeFrame;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.ui.TaplTestsLauncher3;
 import com.android.launcher3.util.rule.ShellCommandRule;
@@ -115,11 +114,8 @@
         // resetLoaderState triggers the launcher to start loading the workspace which allows
         // waitForLauncherCondition to wait for that condition, otherwise the condition would
         // always be true and it wouldn't wait for the changes to be applied.
-        Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "before resetLoaderState");
         resetLoaderState();
-        Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "after resetLoaderState");
         waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading());
-        Log.d(TestProtocol.WORKSPACE_LOADS_FOREVER, "after waitForLauncherCondition");
         Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.getCellX(),
                 mainWidgetCellPos.getCellY());
         assertNotNull(widget);
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;
         }