Merge "Fix jank when launching the All set page on devices that support vibrations" into tm-dev
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 95c67dd..7c1e152 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -388,34 +388,34 @@
         mInsets.set(insets);
         DeviceProfile grid = mActivityContext.getDeviceProfile();
 
-        for (int i = 0; i < mAH.size(); i++) {
-            mAH.get(i).mPadding.bottom = insets.bottom;
-            mAH.get(i).mPadding.left = mAH.get(i).mPadding.right = grid.allAppsLeftRightPadding;
-            mAH.get(i).applyPadding();
-        }
+        applyAdapterPaddings(grid);
 
         MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
-        int leftRightMargin = grid.allAppsLeftRightMargin;
-        mlp.leftMargin = insets.left + leftRightMargin;
-        mlp.rightMargin = insets.right + leftRightMargin;
+        mlp.leftMargin = insets.left;
+        mlp.rightMargin = insets.right;
         setLayoutParams(mlp);
 
         if (grid.isVerticalBarLayout()) {
             setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
         } else {
-            setPadding(0, grid.allAppsTopPadding, 0, 0);
+            setPadding(grid.allAppsLeftRightMargin, grid.allAppsTopPadding,
+                    grid.allAppsLeftRightMargin, 0);
         }
 
         InsettableFrameLayout.dispatchInsets(this, insets);
     }
 
+    /**
+     * Returns a padding in case a scrim is shown on the bottom of the view and a padding is needed.
+     */
+    protected int getNavBarScrimHeight(WindowInsets insets) {
+        return 0;
+    }
+
     @Override
     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
-        if (Utilities.ATLEAST_Q) {
-            mNavBarScrimHeight = insets.getTappableElementInsets().bottom;
-        } else {
-            mNavBarScrimHeight = insets.getStableInsetBottom();
-        }
+        mNavBarScrimHeight = getNavBarScrimHeight(insets);
+        applyAdapterPaddings(mActivityContext.getDeviceProfile());
         return super.dispatchApplyWindowInsets(insets);
     }
 
@@ -483,6 +483,15 @@
         mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
     }
 
+    private void applyAdapterPaddings(DeviceProfile grid) {
+        int bottomPadding = Math.max(mInsets.bottom, mNavBarScrimHeight);
+        for (int i = 0; i < mAH.size(); i++) {
+            mAH.get(i).mPadding.bottom = bottomPadding;
+            mAH.get(i).mPadding.left = mAH.get(i).mPadding.right = grid.allAppsLeftRightPadding;
+            mAH.get(i).applyPadding();
+        }
+    }
+
     private void setDeviceManagementResources() {
         if (mActivityContext.getStringCache() != null) {
             Button personalTab = findViewById(R.id.tab_personal);
diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
index 8601819..20f5e74 100644
--- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
@@ -18,9 +18,11 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
+import android.view.WindowInsets;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.Utilities;
 
 /**
  * AllAppsContainerView with launcher specific callbacks
@@ -58,4 +60,13 @@
         }
         return super.onTouchEvent(ev);
     }
+
+    @Override
+    protected int getNavBarScrimHeight(WindowInsets insets) {
+        if (Utilities.ATLEAST_Q) {
+            return insets.getTappableElementInsets().bottom;
+        } else {
+            return insets.getStableInsetBottom();
+        }
+    }
 }
diff --git a/src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java b/src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java
index d2d569f..9442734 100644
--- a/src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java
@@ -18,7 +18,6 @@
 
 import static com.android.launcher3.Utilities.ATLEAST_R;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
-import static com.android.launcher3.widget.BaseWidgetSheet.MAX_WIDTH_SCALE_FOR_LARGER_SCREEN;
 
 import android.animation.PropertyValuesHolder;
 import android.annotation.SuppressLint;
@@ -106,7 +105,10 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
         int widthUsed;
-        if (mInsets.bottom > 0) {
+        if (deviceProfile.isTablet) {
+            int margin = deviceProfile.allAppsLeftRightMargin;
+            widthUsed = Math.max(2 * margin, 2 * (mInsets.left + mInsets.right));
+        } else if (mInsets.bottom > 0) {
             widthUsed = mInsets.left + mInsets.right;
         } else {
             Rect padding = deviceProfile.workspacePadding;
@@ -114,18 +116,8 @@
                     2 * (mInsets.left + mInsets.right));
         }
 
-        if (deviceProfile.isTablet || deviceProfile.isTwoPanels) {
-            // In large screen devices, we restrict the width of the widgets picker to show part of
-            // the home screen. Let's ensure the minimum width used is at least the minimum width
-            // that isn't taken by the widgets picker.
-            int minUsedWidth = (int) (deviceProfile.availableWidthPx
-                    * (1 - MAX_WIDTH_SCALE_FOR_LARGER_SCREEN));
-            widthUsed = Math.max(widthUsed, minUsedWidth);
-        }
-
-        int heightUsed = mInsets.top + deviceProfile.edgeMarginPx;
         measureChildWithMargins(mContent, widthMeasureSpec,
-                widthUsed, heightMeasureSpec, heightUsed);
+                widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
         setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
                 MeasureSpec.getSize(heightMeasureSpec));
     }
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index c7bb612..1bcba14 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -16,6 +16,8 @@
 package com.android.launcher3.widget;
 
 import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.AttributeSet;
@@ -23,6 +25,7 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnLongClickListener;
+import android.view.WindowInsets;
 import android.widget.Toast;
 
 import androidx.annotation.GuardedBy;
@@ -43,6 +46,7 @@
 import com.android.launcher3.touch.ItemLongClickListener;
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.window.WindowManagerProxy;
 import com.android.launcher3.views.AbstractSlideInView;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.ArrowTipView;
@@ -55,11 +59,6 @@
         PopupDataProvider.PopupDataChangeListener, Insettable {
     /** The default number of cells that can fit horizontally in a widget sheet. */
     protected static final int DEFAULT_MAX_HORIZONTAL_SPANS = 4;
-    /**
-     * The maximum scale, [0, 1], of the device screen width that the widgets picker can consume
-     * on large screen devices.
-     */
-    protected static final float MAX_WIDTH_SCALE_FOR_LARGER_SCREEN = 0.89f;
 
     protected static final String KEY_WIDGETS_EDUCATION_TIP_SEEN =
             "launcher.widgets_education_tip_seen";
@@ -70,10 +69,15 @@
 
     private int mContentHorizontalMarginInPx;
 
+    protected int mNavBarScrimHeight;
+    private final Paint mNavBarScrimPaint;
+
     public BaseWidgetSheet(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         mContentHorizontalMarginInPx = getResources().getDimensionPixelSize(
                 R.dimen.widget_list_horizontal_margin);
+        mNavBarScrimPaint = new Paint();
+        mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
     }
 
     protected int getScrimColor(Context context) {
@@ -83,6 +87,9 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
+        WindowInsets windowInsets = WindowManagerProxy.INSTANCE.get(getContext())
+                .normalizeWindowInsets(getContext(), getRootWindowInsets(), new Rect());
+        mNavBarScrimHeight = getNavBarScrimHeight(windowInsets);
         mActivityContext.getPopupDataProvider().setChangeListener(this);
     }
 
@@ -136,6 +143,30 @@
         }
     }
 
