Snap for 7482035 from a6dd5b49d7f0dd7cd2cce50e1e0149802bd00ad1 to sc-v2-release

Change-Id: I68ea6ec7a27d3a5e2d865fbedf25553c673fc37d
diff --git a/go/quickstep/res/layout/overview_panel.xml b/go/quickstep/res/layout/overview_panel.xml
deleted file mode 100644
index 241b63d..0000000
--- a/go/quickstep/res/layout/overview_panel.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-     Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <com.android.quickstep.views.LauncherRecentsView
-        android:id="@+id/overview_panel"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:accessibilityPaneTitle="@string/accessibility_recent_apps"
-        android:clipChildren="false"
-        android:clipToPadding="false"
-        android:background="?attr/overviewBackgroundColor"
-        android:visibility="invisible" />
-
-    <com.android.quickstep.views.SplitPlaceholderView
-        android:id="@+id/split_placeholder"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/split_placeholder_size"
-        android:background="@android:color/darker_gray"
-        android:visibility="gone" />
-
-    <include
-        android:id="@+id/overview_actions_view"
-        layout="@layout/overview_actions_container" />
-
-</merge>
diff --git a/go/quickstep/res/values/attrs.xml b/go/quickstep/res/values/attrs.xml
index 3adf462..03eab50 100644
--- a/go/quickstep/res/values/attrs.xml
+++ b/go/quickstep/res/values/attrs.xml
@@ -16,7 +16,6 @@
 -->
 <resources>
     <!-- Attributes used for Overview theming -->
-    <attr name="overviewBackgroundColor" format="color" />
     <attr name="overviewButtonTextColor" format="color" />
     <attr name="overviewButtonIconColor" format="color" />
     <attr name="overviewButtonBackgroundColor" format="color" />
diff --git a/go/quickstep/res/values/colors.xml b/go/quickstep/res/values/colors.xml
index f815f54..ae72ef6 100644
--- a/go/quickstep/res/values/colors.xml
+++ b/go/quickstep/res/values/colors.xml
@@ -16,10 +16,8 @@
 -->
 <resources>
     <!-- Overview -->
-    <color name="go_overview_background_color">#DADADA</color>
-    <color name="go_overview_background_color_dark">#000000</color>
     <color name="go_overview_text_color">#3C4043</color>
     <color name="go_overview_text_color_dark">#F8F9FA</color>
     <color name="go_overview_button_color">#70FFFFFF</color>
-    <color name="go_overview_button_color_dark">#303030</color>
+    <color name="go_overview_button_color_dark">#474747</color>
 </resources>
diff --git a/go/quickstep/res/values/styles.xml b/go/quickstep/res/values/styles.xml
index 59f7377..ffe8f46 100644
--- a/go/quickstep/res/values/styles.xml
+++ b/go/quickstep/res/values/styles.xml
@@ -17,14 +17,12 @@
 <resources>
     <!-- App themes -->
     <style name="AppTheme" parent="@style/LauncherTheme">
-        <item name="overviewBackgroundColor">@color/go_overview_background_color</item>
         <item name="overviewButtonTextColor">@color/go_overview_text_color</item>
         <item name="overviewButtonIconColor">@color/go_overview_text_color</item>
         <item name="overviewButtonBackgroundColor">@color/go_overview_button_color</item>
     </style>
 
     <style name="AppTheme.Dark" parent="@style/LauncherTheme.Dark">
-        <item name="overviewBackgroundColor">@color/go_overview_background_color_dark</item>
         <item name="overviewButtonTextColor">@color/go_overview_text_color_dark</item>
         <item name="overviewButtonIconColor">@color/go_overview_text_color_dark</item>
         <item name="overviewButtonBackgroundColor">@color/go_overview_button_color_dark</item>
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index 3a6e9b5..b823c36 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -51,7 +51,8 @@
     public static final String ACTIONS_URL = "niu_actions_app_url";
     public static final String ACTIONS_APP_PACKAGE = "niu_actions_app_package";
     public static final String ACTIONS_ERROR_CODE = "niu_actions_app_error_code";
-    public static final int ERROR_PERMISSIONS = 1;
+    public static final int ERROR_PERMISSIONS_STRUCTURE = 1;
+    public static final int ERROR_PERMISSIONS_SCREENSHOT = 2;
     private static final String TAG = "TaskOverlayFactoryGo";
 
     private AssistContentRequester mContentRequester;
@@ -75,7 +76,8 @@
         private String mNIUPackageName;
         private String mTaskPackageName;
         private String mWebUrl;
