Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc14a2cc authored by Ioana Alexandru's avatar Ioana Alexandru
Browse files

Load monochrome app icon in SBIV

Previously, we were resolving the drawable just to check if we have a
monochrome version of the icon, and then resolving it again in SBIV. Now
we're only doing it once.

Bug: 335211019
Test: manually tested a few apps
Flag: android.app.notifications_use_monochrome_app_icon DEVELOPMENT
Change-Id: Id3eb0aa9098fd8a073faa1c063c72c91e0dd145b
parent 4e22af12
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -25,7 +25,17 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;

public class StatusBarIcon implements Parcelable {
    public enum Type {PeopleAvatar, MonochromeAppIcon, NotifSmallIcon, SystemIcon}
    public enum Type {
        // Notification: the sender avatar for important conversations
        PeopleAvatar,
        // Notification: the monochrome version of the app icon if available; otherwise fall back to
        // the small icon
        MaybeMonochromeAppIcon,
        // Notification: the small icon from the notification
        NotifSmallIcon,
        // The wi-fi, cellular or battery icon.
        SystemIcon
    }

    public UserHandle user;
    public String pkg;
+30 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.app.ActivityManager;
import android.app.Notification;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -35,6 +36,7 @@ import android.graphics.Color;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Trace;
@@ -94,6 +96,8 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
    public static final int STATE_DOT = 1;
    public static final int STATE_HIDDEN = 2;

    public static final float APP_ICON_SCALE = .75f;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({STATE_ICON, STATE_DOT, STATE_HIDDEN})
    public @interface VisibleState { }
@@ -499,7 +503,12 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
            userId = UserHandle.USER_SYSTEM;
        }

        Drawable icon = statusBarIcon.icon.loadDrawableAsUser(context, userId);
        // Try to load the monochrome app icon if applicable
        Drawable icon = maybeGetMonochromeAppIcon(context, statusBarIcon);
        // Otherwise, just use the icon normally
        if (icon == null) {
            icon = statusBarIcon.icon.loadDrawableAsUser(context, userId);
        }

        TypedValue typedValue = new TypedValue();
        sysuiContext.getResources().getValue(R.dimen.status_bar_icon_scale_factor,
@@ -526,6 +535,26 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
        return new ScalingDrawableWrapper(icon, scaleFactor);
    }

    @Nullable
    private Drawable maybeGetMonochromeAppIcon(Context context,
            StatusBarIcon statusBarIcon) {
        if (android.app.Flags.notificationsUseMonochromeAppIcon()
                && statusBarIcon.type == StatusBarIcon.Type.MaybeMonochromeAppIcon) {
            // Check if we have a monochrome app icon
            PackageManager pm = context.getPackageManager();
            Drawable appIcon = context.getApplicationInfo().loadIcon(pm);
            if (appIcon instanceof AdaptiveIconDrawable) {
                Drawable monochrome = ((AdaptiveIconDrawable) appIcon).getMonochrome();
                if (monochrome != null) {
                    setCropToPadding(true);
                    setScaleType(ScaleType.CENTER);
                    return new ScalingDrawableWrapper(monochrome, APP_ICON_SCALE);
                }
            }
        }
        return null;
    }

    public StatusBarIcon getStatusBarIcon() {
        return mIcon;
    }
+3 −32
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ import android.app.Notification
import android.app.Notification.MessagingStyle
import android.app.Person
import android.content.pm.LauncherApps
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon
import android.os.Build
import android.os.Bundle
@@ -232,12 +230,7 @@ constructor(
            } else if (
                android.app.Flags.notificationsUseMonochromeAppIcon() && n.shouldUseAppIcon()
            ) {
                val monochrome = getMonochromeAppIcon(entry)
                if (monochrome != null) {
                    monochrome to StatusBarIcon.Type.MonochromeAppIcon
                } else {
                    n.smallIcon to StatusBarIcon.Type.NotifSmallIcon
                }
                n.smallIcon to StatusBarIcon.Type.MaybeMonochromeAppIcon
            } else {
                n.smallIcon to StatusBarIcon.Type.NotifSmallIcon
            }
@@ -277,7 +270,8 @@ constructor(
            when (descriptor.type) {
                StatusBarIcon.Type.PeopleAvatar -> entry.icons.peopleAvatarDescriptor = descriptor
                // When notificationsUseMonochromeAppIcon is enabled, we use the appIconDescriptor.
                StatusBarIcon.Type.MonochromeAppIcon -> entry.icons.appIconDescriptor = descriptor
                StatusBarIcon.Type.MaybeMonochromeAppIcon ->
                    entry.icons.appIconDescriptor = descriptor
                // When notificationsUseAppIcon is enabled, the app icon overrides the small icon.
                // But either way, it's a good idea to cache the descriptor.
                else -> entry.icons.smallIconDescriptor = descriptor
@@ -321,29 +315,6 @@ constructor(
        )
    }

    // TODO(b/335211019): Should we merge this with the method in GroupHelper?
    private fun getMonochromeAppIcon(entry: NotificationEntry): Icon? {
        // TODO(b/335211019): This should be done in the background.
        var monochromeIcon: Icon? = null
        try {
            val appIcon: Drawable = iconBuilder.getAppIcon(entry.sbn.notification)
            if (appIcon is AdaptiveIconDrawable) {
                if (appIcon.monochrome != null) {
                    monochromeIcon =
                        Icon.createWithResourceAdaptiveDrawable(
                            /* resPackage = */ entry.sbn.packageName,
                            /* resId = */ appIcon.sourceDrawableResId,
                            /* useMonochrome = */ true,
                            /* inset = */ -3.0f * AdaptiveIconDrawable.getExtraInsetFraction()
                        )
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to getAppIcon() in getMonochromeAppIcon()", e)
        }
        return monochromeIcon
    }

    private suspend fun getLauncherShortcutIconForPeopleAvatar(entry: NotificationEntry) =
        withContext(bgCoroutineContext) {
            var icon: Icon? = null