Removing some dependency on icon shape

Bug: 183641907
Test: Manual
Change-Id: Ifd492a850bb9918ad378385abe544362e34e70b0
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index b4aa596..5ba1fe1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -15,12 +15,11 @@
  */
 package com.android.launcher3.uioverrides;
 
-import static com.android.launcher3.graphics.IconShape.getShape;
-
 import android.content.Context;
 import android.graphics.BlurMaskFilter;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Rect;
@@ -37,6 +36,7 @@
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.graphics.IconPalette;
+import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.IconNormalizer;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -58,9 +58,13 @@
     private final DeviceProfile mDeviceProfile;
     private final Paint mIconRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final Path mRingPath = new Path();
-    private boolean mIsPinned = false;
-    private final int mNormalizedIconRadius;
+    private final int mNormalizedIconSize;
+    private final Path mShapePath;
+    private final Matrix mTmpMatrix = new Matrix();
+
     private final BlurMaskFilter mShadowFilter;
+
+    private boolean mIsPinned = false;
     private int mPlateColor;
     boolean mDrawForDrag = false;
 
@@ -75,24 +79,18 @@
     public PredictedAppIcon(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         mDeviceProfile = ActivityContext.lookupContext(context).getDeviceProfile();
-        mNormalizedIconRadius = IconNormalizer.getNormalizedCircleSize(getIconSize()) / 2;
+        mNormalizedIconSize = IconNormalizer.getNormalizedCircleSize(getIconSize());
         int shadowSize = context.getResources().getDimensionPixelSize(
                 R.dimen.blur_size_thin_outline);
         mShadowFilter = new BlurMaskFilter(shadowSize, BlurMaskFilter.Blur.OUTER);
+        mShapePath = GraphicsUtils.getShapePath(mNormalizedIconSize);
     }
 
     @Override
     public void onDraw(Canvas canvas) {
         int count = canvas.save();
         if (!mIsPinned) {
-            boolean isBadged = false;
-            if (getTag() instanceof WorkspaceItemInfo) {
-                WorkspaceItemInfo info = (WorkspaceItemInfo) getTag();
-                isBadged = !Process.myUserHandle().equals(info.user)
-                        || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
-                        || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
-            }
-            drawEffect(canvas, isBadged);
+            drawEffect(canvas);
             canvas.translate(getWidth() * RING_EFFECT_RATIO, getHeight() * RING_EFFECT_RATIO);
             canvas.scale(1 - 2 * RING_EFFECT_RATIO, 1 - 2 * RING_EFFECT_RATIO);
         }
@@ -161,33 +159,58 @@
     }
 
     private int getOutlineOffsetX() {
-        return (getMeasuredWidth() / 2) - mNormalizedIconRadius;
+        return (getMeasuredWidth() - mNormalizedIconSize) / 2;
     }
 
     private int getOutlineOffsetY() {
         if (mDisplay != DISPLAY_TASKBAR) {
             return getPaddingTop() + mDeviceProfile.folderIconOffsetYPx;
         }
-        return (getMeasuredHeight() / 2) - mNormalizedIconRadius;
+        return (getMeasuredHeight() - mNormalizedIconSize) / 2;
     }
 