-        private boolean mAssistPermissionsEnabled;
+        private boolean mAssistStructurePermitted;
+        private boolean mAssistScreenshotPermitted;
         private AssistContentRequester mFactoryContentRequester;
 
         private TaskOverlayGo(TaskThumbnailView taskThumbnailView,
@@ -104,7 +106,7 @@
             getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
             mTaskPackageName = task.key.getPackageName();
 
-            if (!mAssistPermissionsEnabled) {
+            if (!mAssistStructurePermitted || !mAssistScreenshotPermitted) {
                 return;
             }
 
@@ -131,10 +133,14 @@
         private void sendNIUIntent(String actionType) {
             Intent intent = createNIUIntent(actionType);
             // Only add and send the image if the appropriate permissions are held
-            if (mAssistPermissionsEnabled) {
+            if (mAssistStructurePermitted && mAssistScreenshotPermitted) {
                 mImageApi.shareAsDataWithExplicitIntent(/* crop */ null, intent);
             } else {
-                intent.putExtra(ACTIONS_ERROR_CODE, ERROR_PERMISSIONS);
+                // If both permissions are disabled, the structure error code takes priority
+                // The user must enable that one before they can enable screenshots
+                int code = mAssistStructurePermitted ? ERROR_PERMISSIONS_SCREENSHOT
+                        : ERROR_PERMISSIONS_STRUCTURE;
+                intent.putExtra(ACTIONS_ERROR_CODE, code);
                 try {
                     mApplicationContext.startActivity(intent);
                 } catch (ActivityNotFoundException e) {
@@ -164,11 +170,10 @@
         @VisibleForTesting
         public void checkSettings() {
             ContentResolver contentResolver = mApplicationContext.getContentResolver();
-            boolean structureEnabled = Settings.Secure.getInt(contentResolver,
+            mAssistStructurePermitted = Settings.Secure.getInt(contentResolver,
                     Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1) != 0;
-            boolean screenshotEnabled = Settings.Secure.getInt(contentResolver,
+            mAssistScreenshotPermitted = Settings.Secure.getInt(contentResolver,
                     Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1) != 0;
-            mAssistPermissionsEnabled = structureEnabled && screenshotEnabled;
 
             String assistantPackage =
                     Settings.Secure.getString(contentResolver, Settings.Secure.ASSISTANT);
diff --git a/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java b/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
index 5471e49..1386ac0 100644
--- a/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
+++ b/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
@@ -41,20 +41,11 @@
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.BgDataModel.FixedContainerItems;
 import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
-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.model.data.WorkspaceItemInfo;
 import com.android.launcher3.shadows.ShadowDeviceFlag;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LauncherModelHelper;
-import com.android.launcher3.util.ViewOnDrawExecutor;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
-import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -68,9 +59,6 @@
 import org.robolectric.shadows.ShadowPackageManager;
 import org.robolectric.util.ReflectionHelpers;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -243,60 +231,5 @@
         public IntSet getPagesToBindSynchronously() {
             return IntSet.wrap(0);
         }
-
-        @Override
-        public void clearPendingBinds() { }
-
-        @Override
-        public void startBinding() { }
-
-        @Override
-        public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
-
-        @Override
-        public void bindScreens(IntArray orderedScreenIds) { }
-
-        @Override
-        public void finishFirstPageBind(ViewOnDrawExecutor executor) { }
-
-        @Override
-        public void finishBindingItems(IntSet pagesBoundFirst) { }
-
-        @Override
-        public void preAddApps() { }
-
-        @Override
-        public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
-                ArrayList<ItemInfo> addAnimated) { }
-
-        @Override
-        public void bindIncrementalDownloadProgressUpdated(AppInfo app) { }
-
-        @Override
-        public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
-
-        @Override
-        public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
-
-        @Override
-        public void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
-
-        @Override
-        public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
-
-        @Override
-        public void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
-
-        @Override
-        public void onPagesBoundSynchronously(IntSet pages) { }
-
-        @Override
-        public void executeOnNextDraw(ViewOnDrawExecutor executor) { }
-
-        @Override
-        public void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap) { }
-
-        @Override
-        public void bindAllApplications(AppInfo[] apps, int flags) { }
     }
 }
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 5b4e5f2..e6333d1 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -161,14 +161,14 @@
         if (mSurface != surface) {
             mSurface = surface;
             if (surface != null) {
-                dispatchTransactionSurface(mDepth);
+                dispatchTransactionSurface();
             }
         }
     }
 
     @Override
     public void setState(LauncherState toState) {
-        if (mSurface == null || mIgnoreStateChangesDuringMultiWindowAnimation) {
+        if (mIgnoreStateChangesDuringMultiWindowAnimation) {
             return;
         }
 
@@ -176,7 +176,7 @@
         if (Float.compare(mDepth, toDepth) != 0) {
             setDepth(toDepth);
         } else if (toState == LauncherState.OVERVIEW) {
-            dispatchTransactionSurface(mDepth);
+            dispatchTransactionSurface();
         }
     }
 
@@ -202,35 +202,30 @@
         if (Float.compare(mDepth, depthF) == 0) {
             return;
         }
-        if (dispatchTransactionSurface(depthF)) {
-            mDepth = depthF;
-        }
+        mDepth = depthF;
+        dispatchTransactionSurface();
     }
 
-    private boolean dispatchTransactionSurface(float depth) {
+    private void dispatchTransactionSurface() {
         boolean supportsBlur = BlurUtils.supportsBlursOnWindows();
-        if (supportsBlur && (mSurface == null || !mSurface.isValid())) {
-            return false;
-        }
         ensureDependencies();
         IBinder windowToken = mLauncher.getRootView().getWindowToken();
         if (windowToken != null) {
-            mWallpaperManager.setWallpaperZoomOut(windowToken, depth);
+            mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
         }
 
-        if (supportsBlur) {
+        if (supportsBlur && (mSurface != null && mSurface.isValid())) {
             // We cannot mark the window as opaque in overview because there will be an app window
             // below the launcher layer, and we need to draw it -- without blurs.
             boolean isOverview = mLauncher.isInState(LauncherState.OVERVIEW);
             boolean opaque = mLauncher.getScrimView().isFullyOpaque() && !isOverview;
 
-            int blur = opaque || isOverview ? 0 : (int) (depth * mMaxBlurRadius);
+            int blur = opaque || isOverview ? 0 : (int) (mDepth * mMaxBlurRadius);
             new SurfaceControl.Transaction()
                     .setBackgroundBlurRadius(mSurface, blur)
                     .setOpaque(mSurface, opaque)
                     .apply();
         }
-        return true;
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index eb524a9..0e2fbbc 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -86,7 +86,7 @@
             StateAnimationConfig config) {
         RecentsView overview = mActivity.getOverviewPanel();
         if (toState == NORMAL && fromState == OVERVIEW) {
-            config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, DEACCEL);
+            config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR, 0, 0.25f));
             config.setInterpolator(ANIM_SCRIM_FADE, LINEAR);
             config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
             config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
index a3cd7df..510820a 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
@@ -26,6 +26,8 @@
 
 import static com.android.launcher3.Utilities.squaredHypot;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Resources;
@@ -199,6 +201,14 @@
                         float progress = (float) valueAnimator.getAnimatedValue();
                         SystemUiProxy.INSTANCE.get(mContext).onAssistantProgress(progress);
                     });
+                    // Ensure that we always send a zero at the end to clear the invocation state.
+                    animator.addListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            super.onAnimationEnd(animation);
+                            SystemUiProxy.INSTANCE.get(mContext).onAssistantProgress(0f);
+                        }
+                    });
                     animator.setInterpolator(Interpolators.DEACCEL_2);
                     animator.start();
                 }
