Merge "Folder icon polish." into sc-dev am: 46378eb881

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/15339889

Change-Id: If24654967e2ddc5e8672ae00776ef65f322a4c70
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 88e8171..5a3e7dd 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -22,6 +22,7 @@
 import static com.android.launcher3.ResourceUtils.pxFromDp;
 import static com.android.launcher3.Utilities.dpiFromPx;
 import static com.android.launcher3.Utilities.pxFromSp;
+import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
 import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
 
 import android.annotation.SuppressLint;
@@ -394,7 +395,8 @@
     }
 
     private void updateHotseatIconSize(int hotseatIconSizePx) {
-        hotseatCellHeightPx = hotseatIconSizePx;
+        // Ensure there is enough space for folder icons, which have a slightly larger radius.
+        hotseatCellHeightPx = (int) Math.ceil(hotseatIconSizePx * ICON_OVERLAP_FACTOR);
         if (isVerticalBarLayout()) {
             hotseatBarSizePx = hotseatIconSizePx + hotseatBarSidePaddingStartPx
                     + hotseatBarSidePaddingEndPx;
@@ -473,7 +475,7 @@
         if (workspaceCellPaddingY < iconTextHeight) {
             iconTextSizePx = 0;
             iconDrawablePaddingPx = 0;
-            cellHeightPx = iconSizePx;
+            cellHeightPx = (int) Math.ceil(iconSizePx * ICON_OVERLAP_FACTOR);
             autoResizeAllAppsCells();
         }
     }
@@ -560,7 +562,8 @@
             desiredWorkspaceLeftRightMarginPx = (int) (desiredWorkspaceLeftRightOriginalPx * scale);
         } else {
             cellWidthPx = iconSizePx + iconDrawablePaddingPx;
-            cellHeightPx = iconSizePx + iconDrawablePaddingPx
+            cellHeightPx = (int) Math.ceil(iconSizePx * ICON_OVERLAP_FACTOR)
+                    + iconDrawablePaddingPx
                     + Utilities.calculateTextHeight(iconTextSizePx);
             int cellPaddingY = (getCellSize().y - cellHeightPx) / 2;
             if (iconDrawablePaddingPx > cellPaddingY && !isVerticalLayout
@@ -844,14 +847,16 @@
         return isVerticalBarLayout();
     }
 
-    public int getCellHeight(@ContainerType int containerType) {
+    public int getCellContentHeight(@ContainerType int containerType) {
         switch (containerType) {
             case CellLayout.WORKSPACE:
                 return cellHeightPx;
             case CellLayout.FOLDER:
                 return folderCellHeightPx;
             case CellLayout.HOTSEAT:
-                return hotseatCellHeightPx;
+                // The hotseat is the only container where the cell height is going to be
+                // different from the content within that cell.
+                return iconSizePx;
             default:
                 // ??
                 return 0;
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 42b4e89..0a6f06c 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -207,8 +207,8 @@
                 ? dp.workspacePadding.bottom
                 : dp.hotseatBarSizePx - dp.hotseatCellHeightPx - mQsbHeight;
 
-        if (dp.isScalableGrid && dp.qsbBottomMarginPx <= freeSpace) {
-            return dp.qsbBottomMarginPx;
+        if (dp.isScalableGrid) {
+            return Math.min(dp.qsbBottomMarginPx, freeSpace);
         } else {
             return (int) (freeSpace * QSB_CENTER_FACTOR) + (dp.isTaskbarPresent
                     ? dp.taskbarSize
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 2a5187d..519b63d 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -122,7 +122,7 @@
 
     public int getCellContentHeight() {
         return Math.min(getMeasuredHeight(),
-                mActivity.getDeviceProfile().getCellHeight(mContainerType));
+                mActivity.getDeviceProfile().getCellContentHeight(mContainerType));
     }
 
     public void measureChild(View child) {
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
index ea1fbdb..98c0cfc 100644
--- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -21,11 +21,11 @@
 import android.annotation.TargetApi;
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
+import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.util.Log;
@@ -129,10 +129,19 @@
                     canvas.restore();
                 });
 
+        Bitmap bgBitmap = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
+                (canvas) -> {
+                    Paint p = new Paint();
+                    p.setColor(bg.getBgColor());
+
+                    canvas.drawCircle(dragViewSize.x / 2f, dragViewSize.y / 2f, bg.getRadius(), p);
+                });
+
         ShiftedBitmapDrawable badge = new ShiftedBitmapDrawable(badgeBmp, 0, 0);
         ShiftedBitmapDrawable foreground = new ShiftedBitmapDrawable(previewBitmap, 0, 0);
+        ShiftedBitmapDrawable background = new ShiftedBitmapDrawable(bgBitmap, 0, 0);
 
-        return new FolderAdaptiveIcon(new ColorDrawable(bg.getBgColor()), foreground, badge, mask);
+        return new FolderAdaptiveIcon(background, foreground, badge, mask);
     }
 
     @Override
diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
index 54967a99..8cd91d3 100644
--- a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
@@ -7,7 +7,9 @@
 
     private static final float MIN_SCALE = 0.44f;
     private static final float MAX_SCALE = 0.51f;
-    private static final float MAX_RADIUS_DILATION = 0.1f;
+    private static final float MAX_RADIUS_DILATION = 0.25f;
+    // The max amount of overlap the preview items can go outside of the background bounds.
+    public static final float ICON_OVERLAP_FACTOR = 1 + (MAX_RADIUS_DILATION / 2f);
     private static final float ITEM_RADIUS_SCALE_FACTOR = 1.15f;
 
     public static final int EXIT_INDEX = -2;
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index e704957..96030f9 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.folder;
 
+import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
 import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_AUTO_LABELED;
@@ -236,6 +237,8 @@
     public void getPreviewBounds(Rect outBounds) {
         mPreviewItemManager.recomputePreviewDrawingParams();
         mBackground.getBounds(outBounds);
+        // The preview items go outside of the bounds of the background.
+        Utilities.scaleRectAboutCenter(outBounds, ICON_OVERLAP_FACTOR);
     }
 
     public float getBackgroundStrokeWidth() {
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index 460521f..18d0b10 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.folder;
 
+import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
 import static com.android.launcher3.graphics.IconShape.getShape;
 import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
@@ -186,7 +187,7 @@
         outBounds.set(left, top, right, bottom);
     }
 
-    int getRadius() {
+    public int getRadius() {
         return previewSize / 2;
     }
 
@@ -348,7 +349,12 @@
 
     public Path getClipPath() {
         mPath.reset();
-        getShape().addToPath(mPath, getOffsetX(), getOffsetY(), getScaledRadius());
+        float radius = getScaledRadius() * ICON_OVERLAP_FACTOR;
+        // Find the difference in radius so that the clip path remains centered.
+        float radiusDifference = radius - getRadius();
+        float offsetX = basePreviewOffsetX - radiusDifference;
+        float offsetY = basePreviewOffsetY - radiusDifference;
+        getShape().addToPath(mPath, offsetX, offsetY, radius);
         return mPath;
     }