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

Commit e55f9343 authored by Ioana Alexandru's avatar Ioana Alexandru Committed by Android (Google) Code Review
Browse files

Merge changes I10b2c9cc,Id8ebf066 into main

* changes:
  Use app icon in notification row.
  Use monochrome app icon for notifs
parents 2b994966 25e378b8
Loading
Loading
Loading
Loading
+90 −5
Original line number Diff line number Diff line
@@ -1632,6 +1632,7 @@ public class Notification implements Parcelable
    private Icon mSmallIcon;
    @UnsupportedAppUsage
    private Icon mLargeIcon;
    private Icon mAppIcon;
    @UnsupportedAppUsage
    private String mChannelId;
@@ -3109,16 +3110,17 @@ public class Notification implements Parcelable
    }
    /**
     * Get the resource ID of the app icon from application info.
     * @hide
     */
    public int loadHeaderAppIconRes(Context context) {
    public int getHeaderAppIconRes(Context context) {
        ApplicationInfo info = null;
        if (extras.containsKey(EXTRA_BUILDER_APPLICATION_INFO)) {
            info = extras.getParcelable(
                    EXTRA_BUILDER_APPLICATION_INFO,
                    ApplicationInfo.class);
        }
        if (info == null) {
        if (info == null && context != null) {
            info = context.getApplicationInfo();
        }
        if (info != null) {
@@ -3127,6 +3129,29 @@ public class Notification implements Parcelable
        return 0;
    }
    /**
     * Load the app icon drawable from the package manager. This could result in a binder call.
     * @hide
     */
    public Drawable loadHeaderAppIcon(Context context) {
        Trace.beginSection("Notification#loadHeaderAppIcon");
        try {
            final PackageManager pm = context.getPackageManager();
            if (extras.containsKey(EXTRA_BUILDER_APPLICATION_INFO)) {
                final ApplicationInfo info = extras.getParcelable(
                        EXTRA_BUILDER_APPLICATION_INFO,
                        ApplicationInfo.class);
                if (info != null) {
                    return pm.getApplicationIcon(info);
                }
            }
            return pm.getApplicationIcon(context.getApplicationInfo());
        } finally {
            Trace.endSection();
        }
    }
    /**
     * Removes heavyweight parts of the Notification object for archival or for sending to
     * listeners when the full contents are not necessary.
@@ -4123,6 +4148,52 @@ public class Notification implements Parcelable
        mSmallIcon = icon;
    }
    /**
     * The colored app icon that can replace the small icon in the notification starting in V.
     *
     * Before using this value, you should first check whether it's actually being used by the
     * notification by calling {@link Notification#shouldUseAppIcon()}.
     *
     * @hide
     */
    public Icon getAppIcon() {
        if (mAppIcon != null) {
            return mAppIcon;
        }
        // If the app icon hasn't been loaded yet, check if we can load it without a context.
        if (extras.containsKey(EXTRA_BUILDER_APPLICATION_INFO)) {
            final ApplicationInfo info = extras.getParcelable(
                    EXTRA_BUILDER_APPLICATION_INFO,
                    ApplicationInfo.class);
            if (info != null) {
                int appIconRes = info.icon;
                if (appIconRes == 0) {
                    Log.w(TAG, "Failed to get the app icon: no icon in application info");
                    return null;
                }
                mAppIcon = Icon.createWithResource(info.packageName, appIconRes);
                return mAppIcon;
            } else {
                Log.e(TAG, "Failed to get the app icon: "
                        + "there's an EXTRA_BUILDER_APPLICATION_INFO in extras but it's null");
            }
        } else {
            Log.w(TAG, "Failed to get the app icon: no application info in extras");
        }
        return null;
    }
    /**
     * Whether the notification is using the app icon instead of the small icon.
     * @hide
     */
    public boolean shouldUseAppIcon() {
        if (Flags.notificationsUseAppIconInRow()) {
            return getAppIcon() != null;
        }
        return false;
    }
    /**
     * The large icon shown in this notification's content view.
     * @see Builder#getLargeIcon()
@@ -6116,16 +6187,30 @@ public class Notification implements Parcelable
            if (Flags.notificationsUseAppIcon()) {
                // Override small icon with app icon
                mN.mSmallIcon = Icon.createWithResource(mContext,
                        mN.loadHeaderAppIconRes(mContext));
                        mN.getHeaderAppIconRes(mContext));
            } else if (mN.mSmallIcon == null && mN.icon != 0) {
                mN.mSmallIcon = Icon.createWithResource(mContext, mN.icon);
            }
            boolean usingAppIcon = false;
            if (Flags.notificationsUseAppIconInRow()) {
                // Use the app icon in the view
                int appIconRes = mN.getHeaderAppIconRes(mContext);
                if (appIconRes != 0) {
                    mN.mAppIcon = Icon.createWithResource(mContext, appIconRes);
                    contentView.setImageViewIcon(R.id.icon, mN.mAppIcon);
                    usingAppIcon = true;
                } else {
                    Log.w(TAG, "bindSmallIcon: could not get the app icon");
                }
            }
            if (!usingAppIcon) {
                contentView.setImageViewIcon(R.id.icon, mN.mSmallIcon);
            }
            contentView.setInt(R.id.icon, "setImageLevel", mN.iconLevel);
            // Don't change color if we're using the app icon.
            if (!Flags.notificationsUseAppIcon()) {
            if (!Flags.notificationsUseAppIcon() && !usingAppIcon) {
                processSmallIconColor(mN.mSmallIcon, contentView, p);
            }
        }
+19 −1
Original line number Diff line number Diff line
@@ -52,13 +52,31 @@ flag {
  bug: "281044385"
}

# vvv Prototypes for using app icons in notifications vvv

flag {
  name: "notifications_use_app_icon"
  namespace: "systemui"
  description: "Experiment to replace the small icon in a notification with the app icon."
  description: "Experiment to replace the small icon in a notification with the app icon. This includes the status bar, AOD, shelf and notification row itself."
  bug: "335211019"
}

flag {
  name: "notifications_use_app_icon_in_row"
  namespace: "systemui"
  description: "Experiment to replace the small icon in a notification row with the app icon."
  bug: "335211019"
}

flag {
  name: "notifications_use_monochrome_app_icon"
  namespace: "systemui"
  description: "Experiment to replace the notification icon in the status bar and shelf with the monochrome app icon, if available."
  bug: "335211019"
}

# ^^^ Prototypes for using app icons in notifications ^^^

flag {
  name: "notification_expansion_optional"
  namespace: "systemui"
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ public class NotificationRowIconView extends CachingIconView {
    @Override
    protected void onFinishInflate() {
        // If showing the app icon, we don't need background or padding.
        if (Flags.notificationsUseAppIcon()) {
        if (Flags.notificationsUseAppIcon() || Flags.notificationsUseAppIconInRow()) {
            setPadding(0, 0, 0, 0);
            setBackground(null);
        }
+18 −4
Original line number Diff line number Diff line
@@ -362,20 +362,34 @@ public class NotificationGroupingUtil {
        }

        protected boolean hasSameIcon(Object parentData, Object childData) {
            Icon parentIcon = ((Notification) parentData).getSmallIcon();
            Icon childIcon = ((Notification) childData).getSmallIcon();
            Icon parentIcon = getIcon((Notification) parentData);
            Icon childIcon = getIcon((Notification) childData);
            return parentIcon.sameAs(childIcon);
        }

        private static Icon getIcon(Notification notification) {
            if (notification.shouldUseAppIcon()) {
                return notification.getAppIcon();
            }
            return notification.getSmallIcon();
        }

        /**
         * @return whether two ImageViews have the same colorFilterSet or none at all
         */
        protected boolean hasSameColor(Object parentData, Object childData) {
            int parentColor = ((Notification) parentData).color;
            int childColor = ((Notification) childData).color;
            int parentColor = getColor((Notification) parentData);
            int childColor = getColor((Notification) childData);
            return parentColor == childColor;
        }

        private static int getColor(Notification notification) {
            if (notification.shouldUseAppIcon()) {
                return 0;  // the color filter isn't applied if using the app icon
            }
            return notification.color;
        }

        @Override
        public boolean isEmpty(View view) {
            return false;
+11 −9
Original line number Diff line number Diff line
@@ -18,25 +18,27 @@ package com.android.systemui.statusbar.notification.icon

import android.app.Notification
import android.content.Context
import android.graphics.drawable.Drawable
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.contentDescForNotification
import javax.inject.Inject

/**
 * Testable wrapper around Context.
 */
class IconBuilder @Inject constructor(
    private val context: Context
) {
/** Testable wrapper around Context. */
class IconBuilder @Inject constructor(private val context: Context) {
    fun createIconView(entry: NotificationEntry): StatusBarIconView {
        return StatusBarIconView(
            context,
            "${entry.sbn.packageName}/0x${Integer.toHexString(entry.sbn.id)}",
                entry.sbn)
            entry.sbn
        )
    }

    fun getIconContentDescription(n: Notification): CharSequence {
        return contentDescForNotification(context, n)
    }

    fun getAppIcon(n: Notification): Drawable {
        return n.loadHeaderAppIcon(context)
    }
}
Loading