diff --git a/res/color-night-v31/all_apps_tabs_background.xml b/res/color-night-v31/all_apps_tabs_background.xml
deleted file mode 100644
index b396f33..0000000
--- a/res/color-night-v31/all_apps_tabs_background.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral2_100"/>
-</selector>
\ No newline at end of file
diff --git a/res/color-night/all_apps_tabs_background.xml b/res/color-night/all_apps_tabs_background.xml
deleted file mode 100644
index c0c1621..0000000
--- a/res/color-night/all_apps_tabs_background.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="#E2E2E2"/>
-</selector>
\ No newline at end of file
diff --git a/res/drawable/all_apps_tabs_background.xml b/res/drawable/all_apps_tabs_background.xml
index 4e95315..bf7ee8c 100644
--- a/res/drawable/all_apps_tabs_background.xml
+++ b/res/drawable/all_apps_tabs_background.xml
@@ -13,13 +13,27 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:enterFadeDuration="500">
     <item
-        android:top="@dimen/all_apps_tabs_vertical_padding"
-        android:bottom="@dimen/all_apps_tabs_vertical_padding">
+        android:id="@+id/unselected"
+        android:state_selected="false">
+        <ripple android:color="@color/all_apps_tab_background_selected">
+            <item>
+                <shape android:shape="rectangle">
+                    <corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
+                    <solid android:color="@color/all_apps_tabs_background" />
+                </shape>
+            </item>
+        </ripple>
+    </item>
+
+    <item
+        android:id="@+id/selected"
+        android:state_selected="true">
         <shape android:shape="rectangle">
-            <solid android:color="@color/all_apps_tabs_background" />
             <corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
+            <solid android:color="@color/all_apps_tab_background_selected" />
         </shape>
     </item>
-</layer-list>
\ No newline at end of file
+</selector>
\ No newline at end of file
diff --git a/res/layout/all_apps_personal_work_tabs.xml b/res/layout/all_apps_personal_work_tabs.xml
index cfaa261..11143fb 100644
--- a/res/layout/all_apps_personal_work_tabs.xml
+++ b/res/layout/all_apps_personal_work_tabs.xml
@@ -14,12 +14,12 @@
   ~ limitations under the License.
 -->
 
-<com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/tabs"
-    android:layout_width="@dimen/all_apps_header_pills_width"
+    android:layout_width="match_parent"
     android:layout_height="@dimen/all_apps_header_pill_height"
     android:layout_gravity="center_horizontal"
-    android:background="@drawable/all_apps_tabs_background"
     android:orientation="horizontal"
     style="@style/TextHeadline">
 
@@ -27,19 +27,25 @@
         android:id="@+id/tab_personal"
         android:layout_width="0dp"
         android:layout_height="match_parent"
+        android:layout_marginEnd="@dimen/all_apps_tabs_button_horizontal_padding"
+        android:layout_marginVertical="@dimen/all_apps_tabs_vertical_padding"
         android:layout_weight="1"
-        android:background="@drawable/personal_work_tabs_ripple"
+        android:background="@drawable/all_apps_tabs_background"
         android:text="@string/all_apps_personal_tab"
         android:textColor="@color/all_apps_tab_text"
-        android:textSize="14sp" />
+        android:textSize="14sp"
+        style="?android:attr/borderlessButtonStyle" />
 
     <Button
         android:id="@+id/tab_work"
         android:layout_width="0dp"
         android:layout_height="match_parent"
+        android:layout_marginStart="@dimen/all_apps_tabs_button_horizontal_padding"
+        android:layout_marginVertical="@dimen/all_apps_tabs_vertical_padding"
         android:layout_weight="1"
-        android:background="@drawable/personal_work_tabs_ripple"
+        android:background="@drawable/all_apps_tabs_background"
         android:text="@string/all_apps_work_tab"
         android:textColor="@color/all_apps_tab_text"
-        android:textSize="14sp" />
+        android:textSize="14sp"
+        style="?android:attr/borderlessButtonStyle" />
 </com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
\ No newline at end of file
diff --git a/res/layout/widgets_full_sheet_search_and_recommendations.xml b/res/layout/widgets_full_sheet_search_and_recommendations.xml
index a89f85f..4a3e20d 100644
--- a/res/layout/widgets_full_sheet_search_and_recommendations.xml
+++ b/res/layout/widgets_full_sheet_search_and_recommendations.xml
@@ -53,7 +53,7 @@
         android:id="@+id/recommended_widget_table"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginHorizontal="16dp"
+        android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
         android:layout_marginTop="8dp"
         android:background="@drawable/widgets_recommendation_background"
         android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml
index 3eaa7ea..7f84050 100644
--- a/res/layout/widgets_list_row_header.xml
+++ b/res/layout/widgets_list_row_header.xml
@@ -19,7 +19,7 @@
     android:id="@+id/widgets_list_header"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginHorizontal="16dp"
+    android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
     android:paddingVertical="@dimen/widget_list_header_view_vertical_padding"
     android:orientation="horizontal"
     launcher:appIconSize="48dp">
