Merge "Using icon color for dot and halo" into sc-dev
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index c436221..e680233 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<com.android.launcher3.taskbar.TaskbarContainerView
+<com.android.launcher3.taskbar.TaskbarDragLayer
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/taskbar_container"
     android:layout_width="wrap_content"
@@ -52,4 +52,4 @@
         android:layout_height="wrap_content"
         android:visibility="gone"/>
 
-</com.android.launcher3.taskbar.TaskbarContainerView>
\ No newline at end of file
+</com.android.launcher3.taskbar.TaskbarDragLayer>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 80754a0..ec77b9b 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -691,7 +691,7 @@
                 floatingIconBounds.right += offsetX;
                 floatingIconBounds.bottom += offsetY;
 
-                SurfaceParams[] params = new SurfaceParams[appTargets.length];
+                ArrayList<SurfaceParams> params = new ArrayList<>();
                 for (int i = appTargets.length - 1; i >= 0; i--) {
                     RemoteAnimationTargetCompat target = appTargets[i];
                     SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash);
@@ -743,9 +743,8 @@
                                 .withWindowCrop(crop)
                                 .withAlpha(1f);
                     }
-                    params[i] = builder.build();
+                    params.add(builder.build());
                 }
-                surfaceApplier.scheduleApply(params);
 
                 if (navBarTarget != null) {
                     final SurfaceParams.Builder navBuilder =
@@ -759,8 +758,10 @@
                     } else {
                         navBuilder.withAlpha(mNavFadeOut.value);
                     }
-                    surfaceApplier.scheduleApply(navBuilder.build());
+                    params.add(navBuilder.build());
                 }
+
+                surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
             }
         });
 
@@ -791,6 +792,8 @@
         SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(floatingView);
         openingTargets.addReleaseCheck(surfaceApplier);
 
+        RemoteAnimationTargetCompat navBarTarget = openingTargets.getNavBarRemoteAnimationTarget();
+
         AnimatorSet animatorSet = new AnimatorSet();
         ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
         appAnimator.setDuration(APP_LAUNCH_DURATION);
@@ -832,6 +835,11 @@
                     windowTargetBounds.height(), 0 /* delay */, APP_LAUNCH_DURATION,
                     EXAGGERATED_EASE);
 
+            final FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION,
+                    NAV_FADE_OUT_INTERPOLATOR);
+            final FloatProp mNavFadeIn = new FloatProp(0f, 1f, ANIMATION_DELAY_NAV_FADE_IN,
+                    ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);
+
             @Override
             public void onUpdate(float percent) {
                 widgetBackgroundBounds.set(mDx.value - mWidth.value / 2f,
@@ -847,7 +855,7 @@
                 matrix.postScale(mAppWindowScale, mAppWindowScale, widgetBackgroundBounds.left,
                         widgetBackgroundBounds.top);
 
-                SurfaceParams[] params = new SurfaceParams[appTargets.length];
+                ArrayList<SurfaceParams> params = new ArrayList<>();
                 float floatingViewAlpha = appTargetsAreTranslucent ? 1 - mPreviewAlpha.value : 1;
                 for (int i = appTargets.length - 1; i >= 0; i--) {
                     RemoteAnimationTargetCompat target = appTargets[i];
@@ -861,9 +869,23 @@
                                 .withAlpha(mPreviewAlpha.value)
                                 .withCornerRadius(mWindowRadius.value / mAppWindowScale);
                     }
-                    params[i] = builder.build();
+                    params.add(builder.build());
                 }
-                surfaceApplier.scheduleApply(params);
+
+                if (navBarTarget != null) {
+                    final SurfaceParams.Builder navBuilder =
+                            new SurfaceParams.Builder(navBarTarget.leash);
+                    if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
+                        navBuilder.withMatrix(matrix)
+                                .withWindowCrop(appWindowCrop)
+                                .withAlpha(mNavFadeIn.value);
+                    } else {
+                        navBuilder.withAlpha(mNavFadeOut.value);
+                    }
+                    params.add(navBuilder.build());
+                }
+
+                surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
             }
         });
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 6726419..c2d107c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -46,7 +46,7 @@
     private final TaskbarHotseatController mHotseatController;
 
     private final TaskbarActivityContext mContext;
-    final TaskbarContainerView mTaskbarContainerView;
+    final TaskbarDragLayer mTaskbarDragLayer;
     final TaskbarView mTaskbarView;
 
     private @Nullable Animator mAnimator;
@@ -55,8 +55,8 @@
     public LauncherTaskbarUIController(
             BaseQuickstepLauncher launcher, TaskbarActivityContext context) {
         mContext = context;
-        mTaskbarContainerView = context.getDragLayer();
-        mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view);
+        mTaskbarDragLayer = context.getDragLayer();
+        mTaskbarView = mTaskbarDragLayer.findViewById(R.id.taskbar_view);
 
         mLauncher = launcher;
         mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
