Merge "Notification visibility APIs."
diff --git a/api/current.txt b/api/current.txt
index cb52442..6a869ab 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4224,6 +4224,9 @@
     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 @@
     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 @@
     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 @@
     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);
   }
 
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 62a84219..2c70803 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -402,6 +402,31 @@
     @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.
@@ -670,6 +695,13 @@
     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 @@
         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 @@
             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 @@
         } 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 @@
         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 @@
             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 @@
                 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;
         }