diff --git a/res/layout/widgets_personal_work_tabs.xml b/res/layout/widgets_personal_work_tabs.xml
index 15275a6..532c422 100644
--- a/res/layout/widgets_personal_work_tabs.xml
+++ b/res/layout/widgets_personal_work_tabs.xml
@@ -20,28 +20,34 @@
     android:id="@+id/tabs"
     android:layout_width="match_parent"
     android:layout_height="@dimen/all_apps_header_pill_height"
-    android:layout_marginHorizontal="32dp"
+    android:gravity="center_horizontal"
     android:orientation="horizontal"
-    android:background="@drawable/all_apps_tabs_background"
+    android:layout_marginHorizontal="@dimen/widget_tabs_horizontal_margin"
     style="@style/TextHeadline">
 
     <Button
         android:id="@+id/tab_personal"
         android:layout_width="0dp"
         android:layout_height="match_parent"
+        android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
+        android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
         android:layout_weight="1"
-        android:background="@drawable/personal_work_tabs_ripple"
+        android:background="@drawable/all_apps_tabs_background"
         android:text="@string/widgets_full_sheet_personal_tab"
         android:textColor="@color/all_apps_tab_text"
-        android:textSize="14sp" />
+        android:textSize="14sp"
+        style="?android:attr/borderlessButtonStyle" />
 
     <Button
         android:id="@+id/tab_work"
         android:layout_width="0dp"
         android:layout_height="match_parent"
+        android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
+        android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
         android:layout_weight="1"
-        android:background="@drawable/personal_work_tabs_ripple"
+        android:background="@drawable/all_apps_tabs_background"
         android:text="@string/widgets_full_sheet_work_tab"
         android:textColor="@color/all_apps_tab_text"
-        android:textSize="14sp" />
+        android:textSize="14sp"
+        style="?android:attr/borderlessButtonStyle" />
 </com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
\ No newline at end of file
diff --git a/res/layout/widgets_search_bar.xml b/res/layout/widgets_search_bar.xml
index 6a4bb4d..0b354e8 100644
--- a/res/layout/widgets_search_bar.xml
+++ b/res/layout/widgets_search_bar.xml
@@ -6,7 +6,7 @@
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:layout_marginTop="24dp"
-    android:layout_marginHorizontal="16dp"
+    android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
     android:background="@drawable/bg_widgets_searchbox">
 
     <com.android.launcher3.ExtendedEditText
diff --git a/res/layout/widgets_table_container.xml b/res/layout/widgets_table_container.xml
index fac21fd..ab470d8 100644
--- a/res/layout/widgets_table_container.xml
+++ b/res/layout/widgets_table_container.xml
@@ -18,4 +18,4 @@
     android:id="@+id/widgets_table"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginHorizontal="16dp"/>
+    android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin" />
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f5c08c5..4e9a16e 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -93,14 +93,14 @@
     <dimen name="all_apps_background_canvas_width">700dp</dimen>
     <dimen name="all_apps_background_canvas_height">475dp</dimen>
     <dimen name="all_apps_header_pill_height">48dp</dimen>
-    <dimen name="all_apps_header_pill_corner_radius">18dp</dimen>
-    <dimen name="all_apps_header_pills_width">348dp</dimen>
+    <dimen name="all_apps_header_pill_corner_radius">12dp</dimen>
     <dimen name="all_apps_header_tab_height">48dp</dimen>
     <dimen name="all_apps_tabs_indicator_height">2dp</dimen>
     <dimen name="all_apps_header_top_padding">36dp</dimen>
     <dimen name="all_apps_header_bottom_padding">6dp</dimen>
     <dimen name="all_apps_work_profile_tab_footer_top_padding">16dp</dimen>
     <dimen name="all_apps_work_profile_tab_footer_bottom_padding">20dp</dimen>
+    <dimen name="all_apps_tabs_button_horizontal_padding">4dp</dimen>
     <dimen name="all_apps_tabs_vertical_padding">6dp</dimen>
     <dimen name="all_apps_divider_height">2dp</dimen>
     <dimen name="all_apps_divider_width">128dp</dimen>
@@ -136,6 +136,11 @@
     <dimen name="widget_cell_horizontal_padding">16dp</dimen>
     <dimen name="widget_cell_font_size">14sp</dimen>
 
+    <dimen name="widget_tabs_button_horizontal_padding">4dp</dimen>
+    <dimen name="widget_tabs_horizontal_margin">32dp</dimen>
+    <dimen name="widget_apps_header_pill_height">48dp</dimen>
+    <dimen name="widget_apps_tabs_vertical_padding">6dp</dimen>
+
     <dimen name="recommended_widgets_table_vertical_padding">8dp</dimen>
 
     <!-- Bottom margin for the search and recommended widgets container without work profile -->
@@ -148,6 +153,7 @@
 
     <dimen name="widget_list_header_view_vertical_padding">20dp</dimen>
     <dimen name="widget_list_entry_spacing">2dp</dimen>
+    <dimen name="widget_list_horizontal_margin">16dp</dimen>
 
     <dimen name="widget_preview_shadow_blur">0.5dp</dimen>
     <dimen name="widget_preview_key_shadow_distance">1dp</dimen>
diff --git a/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java b/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
index 275cf81..07351fe 100644
--- a/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
@@ -35,7 +35,7 @@
 import com.android.launcher3.util.LauncherLayoutBuilder;
 import com.android.launcher3.util.LauncherModelHelper;
 import com.android.launcher3.util.LooperExecutor;
-import com.android.launcher3.util.ViewOnDrawExecutor;
+import com.android.launcher3.util.RunnableList;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -106,14 +106,14 @@
         // No effect on callbacks when removing an callback
         mModelHelper.getModel().removeCallbacks(cb2);
         waitForLoaderAndTempMainThread();
-        assertNull(cb1.mDeferredExecutor);
-        assertNull(cb2.mDeferredExecutor);
+        assertNull(cb1.mPendingTasks);
+        assertNull(cb2.mPendingTasks);
 
         // Reloading only loads registered callbacks
         mModelHelper.getModel().startLoader();
         waitForLoaderAndTempMainThread();
         cb1.verifySynchronouslyBound(3);
