Add a scrim to AllApps and Widgets

Check the size of the scrim and draw on the bottom of AllApps and Widgets.
Add a padding to the bottom of AllApps and Widgets so content is above the scrim.
Change the color of nav buttons for better accessibility.
Correct width of the Widgets sheets to be the same as AllApps sheet.

Fixes: 221107977
Fixes: 214215594
Test: manual, HSV and Window
Change-Id: Ib7510ffcd80231de7fefcdef65b422174dd74593
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 72ca5a7..103bb6d 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -387,34 +387,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);
     }
 
@@ -478,6 +478,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();