+    private int getNavBarScrimHeight(WindowInsets insets) {
+        if (Utilities.ATLEAST_Q) {
+            return insets.getTappableElementInsets().bottom;
+        } else {
+            return insets.getStableInsetBottom();
+        }
+    }
+
+    @Override
+    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        mNavBarScrimHeight = getNavBarScrimHeight(insets);
+        return super.onApplyWindowInsets(insets);
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+
+        if (mNavBarScrimHeight > 0) {
+            canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(),
+                    mNavBarScrimPaint);
+        }
+    }
+
     /** Called when the horizontal margin of the content view has changed. */
     protected abstract void onContentHorizontalMarginChanged(int contentHorizontalMarginInPx);
 
@@ -147,7 +178,10 @@
     protected void doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
         int widthUsed;
-        if (mInsets.bottom > 0) {
+        if (deviceProfile.isTablet) {
+            int margin = deviceProfile.allAppsLeftRightMargin;
+            widthUsed = Math.max(2 * margin, 2 * (mInsets.left + mInsets.right));
+        } else if (mInsets.bottom > 0) {
             widthUsed = mInsets.left + mInsets.right;
         } else {
             Rect padding = deviceProfile.workspacePadding;
@@ -155,15 +189,6 @@
                     2 * (mInsets.left + mInsets.right));
         }
 
-        if (deviceProfile.isTablet || deviceProfile.isTwoPanels) {
-            // In large screen devices, we restrict the width of the widgets picker to show part of
-            // the home screen. Let's ensure the minimum width used is at least the minimum width
-            // that isn't taken by the widgets picker.
-            int minUsedWidth = (int) (deviceProfile.availableWidthPx
-                    * (1 - MAX_WIDTH_SCALE_FOR_LARGER_SCREEN));
-            widthUsed = Math.max(widthUsed, minUsedWidth);
-        }
-
         measureChildWithMargins(mContent, widthMeasureSpec,
                 widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
         setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index b152ddc..bf521cc 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -247,10 +247,12 @@
     @Override
     public void setInsets(Rect insets) {
         super.setInsets(insets);
+        int bottomPadding = Math.max(insets.bottom, mNavBarScrimHeight);
 
         mContent.setPadding(mContent.getPaddingStart(),
-                mContent.getPaddingTop(), mContent.getPaddingEnd(), insets.bottom);
-        if (insets.bottom > 0) {
+                mContent.getPaddingTop(), mContent.getPaddingEnd(),
+                bottomPadding);
+        if (bottomPadding > 0) {
             setupNavBarColor();
         } else {
             clearNavBarColor();
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 341cb5c..a49cdc0 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -328,15 +328,15 @@
     @Override
     public void setInsets(Rect insets) {
         super.setInsets(insets);
-
-        setBottomPadding(mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView, insets.bottom);
-        setBottomPadding(mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView, insets.bottom);
+        int bottomPadding = Math.max(insets.bottom, mNavBarScrimHeight);
+        setBottomPadding(mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView, bottomPadding);
+        setBottomPadding(mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView, bottomPadding);
         if (mHasWorkProfile) {
-            setBottomPadding(mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView, insets.bottom);
+            setBottomPadding(mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView, bottomPadding);
         }
-        ((MarginLayoutParams) mNoWidgetsView.getLayoutParams()).bottomMargin = insets.bottom;
+        ((MarginLayoutParams) mNoWidgetsView.getLayoutParams()).bottomMargin = bottomPadding;
 
-        if (insets.bottom > 0) {
+        if (bottomPadding > 0) {
             setupNavBarColor();
         } else {
             clearNavBarColor();