-        assertNull(cb2.mDeferredExecutor);
+        assertNull(cb2.mPendingTasks);
     }
 
     @Test
@@ -180,19 +180,15 @@
         final List<ItemInfo> mItems = new ArrayList<>();
         IntSet mPageToBindSync = IntSet.wrap(0);
         IntSet mPageBoundSync = new IntSet();
-        ViewOnDrawExecutor mDeferredExecutor;
+        RunnableList mPendingTasks;
         AppInfo[] mAppInfos;
 
         MyCallbacks() { }
 
         @Override
-        public void onPagesBoundSynchronously(IntSet pages) {
-            mPageBoundSync = pages;
-        }
-
-        @Override
-        public void executeOnNextDraw(ViewOnDrawExecutor executor) {
-            mDeferredExecutor = executor;
+        public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
+            mPageBoundSync = boundPages;
+            mPendingTasks = pendingTasks;
         }
 
         @Override
@@ -213,19 +209,19 @@
         public void reset() {
             mItems.clear();
             mPageBoundSync = new IntSet();
-            mDeferredExecutor = null;
+            mPendingTasks = null;
             mAppInfos = null;
         }
 
         public void verifySynchronouslyBound(int totalItems) {
             // Verify that the requested page is bound synchronously
-            assertEquals(mPageBoundSync, mPageToBindSync);
+            assertEquals(mPageToBindSync, mPageBoundSync);
             assertEquals(mItems.size(), 1);
-            assertEquals(mItems.get(0).screenId, mPageBoundSync);
-            assertNotNull(mDeferredExecutor);
+            assertEquals(IntSet.wrap(mItems.get(0).screenId), mPageBoundSync);
+            assertNotNull(mPendingTasks);
 
             // Verify that all other pages are bound properly
-            mDeferredExecutor.runAllTasks();
+            mPendingTasks.executeAllAndDestroy();
             assertEquals(mItems.size(), totalItems);
         }
 
diff --git a/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java b/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java
index fdddab4..caad40e 100644
--- a/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java
@@ -81,7 +81,7 @@
         doLayout(launcher);
         ViewOnDrawExecutor executor = ReflectionHelpers.getField(launcher, "mPendingExecutor");
         if (executor != null) {
-            executor.runAllTasks();
+            executor.markCompleted();
         }
         return launcher;
     }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5a9257d..5720a8c 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -118,6 +118,7 @@
 import com.android.launcher3.allapps.AllAppsStore;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.allapps.DiscoveryBounce;
+import com.android.launcher3.anim.AnimatorListeners;
 import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.compat.AccessibilityManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
@@ -174,6 +175,7 @@
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.PendingRequestArgs;
+import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.util.Themes;
@@ -2060,7 +2062,7 @@
     @Override
     public void clearPendingBinds() {
         if (mPendingExecutor != null) {
-            mPendingExecutor.markCompleted();
+            mPendingExecutor.cancel();
             mPendingExecutor = null;
 
             // We might have set this flag previously and forgot to clear it.
@@ -2482,25 +2484,6 @@
         return info;
     }
 
-    public void onPagesBoundSynchronously(IntSet pages) {
-        mSynchronouslyBoundPages = pages;
-        mWorkspace.setCurrentPage(pages.getArray().get(0));
-        mPagesToBindSynchronously = new IntSet();
-    }
-
-    @Override
-    public void executeOnNextDraw(ViewOnDrawExecutor executor) {
-        clearPendingBinds();
-        mPendingExecutor = executor;
-        if (!isInState(ALL_APPS)) {
-            mAppsView.getAppsStore().enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW);
-            mPendingExecutor.execute(() -> mAppsView.getAppsStore().disableDeferUpdates(
-                    AllAppsStore.DEFER_UPDATES_NEXT_DRAW));
-        }
-
-        executor.attachTo(this);
-    }
-
     public void clearPendingExecutor(ViewOnDrawExecutor executor) {
         if (mPendingExecutor == executor) {
             mPendingExecutor = null;
@@ -2508,22 +2491,31 @@
     }
 
     @Override
-    public void finishFirstPageBind(final ViewOnDrawExecutor executor) {
+    public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
+        mSynchronouslyBoundPages = boundPages;
+        if (!boundPages.isEmpty()) {
+            mWorkspace.setCurrentPage(boundPages.getArray().get(0));
+        }
+        mPagesToBindSynchronously = new IntSet();
+
+        clearPendingBinds();
+        ViewOnDrawExecutor executor = new ViewOnDrawExecutor(pendingTasks);
+        mPendingExecutor = executor;
+        if (!isInState(ALL_APPS)) {
+            mAppsView.getAppsStore().enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW);
+            pendingTasks.add(() -> mAppsView.getAppsStore().disableDeferUpdates(
+                    AllAppsStore.DEFER_UPDATES_NEXT_DRAW));
+        }
+
         AlphaProperty property = mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD);
         if (property.getValue() < 1) {
             ObjectAnimator anim = ObjectAnimator.ofFloat(property, MultiValueAlpha.VALUE, 1);
-            if (executor != null) {
-                anim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        executor.onLoadAnimationCompleted();
-                    }
-                });
-            }
+            anim.addListener(AnimatorListeners.forEndCallback(executor::onLoadAnimationCompleted));
             anim.start();
-        } else if (executor != null) {
+        } else {
             executor.onLoadAnimationCompleted();
         }
