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

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

Merge "Remove app icon prototypes code" into main

parents a997b8ed cb3584f8
Loading
Loading
Loading
Loading
+4 −174
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ public class Notification implements Parcelable
            FOREGROUND_SERVICE_IMMEDIATE,
            FOREGROUND_SERVICE_DEFERRED
    })
    public @interface ServiceNotificationPolicy {};
    public @interface ServiceNotificationPolicy {}
    /**
     * If the Notification associated with starting a foreground service has been
@@ -1754,10 +1754,6 @@ public class Notification implements Parcelable
    private Icon mSmallIcon;
    @UnsupportedAppUsage
    private Icon mLargeIcon;
    private Icon mAppIcon;
    /** Cache for whether the notification was posted by a headless system app. */
    private Boolean mBelongsToHeadlessSystemApp = null;
    @UnsupportedAppUsage
    private String mChannelId;
@@ -3246,86 +3242,6 @@ public class Notification implements Parcelable
                && hasPromotableStyle();
    }
    /**
     * Whether this notification was posted by a headless system app.
     *
     * If we don't have enough information to figure this out, this will return false. Therefore,
     * false negatives are possible, but false positives should not be.
     *
     * @hide
     */
    public boolean belongsToHeadlessSystemApp(Context context) {
        Trace.beginSection("Notification#belongsToHeadlessSystemApp");
        try {
            if (mBelongsToHeadlessSystemApp != null) {
                return mBelongsToHeadlessSystemApp;
            }
            if (context == null) {
                // Without a valid context, we don't know exactly. Let's assume it doesn't belong to
                // a system app, but not cache the value.
                return false;
            }
            ApplicationInfo info = getApplicationInfo(context);
            if (info != null) {
                if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                    // It's not a system app at all.
                    mBelongsToHeadlessSystemApp = false;
                } else {
                    // If there's no launch intent, it's probably a headless app.
                    final PackageManager pm = context.getPackageManager();
                    mBelongsToHeadlessSystemApp = pm.getLaunchIntentForPackage(info.packageName)
                            == null;
                }
            } else {
                // If for some reason we don't have the app info, we don't know; best assume it's
                // not a system app.
                return false;
            }
            return mBelongsToHeadlessSystemApp;
        } finally {
            Trace.endSection();
        }
    }
    /**
     * Get the resource ID of the app icon from application info.
     * @hide
     */
    public int getHeaderAppIconRes(Context context) {
        ApplicationInfo info = getApplicationInfo(context);
        if (info != null) {
            return info.icon;
        }
        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 {
            if (context == null) {
                Log.e(TAG, "Cannot load the app icon drawable with a null context");
                return null;
            }
            final PackageManager pm = context.getPackageManager();
            ApplicationInfo info = getApplicationInfo(context);
            if (info == null) {
                Log.e(TAG, "Cannot load the app icon drawable: no application info");
                return null;
            }
            return pm.getApplicationIcon(info);
        } finally {
            Trace.endSection();
        }
    }
    /**
     * Fetch the application info from the notification, or the context if that isn't available.
     */
@@ -4360,55 +4276,6 @@ 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()) {
            if (belongsToHeadlessSystemApp(/* context = */ null)) {
                return false;
            }
            return getAppIcon() != null;
        }
        return false;
    }
    /**
     * The large icon shown in this notification's content view.
     * @see Builder#getLargeIcon()
@@ -4566,19 +4433,6 @@ public class Notification implements Parcelable
        private static final boolean USE_ONLY_TITLE_IN_LOW_PRIORITY_SUMMARY =
                SystemProperties.getBoolean("notifications.only_title", true);
        /**
         * The lightness difference that has to be added to the primary text color to obtain the
         * secondary text color when the background is light.
         */
        private static final int LIGHTNESS_TEXT_DIFFERENCE_LIGHT = 20;
        /**
         * The lightness difference that has to be added to the primary text color to obtain the
         * secondary text color when the background is dark.
         * A bit less then the above value, since it looks better on dark backgrounds.
         */
        private static final int LIGHTNESS_TEXT_DIFFERENCE_DARK = -10;
        private Context mContext;
        private Notification mN;
        private Bundle mUserExtras = new Bundle();
