From 567097eee8bd64e7bd9672336ffdfaea0c1fc46c Mon Sep 17 00:00:00 2001 From: Charlie Anderson Date: Fri, 28 Feb 2025 19:57:53 +0000 Subject: [PATCH] Make sure profile badging matches shape Bug: 398875512 Test: testing different shapes on work profile Flag: com.android.launcher3.enable_launcher_icon_shapes Change-Id: I5cb9e629f711f2fc607ca646d82a8523c0b43d1b --- src/com/android/launcher3/Utilities.java | 34 +++++++++++++++---- .../launcher3/graphics/ShapeDelegate.kt | 11 ++++-- .../model/data/ItemInfoWithIcon.java | 7 ++-- src/com/android/launcher3/pm/UserCache.java | 2 +- .../launcher3/icons/UserBadgeDrawableTest.kt | 30 +++++++--------- 5 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index cb3a0bc070..9a9bc1d97e 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -18,6 +18,7 @@ package com.android.launcher3; import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN; import static com.android.launcher3.Flags.enableSmartspaceAsAWidget; +import static com.android.launcher3.graphics.ShapeDelegate.DEFAULT_PATH_SIZE; import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; @@ -39,6 +40,7 @@ import android.graphics.ColorFilter; import android.graphics.LightingColorFilter; import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.Path; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; @@ -632,7 +634,7 @@ public final class Utilities { Drawable badge = null; if ((info instanceof ItemInfoWithIcon iiwi) && !iiwi.getMatchingLookupFlag().useLowRes()) { - badge = iiwi.bitmap.getBadgeDrawable(context, useTheme); + badge = iiwi.bitmap.getBadgeDrawable(context, useTheme, getIconShapeOrNull(context)); } if (info instanceof PendingAddShortcutInfo) { @@ -659,8 +661,11 @@ public final class Utilities { // Only fetch badge if the icon is on workspace if (info.id != ItemInfo.NO_ID && badge == null) { badge = appState.getIconCache().getShortcutInfoBadge(si).newIcon( - context, ThemeManager.INSTANCE.get(context).isIconThemeEnabled() - ? FLAG_THEMED : 0); + context, + ThemeManager.INSTANCE.get(context).isIconThemeEnabled() + ? FLAG_THEMED : 0, + getIconShapeOrNull(context) + ); } } } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { @@ -706,10 +711,11 @@ public final class Utilities { if (badge == null) { badge = BitmapInfo.LOW_RES_INFO.withFlags( - UserCache.INSTANCE.get(context) - .getUserInfo(info.user) - .applyBitmapInfoFlags(FlagOp.NO_OP)) - .getBadgeDrawable(context, useTheme); + UserCache.INSTANCE.get(context) + .getUserInfo(info.user) + .applyBitmapInfoFlags(FlagOp.NO_OP) + ) + .getBadgeDrawable(context, useTheme, getIconShapeOrNull(context)); if (badge == null) { badge = new ColorDrawable(Color.TRANSPARENT); } @@ -939,4 +945,18 @@ public final class Utilities { } return null; } + + /** + * Returns current icon shape to use for badges if flag is on, otherwise null. + */ + @Nullable + public static Path getIconShapeOrNull(Context context) { + if (Flags.enableLauncherIconShapes()) { + return ThemeManager.INSTANCE.get(context) + .getIconShape() + .getPath(DEFAULT_PATH_SIZE); + } else { + return null; + } + } } diff --git a/src/com/android/launcher3/graphics/ShapeDelegate.kt b/src/com/android/launcher3/graphics/ShapeDelegate.kt index 9033eac049..7c042929e2 100644 --- a/src/com/android/launcher3/graphics/ShapeDelegate.kt +++ b/src/com/android/launcher3/graphics/ShapeDelegate.kt @@ -203,7 +203,11 @@ interface ShapeDelegate { start = poly.transformed( Matrix().apply { - setRectToRect(RectF(0f, 0f, 100f, 100f), RectF(startRect), FILL) + setRectToRect( + RectF(0f, 0f, DEFAULT_PATH_SIZE, DEFAULT_PATH_SIZE), + RectF(startRect), + FILL, + ) } ), end = @@ -281,7 +285,10 @@ interface ShapeDelegate { PathParser.createPathFromPathData(shapeStr).apply { transform( Matrix().apply { - setScale(AREA_CALC_SIZE / 100f, AREA_CALC_SIZE / 100f) + setScale( + AREA_CALC_SIZE / DEFAULT_PATH_SIZE, + AREA_CALC_SIZE / DEFAULT_PATH_SIZE, + ) } ) } diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java index b60b8cc670..f5e5e16b9e 100644 --- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java +++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java @@ -26,6 +26,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.Flags; +import com.android.launcher3.Utilities; import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.BitmapInfo.DrawableCreationFlags; @@ -325,10 +326,12 @@ public abstract class ItemInfoWithIcon extends ItemInfo { * Returns a FastBitmapDrawable with the icon and context theme applied */ public FastBitmapDrawable newIcon(Context context, @DrawableCreationFlags int creationFlags) { - if (!ThemeManager.INSTANCE.get(context).isIconThemeEnabled()) { + ThemeManager themeManager = ThemeManager.INSTANCE.get(context); + if (!themeManager.isIconThemeEnabled()) { creationFlags &= ~FLAG_THEMED; } - FastBitmapDrawable drawable = bitmap.newIcon(context, creationFlags); + FastBitmapDrawable drawable = bitmap.newIcon( + context, creationFlags, Utilities.getIconShapeOrNull(context)); drawable.setIsDisabled(isDisabled()); return drawable; } diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java index 20c0ecc4b1..98a3882132 100644 --- a/src/com/android/launcher3/pm/UserCache.java +++ b/src/com/android/launcher3/pm/UserCache.java @@ -219,6 +219,6 @@ public class UserCache { public static UserBadgeDrawable getBadgeDrawable(Context context, UserHandle userHandle) { return (UserBadgeDrawable) BitmapInfo.LOW_RES_INFO.withFlags(UserCache.getInstance(context) .getUserInfo(userHandle).applyBitmapInfoFlags(FlagOp.NO_OP)) - .getBadgeDrawable(context, false /* isThemed */); + .getBadgeDrawable(context, false /* isThemed */, null); } } diff --git a/tests/multivalentTests/src/com/android/launcher3/icons/UserBadgeDrawableTest.kt b/tests/multivalentTests/src/com/android/launcher3/icons/UserBadgeDrawableTest.kt index d611ae8dd6..91ba6289ba 100644 --- a/tests/multivalentTests/src/com/android/launcher3/icons/UserBadgeDrawableTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/icons/UserBadgeDrawableTest.kt @@ -34,19 +34,20 @@ class UserBadgeDrawableTest { private val context = InstrumentationRegistry.getInstrumentation().targetContext private val canvas = mock() private val systemUnderTest = - UserBadgeDrawable(context, R.drawable.ic_work_app_badge, R.color.badge_tint_work, false) + UserBadgeDrawable( + context, + R.drawable.ic_work_app_badge, + R.color.badge_tint_work, + false /* isThemed */, + null, /* shape */ + ) @Test fun draw_opaque() { val colorList = mutableListOf() - whenever( - canvas.drawCircle( - any(), - any(), - any(), - any() - ) - ).then { colorList.add(it.getArgument(3).color) } + whenever(canvas.drawCircle(any(), any(), any(), any())).then { + colorList.add(it.getArgument(3).color) + } systemUnderTest.alpha = 255 systemUnderTest.draw(canvas) @@ -57,14 +58,9 @@ class UserBadgeDrawableTest { @Test fun draw_transparent() { val colorList = mutableListOf() - whenever( - canvas.drawCircle( - any(), - any(), - any(), - any() - ) - ).then { colorList.add(it.getArgument(3).color) } + whenever(canvas.drawCircle(any(), any(), any(), any())).then { + colorList.add(it.getArgument(3).color) + } systemUnderTest.alpha = 0 systemUnderTest.draw(canvas)