+        executor.attachTo(this);
     }
 
     /**
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index 12ee676..30755e3 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -18,7 +18,9 @@
 
 import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
 import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
+import android.os.Process;
 import android.util.Log;
 
 import com.android.launcher3.InvariantDeviceProfile;
@@ -33,7 +35,7 @@
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.util.LooperIdleLock;
-import com.android.launcher3.util.ViewOnDrawExecutor;
+import com.android.launcher3.util.RunnableList;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -175,7 +177,6 @@
                 currentScreenIndices = screenIndices;
             }
 
-            final boolean validFirstPage = !currentScreenIndices.isEmpty();
 
             IntSet currentScreenIds  = new IntSet();
             currentScreenIndices.forEach(
@@ -204,40 +205,25 @@
             // Bind workspace screens
             executeCallbacksTask(c -> c.bindScreens(mOrderedScreenIds), mUiExecutor);
 
-            Executor mainExecutor = mUiExecutor;
             // Load items on the current page.
-            bindWorkspaceItems(currentWorkspaceItems, mainExecutor);
-            bindAppWidgets(currentAppWidgets, mainExecutor);
+            bindWorkspaceItems(currentWorkspaceItems, mUiExecutor);
+            bindAppWidgets(currentAppWidgets, mUiExecutor);
             mExtraItems.forEach(item ->
-                    executeCallbacksTask(c -> c.bindExtraContainerItems(item), mainExecutor));
+                    executeCallbacksTask(c -> c.bindExtraContainerItems(item), mUiExecutor));
 
-            // In case of validFirstPage, only bind the first screen, and defer binding the
-            // remaining screens after first onDraw (and an optional the fade animation whichever
-            // happens later).
-            // This ensures that the first screen is immediately visible (eg. during rotation)
-            // In case of !validFirstPage, bind all pages one after other.
+            RunnableList pendingTasks = new RunnableList();
+            Executor pendingExecutor = pendingTasks::add;
+            bindWorkspaceItems(otherWorkspaceItems, pendingExecutor);
+            bindAppWidgets(otherAppWidgets, pendingExecutor);
+            executeCallbacksTask(c -> c.finishBindingItems(currentScreenIndices), pendingExecutor);
+            pendingExecutor.execute(
+                    () -> MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT));
 
-            final Executor deferredExecutor =
-                    validFirstPage ? new ViewOnDrawExecutor() : mainExecutor;
-
-            executeCallbacksTask(c -> c.finishFirstPageBind(
-                    validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null), mainExecutor);
-
-            bindWorkspaceItems(otherWorkspaceItems, deferredExecutor);
-            bindAppWidgets(otherAppWidgets, deferredExecutor);
-            // Tell the workspace that we're done binding items
-            executeCallbacksTask(c -> c.finishBindingItems(currentScreenIndices), deferredExecutor);
-
-            if (validFirstPage) {
-                executeCallbacksTask(c -> {
-                    // We are loading synchronously, which means, some of the pages will be
-                    // bound after first draw. Inform the mCallbacks that page binding is
-                    // not complete, and schedule the remaining pages.
-                    c.onPagesBoundSynchronously(currentScreenIndices);
-                    c.executeOnNextDraw((ViewOnDrawExecutor) deferredExecutor);
-
-                }, mUiExecutor);
-            }
+            executeCallbacksTask(
+                    c -> {
+                        MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+                        c.onInitialBindComplete(currentScreenIndices, pendingTasks);
+                    }, mUiExecutor);
         }
 
         private void bindWorkspaceItems(
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 0740a30..ba825ca 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -49,7 +49,7 @@
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.IntSparseArrayMap;
 import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.ViewOnDrawExecutor;
+import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 
 import java.io.FileDescriptor;
@@ -462,35 +462,41 @@
          * Returns an IntSet of page numbers to bind first, synchronously if possible
          * or an empty IntSet
          */
-        IntSet getPagesToBindSynchronously();
-        void clearPendingBinds();
-        void startBinding();
-        void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons);
-        void bindScreens(IntArray orderedScreenIds);
-        void finishFirstPageBind(ViewOnDrawExecutor executor);
-        void finishBindingItems(IntSet pagesBoundFirst);
-        void preAddApps();
-        void bindAppsAdded(IntArray newScreens,
-                ArrayList<ItemInfo> addNotAnimated, ArrayList<ItemInfo> addAnimated);
+        default IntSet getPagesToBindSynchronously() {
+            return new IntSet();
+        }
+
+        default void clearPendingBinds() { }
+        default void startBinding() { }
+
+        default void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
+        default void bindScreens(IntArray orderedScreenIds) { }
+        default void finishBindingItems(IntSet pagesBoundFirst) { }
+        default void preAddApps() { }
+        default void bindAppsAdded(IntArray newScreens,
+                ArrayList<ItemInfo> addNotAnimated, ArrayList<ItemInfo> addAnimated) { }
 
         /**
          * Binds updated incremental download progress
          */
-        void bindIncrementalDownloadProgressUpdated(AppInfo app);
-        void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated);
-        void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
-        void bindRestoreItemsChange(HashSet<ItemInfo> updates);
-        void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher);
-        void bindAllWidgets(List<WidgetsListBaseEntry> widgets);
-        void onPagesBoundSynchronously(IntSet pages);
-        void executeOnNextDraw(ViewOnDrawExecutor executor);
-        void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap);
+        default void bindIncrementalDownloadProgressUpdated(AppInfo app) { }
+        default void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
+        default void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
+        default void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
+        default void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
+        default void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
+
+        default void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
+            pendingTasks.executeAllAndDestroy();
+        }
+
+        default void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap) { }
 
         /**
          * Binds extra item provided any external source
          */
         default void bindExtraContainerItems(FixedContainerItems item) { }
 
-        void bindAllApplications(AppInfo[] apps, int flags);
+        default void bindAllApplications(AppInfo[] apps, int flags) { }
     }
 }
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index b271a6a..1a96c23 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -35,23 +35,13 @@
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.popup.PopupDataProvider;
 import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.Themes;
-import com.android.launcher3.util.ViewOnDrawExecutor;
 import com.android.launcher3.views.BaseDragLayer;
