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
This commit is contained in:
Charlie Anderson
2025-03-07 21:31:11 +00:00
parent f979f6518b
commit 567097eee8
5 changed files with 55 additions and 29 deletions
+27 -7
View File
@@ -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;
}
}
}
@@ -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,
)
}
)
}
@@ -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;
}
+1 -1
View File
@@ -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);
}
}
@@ -34,19 +34,20 @@ class UserBadgeDrawableTest {
private val context = InstrumentationRegistry.getInstrumentation().targetContext
private val canvas = mock<Canvas>()
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<Int>()
whenever(
canvas.drawCircle(
any(),
any(),
any(),
any()
)
).then { colorList.add(it.getArgument<Paint>(3).color) }
whenever(canvas.drawCircle(any(), any(), any(), any())).then {
colorList.add(it.getArgument<Paint>(3).color)
}
systemUnderTest.alpha = 255
systemUnderTest.draw(canvas)
@@ -57,14 +58,9 @@ class UserBadgeDrawableTest {
@Test
fun draw_transparent() {
val colorList = mutableListOf<Int>()
whenever(
canvas.drawCircle(
any(),
any(),
any(),
any()
)
).then { colorList.add(it.getArgument<Paint>(3).color) }
whenever(canvas.drawCircle(any(), any(), any(), any())).then {
colorList.add(it.getArgument<Paint>(3).color)
}
systemUnderTest.alpha = 0
systemUnderTest.draw(canvas)