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

Commit d9228f11 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Stop populating RemoteViews in Notifications.

Builder now stores its parameters directly in the
Notification object itself, reducing the amount of copying
needed to construct the final Notification as well as
converging the two data structures. All Builder data is now
captured in Notification, so it is easy to reconstruct
a Builder for any Notification object.

This obviates all stripping/unstripping operations because
all Notification objects start life "stripped" of their
RemoteViews, which must be constructed explicitly by clients
(presumably listeners wishing to show the notification to
the user in its conventional form).

Note: While contentView, bigContentView, and
headsUpContentView are being @Deprecated in this CL,
specifying custom RemoteViews is definitely still supported!
You just have to use Builder methods to do so.

Bug: 20153922
Change-Id: I81f8ffed0eb76084b2f2b25b97e325858f0a1d05
parent 5918519f
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -4830,17 +4830,17 @@ package android.app {
    field public android.app.Notification.Action[] actions;
    field public android.media.AudioAttributes audioAttributes;
    field public deprecated int audioStreamType;
    field public android.widget.RemoteViews bigContentView;
    field public deprecated android.widget.RemoteViews bigContentView;
    field public java.lang.String category;
    field public int color;
    field public android.app.PendingIntent contentIntent;
    field public android.widget.RemoteViews contentView;
    field public deprecated android.widget.RemoteViews contentView;
    field public int defaults;
    field public android.app.PendingIntent deleteIntent;
    field public android.os.Bundle extras;
    field public int flags;
    field public android.app.PendingIntent fullScreenIntent;
    field public android.widget.RemoteViews headsUpContentView;
    field public deprecated android.widget.RemoteViews headsUpContentView;
    field public deprecated int icon;
    field public int iconLevel;
    field public deprecated android.graphics.Bitmap largeIcon;
@@ -4931,14 +4931,22 @@ package android.app {
    method public android.app.Notification.Builder extend(android.app.Notification.Extender);
    method public android.os.Bundle getExtras();
    method public deprecated android.app.Notification getNotification();
    method public android.widget.RemoteViews makeBigContentView();
    method public android.widget.RemoteViews makeContentView();
    method public android.widget.RemoteViews makeHeadsUpContentView();
    method public static android.app.Notification.Builder recoverBuilder(android.content.Context, android.app.Notification);
    method public android.app.Notification.Builder setActions(android.app.Notification.Action...);
    method public android.app.Notification.Builder setAutoCancel(boolean);
    method public android.app.Notification.Builder setCategory(java.lang.String);
    method public android.app.Notification.Builder setColor(int);
    method public android.app.Notification.Builder setContent(android.widget.RemoteViews);
    method public deprecated android.app.Notification.Builder setContent(android.widget.RemoteViews);
    method public android.app.Notification.Builder setContentInfo(java.lang.CharSequence);
    method public android.app.Notification.Builder setContentIntent(android.app.PendingIntent);
    method public android.app.Notification.Builder setContentText(java.lang.CharSequence);
    method public android.app.Notification.Builder setContentTitle(java.lang.CharSequence);
    method public android.app.Notification.Builder setCustomBigContentView(android.widget.RemoteViews);
    method public android.app.Notification.Builder setCustomContentView(android.widget.RemoteViews);
    method public android.app.Notification.Builder setCustomHeadsUpContentView(android.widget.RemoteViews);
    method public android.app.Notification.Builder setDefaults(int);
    method public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
    method public android.app.Notification.Builder setExtras(android.os.Bundle);
+12 −4
Original line number Diff line number Diff line
@@ -4947,17 +4947,17 @@ package android.app {
    field public android.app.Notification.Action[] actions;
    field public android.media.AudioAttributes audioAttributes;
    field public deprecated int audioStreamType;
    field public android.widget.RemoteViews bigContentView;
    field public deprecated android.widget.RemoteViews bigContentView;
    field public java.lang.String category;
    field public int color;
    field public android.app.PendingIntent contentIntent;
    field public android.widget.RemoteViews contentView;
    field public deprecated android.widget.RemoteViews contentView;
    field public int defaults;
    field public android.app.PendingIntent deleteIntent;
    field public android.os.Bundle extras;
    field public int flags;
    field public android.app.PendingIntent fullScreenIntent;
    field public android.widget.RemoteViews headsUpContentView;
    field public deprecated android.widget.RemoteViews headsUpContentView;
    field public deprecated int icon;
    field public int iconLevel;
    field public deprecated android.graphics.Bitmap largeIcon;
@@ -5048,14 +5048,22 @@ package android.app {
    method public android.app.Notification.Builder extend(android.app.Notification.Extender);
    method public android.os.Bundle getExtras();
    method public deprecated android.app.Notification getNotification();
    method public android.widget.RemoteViews makeBigContentView();
    method public android.widget.RemoteViews makeContentView();
    method public android.widget.RemoteViews makeHeadsUpContentView();
    method public static android.app.Notification.Builder recoverBuilder(android.content.Context, android.app.Notification);
    method public android.app.Notification.Builder setActions(android.app.Notification.Action...);
    method public android.app.Notification.Builder setAutoCancel(boolean);
    method public android.app.Notification.Builder setCategory(java.lang.String);
    method public android.app.Notification.Builder setColor(int);
    method public android.app.Notification.Builder setContent(android.widget.RemoteViews);
    method public deprecated android.app.Notification.Builder setContent(android.widget.RemoteViews);
    method public android.app.Notification.Builder setContentInfo(java.lang.CharSequence);
    method public android.app.Notification.Builder setContentIntent(android.app.PendingIntent);
    method public android.app.Notification.Builder setContentText(java.lang.CharSequence);
    method public android.app.Notification.Builder setContentTitle(java.lang.CharSequence);
    method public android.app.Notification.Builder setCustomBigContentView(android.widget.RemoteViews);
    method public android.app.Notification.Builder setCustomContentView(android.widget.RemoteViews);
    method public android.app.Notification.Builder setCustomHeadsUpContentView(android.widget.RemoteViews);
    method public android.app.Notification.Builder setDefaults(int);
    method public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
    method public android.app.Notification.Builder setExtras(android.os.Bundle);
+392 −683

File changed.

Preview size limit exceeded, changes collapsed.

+10 −37
Original line number Diff line number Diff line
@@ -207,33 +207,7 @@ public class NotificationManager
     */
    public void notify(String tag, int id, Notification notification)
    {
        int[] idOut = new int[1];
        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        if (notification.sound != null) {
            notification.sound = notification.sound.getCanonicalUri();
            if (StrictMode.vmFileUriExposureEnabled()) {
                notification.sound.checkFileUriExposed("Notification.sound");
            }
        }
        fixLegacySmallIcon(notification, pkg);
        if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
            if (notification.getSmallIcon() == null) {
                throw new IllegalArgumentException("Invalid notification (no valid small icon): "
                    + notification);
            }
        }
        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
        Notification stripped = notification.clone();
        Builder.stripForDelivery(stripped);
        try {
            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                    stripped, idOut, UserHandle.myUserId());
            if (id != idOut[0]) {
                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
            }
        } catch (RemoteException e) {
        }
        notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));
    }

    /**
@@ -251,12 +225,17 @@ public class NotificationManager
            }
        }
        fixLegacySmallIcon(notification, pkg);
        if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
            if (notification.getSmallIcon() == null) {
                throw new IllegalArgumentException("Invalid notification (no valid small icon): "
                        + notification);
            }
        }
        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
        Notification stripped = notification.clone();
        Builder.stripForDelivery(stripped);
        final Notification copy = notification.clone();
        try {
            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                    stripped, idOut, user.getIdentifier());
                    copy, idOut, user.getIdentifier());
            if (id != idOut[0]) {
                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
            }
@@ -287,13 +266,7 @@ public class NotificationManager
     */
    public void cancel(String tag, int id)
    {
        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
        try {
            service.cancelNotificationWithTag(pkg, tag, id, UserHandle.myUserId());
        } catch (RemoteException e) {
        }
        cancelAsUser(tag, id, new UserHandle(UserHandle.myUserId()));
    }

    /**
+17 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
@@ -472,9 +473,10 @@ public abstract class NotificationListenerService extends Service {
                StatusBarNotification sbn = list.get(i);
                Notification notification = sbn.getNotification();
                try {
                    Builder.rebuild(getContext(), notification);
                    // convert icon metadata to legacy format for older clients
                    createLegacyIconExtras(notification);
                    // populate remote views for older clients.
                    maybePopulateRemoteViews(notification);
                } catch (IllegalArgumentException e) {
                    if (corruptNotifications == null) {
                        corruptNotifications = new ArrayList<>(N);
@@ -676,6 +678,18 @@ public abstract class NotificationListenerService extends Service {
        }
    }

    /**
     * Populates remote views for pre-N targeting apps.
     */
    private void maybePopulateRemoteViews(Notification notification) {
        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) {
            Builder builder = Builder.recoverBuilder(getContext(), notification);
            notification.contentView = builder.makeContentView();
            notification.bigContentView = builder.makeBigContentView();
            notification.headsUpContentView = builder.makeHeadsUpContentView();
        }
    }

    private class INotificationListenerWrapper extends INotificationListener.Stub {
        @Override
        public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
@@ -689,9 +703,10 @@ public abstract class NotificationListenerService extends Service {
            }

            try {
                Notification.Builder.rebuild(getContext(), sbn.getNotification());
                Notification notification = sbn.getNotification();
                // convert icon metadata to legacy format for older clients
                createLegacyIconExtras(sbn.getNotification());
                maybePopulateRemoteViews(sbn.getNotification());
            } catch (IllegalArgumentException e) {
                // drop corrupt notification
                sbn = null;
Loading