-import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
 
 /**
  * Launcher activity for secondary displays
@@ -176,67 +166,10 @@
     }
 
     @Override
-    public IntSet getPagesToBindSynchronously() {
-        return new IntSet();
-    }
-
-    @Override
-    public void clearPendingBinds() { }
-
-    @Override
-    public void startBinding() { }
-
-    @Override
-    public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
-
-    @Override
-    public void bindScreens(IntArray orderedScreenIds) { }
-
-    @Override
-    public void finishFirstPageBind(ViewOnDrawExecutor executor) {
-        if (executor != null) {
-            executor.onLoadAnimationCompleted();
-        }
-    }
-
-    @Override
-    public void finishBindingItems(IntSet pagesBoundFirst) { }
-
-    @Override
-    public void preAddApps() { }
-
-    @Override
-    public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
-            ArrayList<ItemInfo> addAnimated) { }
-
-    @Override
     public void bindIncrementalDownloadProgressUpdated(AppInfo app) {
         mAppsView.getAppsStore().updateProgressBar(app);
     }
 
-    @Override
-    public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
-
-    @Override
-    public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
-
-    @Override
-    public void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
-
-    @Override
-    public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
-
-    @Override
-    public void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
-
-    @Override
-    public void onPagesBoundSynchronously(IntSet pages) { }
-
-    @Override
-    public void executeOnNextDraw(ViewOnDrawExecutor executor) {
-        executor.attachTo(getDragLayer(), false, null);
-    }
-
     /**
      * Called when apps-button is clicked
      */
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index 82e24c2..5d90291 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -16,28 +16,21 @@
 
 package com.android.launcher3.util;
 
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.os.Process;
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewTreeObserver.OnDrawListener;
 
-import androidx.annotation.VisibleForTesting;
-
 import com.android.launcher3.Launcher;
 
-import java.util.ArrayList;
-import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 /**
  * An executor which runs all the tasks after the first onDraw is called on the target view.
  */