-    private void drawEffect(Canvas canvas, boolean isBadged) {
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        updateRingPath();
+    }
+
+    @Override
+    public void setTag(Object tag) {
+        super.setTag(tag);
+        updateRingPath();
+    }
+
+    private void updateRingPath() {
+        boolean isBadged = false;
+        if (getTag() instanceof WorkspaceItemInfo) {
+            WorkspaceItemInfo info = (WorkspaceItemInfo) getTag();
+            isBadged = !Process.myUserHandle().equals(info.user)
+                    || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
+                    || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
+        }
+
+        mRingPath.reset();
+        mTmpMatrix.setTranslate(getOutlineOffsetX(), getOutlineOffsetY());
+
+        mRingPath.addPath(mShapePath, mTmpMatrix);
+        if (isBadged) {
+            float outlineSize = mNormalizedIconSize * RING_EFFECT_RATIO;
+            float iconSize = getIconSize() * (1 - 2 * RING_EFFECT_RATIO);
+            float badgeSize = LauncherIcons.getBadgeSizeForIconSize((int) iconSize) + outlineSize;
+            float scale = badgeSize / mNormalizedIconSize;
+            mTmpMatrix.postTranslate(mNormalizedIconSize, mNormalizedIconSize);
+            mTmpMatrix.preScale(scale, scale);
+            mTmpMatrix.preTranslate(-mNormalizedIconSize, -mNormalizedIconSize);
+            mRingPath.addPath(mShapePath, mTmpMatrix);
+        }
+    }
+
+    private void drawEffect(Canvas canvas) {
         // Don't draw ring effect if item is about to be dragged.
         if (mDrawForDrag) {
             return;
         }
-        mRingPath.reset();
-        getShape().addToPath(mRingPath, getOutlineOffsetX(), getOutlineOffsetY(),
-                mNormalizedIconRadius);
-        if (isBadged) {
-            float outlineSize = mNormalizedIconRadius * RING_EFFECT_RATIO * 2;
-            float iconSize = getIconSize() * (1 - 2 * RING_EFFECT_RATIO);
-            float badgeSize = LauncherIcons.getBadgeSizeForIconSize((int) iconSize) + outlineSize;
-            float badgeInset = mNormalizedIconRadius * 2 - badgeSize;
-            getShape().addToPath(mRingPath, getOutlineOffsetX() + badgeInset,
-                    getOutlineOffsetY() + badgeInset, badgeSize / 2);
-
-        }
         mIconRingPaint.setColor(RING_SHADOW_COLOR);
         mIconRingPaint.setMaskFilter(mShadowFilter);
         canvas.drawPath(mRingPath, mIconRingPaint);
@@ -249,8 +272,10 @@
          */
         @Override
         public void drawUnderItem(Canvas canvas) {
-            getShape().drawShape(canvas, mIcon.getOutlineOffsetX(), mIcon.getOutlineOffsetY(),
-                    mIcon.mNormalizedIconRadius, mOutlinePaint);
+            canvas.save();
+            canvas.translate(mIcon.getOutlineOffsetX(), mIcon.getOutlineOffsetY());
+            canvas.drawPath(mIcon.mShapePath, mOutlinePaint);
+            canvas.restore();
         }
 
         /**
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index d333b49..2ace796 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3;
 
-import static com.android.launcher3.graphics.IconShape.getShape;
 import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
 import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
@@ -26,16 +25,13 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
-import android.graphics.BlurMaskFilter;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.Path;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.Process;
 import android.text.TextUtils.TruncateAt;
 import android.util.AttributeSet;
 import android.util.Property;
@@ -50,7 +46,6 @@
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.dragndrop.DraggableView;
 import com.android.launcher3.folder.FolderIcon;
@@ -60,7 +55,6 @@
 import com.android.launcher3.icons.DotRenderer;
 import com.android.launcher3.icons.FastBitmapDrawable;
 import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
-import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.icons.PlaceHolderIconDrawable;
 import com.android.launcher3.icons.cache.HandlerRunnable;
 import com.android.launcher3.model.data.AppInfo;
@@ -97,11 +91,6 @@
 
     private float mScaleForReorderBounce = 1f;
 
-    protected final Paint mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-    private final Path mHighlightPath = new Path();
-    protected int mHighlightColor = Color.TRANSPARENT;
-    private final BlurMaskFilter mHighlightShadowFilter;
-
     private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
             = new Property<BubbleTextView, Float>(Float.TYPE, "dotScale") {
         @Override
@@ -220,10 +209,6 @@
         setEllipsize(TruncateAt.END);
         setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
         setTextAlpha(1f);
-
-        int shadowSize = context.getResources().getDimensionPixelSize(
-                R.dimen.blur_size_click_shadow);
-        mHighlightShadowFilter = new BlurMaskFilter(shadowSize, BlurMaskFilter.Blur.INNER);
     }
 
     @Override
@@ -451,41 +436,10 @@
 
     @Override
     public void onDraw(Canvas canvas) {
-        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && mHighlightColor != Color.TRANSPARENT) {
-            int count = canvas.save();
-            drawFocusHighlight(canvas);
-            canvas.restoreToCount(count);
-        }
         super.onDraw(canvas);
         drawDotIfNecessary(canvas);
     }
 
-    protected void drawFocusHighlight(Canvas canvas) {
-        boolean isBadged = getTag() instanceof ItemInfo && !Process.myUserHandle().equals(
-                ((ItemInfo) getTag()).user);
-        float insetScale = (HIGHLIGHT_SCALE - 1) / 2;
-        canvas.translate(-getIconSize() * insetScale, -insetScale * getIconSize());
-        float outlineSize = getIconSize() * HIGHLIGHT_SCALE;
-        mHighlightPath.reset();
-        mHighlightPaint.reset();
-        getIconBounds(mDotParams.iconBounds);
-        getShape().addToPath(mHighlightPath, mDotParams.iconBounds.left, mDotParams.iconBounds.top,
-                outlineSize / 2);
-        if (isBadged) {
-            float borderSize = outlineSize - getIconSize();
-            float badgeSize = LauncherIcons.getBadgeSizeForIconSize(getIconSize()) + borderSize;
-            float badgeInset = outlineSize - badgeSize;
-            getShape().addToPath(mHighlightPath, mDotParams.iconBounds.left + badgeInset,
-                    mDotParams.iconBounds.top + badgeInset, badgeSize / 2);
-        }
-        mHighlightPaint.setMaskFilter(mHighlightShadowFilter);
-        mHighlightPaint.setColor(mDotParams.color);
-        canvas.drawPath(mHighlightPath, mHighlightPaint);
-        mHighlightPaint.setMaskFilter(null);
-        mHighlightPaint.setColor(mHighlightColor);
-        canvas.drawPath(mHighlightPath, mHighlightPaint);
-    }
-
     /**
      * Draws the notification dot in the top right corner of the icon bounds.
      *
@@ -921,11 +875,9 @@
 
     @Override
     public SafeCloseable prepareDrawDragView() {
-        int highlightColor = mHighlightColor;
-        mHighlightColor = Color.TRANSPARENT;
         resetIconScale();
         setForceHideDot(true);
-        return () -> mHighlightColor = highlightColor;
+        return () -> { };
     }
 
     private void resetIconScale() {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index aea38a0..e17ef29 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
@@ -32,8 +33,8 @@
 import com.android.launcher3.CellLayout.ContainerType;
 import com.android.launcher3.DevicePaddings.DevicePadding;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.graphics.IconShape;
 import com.android.launcher3.icons.DotRenderer;
+import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.IconNormalizer;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.Info;
@@ -46,6 +47,7 @@
     private static final float TABLET_MIN_DPS = 600;
     private static final float LARGE_TABLET_MIN_DPS = 720;
 
+    private static final int DEFAULT_DOT_SIZE = 100;
 
     public final InvariantDeviceProfile inv;
     private final Info mInfo;
@@ -351,11 +353,10 @@
         updateWorkspacePadding();
 
         // This is done last, after iconSizePx is calculated above.
-        mDotRendererWorkSpace = new DotRenderer(iconSizePx, IconShape.getShapePath(),
-                IconShape.DEFAULT_PATH_SIZE);
+        Path dotPath = GraphicsUtils.getShapePath(DEFAULT_DOT_SIZE);
+        mDotRendererWorkSpace = new DotRenderer(iconSizePx, dotPath, DEFAULT_DOT_SIZE);
         mDotRendererAllApps = iconSizePx == allAppsIconSizePx ? mDotRendererWorkSpace :
-                new DotRenderer(allAppsIconSizePx, IconShape.getShapePath(),
-                        IconShape.DEFAULT_PATH_SIZE);
+                new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE);
     }
 
     private void setCellLayoutBorderSpacing(int borderSpacing) {
diff --git a/src/com/android/launcher3/graphics/IconShape.java b/src/com/android/launcher3/graphics/IconShape.java
index b208a40..2da679c 100644
--- a/src/com/android/launcher3/graphics/IconShape.java
+++ b/src/com/android/launcher3/graphics/IconShape.java
@@ -37,20 +37,14 @@
 import android.graphics.drawable.ColorDrawable;
 import android.os.Build;
 import android.util.AttributeSet;
-import android.util.SparseArray;
-import android.util.TypedValue;
 import android.util.Xml;
 import android.view.View;
 import android.view.ViewOutlineProvider;
 
-import androidx.annotation.Nullable;
-
 import com.android.launcher3.R;
 import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
 import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.IconNormalizer;
-import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ClipPathView;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -66,30 +60,16 @@
 public abstract class IconShape {
 
     private static IconShape sInstance = new Circle();
-    private static Path sShapePath;
     private static float sNormalizationScale = ICON_VISIBLE_AREA_FACTOR;
 
-    public static final int DEFAULT_PATH_SIZE = 100;
-
     public static IconShape getShape() {
         return sInstance;
     }
 
-    public static Path getShapePath() {
-        if (sShapePath == null) {
-            Path p = new Path();
-            getShape().addToPath(p, 0, 0, DEFAULT_PATH_SIZE * 0.5f);
-            sShapePath = p;
-        }
-        return sShapePath;
-    }
-
     public static float getNormalizationScale() {
         return sNormalizationScale;
     }
 
-    private SparseArray<TypedValue> mAttrs;
-
     public boolean enableShapeDetection(){
         return false;
     };
@@ -102,11 +82,6 @@
     public abstract <T extends View & ClipPathView> Animator createRevealAnimator(T target,
             Rect startRect, Rect endRect, float endRadius, boolean isReversed);
 
-    @Nullable
-    public TypedValue getAttrValue(int attr) {
-        return mAttrs == null ? null : mAttrs.get(attr);
-    }
-
     /**
      * Abstract shape where the reveal animation is a derivative of a round rect animation
      */
@@ -410,7 +385,6 @@
 
             final int depth = parser.getDepth();
             int[] radiusAttr = new int[] {R.attr.folderIconRadius};
-            IntArray keysToIgnore = new IntArray(0);
 
             while (((type = parser.next()) != XmlPullParser.END_TAG ||
                     parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
@@ -421,7 +395,6 @@
                     IconShape shape = getShapeDefinition(parser.getName(), a.getFloat(0, 1));
                     a.recycle();
 
-                    shape.mAttrs = Themes.createValueMap(context, attrs, keysToIgnore);
                     result.add(shape);
                 }
             }
@@ -467,8 +440,6 @@
         }
 
         // Initialize shape properties
