Merge "Fix "software rendering doesn't support hardware bitmaps" from task bar all apps" into tm-qpr-dev
diff --git a/quickstep/protos_overrides/launcher_atom_extension.proto b/quickstep/protos_overrides/launcher_atom_extension.proto
index a1566f0..f5a277b 100644
--- a/quickstep/protos_overrides/launcher_atom_extension.proto
+++ b/quickstep/protos_overrides/launcher_atom_extension.proto
@@ -22,6 +22,7 @@
 // Wrapper message for containers used at the quickstep level.
 // Message name should match with launcher_atom_extension.proto message at
 // the AOSP level.
+// Next ID = 3
 message ExtendedContainers {
   reserved 2; // Deleted fields
 
@@ -31,10 +32,16 @@
 }
 
 // Represents on-device search result container.
+// Next ID = 4
 message DeviceSearchResultContainer{
   optional int32 query_length = 1;
   optional SearchAttributes search_attributes = 2;
+  // [0, m], m varies based on the display density and resolution
+  // To indicate the location of the tapped on-device search result.
+  // For application, it will be the column number in the apps row.
+  optional int32 grid_x = 3;
 
+  // Next ID = 4
   message SearchAttributes{
 
     // True if results are based on spell corrected query
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 3a0adc9..643b1d5 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -89,7 +89,7 @@
     <string name="blocked_by_policy" msgid="2071401072261365546">"ऐप्लिकेशन या आपका संगठन इस कार्रवाई की अनुमति नहीं देता"</string>
     <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"क्या आपको नेविगेशन ट्यूटोरियल छोड़ना है?"</string>
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"इसे बाद में <xliff:g id="NAME">%1$s</xliff:g> ऐप्लिकेशन पर देखा जा सकता है"</string>
-    <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"अभी नहीं"</string>
+    <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द करें"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"छोड़ें"</string>
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"स्क्रीन घुमाएं"</string>
     <string name="taskbar_edu_opened" msgid="3950252793551919129">"टास्कबार ट्यूटोरियल दिखाया गया"</string>
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 6a6a693..e4f82d2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -18,6 +18,7 @@
 import android.graphics.Insets
 import android.graphics.Region
 import android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES
+import android.view.InsetsState
 import android.view.WindowManager
 import com.android.launcher3.AbstractFloatingView
 import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS
@@ -61,9 +62,6 @@
             )
         )
 
-        windowLayoutParams.providedInternalInsets = arrayOfNulls<Insets>(ITYPE_SIZE)
-        windowLayoutParams.providedInternalImeInsets = arrayOfNulls<Insets>(ITYPE_SIZE)
-
         onTaskbarWindowHeightOrInsetsChanged()
 
         windowLayoutParams.insetsRoundedCornerFrame = true
