Loading iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +14 −7 Original line number Diff line number Diff line Loading @@ -46,13 +46,15 @@ public class BaseIconFactory implements AutoCloseable { private IconNormalizer mNormalizer; private ShadowGenerator mShadowGenerator; private final boolean mShapeDetection; private Drawable mWrapperIcon; private int mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND; protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize, boolean shapeDetection) { mContext = context.getApplicationContext(); mShapeDetection = shapeDetection; mFillResIconDpi = fillResIconDpi; mIconBitmapSize = iconBitmapSize; Loading @@ -64,6 +66,10 @@ public class BaseIconFactory implements AutoCloseable { clear(); } protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { this(context, fillResIconDpi, iconBitmapSize, false); } protected void clear() { mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND; mDisableColorExtractor = false; Loading @@ -78,7 +84,7 @@ public class BaseIconFactory implements AutoCloseable { public IconNormalizer getNormalizer() { if (mNormalizer == null) { mNormalizer = new IconNormalizer(mIconBitmapSize); mNormalizer = new IconNormalizer(mContext, mIconBitmapSize, mShapeDetection); } return mNormalizer; } Loading Loading @@ -212,18 +218,19 @@ public class BaseIconFactory implements AutoCloseable { } AdaptiveIconDrawable dr = (AdaptiveIconDrawable) mWrapperIcon; dr.setBounds(0, 0, 1, 1); scale = getNormalizer().getScale(icon, outIconBounds); if (!(icon instanceof AdaptiveIconDrawable)) { boolean[] outShape = new boolean[1]; scale = getNormalizer().getScale(icon, outIconBounds, dr.getIconMask(), outShape); if (!(icon instanceof AdaptiveIconDrawable) && !outShape[0]) { FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground()); fsd.setDrawable(icon); fsd.setScale(scale); icon = dr; scale = getNormalizer().getScale(icon, outIconBounds); scale = getNormalizer().getScale(icon, outIconBounds, null, null); ((ColorDrawable) dr.getBackground()).setColor(mWrapperBackgroundColor); } } else { scale = getNormalizer().getScale(icon, outIconBounds); scale = getNormalizer().getScale(icon, outIconBounds, null, null); } outScale[0] = scale; Loading iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java +102 −3 Original line number Diff line number Diff line Loading @@ -18,16 +18,22 @@ package com.android.launcher3.icons; import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.util.Log; import java.nio.ByteBuffer; Loading @@ -51,6 +57,9 @@ public class IconNormalizer { private static final int MIN_VISIBLE_ALPHA = 40; // Shape detection related constants private static final float BOUND_RATIO_MARGIN = .05f; private static final float PIXEL_DIFF_PERCENTAGE_THRESHOLD = 0.005f; private static final float SCALE_NOT_INITIALIZED = 0; // Ratio of the diameter of an normalized circular icon to the actual icon size. Loading @@ -59,18 +68,24 @@ public class IconNormalizer { private final int mMaxSize; private final Bitmap mBitmap; private final Canvas mCanvas; private final Paint mPaintMaskShape; private final Paint mPaintMaskShapeOutline; private final byte[] mPixels; private final RectF mAdaptiveIconBounds; private float mAdaptiveIconScale; private boolean mEnableShapeDetection; // for each y, stores the position of the leftmost x and the rightmost x private final float[] mLeftBorder; private final float[] mRightBorder; private final Rect mBounds; private final Path mShapePath; private final Matrix mMatrix; /** package private **/ IconNormalizer(int iconBitmapSize) { IconNormalizer(Context context, int iconBitmapSize, boolean shapeDetection) { // Use twice the icon size as maximum size to avoid scaling down twice. mMaxSize = iconBitmapSize * 2; mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8); Loading @@ -81,7 +96,22 @@ public class IconNormalizer { mBounds = new Rect(); mAdaptiveIconBounds = new RectF(); mPaintMaskShape = new Paint(); mPaintMaskShape.setColor(Color.RED); mPaintMaskShape.setStyle(Paint.Style.FILL); mPaintMaskShape.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR)); mPaintMaskShapeOutline = new Paint(); mPaintMaskShapeOutline.setStrokeWidth( 2 * context.getResources().getDisplayMetrics().density); mPaintMaskShapeOutline.setStyle(Paint.Style.STROKE); mPaintMaskShapeOutline.setColor(Color.BLACK); mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mShapePath = new Path(); mMatrix = new Matrix(); mAdaptiveIconScale = SCALE_NOT_INITIALIZED; mEnableShapeDetection = shapeDetection; } private static float getScale(float hullArea, float boundingArea, float fullArea) { Loading Loading @@ -126,6 +156,72 @@ public class IconNormalizer { return getScale(hullArea, hullArea, size * size); } /** * Returns if the shape of the icon is same as the path. * For this method to work, the shape path bounds should be in [0,1]x[0,1] bounds. */ private boolean isShape(Path maskPath) { // Condition1: // If width and height of the path not close to a square, then the icon shape is // not same as the mask shape. float iconRatio = ((float) mBounds.width()) / mBounds.height(); if (Math.abs(iconRatio - 1) > BOUND_RATIO_MARGIN) { if (DEBUG) { Log.d(TAG, "Not same as mask shape because width != height. " + iconRatio); } return false; } // Condition 2: // Actual icon (white) and the fitted shape (e.g., circle)(red) XOR operation // should generate transparent image, if the actual icon is equivalent to the shape. // Fit the shape within the icon's bounding box mMatrix.reset(); mMatrix.setScale(mBounds.width(), mBounds.height()); mMatrix.postTranslate(mBounds.left, mBounds.top); maskPath.transform(mMatrix, mShapePath); // XOR operation mCanvas.drawPath(mShapePath, mPaintMaskShape); // DST_OUT operation around the mask path outline mCanvas.drawPath(mShapePath, mPaintMaskShapeOutline); // Check if the result is almost transparent return isTransparentBitmap(); } /** * Used to determine if certain the bitmap is transparent. */ private boolean isTransparentBitmap() { ByteBuffer buffer = ByteBuffer.wrap(mPixels); buffer.rewind(); mBitmap.copyPixelsToBuffer(buffer); int y = mBounds.top; // buffer position int index = y * mMaxSize; // buffer shift after every row, width of buffer = mMaxSize int rowSizeDiff = mMaxSize - mBounds.right; int sum = 0; for (; y < mBounds.bottom; y++) { index += mBounds.left; for (int x = mBounds.left; x < mBounds.right; x++) { if ((mPixels[index] & 0xFF) > MIN_VISIBLE_ALPHA) { sum++; } index++; } index += rowSizeDiff; } float percentageDiffPixels = ((float) sum) / (mBounds.width() * mBounds.height()); return percentageDiffPixels < PIXEL_DIFF_PERCENTAGE_THRESHOLD; } /** * Returns the amount by which the {@param d} should be scaled (in both dimensions) so that it * matches the design guidelines for a launcher icon. Loading @@ -140,7 +236,8 @@ public class IconNormalizer { * * @param outBounds optional rect to receive the fraction distance from each edge. */ public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds) { public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds, @Nullable Path path, @Nullable boolean[] outMaskShape) { if (BaseIconFactory.ATLEAST_OREO && d instanceof AdaptiveIconDrawable) { if (mAdaptiveIconScale == SCALE_NOT_INITIALIZED) { mAdaptiveIconScale = normalizeAdaptiveIcon(d, mMaxSize, mAdaptiveIconBounds); Loading Loading @@ -242,7 +339,9 @@ public class IconNormalizer { 1 - ((float) mBounds.right) / width, 1 - ((float) mBounds.bottom) / height); } if (outMaskShape != null && mEnableShapeDetection && outMaskShape.length > 0) { outMaskShape[0] = isShape(path); } // Area of the rectangle required to fit the convex hull float rectArea = (bottomY + 1 - topY) * (rightX + 1 - leftX); return getScale(area, rectArea, width * height); Loading src/com/android/launcher3/dragndrop/DragView.java +1 −1 Original line number Diff line number Diff line Loading @@ -243,7 +243,7 @@ public class DragView extends View implements LauncherStateManager.StateListener nDr = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null); } Utilities.scaleRectAboutCenter(bounds, li.getNormalizer().getScale(nDr, null)); li.getNormalizer().getScale(nDr, null, null, null)); } AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr; Loading src/com/android/launcher3/graphics/IconShape.java +9 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,10 @@ public abstract class IconShape { private SparseArray<TypedValue> mAttrs; public boolean enableShapeDetection(){ return false; }; public abstract void drawShape(Canvas canvas, float offsetX, float offsetY, float radius, Paint paint); Loading Loading @@ -194,6 +198,11 @@ public abstract class IconShape { protected float getStartRadius(Rect startRect) { return startRect.width() / 2f; } @Override public boolean enableShapeDetection() { return true; } } public static class RoundedSquare extends SimpleRectShape { Loading src/com/android/launcher3/icons/LauncherIcons.java +11 −4 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; import com.android.launcher3.graphics.IconShape; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.util.Themes; Loading @@ -50,11 +51,15 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable { private static LauncherIcons sPool; private static int sPoolId = 0; public static LauncherIcons obtain(Context context) { return obtain(context, IconShape.getShape().enableShapeDetection()); } /** * Return a new Message instance from the global pool. Allows us to * avoid allocating new objects in many cases. */ public static LauncherIcons obtain(Context context) { public static LauncherIcons obtain(Context context, boolean shapeDetection) { int poolId; synchronized (sPoolSync) { if (sPool != null) { Loading @@ -67,7 +72,8 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable { } InvariantDeviceProfile idp = LauncherAppState.getIDP(context); return new LauncherIcons(context, idp.fillResIconDpi, idp.iconBitmapSize, poolId); return new LauncherIcons(context, idp.fillResIconDpi, idp.iconBitmapSize, poolId, shapeDetection); } public static void clearPool() { Loading @@ -81,8 +87,9 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable { private LauncherIcons next; private LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId) { super(context, fillResIconDpi, iconBitmapSize); private LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId, boolean shapeDetection) { super(context, fillResIconDpi, iconBitmapSize, shapeDetection); mPoolId = poolId; } Loading Loading
iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +14 −7 Original line number Diff line number Diff line Loading @@ -46,13 +46,15 @@ public class BaseIconFactory implements AutoCloseable { private IconNormalizer mNormalizer; private ShadowGenerator mShadowGenerator; private final boolean mShapeDetection; private Drawable mWrapperIcon; private int mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND; protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize, boolean shapeDetection) { mContext = context.getApplicationContext(); mShapeDetection = shapeDetection; mFillResIconDpi = fillResIconDpi; mIconBitmapSize = iconBitmapSize; Loading @@ -64,6 +66,10 @@ public class BaseIconFactory implements AutoCloseable { clear(); } protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { this(context, fillResIconDpi, iconBitmapSize, false); } protected void clear() { mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND; mDisableColorExtractor = false; Loading @@ -78,7 +84,7 @@ public class BaseIconFactory implements AutoCloseable { public IconNormalizer getNormalizer() { if (mNormalizer == null) { mNormalizer = new IconNormalizer(mIconBitmapSize); mNormalizer = new IconNormalizer(mContext, mIconBitmapSize, mShapeDetection); } return mNormalizer; } Loading Loading @@ -212,18 +218,19 @@ public class BaseIconFactory implements AutoCloseable { } AdaptiveIconDrawable dr = (AdaptiveIconDrawable) mWrapperIcon; dr.setBounds(0, 0, 1, 1); scale = getNormalizer().getScale(icon, outIconBounds); if (!(icon instanceof AdaptiveIconDrawable)) { boolean[] outShape = new boolean[1]; scale = getNormalizer().getScale(icon, outIconBounds, dr.getIconMask(), outShape); if (!(icon instanceof AdaptiveIconDrawable) && !outShape[0]) { FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground()); fsd.setDrawable(icon); fsd.setScale(scale); icon = dr; scale = getNormalizer().getScale(icon, outIconBounds); scale = getNormalizer().getScale(icon, outIconBounds, null, null); ((ColorDrawable) dr.getBackground()).setColor(mWrapperBackgroundColor); } } else { scale = getNormalizer().getScale(icon, outIconBounds); scale = getNormalizer().getScale(icon, outIconBounds, null, null); } outScale[0] = scale; Loading
iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java +102 −3 Original line number Diff line number Diff line Loading @@ -18,16 +18,22 @@ package com.android.launcher3.icons; import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.util.Log; import java.nio.ByteBuffer; Loading @@ -51,6 +57,9 @@ public class IconNormalizer { private static final int MIN_VISIBLE_ALPHA = 40; // Shape detection related constants private static final float BOUND_RATIO_MARGIN = .05f; private static final float PIXEL_DIFF_PERCENTAGE_THRESHOLD = 0.005f; private static final float SCALE_NOT_INITIALIZED = 0; // Ratio of the diameter of an normalized circular icon to the actual icon size. Loading @@ -59,18 +68,24 @@ public class IconNormalizer { private final int mMaxSize; private final Bitmap mBitmap; private final Canvas mCanvas; private final Paint mPaintMaskShape; private final Paint mPaintMaskShapeOutline; private final byte[] mPixels; private final RectF mAdaptiveIconBounds; private float mAdaptiveIconScale; private boolean mEnableShapeDetection; // for each y, stores the position of the leftmost x and the rightmost x private final float[] mLeftBorder; private final float[] mRightBorder; private final Rect mBounds; private final Path mShapePath; private final Matrix mMatrix; /** package private **/ IconNormalizer(int iconBitmapSize) { IconNormalizer(Context context, int iconBitmapSize, boolean shapeDetection) { // Use twice the icon size as maximum size to avoid scaling down twice. mMaxSize = iconBitmapSize * 2; mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8); Loading @@ -81,7 +96,22 @@ public class IconNormalizer { mBounds = new Rect(); mAdaptiveIconBounds = new RectF(); mPaintMaskShape = new Paint(); mPaintMaskShape.setColor(Color.RED); mPaintMaskShape.setStyle(Paint.Style.FILL); mPaintMaskShape.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR)); mPaintMaskShapeOutline = new Paint(); mPaintMaskShapeOutline.setStrokeWidth( 2 * context.getResources().getDisplayMetrics().density); mPaintMaskShapeOutline.setStyle(Paint.Style.STROKE); mPaintMaskShapeOutline.setColor(Color.BLACK); mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mShapePath = new Path(); mMatrix = new Matrix(); mAdaptiveIconScale = SCALE_NOT_INITIALIZED; mEnableShapeDetection = shapeDetection; } private static float getScale(float hullArea, float boundingArea, float fullArea) { Loading Loading @@ -126,6 +156,72 @@ public class IconNormalizer { return getScale(hullArea, hullArea, size * size); } /** * Returns if the shape of the icon is same as the path. * For this method to work, the shape path bounds should be in [0,1]x[0,1] bounds. */ private boolean isShape(Path maskPath) { // Condition1: // If width and height of the path not close to a square, then the icon shape is // not same as the mask shape. float iconRatio = ((float) mBounds.width()) / mBounds.height(); if (Math.abs(iconRatio - 1) > BOUND_RATIO_MARGIN) { if (DEBUG) { Log.d(TAG, "Not same as mask shape because width != height. " + iconRatio); } return false; } // Condition 2: // Actual icon (white) and the fitted shape (e.g., circle)(red) XOR operation // should generate transparent image, if the actual icon is equivalent to the shape. // Fit the shape within the icon's bounding box mMatrix.reset(); mMatrix.setScale(mBounds.width(), mBounds.height()); mMatrix.postTranslate(mBounds.left, mBounds.top); maskPath.transform(mMatrix, mShapePath); // XOR operation mCanvas.drawPath(mShapePath, mPaintMaskShape); // DST_OUT operation around the mask path outline mCanvas.drawPath(mShapePath, mPaintMaskShapeOutline); // Check if the result is almost transparent return isTransparentBitmap(); } /** * Used to determine if certain the bitmap is transparent. */ private boolean isTransparentBitmap() { ByteBuffer buffer = ByteBuffer.wrap(mPixels); buffer.rewind(); mBitmap.copyPixelsToBuffer(buffer); int y = mBounds.top; // buffer position int index = y * mMaxSize; // buffer shift after every row, width of buffer = mMaxSize int rowSizeDiff = mMaxSize - mBounds.right; int sum = 0; for (; y < mBounds.bottom; y++) { index += mBounds.left; for (int x = mBounds.left; x < mBounds.right; x++) { if ((mPixels[index] & 0xFF) > MIN_VISIBLE_ALPHA) { sum++; } index++; } index += rowSizeDiff; } float percentageDiffPixels = ((float) sum) / (mBounds.width() * mBounds.height()); return percentageDiffPixels < PIXEL_DIFF_PERCENTAGE_THRESHOLD; } /** * Returns the amount by which the {@param d} should be scaled (in both dimensions) so that it * matches the design guidelines for a launcher icon. Loading @@ -140,7 +236,8 @@ public class IconNormalizer { * * @param outBounds optional rect to receive the fraction distance from each edge. */ public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds) { public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds, @Nullable Path path, @Nullable boolean[] outMaskShape) { if (BaseIconFactory.ATLEAST_OREO && d instanceof AdaptiveIconDrawable) { if (mAdaptiveIconScale == SCALE_NOT_INITIALIZED) { mAdaptiveIconScale = normalizeAdaptiveIcon(d, mMaxSize, mAdaptiveIconBounds); Loading Loading @@ -242,7 +339,9 @@ public class IconNormalizer { 1 - ((float) mBounds.right) / width, 1 - ((float) mBounds.bottom) / height); } if (outMaskShape != null && mEnableShapeDetection && outMaskShape.length > 0) { outMaskShape[0] = isShape(path); } // Area of the rectangle required to fit the convex hull float rectArea = (bottomY + 1 - topY) * (rightX + 1 - leftX); return getScale(area, rectArea, width * height); Loading
src/com/android/launcher3/dragndrop/DragView.java +1 −1 Original line number Diff line number Diff line Loading @@ -243,7 +243,7 @@ public class DragView extends View implements LauncherStateManager.StateListener nDr = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null); } Utilities.scaleRectAboutCenter(bounds, li.getNormalizer().getScale(nDr, null)); li.getNormalizer().getScale(nDr, null, null, null)); } AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr; Loading
src/com/android/launcher3/graphics/IconShape.java +9 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,10 @@ public abstract class IconShape { private SparseArray<TypedValue> mAttrs; public boolean enableShapeDetection(){ return false; }; public abstract void drawShape(Canvas canvas, float offsetX, float offsetY, float radius, Paint paint); Loading Loading @@ -194,6 +198,11 @@ public abstract class IconShape { protected float getStartRadius(Rect startRect) { return startRect.width() / 2f; } @Override public boolean enableShapeDetection() { return true; } } public static class RoundedSquare extends SimpleRectShape { Loading
src/com/android/launcher3/icons/LauncherIcons.java +11 −4 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; import com.android.launcher3.graphics.IconShape; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.util.Themes; Loading @@ -50,11 +51,15 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable { private static LauncherIcons sPool; private static int sPoolId = 0; public static LauncherIcons obtain(Context context) { return obtain(context, IconShape.getShape().enableShapeDetection()); } /** * Return a new Message instance from the global pool. Allows us to * avoid allocating new objects in many cases. */ public static LauncherIcons obtain(Context context) { public static LauncherIcons obtain(Context context, boolean shapeDetection) { int poolId; synchronized (sPoolSync) { if (sPool != null) { Loading @@ -67,7 +72,8 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable { } InvariantDeviceProfile idp = LauncherAppState.getIDP(context); return new LauncherIcons(context, idp.fillResIconDpi, idp.iconBitmapSize, poolId); return new LauncherIcons(context, idp.fillResIconDpi, idp.iconBitmapSize, poolId, shapeDetection); } public static void clearPool() { Loading @@ -81,8 +87,9 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable { private LauncherIcons next; private LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId) { super(context, fillResIconDpi, iconBitmapSize); private LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId, boolean shapeDetection) { super(context, fillResIconDpi, iconBitmapSize, shapeDetection); mPoolId = poolId; } Loading