-        drawable.setBounds(0, 0, DEFAULT_PATH_SIZE, DEFAULT_PATH_SIZE);
-        sShapePath = new Path(drawable.getIconMask());
         sNormalizationScale = IconNormalizer.normalizeAdaptiveIcon(drawable, size, null);
     }
 }
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index ac0ec5f..13ae866 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -17,9 +17,6 @@
 
 package com.android.launcher3.graphics;
 
-import static com.android.launcher3.graphics.IconShape.DEFAULT_PATH_SIZE;
-import static com.android.launcher3.graphics.IconShape.getShapePath;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -39,6 +36,7 @@
 
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.icons.FastBitmapDrawable;
+import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.util.Themes;
 
@@ -62,6 +60,7 @@
                 }
             };
 
+    private static final int DEFAULT_PATH_SIZE = 100;
     private static final float PROGRESS_WIDTH = 7;
     private static final float PROGRESS_GAP = 2;
     private static final int MAX_PAINT_ALPHA = 255;
@@ -132,7 +131,7 @@
             boolean isDarkMode) {
         super(info.bitmap);
         mItem = info;
-        mShapePath = getShapePath();
+        mShapePath = GraphicsUtils.getShapePath(DEFAULT_PATH_SIZE);
         mScaledTrackPath = new Path();
         mScaledProgressPath = new Path();