Add API so apps can know when a user dismisses a bubble

Test: atest NotificationTest (in other cl)
Bug: 124381186
Change-Id: Icb20c0e8c9f283c19d4d02dc111a7942f73cd8b2
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index dc4f343..0166f52 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -8408,6 +8408,7 @@
     public static final class BubbleMetadata implements Parcelable {
 
         private PendingIntent mPendingIntent;
+        private PendingIntent mDeleteIntent;
         private CharSequence mTitle;
         private Icon mIcon;
         private int mDesiredHeight;
@@ -8436,11 +8437,13 @@
          */
         private static final int FLAG_SUPPRESS_INITIAL_NOTIFICATION = 0x00000002;
 
-        private BubbleMetadata(PendingIntent intent, CharSequence title, Icon icon, int height) {
-            mPendingIntent = intent;
+        private BubbleMetadata(PendingIntent expandIntent, PendingIntent deleteIntent,
+                CharSequence title, Icon icon, int height) {
+            mPendingIntent = expandIntent;
             mTitle = title;
             mIcon = icon;
             mDesiredHeight = height;
+            mDeleteIntent = deleteIntent;
         }
 
         private BubbleMetadata(Parcel in) {
@@ -8449,6 +8452,9 @@
             mIcon = Icon.CREATOR.createFromParcel(in);
             mDesiredHeight = in.readInt();
             mFlags = in.readInt();
+            if (in.readInt() != 0) {
+                mDeleteIntent = PendingIntent.CREATOR.createFromParcel(in);
+            }
         }
 
         /**
@@ -8459,6 +8465,13 @@
         }
 
         /**
+         * @return the pending intent to send when the bubble is dismissed by a user, if one exists.
+         */
+        public PendingIntent getDeleteIntent() {
+            return mDeleteIntent;
+        }
+
+        /**
          * @return the title that will appear along with the app content defined by
          * {@link #getIntent()} for this bubble.
          */
@@ -8525,6 +8538,10 @@
             mIcon.writeToParcel(out, 0);
             out.writeInt(mDesiredHeight);
             out.writeInt(mFlags);
+            out.writeInt(mDeleteIntent != null ? 1 : 0);
+            if (mDeleteIntent != null) {
+                mDeleteIntent.writeToParcel(out, 0);
+            }
         }
 
         private void setFlags(int flags) {
@@ -8541,6 +8558,7 @@
             private Icon mIcon;
             private int mDesiredHeight;
             private int mFlags;
+            private PendingIntent mDeleteIntent;
 
             /**
              * Constructs a new builder object.
@@ -8633,6 +8651,14 @@
             }
 
             /**
+             * Sets an optional intent to send when this bubble is explicitly removed by the user.
+             */
+            public BubbleMetadata.Builder setDeleteIntent(PendingIntent deleteIntent) {
+                mDeleteIntent = deleteIntent;
+                return this;
+            }
+
+            /**
              * Creates the {@link BubbleMetadata} defined by this builder.
              * <p>Will throw {@link IllegalStateException} if required fields have not been set
              * on this builder.</p>
@@ -8647,8 +8673,8 @@
                 if (mIcon == null) {
                     throw new IllegalStateException("Must supply an icon for the bubble");
                 }
-                BubbleMetadata data = new BubbleMetadata(mPendingIntent, mTitle, mIcon,
-                        mDesiredHeight);
+                BubbleMetadata data = new BubbleMetadata(mPendingIntent, mDeleteIntent, mTitle,
+                        mIcon, mDesiredHeight);
                 data.setFlags(mFlags);
                 return data;
             }