-public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
+public class ViewOnDrawExecutor implements OnDrawListener, Runnable,
         OnAttachStateChangeListener {
 
-    private final ArrayList<Runnable> mTasks = new ArrayList<>();
+    private final RunnableList mTasks;
 
     private Consumer<ViewOnDrawExecutor> mOnClearCallback;
     private View mAttachedView;
@@ -46,22 +39,16 @@
     private boolean mLoadAnimationCompleted;
     private boolean mFirstDrawCompleted;
 
-    public void attachTo(Launcher launcher) {
-        attachTo(launcher.getWorkspace(), true /* waitForLoadAnimation */,
-                launcher::clearPendingExecutor);
+    private boolean mCancelled;
+
+    public ViewOnDrawExecutor(RunnableList tasks) {
+        mTasks = tasks;
     }
 
-    /**
-     * Attached the executor to the existence of the view
-     */
-    public void attachTo(View attachedView, boolean waitForLoadAnimation,
-            Consumer<ViewOnDrawExecutor> onClearCallback) {
-        mOnClearCallback = onClearCallback;
-        mAttachedView = attachedView;
+    public void attachTo(Launcher launcher) {
+        mOnClearCallback = launcher::clearPendingExecutor;
+        mAttachedView = launcher.getWorkspace();
         mAttachedView.addOnAttachStateChangeListener(this);
-        if (!waitForLoadAnimation) {
-            mLoadAnimationCompleted = true;
-        }
 
         if (mAttachedView.isAttachedToWindow()) {
             attachObserver();
@@ -75,12 +62,6 @@
     }
 
     @Override
-    public void execute(Runnable command) {
-        mTasks.add(command);
-        MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-    }
-
-    @Override
     public void onViewAttachedToWindow(View v) {
         attachObserver();
     }
@@ -105,12 +86,17 @@
     public void run() {
         // Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
         if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
-            runAllTasks();
+            markCompleted();
         }
     }
 
+    /**
+     * Executes all tasks immediately
+     */
     public void markCompleted() {
-        mTasks.clear();
+        if (!mCancelled) {
+            mTasks.executeAllAndDestroy();
+        }
         mCompleted = true;
         if (mAttachedView != null) {
             mAttachedView.getViewTreeObserver().removeOnDrawListener(this);
@@ -119,21 +105,10 @@
         if (mOnClearCallback != null) {
             mOnClearCallback.accept(this);
         }
-        MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
     }
 
-    protected boolean isCompleted() {
-        return mCompleted;
-    }
-
-    /**
-     * Executes all tasks immediately
-     */
-    @VisibleForTesting
-    public void runAllTasks() {
-        for (final Runnable r : mTasks) {
-            r.run();
-        }
+    public void cancel() {
+        mCancelled = true;
         markCompleted();
     }
 }
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java
index 6dc6971..fe83f3f 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java
@@ -60,6 +60,10 @@
     private static final int FLAG_ACTIVITY_RESUMED = 1 << 3;
     private static final int FLAGS_SHOULD_LISTEN =
             FLAG_STATE_IS_NORMAL | FLAG_ACTIVITY_STARTED | FLAG_ACTIVITY_RESUMED;
+    // TODO(b/191735836): Replace with ActivityOptions.KEY_SPLASH_SCREEN_STYLE when un-hidden
+    private static final String KEY_SPLASH_SCREEN_STYLE = "android.activity.splashScreenStyle";
+    // TODO(b/191735836): Replace with SplashScreen.SPLASH_SCREEN_STYLE_EMPTY when un-hidden
+    private static final int SPLASH_SCREEN_STYLE_EMPTY = 0;
 
     public static final int APPWIDGET_HOST_ID = 1024;
 
@@ -329,7 +333,9 @@
         if (view == null) return null;
         Object tag = view.getTag();
         if (!(tag instanceof ItemInfo)) return null;
-        return activity.getActivityLaunchOptions(view, (ItemInfo) tag).toBundle();
+        Bundle bundle = activity.getActivityLaunchOptions(view, (ItemInfo) tag).toBundle();
+        bundle.putInt(KEY_SPLASH_SCREEN_STYLE, SPLASH_SCREEN_STYLE_EMPTY);
+        return bundle;
     }
 
     private void sendActionCancelled(final BaseActivity activity, final int requestCode) {
diff --git a/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
index df5d465..11185fb 100644
--- a/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
+++ b/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
@@ -16,118 +16,43 @@
 package com.android.launcher3.workprofile;
 
 import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.util.AttributeSet;
-import android.view.View;
 import android.widget.Button;
 import android.widget.LinearLayout;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
 import com.android.launcher3.pageindicators.PageIndicator;
 
 /**
  * Supports two indicator colors, dedicated for personal and work tabs.
  */
 public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageIndicator {
-    private final Paint mSelectedIndicatorPaint;
-
-    private int mTabVerticalPadding;
-    private final int mSelectedIndicatorRadius;
-
-    private int mIndicatorLeft = -1;
-    private int mIndicatorRight = -1;
-    private float mScrollOffset;
-    private int mSelectedPosition = 0;
-
     private OnActivePageChangedListener mOnActivePageChangedListener;
     private int mLastActivePage = 0;
-    private boolean mIsRtl;
 
     public PersonalWorkSlidingTabStrip(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
-        setWillNotDraw(false);
-
-        mTabVerticalPadding =
-                getResources().getDimensionPixelSize(R.dimen.all_apps_tabs_vertical_padding);
-
-        mSelectedIndicatorRadius = getResources().getDimensionPixelSize(
-                R.dimen.all_apps_header_pill_corner_radius);
-
-        mSelectedIndicatorPaint = new Paint();
-        mSelectedIndicatorPaint.setColor(
-                context.getColor(R.color.all_apps_tab_background_selected));
-
-        mIsRtl = Utilities.isRtl(getResources());
     }
 
     /**
      * Highlights tab with index pos
      */
     public void updateTabTextColor(int pos) {
-        mSelectedPosition = pos;
         for (int i = 0; i < getChildCount(); i++) {
             Button tab = (Button) getChildAt(i);
             tab.setSelected(i == pos);
         }
     }
 
-    private void updateIndicatorPosition(float scrollOffset) {
-        mScrollOffset = scrollOffset;
-        updateIndicatorPosition();
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        super.onLayout(changed, l, t, r, b);
-        updateTabTextColor(mSelectedPosition);
-        updateIndicatorPosition(mScrollOffset);
-    }
-
-    private void updateIndicatorPosition() {
-        int left = -1, right = -1;
-        final View leftTab = getLeftTab();
-        if (leftTab != null) {
-            left = (int) (leftTab.getLeft() + leftTab.getWidth() * mScrollOffset);
-            right = left + leftTab.getWidth();
-        }
-        setIndicatorPosition(left, right);
-    }
-
-    private View getLeftTab() {
-        return mIsRtl ? getChildAt(1) : getChildAt(0);
-    }
-
-    private void setIndicatorPosition(int left, int right) {
-        if (left != mIndicatorLeft || right != mIndicatorRight) {
-            mIndicatorLeft = left;
-            mIndicatorRight = right;
-            invalidate();
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        canvas.drawRoundRect(mIndicatorLeft, mTabVerticalPadding, mIndicatorRight,
-                getHeight() - mTabVerticalPadding, mSelectedIndicatorRadius,
-                mSelectedIndicatorRadius, mSelectedIndicatorPaint);
-    }
-
     @Override
     public void setScroll(int currentScroll, int totalScroll) {
-        float scrollOffset = ((float) currentScroll) / totalScroll;
-        updateIndicatorPosition(scrollOffset);
     }
 
     @Override
     public void setActiveMarker(int activePage) {
         updateTabTextColor(activePage);
-        updateIndicatorPosition(mIsRtl ? 1 - activePage : activePage);
         if (mOnActivePageChangedListener != null && mLastActivePage != activePage) {
             mOnActivePageChangedListener.onActivePageChanged(activePage);
         }
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index e32250e..1cb6b2d 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -25,6 +25,7 @@
 import androidx.test.uiautomator.By;
 import androidx.test.uiautomator.BySelector;
 import androidx.test.uiautomator.Direction;
+import androidx.test.uiautomator.StaleObjectException;
 import androidx.test.uiautomator.UiObject2;
 
 import com.android.launcher3.testing.TestProtocol;
@@ -61,7 +62,13 @@
 
     private boolean hasClickableIcon(UiObject2 allAppsContainer, UiObject2 appListRecycler,
             BySelector appIconSelector, int displayBottom) {
-        final UiObject2 icon = appListRecycler.findObject(appIconSelector);
+        final UiObject2 icon;
+        try {
+            icon = appListRecycler.findObject(appIconSelector);
+        } catch (StaleObjectException e) {
+            mLauncher.fail("All apps recycler disappeared from screen");
+            return false;
+        }
         if (icon == null) {
             LauncherInstrumentation.log("hasClickableIcon: icon not visible");
             return false;
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 95a15c0..07f51b7 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -501,7 +501,7 @@
         }
     }
 
-    private void fail(String message) {
+    void fail(String message) {
         checkForAnomaly();
         Assert.fail(formatSystemHealthMessage(formatErrorWithEvents(
                 "http://go/tapl test failure:\nSummary: " + getContextDescription()
@@ -1469,6 +1469,9 @@
     Rect getVisibleBounds(UiObject2 object) {
         try {
             return object.getVisibleBounds();
+        } catch (StaleObjectException e) {
+            fail("Object " + object + " disappeared from screen");
+            return null;
         } catch (Throwable t) {
             fail(t.toString());
             return null;