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

Commit 0bf2ed8a authored by Dan Sandler's avatar Dan Sandler
Browse files

Notification visibility APIs.

The new visibility property allows an application to signal
to SystemUI whether a notification's contents are safe to
show in "public" situations, i.e. outside of a secure
lockscreen, or whether they should be treated as "private"
(where only the icon is revealed).

Apps that post information that includes no personal or
sensitive information (e.g. a weather alert) can use
VISIBILITY_PUBLIC to allow users to see (and potentially
even dismiss) this kind of notification without unlocking
their devices.

The historical treatment of Android notifications
corresponds to VISIBILITY_PRIVATE, which is the default
visibility setting for all notifications, including apps
that are not aware of this API.

VISIBILITY_PRIVATE notifications may optionally specify a
publicVersion, which is a whole other Notification object
whose contentView will be shown in public contexts. This
allows an app to provide a "redacted" public version of its
notification that is more useful than the system-supplied
version (showing just the icon and app name) but still
conceals private information. For example, a messaging app
that today posts a Notification including the sender and
contents of each message could additionally specify a
publicVersion that says, simply, "N new messages".

There's also VISIBILITY_SECRET for notifications that should
be totally concealed (that is, no icon) in public contexts.
To reveal any hint of this kind of notification would
require the user to unlock the device.

Change-Id: I1552db36c469954d27d3c92ba21ac5c703d47ae1
parent 015d67f4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -4224,6 +4224,9 @@ package android.app {
    field public static final int PRIORITY_MAX = 2; // 0x2
    field public static final int PRIORITY_MIN = -2; // 0xfffffffe
    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
    field public android.app.Notification.Action[] actions;
    field public int audioStreamType;
    field public android.widget.RemoteViews bigContentView;
@@ -4242,10 +4245,12 @@ package android.app {
    field public int ledOnMS;
    field public int number;
    field public int priority;
    field public android.app.Notification publicVersion;
    field public android.net.Uri sound;
    field public java.lang.CharSequence tickerText;
    field public android.widget.RemoteViews tickerView;
    field public long[] vibrate;
    field public int visibility;
    field public long when;
  }
@@ -4299,6 +4304,7 @@ package android.app {
    method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
    method public android.app.Notification.Builder setPriority(int);
    method public android.app.Notification.Builder setProgress(int, int, boolean);
    method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
    method public android.app.Notification.Builder setShowWhen(boolean);
    method public android.app.Notification.Builder setSmallIcon(int);
    method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -4310,6 +4316,7 @@ package android.app {
    method public android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
    method public android.app.Notification.Builder setUsesChronometer(boolean);
    method public android.app.Notification.Builder setVibrate(long[]);
    method public android.app.Notification.Builder setVisibility(int);
    method public android.app.Notification.Builder setWhen(long);
  }
+86 −0
Original line number Diff line number Diff line
@@ -402,6 +402,31 @@ public class Notification implements Parcelable
    @Priority
    public int priority;


    /**
     * Sphere of visibility of this notification, which affects how and when the SystemUI reveals 
     * the notification's presence and contents in untrusted situations (namely, on the secure 
     * lockscreen).
     *
     * The default level, {@link #VISIBILITY_PRIVATE}, behaves exactly as notifications have always
     * done on Android: The notification's {@link #icon} and {@link #tickerText} (if available) are
     * shown in all situations, but the contents are only available if the device is unlocked for
     * the appropriate user.
     *
     * A more permissive policy can be expressed by {@link #VISIBILITY_PUBLIC}; such a notification
     * can be read even in an "insecure" context (that is, above a secure lockscreen).
     * To modify the public version of this notification—for example, to redact some portions—see
     * {@link Builder#setPublicVersion(Notification)}.
     *
     * Finally, a notification can be made {@link #VISIBILITY_SECRET}, which will suppress its icon
     * and ticker until the user has bypassed the lockscreen.
     */
    public int visibility;

    public static final int VISIBILITY_PUBLIC = 1;
    public static final int VISIBILITY_PRIVATE = 0;
    public static final int VISIBILITY_SECRET = -1;

    /**
     * @hide
     * Notification type: incoming call (voice or video) or similar synchronous communication request.
@@ -669,6 +694,13 @@ public class Notification implements Parcelable
     */
    public Action[] actions;

    /**
     * Replacement version of this notification whose content will be shown
     * in an insecure context such as atop a secure keyguard. See {@link #visibility}
     * and {@link #VISIBILITY_PUBLIC}.
     */
    public Notification publicVersion;

    /**
     * Constructs a Notification object with default values.
     * You might want to consider using {@link Builder} instead.
@@ -768,6 +800,12 @@ public class Notification implements Parcelable
        if (parcel.readInt() != 0) {
            bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
        }

        visibility = parcel.readInt();

        if (parcel.readInt() != 0) {
            publicVersion = Notification.CREATOR.createFromParcel(parcel);
        }
    }

    @Override
@@ -853,6 +891,13 @@ public class Notification implements Parcelable
            that.bigContentView = this.bigContentView.clone();
        }

        that.visibility = this.visibility;

        if (this.publicVersion != null) {
            that.publicVersion = new Notification();
            this.publicVersion.cloneInto(that.publicVersion, heavy);
        }

        if (!heavy) {
            that.lightenPayload(); // will clean out extras
        }
@@ -978,6 +1023,15 @@ public class Notification implements Parcelable
        } else {
            parcel.writeInt(0);
        }

        parcel.writeInt(visibility);

        if (publicVersion != null) {
            parcel.writeInt(1);
            publicVersion.writeToParcel(parcel, 0);
        } else {
            parcel.writeInt(0);
        }
    }

    /**
@@ -1181,6 +1235,8 @@ public class Notification implements Parcelable
        private boolean mUseChronometer;
        private Style mStyle;
        private boolean mShowWhen = true;
        private int mVisibility = VISIBILITY_PRIVATE;
        private Notification mPublicVersion = null;

        /**
         * Constructs a new Builder with the defaults:
@@ -1627,6 +1683,30 @@ public class Notification implements Parcelable
            return this;
        }

        /**
         * Specify the value of {@link #visibility}.

         * @param visibility One of {@link #VISIBILITY_PRIVATE} (the default),
         * {@link #VISIBILITY_SECRET}, or {@link #VISIBILITY_PUBLIC}.
         *
         * @return The same Builder.
         */
        public Builder setVisibility(int visibility) {
            mVisibility = visibility;
            return this;
        }

        /**
         * Supply a replacement Notification whose contents should be shown in insecure contexts
         * (i.e. atop the secure lockscreen). See {@link #visibility} and {@link #VISIBILITY_PUBLIC}.
         * @param n A replacement notification, presumably with some or all info redacted.
         * @return The same Builder.
         */
        public Builder setPublicVersion(Notification n) {
            mPublicVersion = n;
            return this;
        }

        private void setFlag(int mask, boolean value) {
            if (value) {
                mFlags |= mask;
@@ -1839,6 +1919,12 @@ public class Notification implements Parcelable
                n.actions = new Action[mActions.size()];
                mActions.toArray(n.actions);
            }
            n.visibility = mVisibility;

            if (mPublicVersion != null) {
                n.publicVersion = new Notification();
                mPublicVersion.cloneInto(n.publicVersion, true);
            }

            return n;
        }