@@ -75,32 +73,23 @@
     }
 
     fun onTaskbarWindowHeightOrInsetsChanged() {
-        var reducingSize = getReducingInsetsForTaskbarInsetsHeight(
-            controllers.taskbarStashController.contentHeightToReportToApps)
+        var contentHeight = controllers.taskbarStashController.contentHeightToReportToApps
+        contentRegion.set(0, windowLayoutParams.height - contentHeight,
+            context.deviceProfile.widthPx, windowLayoutParams.height)
+        var tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps
+        for (provider in windowLayoutParams.providedInsets) {
+            if (provider.type == ITYPE_EXTRA_NAVIGATION_BAR) {
+                provider.insetsSize = Insets.of(0, 0, 0, contentHeight)
+            } else if (provider.type == ITYPE_BOTTOM_TAPPABLE_ELEMENT
+                      || provider.type == ITYPE_BOTTOM_MANDATORY_GESTURES) {
+                provider.insetsSize = Insets.of(0, 0, 0, tappableHeight)
+            }
+        }
 
-        contentRegion.set(0, reducingSize.top,
-                context.deviceProfile.widthPx, windowLayoutParams.height)
-        windowLayoutParams.providedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
-        windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
-        reducingSize = getReducingInsetsForTaskbarInsetsHeight(
-            controllers.taskbarStashController.tappableHeightToReportToApps)
-        windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
-        windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
-
-        reducingSize = getReducingInsetsForTaskbarInsetsHeight(taskbarHeightForIme)
-        windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
-        windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
-        windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
-    }
-
-    /**
-     * WindowLayoutParams.providedInternal*Insets expects Insets that subtract from the window frame
-     * height (i.e. WindowLayoutParams#height). So for Taskbar to report bottom insets to apps, it
-     * actually provides insets from the top of its window frame.
-     * @param height The number of pixels from the bottom of the screen that Taskbar insets.
-     */
-    private fun getReducingInsetsForTaskbarInsetsHeight(height: Int): Insets {
-        return Insets.of(0, windowLayoutParams.height - height, 0, 0)
+        var imeInsetsSize = Insets.of(0, 0, 0, taskbarHeightForIme)
+        for (provider in windowLayoutParams.providedInsets) {
+            provider.imeInsetsSize = imeInsetsSize
+        }
     }
 
     /**
@@ -151,13 +140,10 @@
     override fun dumpLogs(prefix: String, pw: PrintWriter) {
         pw.println(prefix + "TaskbarInsetsController:")
         pw.println("$prefix\twindowHeight=${windowLayoutParams.height}")
-        pw.println("$prefix\tprovidedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR]=" +
-                "${windowLayoutParams.providedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR]}")
-        pw.println("$prefix\tprovidedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]=" +
-                "${windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]}")
-        pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]=" +
-                "${windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]}")
-        pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]=" +
-                "${windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]}")
+        for (provider in windowLayoutParams.providedInsets) {
+            pw.println("$prefix\tprovidedInsets: (type=" + InsetsState.typeToString(provider.type)
+                    + " insetsSize=" + provider.insetsSize
+                    + " imeInsetsSize=" + provider.imeInsetsSize + ")")
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 38a36e4..f6589de 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1799,6 +1799,7 @@
                     new PictureInPictureSurfaceTransaction.Builder()
                             .setAlpha(0f)
                             .build();
+            tx.setShouldDisableCanAffectSystemUiFlags(false);
             int[] taskIds = TopTaskTracker.INSTANCE.get(mContext).getRunningSplitTaskIds();
             for (int taskId : taskIds) {
                 mRecentsAnimationController.setFinishTaskTransaction(taskId,
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index dffdc5a..1e7e89e 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -235,6 +235,10 @@
             }
         };
 
+        RecentsView<?, ?> visibleRecentsView = activityInterface.getVisibleRecentsView();
+        if (visibleRecentsView != null) {
+            visibleRecentsView.moveFocusedTaskToFront();
+        }
         if (mTaskAnimationManager.isRecentsAnimationRunning()) {
             cmd.mActiveCallbacks = mTaskAnimationManager.continueRecentsAnimation(gestureState);
             cmd.mActiveCallbacks.addListener(interactionHandler);
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index d11d50b..1634c08 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -165,7 +165,7 @@
     }
 
     @Override
-    public void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) {
+    public boolean onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) {
         mThumbnailCache.updateTaskSnapShot(taskId, snapshot);
 
         for (int i = mThumbnailChangeListeners.size() - 1; i >= 0; i--) {
@@ -174,6 +174,7 @@
                 task.thumbnail = snapshot;
             }
         }
+        return true;
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 3b9e2b2..45c8036 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -582,14 +582,18 @@
     }
 
     private static int getGridX(LauncherAtom.ItemInfo info, boolean parent) {
-        if (info.getContainerInfo().getContainerCase() == FOLDER) {
+        LauncherAtom.ContainerInfo containerInfo = info.getContainerInfo();
+        if (containerInfo.getContainerCase() == FOLDER) {
             if (parent) {
-                return info.getContainerInfo().getFolder().getWorkspace().getGridX();
+                return containerInfo.getFolder().getWorkspace().getGridX();
             } else {
-                return info.getContainerInfo().getFolder().getGridX();
+                return containerInfo.getFolder().getGridX();
             }
+        } else if (containerInfo.getContainerCase() == EXTENDED_CONTAINERS) {
+            return containerInfo.getExtendedContainers()
+                    .getDeviceSearchResultContainer().getGridX();
         } else {
-            return info.getContainerInfo().getWorkspace().getGridX();
+            return containerInfo.getWorkspace().getGridX();
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index b222f51..833d705 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -279,7 +279,10 @@
         // get the final leash operations but do not apply to the leash.
         final SurfaceControl.Transaction tx =
                 PipSurfaceTransactionHelper.newSurfaceControlTransaction();
-        return onAnimationUpdate(tx, new RectF(mDestinationBounds), END_PROGRESS);
+        final PictureInPictureSurfaceTransaction pipTx =
+                onAnimationUpdate(tx, new RectF(mDestinationBounds), END_PROGRESS);
+        pipTx.setShouldDisableCanAffectSystemUiFlags(true);
+        return pipTx;
     }
 
     private RotatedPosition getRotatedPosition(float progress) {
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index dbb20e0..1acdec1 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -390,10 +390,8 @@
                 .withWindowCrop(mTmpCropRect)
                 .withCornerRadius(getCurrentCornerRadius());
 
-        if (ENABLE_QUICKSTEP_LIVE_TILE.get() && params.getRecentsSurface() != null) {
-            // When relativeLayer = 0, it reverts the surfaces back to the original order.
-            builder.withRelativeLayerTo(params.getRecentsSurface(),
-                    mDrawsBelowRecents ? Integer.MIN_VALUE : 0);
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            builder.withLayer(mDrawsBelowRecents ? Integer.MIN_VALUE : 0);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 8f6fba7..12ddc38 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -141,8 +141,8 @@
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.ResourceBasedOverride.Overrides;
 import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.TranslateEdgeEffect;
 import com.android.launcher3.util.ViewPool;
@@ -4562,6 +4562,7 @@
                     new PictureInPictureSurfaceTransaction.Builder()
                             .setAlpha(0f)
                             .build();
+            tx.setShouldDisableCanAffectSystemUiFlags(false);
             int[] taskIds = TopTaskTracker.INSTANCE.get(getContext()).getRunningSplitTaskIds();
             for (int taskId : taskIds) {
                 mRecentsAnimationController.setFinishTaskTransaction(taskId,
diff --git a/res/layout/all_apps_fast_scroller.xml b/res/layout/all_apps_fast_scroller.xml
index f6a6156..0f1d933 100644
--- a/res/layout/all_apps_fast_scroller.xml
+++ b/res/layout/all_apps_fast_scroller.xml
@@ -22,6 +22,7 @@
         style="@style/FastScrollerPopup"
         android:layout_alignParentEnd="true"
         android:layout_alignTop="@+id/all_apps_header"
+        android:layout_marginTop="@dimen/all_apps_header_bottom_padding"
         android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
 
     <com.android.launcher3.views.RecyclerViewFastScroller
@@ -31,6 +32,7 @@
         android:layout_alignParentBottom="true"
         android:layout_alignParentEnd="true"
         android:layout_alignTop="@+id/all_apps_header"
+        android:layout_marginTop="@dimen/all_apps_header_bottom_padding"
         android:layout_marginEnd="@dimen/fastscroll_end_margin"
         launcher:canThumbDetach="true" />
 
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 37ca89a..d23eac2 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -161,12 +161,12 @@
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"شخصی"</string>
     <string name="all_apps_work_tab" msgid="4884822796154055118">"کاری"</string>
     <string name="work_profile_toggle_label" msgid="3081029915775481146">"نمایه کاری"</string>
-    <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"برنامه‌های کاری دارای نشان هستند و سرپرست سیستم می‌تواند آن‌ها را ببیند"</string>
+    <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"برنامه‌های کاری نشان‌دار هستند و سرپرست فناوری اطلاعات می‌تواند آن‌ها را ببیند"</string>
     <string name="work_profile_edu_accept" msgid="6069788082535149071">"متوجه‌ام"</string>
     <string name="work_apps_paused_title" msgid="3040901117349444598">"برنامه‌های کاری موقتاً متوقف شده‌اند."</string>
     <string name="work_apps_paused_body" msgid="261634750995824906">"برنامه‌های کاری نمی‌توانند برای شما اعلان ارسال کنند، از باتری استفاده کنند، یا به مکانتان دسترسی داشته باشند"</string>
     <string name="work_apps_paused_content_description" msgid="5149623040804051095">"برنامه‌های کاری خاموش است. برنامه‌های کاری نمی‌توانند برای شما اعلان ارسال کنند، از باتری استفاده کنند، یا به مکانتان دسترسی داشته باشند"</string>
-    <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"برنامه‌های کاری دارای نشان هستند و سرپرست سیستم می‌تواند آن‌ها را ببیند."</string>
+    <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"برنامه‌های کاری نشان‌دار هستند و سرپرست فناوری اطلاعات می‌تواند آن‌ها را ببیند."</string>
     <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"متوجه‌ام"</string>
     <string name="work_apps_pause_btn_text" msgid="4669288269140620646">"توقف موقت برنامه‌های کاری"</string>
     <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"روشن کردن برنامه‌های کاری"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index aea8195..fa2b789 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -75,7 +75,7 @@
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"நிறுவல் நீக்கு"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"ஆப்ஸ் தகவல்"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"நிறுவு"</string>
-    <string name="dismiss_prediction_label" msgid="3357562989568808658">"ஆப்ஸைப் பரிந்துரைக்க வேண்டாம்"</string>
+    <string name="dismiss_prediction_label" msgid="3357562989568808658">"ஆப்ஸ் பரிந்துரைக்காதே"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"கணிக்கப்பட்ட ஆப்ஸைப் பின் செய்தல்"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"குறுக்குவழிகளை நிறுவுதல்"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் ஆப்ஸை அனுமதிக்கிறது."</string>
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index 7bbdbd1..7a75ddb 100644
--- a/res/values-v31/colors.xml
+++ b/res/values-v31/colors.xml
@@ -56,4 +56,9 @@
 
     <color name="workspace_accent_color_light">@android:color/system_accent1_100</color>
     <color name="workspace_accent_color_dark">@android:color/system_accent2_600</color>
+
+    <color name="preload_icon_accent_color_light">@android:color/system_accent1_600</color>
+    <color name="preload_icon_background_color_light">@android:color/system_accent2_200</color>
+    <color name="preload_icon_accent_color_dark">@android:color/system_accent1_300</color>
+    <color name="preload_icon_background_color_dark">@android:color/system_neutral2_700</color>
 </resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 165ec5e..9f25905 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -53,6 +53,8 @@
     <attr name="workProfileOverlayTextColor" format="color" />
     <attr name="workspaceAccentColor" format="color" />
     <attr name="dropTargetHoverTextColor" format="color" />
+    <attr name="preloadIconAccentColor" format="color" />
+    <attr name="preloadIconBackgroundColor" format="color" />
 
     <attr name="allAppsButtonBgColor" format="color" />
     <attr name="allAppsButtonColor1" format="color" />
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 2bc9239..309a1c5 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -85,4 +85,9 @@
     <color name="all_apps_button_color_2">#00677E</color>
     <color name="all_apps_button_color_3">#5F757E</color>
     <color name="all_apps_button_color_4">#005A6E</color>
+
+    <color name="preload_icon_accent_color_light">#00668B</color>
+    <color name="preload_icon_background_color_light">#B5CAD7</color>
+    <color name="preload_icon_accent_color_dark">#4BB6E8</color>
+    <color name="preload_icon_background_color_dark">#40484D</color>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 2109510..65bba7b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -65,6 +65,8 @@
         <item name="workspaceAccentColor">@color/workspace_accent_color_light</item>
         <item name="dropTargetHoverTextColor">@color/workspace_text_color_dark</item>
         <item name="overviewScrimColor">@color/overview_scrim</item>
+        <item name="preloadIconAccentColor">@color/preload_icon_accent_color_light</item>
+        <item name="preloadIconBackgroundColor">@color/preload_icon_background_color_light</item>
 
         <item name="android:windowTranslucentStatus">false</item>
         <item name="android:windowTranslucentNavigation">false</item>
@@ -123,6 +125,8 @@
         <item name="workProfileOverlayTextColor">@android:color/white</item>
         <item name="eduHalfSheetBGColor">#DD000000</item>
         <item name="overviewScrimColor">@color/overview_scrim_dark</item>
+        <item name="preloadIconAccentColor">@color/preload_icon_accent_color_dark</item>
+        <item name="preloadIconBackgroundColor">@color/preload_icon_background_color_dark</item>
     </style>
 
     <style name="LauncherTheme.Dark.DarkMainColor" parent="@style/LauncherTheme.Dark">
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index d26e1ab..ebed31b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2776,7 +2776,7 @@
             View v = getFirstMatch(Collections.singletonList(activeRecyclerView),
                     preferredItem, packageAndUserAndApp);
 
-            if (activeRecyclerView.getCurrentScrollY() > 0) {
+            if (v != null && activeRecyclerView.getCurrentScrollY() > 0) {
                 RectF locationBounds = new RectF();
                 FloatingIconView.getLocationBoundsForView(this, v, false, locationBounds,
                         new Rect());
@@ -2804,6 +2804,7 @@
      * @param containers List of ViewGroups to scan, in order of preference.
      * @param operators List of operators, in order starting from best matching operator.
      */
