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

Commit 25e378b8 authored by Ioana Alexandru's avatar Ioana Alexandru
Browse files

Use app icon in notification row.

Bug: 335211019
Test: manually tested a few apps
Flag: android.app.notifications_use_app_icon_in_row DEVELOPMENT
Change-Id: I10b2c9cc097a5053c5982c5ed4a1fdd1e6b479d5
parent 018dbd83
Loading
Loading
Loading
Loading
+68 −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) {
@@ -3128,6 +3130,7 @@ public class Notification implements Parcelable
    }
    /**
     * Load the app icon drawable from the package manager. This could result in a binder call.
     * @hide
     */
    public Drawable loadHeaderAppIcon(Context context) {
@@ -4145,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()
@@ -6134,16 +6183,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);
            }
        }
+12 −1
Original line number Diff line number Diff line
@@ -52,10 +52,19 @@ 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"
}

@@ -66,6 +75,8 @@ flag {
  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;
+6 −2
Original line number Diff line number Diff line
@@ -191,8 +191,12 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
        updateTransformedTypes();
        addRemainingTransformTypes();
        updateCropToPaddingForImageViews();
        Notification notification = row.getEntry().getSbn().getNotification();
        mIcon.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon());
        Notification n = row.getEntry().getSbn().getNotification();
        if (n.shouldUseAppIcon()) {
            mIcon.setTag(ImageTransformState.ICON_TAG, n.getAppIcon());
        } else {
            mIcon.setTag(ImageTransformState.ICON_TAG, n.getSmallIcon());
        }

        // We need to reset all views that are no longer transforming in case a view was previously
        // transformed, but now we decided to transform its container instead.