@@ -6451,37 +6305,13 @@ public class Notification implements Parcelable
        }
        private void bindSmallIcon(RemoteViews contentView, StandardTemplateParams p) {
            if (Flags.notificationsUseAppIcon()) {
                // Override small icon with app icon
                mN.mSmallIcon = Icon.createWithResource(mContext,
                        mN.getHeaderAppIconRes(mContext));
            } else if (mN.mSmallIcon == null && mN.icon != 0) {
            if (mN.mSmallIcon == null && mN.icon != 0) {
                mN.mSmallIcon = Icon.createWithResource(mContext, mN.icon);
            }
            boolean usingAppIcon = false;
            if (Flags.notificationsUseAppIconInRow() && !mN.belongsToHeadlessSystemApp(mContext)) {
                // 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);
                    contentView.setBoolean(R.id.icon, "setShouldShowAppIcon", true);
                    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() && !usingAppIcon) {
            processSmallIconColor(mN.mSmallIcon, contentView, p);
        }
        }
        /**
         * @return true if the built notification will show the time or the chronometer; false
+1 −27
Original line number Diff line number Diff line
@@ -8,8 +8,7 @@ container: "system"
flag {
  name: "notifications_redesign_app_icons"
  namespace: "systemui"
  description: "Notifications Redesign: Use app icons in notification rows (not to be confused with"
    " notifications_use_app_icons, notifications_use_app_icon_in_row which are just experiments)."
  description: "Notifications Redesign: Use app icons in notification rows"
  bug: "371174789"
}

@@ -110,31 +109,6 @@ flag {
  }
}

# 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. 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"
+0 −3
Original line number Diff line number Diff line
@@ -40,9 +40,6 @@ public class StatusBarIcon implements Parcelable {
    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.
+1 −59
Original line number Diff line number Diff line
@@ -22,11 +22,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -35,8 +31,6 @@ import android.util.AttributeSet;
import android.view.RemotableViewMethod;
import android.widget.RemoteViews;

import com.android.internal.R;

/**
 * An image view that holds the icon displayed at the start of a notification row.
 * This can generally either display the "small icon" of a notification set via
@@ -48,7 +42,6 @@ public class NotificationRowIconView extends CachingIconView {
    private NotificationIconProvider mIconProvider;

    private boolean mApplyCircularCrop = false;
    private boolean mShouldShowAppIcon = false;
    private Drawable mAppIcon = null;

    // Padding, background and colors set on the view prior to being overridden when showing the app
@@ -77,17 +70,6 @@ public class NotificationRowIconView extends CachingIconView {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onFinishInflate() {
        // If showing the app icon, we don't need background or padding.
        if (Flags.notificationsUseAppIcon()) {
            setPadding(0, 0, 0, 0);
            setBackground(null);
        }

        super.onFinishInflate();
    }

    /**
     * Sets the icon provider for this view. This is used to determine whether we should show the
     * app icon instead of the small icon, and to fetch the app icon if needed.
@@ -153,38 +135,13 @@ public class NotificationRowIconView extends CachingIconView {
        return super.setImageIconAsync(icon);
    }

    /** Whether the icon represents the app icon (instead of the small icon). */
    @RemotableViewMethod
    public void setShouldShowAppIcon(boolean shouldShowAppIcon) {
        if (Flags.notificationsUseAppIconInRow()) {
            if (mShouldShowAppIcon == shouldShowAppIcon) {
                return; // no change
            }

            mShouldShowAppIcon = shouldShowAppIcon;
            if (mShouldShowAppIcon) {
                adjustViewForAppIcon();
            } else {
                // Restore original padding and background if needed
                restoreViewForSmallIcon();
            }
        }
    }

    /**
     * Override padding and background from the view to display the app icon.
     */
    private void adjustViewForAppIcon() {
        removePadding();

        if (Flags.notificationsUseAppIconInRow()) {
            addWhiteBackground();
        } else {
            // No need to set the background for notification redesign, since the icon
            // factory already does that for us.
        removeBackground();
    }
    }

    /**
     * Restore padding and background overridden by {@link this#adjustViewForAppIcon}.
@@ -221,21 +178,6 @@ public class NotificationRowIconView extends CachingIconView {
        setBackground(null);
    }

    private void addWhiteBackground() {
        if (mOriginalBackground == null) {
            mOriginalBackground = getBackground();
        }

        // Make the background white in case the icon itself doesn't have one.
        ColorFilter colorFilter = new PorterDuffColorFilter(Color.WHITE,
                PorterDuff.Mode.SRC_ATOP);

        if (mOriginalBackground == null) {
            setBackground(getContext().getDrawable(R.drawable.notification_icon_circle));
        }
        getBackground().mutate().setColorFilter(colorFilter);
    }

    private void restoreBackground() {
        // NOTE: This will not work if the original background was null, but that's better than
        //  accidentally clearing the background. We expect that there's generally going to be one
+4 −18
Original line number Diff line number Diff line
@@ -383,34 +383,20 @@ public class NotificationGroupingUtil {
        }

        protected boolean hasSameIcon(Object parentData, Object childData) {
            Icon parentIcon = getIcon((Notification) parentData);
            Icon childIcon = getIcon((Notification) childData);
            Icon parentIcon = ((Notification) parentData).getSmallIcon();
            Icon childIcon = ((Notification) childData).getSmallIcon();
            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 = getColor((Notification) parentData);
            int childColor = getColor((Notification) childData);
            int parentColor = ((Notification) parentData).color;
            int childColor = ((Notification) childData).color;
            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;
Loading