+    @Nullable
     private static View getFirstMatch(Iterable<ViewGroup> containers,
             final Predicate<ItemInfo>... operators) {
         for (Predicate<ItemInfo> operator : operators) {
@@ -2821,6 +2822,7 @@
      * Returns the first view matching the operator in the given ViewGroups, or null if none.
      * Forward iteration matters.
      */
+    @Nullable
     private static View mapOverViewGroup(ViewGroup container, Predicate<ItemInfo> op) {
         final int itemCount = container.getChildCount();
         for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 2cefc6c..499e749 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -128,6 +128,7 @@
     private final int mScrimColor;
     private final int mHeaderProtectionColor;
     protected final float mHeaderThreshold;
+    private int mHeaderBottomAdjustment;
     private ScrimView mScrimView;
     private int mHeaderColor;
     private int mTabsProtectionAlpha;
@@ -140,6 +141,8 @@
         mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
         mHeaderThreshold = getResources().getDimensionPixelSize(
                 R.dimen.dynamic_grid_cell_border_spacing);
+        mHeaderBottomAdjustment = getResources().getDimensionPixelSize(
+                R.dimen.all_apps_header_bottom_adjustment);
         mHeaderProtectionColor = Themes.getAttrColor(context, R.attr.allappsHeaderProtectionColor);
 
         mWorkManager = new WorkProfileManager(
@@ -301,6 +304,10 @@
             mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
             return true;
         }
+        if (isSearching()) {
+            // if in search state, consume touch event.
+            return true;
+        }
         return false;
     }
 
@@ -722,6 +729,9 @@
         mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
         if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
             int bottom = getHeaderBottom();
+            if (!mUsingTabs) {
+                bottom += getFloatingHeaderView().getPaddingBottom() - mHeaderBottomAdjustment;
+            }
             canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint);
             int tabsHeight = getFloatingHeaderView().getPeripheralProtectionHeight();
             if (mTabsProtectionAlpha > 0 && tabsHeight != 0) {
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 641161b..6ecbad2 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -81,7 +81,6 @@
 
     protected final Map<AllAppsRow, PluginHeaderRow> mPluginRows = new ArrayMap<>();
 
-    private final int mHeaderTopPadding;
     // These two values are necessary to ensure that the header protection is drawn correctly.
     private final int mHeaderTopAdjustment;
     private final int mHeaderBottomAdjustment;
@@ -118,8 +117,6 @@
 
     public FloatingHeaderView(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
-        mHeaderTopPadding = context.getResources()
-                .getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
         mHeaderTopAdjustment = context.getResources()
                 .getDimensionPixelSize(R.dimen.all_apps_header_top_adjustment);
         mHeaderBottomAdjustment = context.getResources()
@@ -326,7 +323,7 @@
         int uncappedTranslationY = mTranslationY;
         mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
 
-        if (mCollapsed || uncappedTranslationY < mTranslationY - mHeaderTopPadding) {
+        if (mCollapsed || uncappedTranslationY < mTranslationY - getPaddingTop()) {
             // we hide it completely if already capped (for opening search anim)
             for (FloatingHeaderRow row : mAllRows) {
                 row.setVerticalScroll(0, true /* isScrolledOut */);
@@ -339,7 +336,10 @@
 
         mTabLayout.setTranslationY(mTranslationY);
 
-        int clipTop = mHeaderTopPadding - mHeaderTopAdjustment;
+        int clipTop = getPaddingTop() - mHeaderTopAdjustment;
+        if (mTabsHidden) {
+            clipTop += getPaddingBottom() - mHeaderBottomAdjustment;
+        }
         mRVClip.top = mTabsHidden ? clipTop : 0;
         mHeaderClip.top = clipTop;
         // clipping on a draw might cause additional redraw
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 9e1cd28..38b5c65 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -96,6 +96,9 @@
     public static final BooleanFlag ENABLE_QUICK_SEARCH = new DeviceFlag("ENABLE_QUICK_SEARCH",
             true, "Use quick search behavior.");
 
+    public static final BooleanFlag ENABLE_HIDE_HEADER = new DeviceFlag("ENABLE_HIDE_HEADER",
+            true, "Hide header on keyboard before typing in all apps");
+
     public static final BooleanFlag COLLECT_SEARCH_HISTORY = new DeviceFlag(
             "COLLECT_SEARCH_HISTORY", false, "Allow launcher to collect search history for log");
 
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index d2e4c51..0eb86b1 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -28,11 +28,9 @@
 import android.graphics.Path;
 import android.graphics.PathMeasure;
 import android.graphics.Rect;
-import android.util.Pair;
 import android.util.Property;
-import android.util.SparseArray;
-import android.view.ContextThemeWrapper;
 
+import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.icons.FastBitmapDrawable;
@@ -40,8 +38,6 @@
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.util.Themes;
 
-import java.lang.ref.WeakReference;
-
 /**
  * Extension of {@link FastBitmapDrawable} which shows a progress bar around the icon.
  */
@@ -61,9 +57,9 @@
             };
 
     private static final int DEFAULT_PATH_SIZE = 100;
-    private static final float PROGRESS_WIDTH = 7;
-    private static final float PROGRESS_GAP = 2;
     private static final int MAX_PAINT_ALPHA = 255;
+    private static final int TRACK_ALPHA = (int) (0.27f * MAX_PAINT_ALPHA);
+    private static final int DISABLED_ICON_ALPHA = (int) (0.6f * MAX_PAINT_ALPHA);
 
     private static final long DURATION_SCALE = 500;
 
@@ -71,13 +67,8 @@
     // Duration = COMPLETE_ANIM_FRACTION * DURATION_SCALE
     private static final float COMPLETE_ANIM_FRACTION = 0.3f;
 
-    private static final int COLOR_TRACK = 0x77EEEEEE;
-    private static final int COLOR_SHADOW = 0x55000000;
-
-    private static final float SMALL_SCALE = 0.6f;
-
-    private static final SparseArray<WeakReference<Pair<Path, Bitmap>>> sShadowCache =
-            new SparseArray<>();
+    private static final float SMALL_SCALE = 0.7f;
+    private static final float PROGRESS_STROKE_SCALE = 0.075f;
 
     private static final int PRELOAD_ACCENT_COLOR_INDEX = 0;
     private static final int PRELOAD_BACKGROUND_COLOR_INDEX = 1;
@@ -94,7 +85,6 @@
     private final Path mScaledProgressPath;
     private final Paint mProgressPaint;
 
-    private Bitmap mShadowBitmap;
     private final int mIndicatorColor;
     private final int mSystemAccentColor;
     private final int mSystemBackgroundColor;
@@ -134,7 +124,6 @@
         mScaledProgressPath = new Path();
 
         mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        mProgressPaint.setStyle(Paint.Style.STROKE);
         mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
         mIndicatorColor = indicatorColor;
 
@@ -149,47 +138,22 @@
     @Override
     protected void onBoundsChange(Rect bounds) {
         super.onBoundsChange(bounds);
+
+        float progressWidth = PROGRESS_STROKE_SCALE * bounds.width();
         mTmpMatrix.setScale(
-                (bounds.width() - 2 * PROGRESS_WIDTH - 2 * PROGRESS_GAP) / DEFAULT_PATH_SIZE,
-                (bounds.height() - 2 * PROGRESS_WIDTH - 2 * PROGRESS_GAP) / DEFAULT_PATH_SIZE);
-        mTmpMatrix.postTranslate(
-                bounds.left + PROGRESS_WIDTH + PROGRESS_GAP,
-                bounds.top + PROGRESS_WIDTH + PROGRESS_GAP);
+                (bounds.width() - 2 * progressWidth) / DEFAULT_PATH_SIZE,
+                (bounds.height() - 2 * progressWidth) / DEFAULT_PATH_SIZE);
+        mTmpMatrix.postTranslate(bounds.left + progressWidth, bounds.top + progressWidth);
 
         mShapePath.transform(mTmpMatrix, mScaledTrackPath);
-        float scale = bounds.width() / DEFAULT_PATH_SIZE;
-        mProgressPaint.setStrokeWidth(PROGRESS_WIDTH * scale);
+        mProgressPaint.setStrokeWidth(progressWidth);
 
-        mShadowBitmap = getShadowBitmap(bounds.width(), bounds.height(),
-                (PROGRESS_GAP ) * scale);
         mPathMeasure.setPath(mScaledTrackPath, true);
         mTrackLength = mPathMeasure.getLength();
 
         setInternalProgress(mInternalStateProgress);
     }
 
-    private Bitmap getShadowBitmap(int width, int height, float shadowRadius) {
-        int key = ((width << 16) | height) * (mIsDarkMode ? -1 : 1);
-        WeakReference<Pair<Path, Bitmap>> shadowRef = sShadowCache.get(key);
-        Pair<Path, Bitmap> cache = shadowRef != null ? shadowRef.get() : null;
-        Bitmap shadow = cache != null && cache.first.equals(mShapePath) ? cache.second : null;
-        if (shadow != null) {
-            return shadow;
-        }
-        shadow = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        Canvas c = new Canvas(shadow);
-        mProgressPaint.setShadowLayer(shadowRadius, 0, 0, mIsStartable
-                ? COLOR_SHADOW : mSystemAccentColor);
-        mProgressPaint.setColor(mIsStartable ? COLOR_TRACK : mSystemBackgroundColor);
-        mProgressPaint.setAlpha(MAX_PAINT_ALPHA);
-        c.drawPath(mScaledTrackPath, mProgressPaint);
-        mProgressPaint.clearShadowLayer();
-        c.setBitmap(null);
-
-        sShadowCache.put(key, new WeakReference<>(Pair.create(mShapePath, shadow)));
-        return shadow;
-    }
-
     @Override
     public void drawInternal(Canvas canvas, Rect bounds) {
         if (mRanFinishAnimation) {
@@ -197,12 +161,17 @@
             return;
         }
 
-        // Draw track.
+        // Draw background.
+        mProgressPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+        mProgressPaint.setColor(mSystemBackgroundColor);
+        canvas.drawPath(mScaledTrackPath, mProgressPaint);
+
+        // Draw track and progress.
+        mProgressPaint.setStyle(Paint.Style.STROKE);
         mProgressPaint.setColor(mIsStartable ? mIndicatorColor : mSystemAccentColor);
+        mProgressPaint.setAlpha(TRACK_ALPHA);
+        canvas.drawPath(mScaledTrackPath, mProgressPaint);
         mProgressPaint.setAlpha(mTrackAlpha);
-        if (mShadowBitmap != null) {
-            canvas.drawBitmap(mShadowBitmap, bounds.left, bounds.top, mProgressPaint);
-        }
         canvas.drawPath(mScaledProgressPath, mProgressPaint);
 
         int saveCount = canvas.save();
@@ -211,6 +180,11 @@
         canvas.restoreToCount(saveCount);
     }
 
+    @Override
+    protected void updateFilter() {
+        setAlpha(mIsDisabled ? DISABLED_ICON_ALPHA : MAX_PAINT_ALPHA);
+    }
+
     /**
      * Updates the install progress based on the level
      */
@@ -326,13 +300,12 @@
     }
 
     private static int[] getPreloadColors(Context context) {
-        Context dayNightThemeContext = new ContextThemeWrapper(
-                context, android.R.style.Theme_DeviceDefault_DayNight);
         int[] preloadColors = new int[2];
 
-        preloadColors[PRELOAD_ACCENT_COLOR_INDEX] = Themes.getColorAccent(dayNightThemeContext);
-        preloadColors[PRELOAD_BACKGROUND_COLOR_INDEX] = Themes.getColorBackgroundFloating(
-                dayNightThemeContext);
+        preloadColors[PRELOAD_ACCENT_COLOR_INDEX] = Themes.getAttrColor(context,
+                R.attr.preloadIconAccentColor);
+        preloadColors[PRELOAD_BACKGROUND_COLOR_INDEX] = Themes.getAttrColor(context,
+                R.attr.preloadIconBackgroundColor);
 
         return preloadColors;
     }
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 7d24fe8..c4ec4e3 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -735,7 +735,9 @@
             UNKNOWN(0),
             COLD(1),
             HOT(2),
-            TIMEOUT(3);
+            TIMEOUT(3),
+            FAIL(4),
+            COLD_USERWAITING(5);
 
             private final int mId;
 
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index acdd9a1..efc83eb 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -58,6 +58,8 @@
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.shortcuts.DeepShortcutView;
 
+import java.util.function.Supplier;
+
 /**
  * A view that is created to look like another view with the purpose of creating fluid animations.
  */
@@ -295,9 +297,11 @@
 
         drawable = drawable == null ? null : drawable.getConstantState().newDrawable();
         int iconOffset = getOffsetForIconBounds(l, drawable, pos);
+        // Clone right away as we are on the background thread instead of blocking the
+        // main thread later
+        Drawable btvClone = btvIcon == null ? null : btvIcon.getConstantState().newDrawable();
         synchronized (outIconLoadResult) {
-            outIconLoadResult.btvDrawable = btvIcon == null || drawable == btvIcon
-                    ? null : btvIcon.getConstantState().newDrawable();
+            outIconLoadResult.btvDrawable = () -> btvClone;
             outIconLoadResult.drawable = drawable;
             outIconLoadResult.badge = badge;
             outIconLoadResult.iconOffset = iconOffset;
@@ -318,7 +322,7 @@
      */
     @UiThread
     private void setIcon(@Nullable Drawable drawable, @Nullable Drawable badge,
-            @Nullable Drawable btvIcon, int iconOffset) {
+            @Nullable Supplier<Drawable> btvIcon, int iconOffset) {
         final DeviceProfile dp = mLauncher.getDeviceProfile();
         final InsettableFrameLayout.LayoutParams lp =
                 (InsettableFrameLayout.LayoutParams) getLayoutParams();
@@ -361,9 +365,9 @@
      *
      * Allows nullable as this may be cleared when drawing is deferred to ClipIconView.
      */
-    private void setOriginalDrawableBackground(@Nullable Drawable btvIcon) {
+    private void setOriginalDrawableBackground(@Nullable Supplier<Drawable> btvIcon) {
         if (!mIsOpening) {
-            mBtvDrawable.setBackground(btvIcon);
+            mBtvDrawable.setBackground(btvIcon == null ? null : btvIcon.get());
         }
     }
 
@@ -518,21 +522,26 @@
         getLocationBoundsForView(l, v, isOpening, position);
 
         final FastBitmapDrawable btvIcon;
+        final Supplier<Drawable> btvDrawableSupplier;
         if (v instanceof BubbleTextView) {
             BubbleTextView btv = (BubbleTextView) v;
             if (info instanceof ItemInfoWithIcon
                     && (((ItemInfoWithIcon) info).runtimeStatusFlags
                     & ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK) != 0) {
                 btvIcon = btv.makePreloadIcon();
+                btvDrawableSupplier = () -> btvIcon;
             } else {
-                btvIcon = (FastBitmapDrawable) btv.getIcon().getConstantState().newDrawable();
+                btvIcon = btv.getIcon();
+                // Clone when needed
+                btvDrawableSupplier = () -> btvIcon.getConstantState().newDrawable();
             }
         } else {
             btvIcon = null;
+            btvDrawableSupplier = null;
         }
 
         IconLoadResult result = new IconLoadResult(info, btvIcon != null && btvIcon.isThemed());
-        result.btvDrawable = btvIcon;
+        result.btvDrawable = btvDrawableSupplier;
 
         final long fetchIconId = sFetchIconId++;
         MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
@@ -647,7 +656,7 @@
     private static class IconLoadResult {
         final ItemInfo itemInfo;
         final boolean isThemed;
-        Drawable btvDrawable;
+        Supplier<Drawable> btvDrawable;
         Drawable drawable;
         Drawable badge;
         int iconOffset;
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
index cc2b440..11ca130 100644
--- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -285,8 +285,6 @@
                 }
                 break;
             case MotionEvent.ACTION_UP:
-                hideKeyboardAsync(ActivityContext.lookupContext(getContext()),
-                        getApplicationWindowToken());
             case MotionEvent.ACTION_CANCEL:
                 mRv.onFastScrollCompleted();
                 mTouchOffsetY = 0;
@@ -310,6 +308,7 @@
     }
 
     private void calcTouchOffsetAndPrepToFastScroll(int downY, int lastY) {
+        hideKeyboardAsync(ActivityContext.lookupContext(getContext()), getWindowToken());
         mIsDragging = true;
         if (mCanThumbDetach) {
             mIsThumbDetached = true;