@@ -99,7 +99,7 @@
         return new TaskbarAnimationControllerCallbacks() {
             @Override
             public void updateTaskbarBackgroundAlpha(float alpha) {
-                mTaskbarContainerView.setTaskbarBackgroundAlpha(alpha);
+                mTaskbarDragLayer.setTaskbarBackgroundAlpha(alpha);
             }
 
             @Override
@@ -109,7 +109,7 @@
 
             @Override
             public void updateImeBarVisibilityAlpha(float alpha) {
-                mTaskbarContainerView.updateImeBarVisibilityAlpha(alpha);
+                mTaskbarDragLayer.updateImeBarVisibilityAlpha(alpha);
             }
 
             @Override
@@ -202,7 +202,7 @@
     }
 
     @Override
-    protected void onImeVisible(TaskbarContainerView containerView, boolean isVisible) {
+    protected void onImeVisible(TaskbarDragLayer containerView, boolean isVisible) {
         mTaskbarAnimationController.animateToVisibilityForIme(isVisible ? 0 : 1);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 70f2788..8c3d453 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -87,7 +87,7 @@
 
     private final DeviceProfile mDeviceProfile;
     private final LayoutInflater mLayoutInflater;
-    private final TaskbarContainerView mTaskbarContainerView;
+    private final TaskbarDragLayer mDragLayer;
     private final TaskbarIconController mIconController;
     private final MyDragController mDragController;
 
@@ -123,9 +123,9 @@
         mDeviceProfile.updateIconSize(iconScale, getResources());
 
         mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
-        mTaskbarContainerView = (TaskbarContainerView) mLayoutInflater
+        mDragLayer = (TaskbarDragLayer) mLayoutInflater
                 .inflate(R.layout.taskbar, null, false);
-        mIconController = new TaskbarIconController(this, mTaskbarContainerView);
+        mIconController = new TaskbarIconController(this, mDragLayer);
         mDragController = new MyDragController(this);
 
         Display display = windowContext.getDisplay();
@@ -157,7 +157,7 @@
         );
 
         mIconController.init(mOnTaskbarIconClickListener, mOnTaskbarIconLongClickListener);
-        mWindowManager.addView(mTaskbarContainerView, mWindowLayoutParams);
+        mWindowManager.addView(mDragLayer, mWindowLayoutParams);
     }
 
     /**
@@ -168,7 +168,7 @@
             return;
         }
         mWindowLayoutParams.height = height;
-        mWindowManager.updateViewLayout(mTaskbarContainerView, mWindowLayoutParams);
+        mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
     }
 
     public boolean canShowNavButtons() {
@@ -181,8 +181,8 @@
     }
 
     @Override
-    public TaskbarContainerView getDragLayer() {
-        return mTaskbarContainerView;
+    public TaskbarDragLayer getDragLayer() {
+        return mDragLayer;
     }
 
     @Override
@@ -192,7 +192,7 @@
 
     @Override
     public Rect getFolderBoundingBox() {
-        return mTaskbarContainerView.getFolderBoundingBox();
+        return mDragLayer.getFolderBoundingBox();
     }
 
     @Override
@@ -216,15 +216,28 @@
     public void onDestroy() {
         setUIController(TaskbarUIController.DEFAULT);
         mIconController.onDestroy();
-        mWindowManager.removeViewImmediate(mTaskbarContainerView);
+        mWindowManager.removeViewImmediate(mDragLayer);
     }
 
     void onNavigationButtonClick(@TaskbarButton int buttonType) {
         mNavButtonController.onButtonClick(buttonType);
     }
 
-    public TaskbarIconController getIconController() {
-        return mIconController;
+    /**
+     * Should be called when the IME visibility changes, so we can hide/show Taskbar accordingly.
+     */
+    public void setImeIsVisible(boolean isImeVisible) {
+        mIconController.setImeIsVisible(isImeVisible);
+    }
+
+    /**
+     * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from
+     * instantiating at all, which is what's responsible for sending sysui state flags over.
+     *
+     * @param vis IME visibility flag
+     */
+    public void updateImeStatus(int displayId, int vis, boolean showImeSwitcher) {
+        mIconController.updateImeStatus(displayId, vis, showImeSwitcher);
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
similarity index 90%
rename from quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
rename to quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
index 5034791..45ec911 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
@@ -35,7 +35,7 @@
 /**
  * Top-level ViewGroup that hosts the TaskbarView as well as Views created by it such as Folder.
  */
-public class TaskbarContainerView extends BaseDragLayer<TaskbarActivityContext> {
+public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
 
     private final int mFolderMargin;
     private final Paint mTaskbarBackgroundPaint;
@@ -45,20 +45,20 @@
 
     private final OnComputeInsetsListener mTaskbarInsetsComputer = this::onComputeTaskbarInsets;
 
-    public TaskbarContainerView(@NonNull Context context) {
+    public TaskbarDragLayer(@NonNull Context context) {
         this(context, null);
     }
 
-    public TaskbarContainerView(@NonNull Context context, @Nullable AttributeSet attrs) {
+    public TaskbarDragLayer(@NonNull Context context, @Nullable AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
-    public TaskbarContainerView(@NonNull Context context, @Nullable AttributeSet attrs,
+    public TaskbarDragLayer(@NonNull Context context, @Nullable AttributeSet attrs,
             int defStyleAttr) {
         this(context, attrs, defStyleAttr, 0);
     }
 
-    public TaskbarContainerView(@NonNull Context context, @Nullable AttributeSet attrs,
+    public TaskbarDragLayer(@NonNull Context context, @Nullable AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
         super(context, attrs, 1 /* alphaChannelCount */);
         mFolderMargin = getResources().getDimensionPixelSize(R.dimen.taskbar_folder_margin);
@@ -118,7 +118,7 @@
     public void onViewRemoved(View child) {
         super.onViewRemoved(child);
         if (mControllerCallbacks != null) {
-            mControllerCallbacks.onContainerViewRemoved();
+            mControllerCallbacks.onDragLayerViewRemoved();
         }
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarIconController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarIconController.java
index 2a37915..683a5b9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarIconController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarIconController.java
@@ -41,7 +41,7 @@
     private final Rect mTempRect = new Rect();
 
     private final TaskbarActivityContext mActivity;
-    private final TaskbarContainerView mContainerView;
+    private final TaskbarDragLayer mDragLayer;
 
     private final TaskbarView mTaskbarView;
     private final ImeBarView mImeBarView;
@@ -49,15 +49,15 @@
     @NonNull
     private TaskbarUIController mUIController = TaskbarUIController.DEFAULT;
 
-    TaskbarIconController(TaskbarActivityContext activity, TaskbarContainerView containerView) {
+    TaskbarIconController(TaskbarActivityContext activity, TaskbarDragLayer dragLayer) {
         mActivity = activity;
-        mContainerView = containerView;
-        mTaskbarView = mContainerView.findViewById(R.id.taskbar_view);
-        mImeBarView = mContainerView.findViewById(R.id.ime_bar_view);
+        mDragLayer = dragLayer;
+        mTaskbarView = mDragLayer.findViewById(R.id.taskbar_view);
+        mImeBarView = mDragLayer.findViewById(R.id.ime_bar_view);
     }
 
     public void init(OnClickListener clickListener, OnLongClickListener longClickListener) {
-        mContainerView.addOnLayoutChangeListener((v, a, b, c, d, e, f, g, h) ->
+        mDragLayer.addOnLayoutChangeListener((v, a, b, c, d, e, f, g, h) ->
                 mUIController.alignRealHotseatWithTaskbar());
 
         ButtonProvider buttonProvider = new ButtonProvider(mActivity);
@@ -65,11 +65,11 @@
         mTaskbarView.construct(clickListener, longClickListener, buttonProvider);
         mTaskbarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
 
-        mContainerView.init(new Callbacks(), mTaskbarView);
+        mDragLayer.init(new Callbacks(), mTaskbarView);
     }
 
     public void onDestroy() {
-        mContainerView.onDestroy();
+        mDragLayer.onDestroy();
     }
 
     public void setUIController(@NonNull TaskbarUIController uiController) {
@@ -96,11 +96,11 @@
      */
     public void setImeIsVisible(boolean isImeVisible) {
         mTaskbarView.setTouchesEnabled(!isImeVisible);
-        mUIController.onImeVisible(mContainerView, isImeVisible);
+        mUIController.onImeVisible(mDragLayer, isImeVisible);
     }
 
     /**
-     * Callbacks for {@link TaskbarContainerView} to interact with the icon controller
+     * Callbacks for {@link TaskbarDragLayer} to interact with the icon controller
      */
     public class Callbacks {
 
@@ -109,7 +109,7 @@
          */
         public void updateInsetsTouchability(InsetsInfo insetsInfo) {
             insetsInfo.touchableRegion.setEmpty();
-            if (mContainerView.getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
+            if (mDragLayer.getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
                 // Let touches pass through us.
                 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
             } else if (mImeBarView.getVisibility() == VISIBLE) {
@@ -122,7 +122,7 @@
                 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
             } else {
                 if (mTaskbarView.mSystemButtonContainer.getVisibility() == VISIBLE) {
-                    mContainerView.getDescendantRectRelativeToSelf(
+                    mDragLayer.getDescendantRectRelativeToSelf(
                             mTaskbarView.mSystemButtonContainer, mTempRect);
                     insetsInfo.touchableRegion.set(mTempRect);
                 }
@@ -135,15 +135,15 @@
             // mTaskbarView is, since its position never changes and insets rather than overlays.
             insetsInfo.contentInsets.left = mTaskbarView.getLeft();
             insetsInfo.contentInsets.top = mTaskbarView.getTop();
-            insetsInfo.contentInsets.right = mContainerView.getWidth() - mTaskbarView.getRight();
-            insetsInfo.contentInsets.bottom = mContainerView.getHeight() - mTaskbarView.getBottom();
+            insetsInfo.contentInsets.right = mDragLayer.getWidth() - mTaskbarView.getRight();
+            insetsInfo.contentInsets.bottom = mDragLayer.getHeight() - mTaskbarView.getBottom();
         }
 
-        public void onContainerViewRemoved() {
-            int count = mContainerView.getChildCount();
+        public void onDragLayerViewRemoved() {
+            int count = mDragLayer.getChildCount();
             // Ensure no other children present (like Folders, etc)
             for (int i = 0; i < count; i++) {
-                View v = mContainerView.getChildAt(i);
+                View v = mDragLayer.getChildAt(i);
                 if (!((v instanceof TaskbarView) || (v instanceof ImeBarView))) {
                     return;
                 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 263aa11..d026bfb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -139,7 +139,7 @@
     public void onSystemUiFlagsChanged(int systemUiStateFlags) {
         boolean isImeVisible = (systemUiStateFlags & SYSUI_STATE_IME_SHOWING) != 0;
         if (mTaskbarActivityContext != null) {
-            mTaskbarActivityContext.getIconController().setImeIsVisible(isImeVisible);
+            mTaskbarActivityContext.setImeIsVisible(isImeVisible);
         }
     }
 
@@ -154,8 +154,7 @@
     public void updateImeStatus(int displayId, int vis, int backDisposition,
             boolean showImeSwitcher) {
         if (mTaskbarActivityContext != null) {
-            mTaskbarActivityContext.getIconController()
-                    .updateImeStatus(displayId, vis, showImeSwitcher);
+            mTaskbarActivityContext.updateImeStatus(displayId, vis, showImeSwitcher);
         }
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index e16f5e6..50adead 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -35,7 +35,7 @@
         return true;
     }
 
-    protected void onImeVisible(TaskbarContainerView container, boolean isVisible) {
+    protected void onImeVisible(TaskbarDragLayer container, boolean isVisible) {
         container.updateImeBarVisibilityAlpha(isVisible ? 1 : 0);
     }
 }
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java
index edd3dc3..93b3482 100644
--- a/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java
@@ -41,7 +41,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
+import java.util.Locale;
 
 /**
  * Applies spring forces to animate from a starting rect to a target rect,
@@ -353,7 +353,8 @@
 
     private Interpolator getAppCloseInterpolator(Context context) {
         ResourceProvider rp = DynamicResource.provider(context);
-        String path = String.format("M 0,0 C %f, %f, %f, %f, %f, %f C %f, %f, %f, %f, 1, 1",
+        String path = String.format(Locale.ENGLISH,
+                "M 0,0 C %f, %f, %f, %f, %f, %f C %f, %f, %f, %f, 1, 1",
                 rp.getFloat(R.dimen.c1_a),
                 rp.getFloat(R.dimen.c1_b),
                 rp.getFloat(R.dimen.c1_c),
diff --git a/res/drawable/widgets_list_bottom_ripple.xml b/res/drawable/widgets_list_bottom_ripple.xml
index 72262d4..971d6f3 100644
--- a/res/drawable/widgets_list_bottom_ripple.xml
+++ b/res/drawable/widgets_list_bottom_ripple.xml
@@ -21,6 +21,7 @@
     android:color="?android:attr/colorControlHighlight">
     <item android:id="@android:id/mask">
         <shape android:shape="rectangle">
+            <solid android:color="@color/widgets_picker_surface" />
             <corners
                 android:topLeftRadius="@dimen/widget_list_content_corner_radius"
                 android:topRightRadius="@dimen/widget_list_content_corner_radius"
diff --git a/res/drawable/widgets_list_middle_ripple.xml b/res/drawable/widgets_list_middle_ripple.xml
index 1136bea..2b77d4d 100644
--- a/res/drawable/widgets_list_middle_ripple.xml
+++ b/res/drawable/widgets_list_middle_ripple.xml
@@ -21,6 +21,7 @@
     android:color="?android:attr/colorControlHighlight">
     <item android:id="@android:id/mask">
         <shape android:shape="rectangle">
+            <solid android:color="@color/widgets_picker_surface" />
             <corners
                 android:topLeftRadius="@dimen/widget_list_content_corner_radius"
                 android:topRightRadius="@dimen/widget_list_content_corner_radius"
diff --git a/res/drawable/widgets_list_single_item_ripple.xml b/res/drawable/widgets_list_single_item_ripple.xml
index a82918e..c09944d 100644
--- a/res/drawable/widgets_list_single_item_ripple.xml
+++ b/res/drawable/widgets_list_single_item_ripple.xml
@@ -21,6 +21,7 @@
     android:color="?android:attr/colorControlHighlight">
     <item android:id="@android:id/mask">
         <shape android:shape="rectangle">
+            <solid android:color="@color/widgets_picker_surface" />
             <corners
                 android:topLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
                 android:topRightRadius="@dimen/widget_list_top_bottom_corner_radius"
diff --git a/res/drawable/widgets_list_top_ripple.xml b/res/drawable/widgets_list_top_ripple.xml
index 4ad185c..f79ab72 100644
--- a/res/drawable/widgets_list_top_ripple.xml
+++ b/res/drawable/widgets_list_top_ripple.xml
@@ -21,6 +21,7 @@
     android:color="?android:attr/colorControlHighlight">
     <item android:id="@android:id/mask">
         <shape android:shape="rectangle">
+            <solid android:color="@color/widgets_picker_surface" />
             <corners
                 android:topLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
                 android:topRightRadius="@dimen/widget_list_top_bottom_corner_radius"
diff --git a/res/layout/all_apps_personal_work_tabs.xml b/res/layout/all_apps_personal_work_tabs.xml
index 686dda8..ebb69f6 100644
--- a/res/layout/all_apps_personal_work_tabs.xml
+++ b/res/layout/all_apps_personal_work_tabs.xml
@@ -21,7 +21,6 @@
     android:layout_gravity="center_horizontal"
     android:background="@drawable/all_apps_tabs_background"
     android:orientation="horizontal"
-    android:elevation="2dp"
     style="@style/TextHeadline">
 
     <Button
diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml
index 08635c6..1859bd8 100644
--- a/res/layout/widgets_bottom_sheet.xml
+++ b/res/layout/widgets_bottom_sheet.xml
@@ -21,7 +21,6 @@
     android:layout_height="wrap_content"
     android:paddingTop="16dp"
     android:background="@drawable/widgets_bottom_sheet_background"
-    android:elevation="@dimen/deep_shortcuts_elevation"
     android:layout_gravity="bottom"
     android:theme="?attr/widgetsTheme">
 
diff --git a/res/layout/widgets_full_sheet_paged_view.xml b/res/layout/widgets_full_sheet_paged_view.xml
index 580ca49..f0ddc2b 100644
--- a/res/layout/widgets_full_sheet_paged_view.xml
+++ b/res/layout/widgets_full_sheet_paged_view.xml
@@ -21,6 +21,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:clipToPadding="false"
+        android:paddingTop="@dimen/widget_picker_view_pager_top_padding"
         android:descendantFocusability="afterDescendants"
         launcher:pageIndicator="@+id/tabs">
 
diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml
index a0a0456..278d3dc 100644
--- a/res/layout/widgets_list_row_header.xml
+++ b/res/layout/widgets_list_row_header.xml
@@ -74,6 +74,7 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
         android:layout_alignParentEnd="true"
+        android:enabled="false"
         android:clickable="false"
         android:importantForAccessibility="no"
         android:button="@drawable/widgets_tray_expand_button"/>
diff --git a/res/layout/widgets_personal_work_tabs.xml b/res/layout/widgets_personal_work_tabs.xml
index 72d83e8..15275a6 100644
--- a/res/layout/widgets_personal_work_tabs.xml
+++ b/res/layout/widgets_personal_work_tabs.xml
@@ -20,10 +20,9 @@
     android:id="@+id/tabs"
     android:layout_width="match_parent"
     android:layout_height="@dimen/all_apps_header_pill_height"
-    android:layout_marginHorizontal="16dp"
+    android:layout_marginHorizontal="32dp"
     android:orientation="horizontal"
     android:background="@drawable/all_apps_tabs_background"
-    android:elevation="2dp"
     style="@style/TextHeadline">
 
     <Button
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index bfa02c0..2882b1f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -146,6 +146,8 @@
     <dimen name="widget_picker_education_tip_width">120dp</dimen>
     <dimen name="widget_picker_education_tip_min_margin">4dp</dimen>
 
+    <dimen name="widget_picker_view_pager_top_padding">16dp</dimen>
+
     <!-- Padding applied to shortcut previews -->
     <dimen name="shortcut_preview_padding_left">0dp</dimen>
     <dimen name="shortcut_preview_padding_right">0dp</dimen>
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index af7896a..a0c598a 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -298,7 +298,7 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        if (mHeaderCollapsed && mTabLayout.getVisibility() == VISIBLE
+        if (mHeaderCollapsed && !mCollapsed && mTabLayout.getVisibility() == VISIBLE
                 && mHeaderColor != Color.TRANSPARENT) {
             mBGPaint.setColor(mHeaderColor);
             mBGPaint.setAlpha((int) (255 * mHeaderAnimator.getAnimatedFraction()));
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index 60a1732..8ca157b 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -236,6 +236,7 @@
             return;
         }
         observer.destroyed = true;
+        observer.renderer.getHostToken().unlinkToDeath(observer, 0);
         Executors.MAIN_EXECUTOR.execute(observer.renderer::destroy);
         PreviewLifecycleObserver cached = mActivePreviews.get(observer.renderer.getHostToken());
         if (cached == observer) {
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 5f014db..2a1aec8 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -45,6 +45,8 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowInsets;
+import android.view.WindowManager;
 import android.widget.TextClock;
 
 import com.android.launcher3.BubbleTextView;
@@ -56,6 +58,7 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.WorkspaceLayoutManager;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.FolderIcon;
@@ -205,10 +208,19 @@
         mIdp = idp;
         mDp = idp.getDeviceProfile(context).copy(context);
 
-        // TODO: get correct insets once display cutout API is available.
-        mInsets = new Rect();
-        mInsets.left = mInsets.right = (mDp.widthPx - mDp.availableWidthPx) / 2;
-        mInsets.top = mInsets.bottom = (mDp.heightPx - mDp.availableHeightPx) / 2;
+        if (Utilities.ATLEAST_R) {
+            WindowInsets currentWindowInsets = context.getSystemService(WindowManager.class)
+                    .getCurrentWindowMetrics().getWindowInsets();
+            mInsets = new Rect(
+                    currentWindowInsets.getSystemWindowInsetLeft(),
+                    currentWindowInsets.getSystemWindowInsetTop(),
+                    currentWindowInsets.getSystemWindowInsetRight(),
+                    currentWindowInsets.getSystemWindowInsetBottom());
+        } else {
+            mInsets = new Rect();
+            mInsets.left = mInsets.right = (mDp.widthPx - mDp.availableWidthPx) / 2;
+            mInsets.top = mInsets.bottom = (mDp.heightPx - mDp.availableHeightPx) / 2;
+        }
         mDp.updateInsets(mInsets);
 
         BaseIconFactory iconFactory =
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index 8c39eae..a8c3d15 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -32,6 +32,7 @@
 import android.view.SurfaceControlViewHost;
 import android.view.SurfaceControlViewHost.SurfacePackage;
 import android.view.View;
+import android.view.WindowManager.LayoutParams;
 import android.view.animation.AccelerateDecelerateInterpolator;
 
 import androidx.annotation.UiThread;
@@ -41,6 +42,7 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.graphics.LauncherPreviewRenderer.PreviewContext;
 import com.android.launcher3.model.BgDataModel;
 import com.android.launcher3.model.GridSizeMigrationTask;
@@ -139,6 +141,10 @@
         if (mWallpaperColors != null) {
             // Create a themed context, without affecting the main application context
             Context context = mContext.createDisplayContext(mDisplay);
+            if (Utilities.ATLEAST_R) {
+                context = context.createWindowContext(
+                        LayoutParams.TYPE_APPLICATION_OVERLAY, null);
+            }
             LocalColorExtractor.newInstance(mContext)
                     .applyColorsOverride(context, mWallpaperColors);
             inflationContext = new ContextThemeWrapper(context,
diff --git a/src/com/android/launcher3/views/ArrowTipView.java b/src/com/android/launcher3/views/ArrowTipView.java
index a6f2b42..4ee365e 100644
--- a/src/com/android/launcher3/views/ArrowTipView.java
+++ b/src/com/android/launcher3/views/ArrowTipView.java
@@ -196,7 +196,6 @@
         parent.addView(this);
         requestLayout();
 
-        post(() -> setY(yCoord - getHeight()));
         post(() -> {
             float halfWidth = getWidth() / 2f;
             float xCoord;
@@ -208,7 +207,9 @@
                 xCoord = arrowXCoord - halfWidth;
             }
             setX(xCoord);
-            findViewById(R.id.arrow).setX(arrowXCoord - xCoord);
+            setY(yCoord - getHeight());
+            View arrowView = findViewById(R.id.arrow);
+            arrowView.setX(arrowXCoord - xCoord - arrowView.getWidth() / 2f);
             requestLayout();
         });
 
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index f7e295e..e6791c3 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -26,6 +26,9 @@
 import android.view.View.OnLongClickListener;
 import android.widget.Toast;
 
+import androidx.annotation.Nullable;
+import androidx.core.view.ViewCompat;
+
 import com.android.launcher3.DragSource;
 import com.android.launcher3.DropTarget.DragObject;
 import com.android.launcher3.Launcher;
@@ -39,6 +42,7 @@
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.AbstractSlideInView;
+import com.android.launcher3.views.ArrowTipView;
 
 /**
  * Base class for various widgets popup
@@ -47,6 +51,9 @@
         implements OnClickListener, OnLongClickListener, DragSource,
         PopupDataProvider.PopupDataChangeListener {
 
+    protected static final String KEY_WIDGETS_EDUCATION_TIP_SEEN =
+            "launcher.widgets_education_tip_seen";
+
     /* Touch handling related member variables. */
     private Toast mWidgetInstructionToast;
 
@@ -196,4 +203,28 @@
         toast.show();
         return toast;
     }
+
+    /** Shows education tip on top center of {@code view} if view is laid out. */
+    @Nullable
+    protected ArrowTipView showEducationTipOnViewIfPossible(@Nullable View view) {
+        if (view == null || !ViewCompat.isLaidOut(view)) {
+            return null;
+        }
+
+        mActivityContext.getSharedPrefs().edit()
+                .putBoolean(KEY_WIDGETS_EDUCATION_TIP_SEEN, true).apply();
+        int[] coords = new int[2];
+        view.getLocationOnScreen(coords);
+        ArrowTipView arrowTipView = new ArrowTipView(mActivityContext);
+        return arrowTipView.showAtLocation(
+                getContext().getString(R.string.long_press_widget_to_add),
+                /* arrowXCoord= */coords[0] + view.getWidth() / 2,
+                /* yCoord= */coords[1]);
+    }
+
+    /** Returns {@code true} if tip has previously been shown on any of {@link BaseWidgetSheet}. */
+    protected boolean hasSeenEducationTip() {
+        return mActivityContext.getSharedPrefs().getBoolean(KEY_WIDGETS_EDUCATION_TIP_SEEN, false)
+                || Utilities.IS_RUNNING_IN_TEST_HARNESS;
+    }
 }
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 787a2d1..81df100 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -68,12 +68,43 @@
             };
 
     private static final int DEFAULT_CLOSE_DURATION = 200;
+    private static final long EDUCATION_TIP_DELAY_MS = 300;
+
     private ItemInfo mOriginalItemInfo;
     private Rect mInsets;
     private final int mMaxTableHeight;
     private int mMaxHorizontalSpan = 4;
     private Configuration mCurrentConfiguration;
 
+    private final OnLayoutChangeListener mLayoutChangeListenerToShowTips =
+            new OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                    if (hasSeenEducationTip()) {
+                        removeOnLayoutChangeListener(this);
+                        return;
+                    }
+                    // Widgets are loaded asynchronously, We are adding a delay because we only want
+                    // to show the tip when the widget preview has finished loading and rendering in
+                    // this view.
+                    removeCallbacks(mShowEducationTipTask);
+                    postDelayed(mShowEducationTipTask, EDUCATION_TIP_DELAY_MS);
+                }
+            };
+
+    private final Runnable mShowEducationTipTask = () -> {
+        if (hasSeenEducationTip()) {
+            removeOnLayoutChangeListener(mLayoutChangeListenerToShowTips);
+            return;
+        }
+        View viewForTip = ((ViewGroup) ((TableLayout) findViewById(R.id.widgets_table))
+                                    .getChildAt(0)).getChildAt(0);
+        if (showEducationTipOnViewIfPossible(viewForTip) != null) {
+            removeOnLayoutChangeListener(mLayoutChangeListenerToShowTips);
+        }
+    };
+
     public WidgetsBottomSheet(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -88,6 +119,9 @@
         // take over the entire view vertically.
         mMaxTableHeight = deviceProfile.inv.numRows * 2 / 3  * deviceProfile.cellHeightPx;
         mCurrentConfiguration = new Configuration(getResources().getConfiguration());
+        if (!hasSeenEducationTip()) {
+            addOnLayoutChangeListener(mLayoutChangeListenerToShowTips);
+        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 039cad8..c09beb6 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -41,7 +41,6 @@
 
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
-import androidx.core.view.ViewCompat;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.launcher3.DeviceProfile;
@@ -49,11 +48,9 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.compat.AccessibilityManagerCompat;
 import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.views.ArrowTipView;
 import com.android.launcher3.views.RecyclerViewFastScroller;
 import com.android.launcher3.views.TopRoundedCornerView;
 import com.android.launcher3.widget.BaseWidgetSheet;
@@ -86,7 +83,6 @@
     // resolution or landscape on phone. This ratio defines the max percentage of content area that
     // the table can display.
     private static final float RECOMMENDATION_TABLE_HEIGHT_RATIO = 0.75f;
-    private static final String WIDGETS_EDUCATION_TIP_SEEN = "launcher.widgets_education_tip_seen";
 
     private final Rect mInsets = new Rect();
     private final boolean mHasWorkProfile;
@@ -120,12 +116,12 @@
             return;
         }
         View viewForTip = getViewToShowEducationTip();
-        if (viewForTip != null && ViewCompat.isLaidOut(viewForTip)) {
+        if (showEducationTipOnViewIfPossible(viewForTip) != null) {
             removeOnLayoutChangeListener(mLayoutChangeListenerToShowTips);
-            showEducationTipOnView(viewForTip);
         }
     };
     private final int mTabsHeight;
+    private final int mViewPagerTopPadding;
     private final int mWidgetCellHorizontalPadding;
 
     @Nullable private WidgetsRecyclerView mCurrentWidgetsRecyclerView;
@@ -148,6 +144,10 @@
                 ? getContext().getResources()
                         .getDimensionPixelSize(R.dimen.all_apps_header_pill_height)
                 : 0;
+        mViewPagerTopPadding = mHasWorkProfile
+                ? getContext().getResources()
+                    .getDimensionPixelSize(R.dimen.widget_picker_view_pager_top_padding)
+                : 0;
         mWidgetCellHorizontalPadding = 2 * getResources().getDimensionPixelOffset(
                 R.dimen.widget_cell_horizontal_padding);
     }
@@ -499,8 +499,8 @@
                 noWidgetsViewHeight = noWidgetsViewTextBounds.height();
             }
             float maxTableHeight = (mActivityContext.getDeviceProfile().availableHeightPx
-                                        - mTabsHeight - getHeaderViewHeight() - noWidgetsViewHeight)
-                                                * RECOMMENDATION_TABLE_HEIGHT_RATIO;
+                    - mTabsHeight - mViewPagerTopPadding - getHeaderViewHeight()
+                    - noWidgetsViewHeight) * RECOMMENDATION_TABLE_HEIGHT_RATIO;
 
             List<ArrayList<WidgetItem>> recommendedWidgetsInTable =
                     WidgetsTableUtils.groupWidgetItemsIntoTable(recommendedWidgets,
@@ -605,7 +605,7 @@
         return measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mCollapseHandle)
                 + measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mHeaderTitle)
                 + measureHeightWithVerticalMargins(
-                (View) mSearchAndRecommendationViewHolder.mSearchBar);
+                        (View) mSearchAndRecommendationViewHolder.mSearchBarContainer);
     }
 
     /** private the height, in pixel, + the vertical margins of a given view. */
@@ -641,18 +641,6 @@
         getWindowInsetsController().hide(WindowInsets.Type.ime());
     }
 
-    private void showEducationTipOnView(View view) {
-        mActivityContext.getSharedPrefs().edit()
-                .putBoolean(WIDGETS_EDUCATION_TIP_SEEN, true).apply();
-        int[] coords = new int[2];
-        view.getLocationOnScreen(coords);
-        ArrowTipView arrowTipView = new ArrowTipView(mActivityContext);
-        arrowTipView.showAtLocation(
-                getContext().getString(R.string.long_press_widget_to_add),
-                /* arrowXCoord= */coords[0] + view.getWidth() / 2,
-                /* yCoord= */coords[1]);
-    }
-
     @Nullable private View getViewToShowEducationTip() {
         if (mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.getVisibility() == VISIBLE
                 && mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.getChildCount() > 0
@@ -681,11 +669,6 @@
         return null;
     }
 
-    private boolean hasSeenEducationTip() {
-        return mActivityContext.getSharedPrefs().getBoolean(WIDGETS_EDUCATION_TIP_SEEN, false)
-                || Utilities.IS_RUNNING_IN_TEST_HARNESS;
-    }
-
     /** A holder class for holding adapters & their corresponding recycler view. */
     private final class AdapterHolder {
         static final int PRIMARY = 0;
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 57f40db..4cf52f0 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -496,13 +496,14 @@
     private void fail(String message) {
         checkForAnomaly();
         Assert.fail(formatSystemHealthMessage(formatErrorWithEvents(
-                "http://go/tapl test failure:\nOverview: " + getContextDescription()
+                "http://go/tapl test failure:\nSummary: " + getContextDescription()
                         + " - visible state is " + getVisibleStateMessage()
                         + ";\nDetails: " + message, true)));
     }
 
     private String getContextDescription() {
-        return mDiagnosticContext.isEmpty() ? "" : String.join(", ", mDiagnosticContext);
+        return mDiagnosticContext.isEmpty()
+                ? "(no context)" : String.join(", ", mDiagnosticContext);
     }
 
     void assertTrue(String message, boolean condition) {