Separate concept of VIC from DND

(Very important conversations). Track VICs in a different
field, and update DND (and public apis) to allow
all, important, or no conversations through.

Test: atest, cts
Bug: 137397357

Change-Id: Iae04546eb7c0b1e79cfdbeec7311628cd7ad634a
diff --git a/api/current.txt b/api/current.txt
index 2416493..d325278 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5918,6 +5918,7 @@
     method public long[] getVibrationPattern();
     method public boolean hasUserSetImportance();
     method public boolean hasUserSetSound();
+    method public boolean isImportantConversation();
     method public void setAllowBubbles(boolean);
     method public void setBypassDnd(boolean);
     method public void setConversationId(@Nullable String, @Nullable String);
@@ -6030,14 +6031,19 @@
   public static class NotificationManager.Policy implements android.os.Parcelable {
     ctor public NotificationManager.Policy(int, int, int);
     ctor public NotificationManager.Policy(int, int, int, int);
+    ctor public NotificationManager.Policy(int, int, int, int, int);
     method public int describeContents();
     method public static String priorityCategoriesToString(int);
     method public static String prioritySendersToString(int);
     method public static String suppressedEffectsToString(int);
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CONVERSATION_SENDERS_ANYONE = 1; // 0x1
+    field public static final int CONVERSATION_SENDERS_IMPORTANT = 2; // 0x2
+    field public static final int CONVERSATION_SENDERS_NONE = 3; // 0x3
     field @NonNull public static final android.os.Parcelable.Creator<android.app.NotificationManager.Policy> CREATOR;
     field public static final int PRIORITY_CATEGORY_ALARMS = 32; // 0x20
     field public static final int PRIORITY_CATEGORY_CALLS = 8; // 0x8
+    field public static final int PRIORITY_CATEGORY_CONVERSATIONS = 256; // 0x100
     field public static final int PRIORITY_CATEGORY_EVENTS = 2; // 0x2
     field public static final int PRIORITY_CATEGORY_MEDIA = 64; // 0x40
     field public static final int PRIORITY_CATEGORY_MESSAGES = 4; // 0x4
@@ -6058,6 +6064,7 @@
     field public static final int SUPPRESSED_EFFECT_STATUS_BAR = 32; // 0x20
     field public final int priorityCallSenders;
     field public final int priorityCategories;
+    field public final int priorityConversationSenders;
     field public final int priorityMessageSenders;
     field public final int suppressedVisualEffects;
   }
@@ -43775,12 +43782,14 @@
     method public int getPriorityCallSenders();
     method public int getPriorityCategoryAlarms();
     method public int getPriorityCategoryCalls();
+    method public int getPriorityCategoryConversations();
     method public int getPriorityCategoryEvents();
     method public int getPriorityCategoryMedia();
     method public int getPriorityCategoryMessages();
     method public int getPriorityCategoryReminders();
     method public int getPriorityCategoryRepeatCallers();
     method public int getPriorityCategorySystem();
+    method public int getPriorityConversationSenders();
     method public int getPriorityMessageSenders();
     method public int getVisualEffectAmbient();
     method public int getVisualEffectBadge();
@@ -43790,6 +43799,10 @@
     method public int getVisualEffectPeek();
     method public int getVisualEffectStatusBar();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CONVERSATION_SENDERS_ANYONE = 1; // 0x1
+    field public static final int CONVERSATION_SENDERS_IMPORTANT = 2; // 0x2
+    field public static final int CONVERSATION_SENDERS_NONE = 3; // 0x3
+    field public static final int CONVERSATION_SENDERS_UNSET = 0; // 0x0
     field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.ZenPolicy> CREATOR;
     field public static final int PEOPLE_TYPE_ANYONE = 1; // 0x1
     field public static final int PEOPLE_TYPE_CONTACTS = 2; // 0x2
@@ -43806,6 +43819,7 @@
     method @NonNull public android.service.notification.ZenPolicy.Builder allowAlarms(boolean);
     method @NonNull public android.service.notification.ZenPolicy.Builder allowAllSounds();
     method @NonNull public android.service.notification.ZenPolicy.Builder allowCalls(int);
+    method @NonNull public android.service.notification.ZenPolicy.Builder allowConversations(int);
     method @NonNull public android.service.notification.ZenPolicy.Builder allowEvents(boolean);
     method @NonNull public android.service.notification.ZenPolicy.Builder allowMedia(boolean);
     method @NonNull public android.service.notification.ZenPolicy.Builder allowMessages(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index fda3ab4..52d85cf 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -416,6 +416,7 @@
     method public void setFgServiceShown(boolean);
     method public void setImportanceLockedByCriticalDeviceFunction(boolean);
     method public void setImportanceLockedByOEM(boolean);
+    method public void setImportantConversation(boolean);
     method public void setOriginalImportance(int);
   }
 
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 4b24e09..7212be8 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -31,7 +31,6 @@
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.Preconditions;
@@ -105,6 +104,7 @@
     private static final String ATT_ORIG_IMP = "orig_imp";
     private static final String ATT_PARENT_CHANNEL = "parent";
     private static final String ATT_CONVERSATION_ID = "conv_id";
+    private static final String ATT_IMP_CONVERSATION = "imp_conv";
     private static final String ATT_DEMOTE = "dem";
     private static final String DELIMITER = ",";
 
@@ -196,6 +196,7 @@
     private String mParentId = null;
     private String mConversationId = null;
     private boolean mDemoted = false;
+    private boolean mImportantConvo = false;
 
     /**
      * Creates a notification channel.
@@ -263,6 +264,7 @@
         mParentId = in.readString();
         mConversationId = in.readString();
         mDemoted = in.readBoolean();
+        mImportantConvo = in.readBoolean();
     }
 
     @Override
@@ -321,6 +323,7 @@
         dest.writeString(mParentId);
         dest.writeString(mConversationId);
         dest.writeBoolean(mDemoted);
+        dest.writeBoolean(mImportantConvo);
     }
 
     /**
@@ -354,6 +357,14 @@
     }
 
     /**
+     * @hide
+     */
+    @TestApi
+    public void setImportantConversation(boolean importantConvo) {
+        mImportantConvo = importantConvo;
+    }
+
+    /**
      * Allows users to block notifications sent through this channel, if this channel belongs to
      * a package that is signed with the system signature. If the channel does not belong to a
      * package that is signed with the system signature, this method does nothing.
@@ -601,6 +612,18 @@
     }
 
     /**
+     * Whether or not notifications in this conversation are considered important.
+     *
+     * <p>Important conversations may get special visual treatment, and might be able to bypass DND.
+     *
+     * <p>This is only valid for channels that represent conversations, that is, those with a valid
+     * {@link #getConversationId() conversation id}.
+     */
+    public boolean isImportantConversation() {
+        return mImportantConvo;
+    }
+
+    /**
      * Returns the notification sound for this channel.
      */
     public Uri getSound() {
@@ -852,6 +875,7 @@
         setConversationId(parser.getAttributeValue(null, ATT_PARENT_CHANNEL),
                 parser.getAttributeValue(null, ATT_CONVERSATION_ID));
         setDemoted(safeBool(parser, ATT_DEMOTE, false));
+        setImportantConversation(safeBool(parser, ATT_IMP_CONVERSATION, false));
     }
 
     @Nullable
@@ -985,6 +1009,9 @@
         if (isDemoted()) {
             out.attribute(null, ATT_DEMOTE, Boolean.toString(isDemoted()));
         }
+        if (isImportantConversation()) {
+            out.attribute(null, ATT_IMP_CONVERSATION, Boolean.toString(isImportantConversation()));
+        }
 
         // mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of
         // truth and so aren't written to this xml file
@@ -1145,7 +1172,8 @@
                 && mOriginalImportance == that.mOriginalImportance
                 && Objects.equals(getParentChannelId(), that.getParentChannelId())
                 && Objects.equals(getConversationId(), that.getConversationId())
-                && isDemoted() == that.isDemoted();
+                && isDemoted() == that.isDemoted()
+                && isImportantConversation() == that.isImportantConversation();
     }
 
     @Override
@@ -1156,7 +1184,7 @@
                 isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(),
                 getAudioAttributes(), isBlockableSystem(), mAllowBubbles,
                 mImportanceLockedByOEM, mImportanceLockedDefaultApp, mOriginalImportance,
-                mParentId, mConversationId, mDemoted);
+                mParentId, mConversationId, mDemoted, mImportantConvo);
         result = 31 * result + Arrays.hashCode(mVibration);
         return result;
     }
@@ -1204,7 +1232,8 @@
                 + ", mOriginalImp=" + mOriginalImportance
                 + ", mParent=" + mParentId
                 + ", mConversationId=" + mConversationId
-                + ", mDemoted=" + mDemoted;
+                + ", mDemoted=" + mDemoted
+                + ", mImportantConvo=" + mImportantConvo;
     }
 
     /** @hide */
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 1a8e15c..528b508 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -46,6 +46,7 @@
 import android.service.notification.Condition;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenPolicy;
 import android.util.Log;
 import android.util.proto.ProtoOutputStream;
 
@@ -1555,19 +1556,24 @@
         public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
         /**System (catch-all for non-never suppressible sounds) are prioritized */
         public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
+        /**
+         * Conversations are allowed through DND.
+         */
+        public static final int PRIORITY_CATEGORY_CONVERSATIONS = 1 << 8;
 
         /**
          * @hide
          */
         public static final int[] ALL_PRIORITY_CATEGORIES = {
-            PRIORITY_CATEGORY_ALARMS,
-            PRIORITY_CATEGORY_MEDIA,
-            PRIORITY_CATEGORY_SYSTEM,
-            PRIORITY_CATEGORY_REMINDERS,
-            PRIORITY_CATEGORY_EVENTS,
-            PRIORITY_CATEGORY_MESSAGES,
-            PRIORITY_CATEGORY_CALLS,
-            PRIORITY_CATEGORY_REPEAT_CALLERS,
+                PRIORITY_CATEGORY_ALARMS,
+                PRIORITY_CATEGORY_MEDIA,
+                PRIORITY_CATEGORY_SYSTEM,
+                PRIORITY_CATEGORY_REMINDERS,
+                PRIORITY_CATEGORY_EVENTS,
+                PRIORITY_CATEGORY_MESSAGES,
+                PRIORITY_CATEGORY_CALLS,
+                PRIORITY_CATEGORY_REPEAT_CALLERS,
+                PRIORITY_CATEGORY_CONVERSATIONS,
         };
 
         /** Any sender is prioritized. */
@@ -1577,6 +1583,31 @@
         /** Only starred contacts are prioritized. */
         public static final int PRIORITY_SENDERS_STARRED = 2;
 
+
+        /** @hide */
+        @IntDef(prefix = { "CONVERSATION_SENDERS_" }, value = {
+                CONVERSATION_SENDERS_ANYONE,
+                CONVERSATION_SENDERS_IMPORTANT,
+                CONVERSATION_SENDERS_NONE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface ConversationSenders {}
+        /**
+         * Used to indicate all conversations can bypass dnd.
+         */
+        public static final int CONVERSATION_SENDERS_ANYONE = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
+
+        /**
+         * Used to indicate important conversations can bypass dnd.
+         */
+        public static final int CONVERSATION_SENDERS_IMPORTANT =
+                ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
+
+        /**
+         * Used to indicate no conversations can bypass dnd.
+         */
+        public static final int CONVERSATION_SENDERS_NONE = ZenPolicy.CONVERSATION_SENDERS_NONE;
+
         /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
         public final int priorityCategories;
 
@@ -1589,6 +1620,18 @@
         public final int priorityMessageSenders;
 
         /**
+         * Notification senders to prioritize for conversations. One of:
+         * {@link #CONVERSATION_SENDERS_NONE}, {@link #CONVERSATION_SENDERS_IMPORTANT},
+         * {@link #CONVERSATION_SENDERS_ANYONE}.
+         */
+        public final int priorityConversationSenders;
+
+        /**
+         * @hide
+         */
+        public static final int CONVERSATION_SENDERS_UNSET = -1;
+
+        /**
          * @hide
          */
         public static final int SUPPRESSED_EFFECTS_UNSET = -1;
@@ -1665,21 +1708,6 @@
                 SUPPRESSED_EFFECT_NOTIFICATION_LIST
         };
 
-        private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
-                SUPPRESSED_EFFECT_SCREEN_OFF,
-                SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
-                SUPPRESSED_EFFECT_LIGHTS,
-                SUPPRESSED_EFFECT_AMBIENT,
-        };
-
-        private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
-                SUPPRESSED_EFFECT_SCREEN_ON,
-                SUPPRESSED_EFFECT_PEEK,
-                SUPPRESSED_EFFECT_STATUS_BAR,
-                SUPPRESSED_EFFECT_BADGE,
-                SUPPRESSED_EFFECT_NOTIFICATION_LIST
-        };
-
         /**
          * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
          * Bitmask of SUPPRESSED_EFFECT_* constants.
@@ -1718,17 +1746,16 @@
          */
         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
-                    SUPPRESSED_EFFECTS_UNSET, STATE_UNSET);
+                    SUPPRESSED_EFFECTS_UNSET, STATE_UNSET, CONVERSATION_SENDERS_UNSET);
         }
 
         /**
          * Constructs a policy for Do Not Disturb priority mode behavior.
          *
          * <p>
-         *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
+         *     Apps that target API levels below {@link Build.VERSION_CODES#R} cannot
          *     change user-designated values to allow or disallow
-         *     {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
-         *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
+         *     {@link Policy#PRIORITY_CATEGORY_CONVERSATIONS}, from bypassing dnd.
          * <p>
          *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
          *     only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
@@ -1752,27 +1779,68 @@
          */
         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
                 int suppressedVisualEffects) {
-            this.priorityCategories = priorityCategories;
-            this.priorityCallSenders = priorityCallSenders;
-            this.priorityMessageSenders = priorityMessageSenders;
-            this.suppressedVisualEffects = suppressedVisualEffects;
-            this.state = STATE_UNSET;
+            this(priorityCategories, priorityCallSenders, priorityMessageSenders,
+                    suppressedVisualEffects, STATE_UNSET, CONVERSATION_SENDERS_UNSET);
+        }
+
+        /**
+         * Constructs a policy for Do Not Disturb priority mode behavior.
+         *
+         * <p>
+         *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
+         *     change user-designated values to allow or disallow
+         *     {@link Policy#PRIORITY_CATEGORY_CONVERSATIONS} from bypassing dnd. If you do need
+         *     to change them, use a {@link ZenPolicy} associated with an {@link AutomaticZenRule}
+         *     instead of changing the global setting.
+         * <p>
+         *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
+         *     change user-designated values to allow or disallow
+         *     {@link Policy#PRIORITY_CATEGORY_ALARMS},
+         *     {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
+         *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
+         * <p>
+         *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
+         *     only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
+         *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
+         *     All other suppressed effects will be ignored and reconstituted from the screen on
+         *     and screen off values.
+         * <p>
+         *     Apps that target {@link Build.VERSION_CODES#P} or above can set any
+         *     suppressed visual effects. However, if any suppressed effects >
+         *     {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
+         *     and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
+         *     the more specific suppressed visual effect bits. Apps should migrate to targeting
+         *     specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
+         *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
+         *
+         * @param priorityCategories bitmask of categories of notifications that can bypass DND.
+         * @param priorityCallSenders which callers can bypass DND.
+         * @param priorityMessageSenders which message senders can bypass DND.
+         * @param suppressedVisualEffects which visual interruptions should be suppressed from
+         *                                notifications that are filtered by DND.
+         */
+        public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
+                int suppressedVisualEffects, int priorityConversationSenders) {
+            this(priorityCategories, priorityCallSenders, priorityMessageSenders,
+                    suppressedVisualEffects, STATE_UNSET, priorityConversationSenders);
         }
 
         /** @hide */
         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
-                int suppressedVisualEffects, int state) {
+                int suppressedVisualEffects, int state, int priorityConversationSenders) {
             this.priorityCategories = priorityCategories;
             this.priorityCallSenders = priorityCallSenders;
             this.priorityMessageSenders = priorityMessageSenders;
             this.suppressedVisualEffects = suppressedVisualEffects;
             this.state = state;
+            this.priorityConversationSenders = priorityConversationSenders;
         }
 
+
         /** @hide */
         public Policy(Parcel source) {
             this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
-                    source.readInt());
+                    source.readInt(), source.readInt());
         }
 
         @Override
@@ -1782,6 +1850,7 @@
             dest.writeInt(priorityMessageSenders);
             dest.writeInt(suppressedVisualEffects);
             dest.writeInt(state);
+            dest.writeInt(priorityConversationSenders);
         }
 
         @Override
@@ -1792,7 +1861,7 @@
         @Override
         public int hashCode() {
             return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
-                    suppressedVisualEffects, state);
+                    suppressedVisualEffects, state, priorityConversationSenders);
         }
 
         @Override
@@ -1805,7 +1874,8 @@
                     && other.priorityMessageSenders == priorityMessageSenders
                     && suppressedVisualEffectsEqual(suppressedVisualEffects,
                     other.suppressedVisualEffects)
-                    && other.state == this.state;
+                    && other.state == this.state
+                    && other.priorityConversationSenders == this.priorityConversationSenders;
         }
 
         private boolean suppressedVisualEffectsEqual(int suppressedEffects,
@@ -1867,6 +1937,8 @@
                     + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
                     + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
                     + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
+                    + ",priorityConvSenders="
+                    + conversationSendersToString(priorityConversationSenders)
                     + ",suppressedVisualEffects="
                     + suppressedEffectsToString(suppressedVisualEffects)
                     + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
@@ -2003,6 +2075,7 @@
                 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
                 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
                 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
+                case PRIORITY_CATEGORY_CONVERSATIONS: return "PRIORITY_CATEGORY_CONVERSATIONS";
                 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
             }
         }
@@ -2016,7 +2089,25 @@
             }
         }
 
-        public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
+        /**
+         * @hide
+         */
+        public static @NonNull String conversationSendersToString(int priorityConversationSenders) {
+            switch (priorityConversationSenders) {
+                case CONVERSATION_SENDERS_ANYONE:
+                    return "anyone";
+                case CONVERSATION_SENDERS_IMPORTANT:
+                    return "important";
+                case CONVERSATION_SENDERS_NONE:
+                    return "none";
+                case CONVERSATION_SENDERS_UNSET:
+                    return "unset";
+            }
+            return "invalidConversationType{" + priorityConversationSenders + "}";
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR
+                = new Parcelable.Creator<Policy>() {
             @Override
             public Policy createFromParcel(Parcel in) {
                 return new Policy(in);
@@ -2054,6 +2145,11 @@
         }
 
         /** @hide **/
+        public boolean allowConversations() {
+            return (priorityCategories & PRIORITY_CATEGORY_CONVERSATIONS) != 0;
+        }
+
+        /** @hide **/
         public boolean allowMessages() {
             return (priorityCategories & PRIORITY_CATEGORY_MESSAGES) != 0;
         }
@@ -2079,6 +2175,11 @@
         }
 
         /** @hide **/
+        public int allowConversationsFrom() {
+            return priorityConversationSenders;
+        }
+
+        /** @hide **/
         public boolean showFullScreenIntents() {
             return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0;
         }
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 3f9462c..af91596 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -16,6 +16,9 @@
 
 package android.service.notification;
 
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
@@ -99,6 +102,8 @@
     private static final boolean DEFAULT_ALLOW_REMINDERS = false;
     private static final boolean DEFAULT_ALLOW_EVENTS = false;
     private static final boolean DEFAULT_ALLOW_REPEAT_CALLERS = true;
+    private static final boolean DEFAULT_ALLOW_CONV = true;
+    private static final int DEFAULT_ALLOW_CONV_FROM = ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
     private static final boolean DEFAULT_CHANNELS_BYPASSING_DND = false;
     private static final int DEFAULT_SUPPRESSED_VISUAL_EFFECTS = 0;
 
@@ -120,6 +125,8 @@
     private static final String ALLOW_ATT_EVENTS = "events";
     private static final String ALLOW_ATT_SCREEN_OFF = "visualScreenOff";
     private static final String ALLOW_ATT_SCREEN_ON = "visualScreenOn";
+    private static final String ALLOW_ATT_CONV = "conv";
+    private static final String ALLOW_ATT_CONV_FROM = "convFrom";
     private static final String DISALLOW_TAG = "disallow";
     private static final String DISALLOW_ATT_VISUAL_EFFECTS = "visualEffects";
     private static final String STATE_TAG = "state";
@@ -170,6 +177,8 @@
     public boolean allowEvents = DEFAULT_ALLOW_EVENTS;
     public int allowCallsFrom = DEFAULT_CALLS_SOURCE;
     public int allowMessagesFrom = DEFAULT_SOURCE;
+    public boolean allowConversations = DEFAULT_ALLOW_CONV;
+    public int allowConversationsFrom = DEFAULT_ALLOW_CONV_FROM;
     public int user = UserHandle.USER_SYSTEM;
     public int suppressedVisualEffects = DEFAULT_SUPPRESSED_VISUAL_EFFECTS;
     public boolean areChannelsBypassingDnd = DEFAULT_CHANNELS_BYPASSING_DND;
@@ -207,6 +216,8 @@
         allowSystem = source.readInt() == 1;
         suppressedVisualEffects = source.readInt();
         areChannelsBypassingDnd = source.readInt() == 1;
+        allowConversations = source.readBoolean();
+        allowConversationsFrom = source.readInt();
     }
 
     @Override
@@ -239,6 +250,8 @@
         dest.writeInt(allowSystem ? 1 : 0);
         dest.writeInt(suppressedVisualEffects);
         dest.writeInt(areChannelsBypassingDnd ? 1 : 0);
+        dest.writeBoolean(allowConversations);
+        dest.writeInt(allowConversationsFrom);
     }
 
     @Override
@@ -253,8 +266,11 @@
                 .append(",allowCalls=").append(allowCalls)
                 .append(",allowRepeatCallers=").append(allowRepeatCallers)
                 .append(",allowMessages=").append(allowMessages)
+                .append(",allowConversations=").append(allowConversations)
                 .append(",allowCallsFrom=").append(sourceToString(allowCallsFrom))
                 .append(",allowMessagesFrom=").append(sourceToString(allowMessagesFrom))
+                .append(",allowConvFrom=").append(ZenPolicy.conversationTypeToString
+                        (allowConversationsFrom))
                 .append(",suppressedVisualEffects=").append(suppressedVisualEffects)
                 .append(",areChannelsBypassingDnd=").append(areChannelsBypassingDnd)
                 .append(",\nautomaticRules=").append(rulesToString())
@@ -431,7 +447,9 @@
                 && Objects.equals(other.automaticRules, automaticRules)
                 && Objects.equals(other.manualRule, manualRule)
                 && other.suppressedVisualEffects == suppressedVisualEffects
-                && other.areChannelsBypassingDnd == areChannelsBypassingDnd;
+                && other.areChannelsBypassingDnd == areChannelsBypassingDnd
+                && other.allowConversations == allowConversations
+                && other.allowConversationsFrom == allowConversationsFrom;
     }
 
     @Override
@@ -440,7 +458,8 @@
                 allowRepeatCallers, allowMessages,
                 allowCallsFrom, allowMessagesFrom, allowReminders, allowEvents,
                 user, automaticRules, manualRule,
-                suppressedVisualEffects, areChannelsBypassingDnd);
+                suppressedVisualEffects, areChannelsBypassingDnd, allowConversations,
+                allowConversationsFrom);
     }
 
     private static String toDayList(int[] days) {
@@ -518,10 +537,13 @@
                             DEFAULT_ALLOW_MESSAGES);
                     rt.allowReminders = safeBoolean(parser, ALLOW_ATT_REMINDERS,
                             DEFAULT_ALLOW_REMINDERS);
+                    rt.allowConversations = safeBoolean(parser, ALLOW_ATT_CONV, DEFAULT_ALLOW_CONV);
                     rt.allowEvents = safeBoolean(parser, ALLOW_ATT_EVENTS, DEFAULT_ALLOW_EVENTS);
                     final int from = safeInt(parser, ALLOW_ATT_FROM, -1);
                     final int callsFrom = safeInt(parser, ALLOW_ATT_CALLS_FROM, -1);
                     final int messagesFrom = safeInt(parser, ALLOW_ATT_MESSAGES_FROM, -1);
+                    rt.allowConversationsFrom = safeInt(parser, ALLOW_ATT_CONV_FROM,
+                            DEFAULT_ALLOW_CONV_FROM);
                     if (isValidSource(callsFrom) && isValidSource(messagesFrom)) {
                         rt.allowCallsFrom = callsFrom;
                         rt.allowMessagesFrom = messagesFrom;
@@ -602,6 +624,8 @@
         out.attribute(null, ALLOW_ATT_ALARMS, Boolean.toString(allowAlarms));
         out.attribute(null, ALLOW_ATT_MEDIA, Boolean.toString(allowMedia));
         out.attribute(null, ALLOW_ATT_SYSTEM, Boolean.toString(allowSystem));
+        out.attribute(null, ALLOW_ATT_CONV, Boolean.toString(allowConversations));
+        out.attribute(null, ALLOW_ATT_CONV_FROM, Integer.toString(allowConversationsFrom));
         out.endTag(null, ALLOW_TAG);
 
         out.startTag(null, DISALLOW_TAG);
@@ -944,6 +968,7 @@
         int suppressedVisualEffects = 0;
         int callSenders = defaultPolicy.priorityCallSenders;
         int messageSenders = defaultPolicy.priorityMessageSenders;
+        int conversationSenders = defaultPolicy.priorityConversationSenders;
 
         if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_REMINDERS,
                 isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_REMINDERS, defaultPolicy))) {
@@ -962,6 +987,14 @@
                     messageSenders);
         }
 
+        if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_CONVERSATIONS,
+                isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CONVERSATIONS, defaultPolicy))) {
+            priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
+            conversationSenders = getNotificationPolicySenders(
+                    zenPolicy.getPriorityConversationSenders(),
+                    conversationSenders);
+        }
+
         if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_CALLS,
                 isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS, defaultPolicy))) {
             priorityCategories |= Policy.PRIORITY_CATEGORY_CALLS;
@@ -1047,7 +1080,7 @@
         }
 
         return new NotificationManager.Policy(priorityCategories, callSenders,
-                messageSenders, suppressedVisualEffects, defaultPolicy.state);
+                messageSenders, suppressedVisualEffects, defaultPolicy.state, conversationSenders);
     }
 
     private boolean isPriorityCategoryEnabled(int categoryType, Policy policy) {
@@ -1088,11 +1121,14 @@
         }
     }
 
-
     public Policy toNotificationPolicy() {
         int priorityCategories = 0;
         int priorityCallSenders = Policy.PRIORITY_SENDERS_CONTACTS;
         int priorityMessageSenders = Policy.PRIORITY_SENDERS_CONTACTS;
+        int priorityConversationSenders = Policy.CONVERSATION_SENDERS_IMPORTANT;
+        if (allowConversations) {
+            priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
+        }
         if (allowCalls) {
             priorityCategories |= Policy.PRIORITY_CATEGORY_CALLS;
         }
@@ -1119,10 +1155,12 @@
         }
         priorityCallSenders = sourceToPrioritySenders(allowCallsFrom, priorityCallSenders);
         priorityMessageSenders = sourceToPrioritySenders(allowMessagesFrom, priorityMessageSenders);
+        priorityConversationSenders = allowConversationsFrom;
 
         return new Policy(priorityCategories, priorityCallSenders, priorityMessageSenders,
                 suppressedVisualEffects, areChannelsBypassingDnd
-                ? Policy.STATE_CHANNELS_BYPASSING_DND : 0);
+                ? Policy.STATE_CHANNELS_BYPASSING_DND : 0,
+                priorityConversationSenders);
     }
 
     /**
@@ -1157,6 +1195,27 @@
         }
     }
 
+    private static int normalizePrioritySenders(int prioritySenders, int def) {
+        if (!(prioritySenders == Policy.PRIORITY_SENDERS_CONTACTS
+                || prioritySenders == Policy.PRIORITY_SENDERS_STARRED
+                || prioritySenders == Policy.PRIORITY_SENDERS_ANY)) {
+            return def;
+        }
+        return prioritySenders;
+    }
+
+    private static int normalizeConversationSenders(boolean allowed, int senders, int def) {
+        if (!allowed) {
+            return CONVERSATION_SENDERS_NONE;
+        }
+        if (!(senders == CONVERSATION_SENDERS_ANYONE
+                || senders == CONVERSATION_SENDERS_IMPORTANT
+                || senders == CONVERSATION_SENDERS_NONE)) {
+            return def;
+        }
+        return senders;
+    }
+
     public void applyNotificationPolicy(Policy policy) {
         if (policy == null) return;
         allowAlarms = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_ALARMS) != 0;
@@ -1168,12 +1227,17 @@
         allowMessages = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MESSAGES) != 0;
         allowRepeatCallers = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_REPEAT_CALLERS)
                 != 0;
-        allowCallsFrom = prioritySendersToSource(policy.priorityCallSenders, allowCallsFrom);
-        allowMessagesFrom = prioritySendersToSource(policy.priorityMessageSenders,
+        allowCallsFrom = normalizePrioritySenders(policy.priorityCallSenders, allowCallsFrom);
+        allowMessagesFrom = normalizePrioritySenders(policy.priorityMessageSenders,
                 allowMessagesFrom);
         if (policy.suppressedVisualEffects != Policy.SUPPRESSED_EFFECTS_UNSET) {
             suppressedVisualEffects = policy.suppressedVisualEffects;
         }
+        allowConversations = (policy.priorityCategories
+                & Policy.PRIORITY_CATEGORY_CONVERSATIONS) != 0;
+        allowConversationsFrom = normalizeConversationSenders(allowConversations,
+                policy.priorityConversationSenders,
+                allowConversationsFrom);
         if (policy.state != Policy.STATE_UNSET) {
             areChannelsBypassingDnd = (policy.state & Policy.STATE_CHANNELS_BYPASSING_DND) != 0;
         }
@@ -1919,10 +1983,13 @@
                 & NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS) != 0;
         boolean allowRepeatCallers = (policy.priorityCategories
                 & NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS) != 0;
+        boolean allowConversations = (policy.priorityConversationSenders
+                & Policy.PRIORITY_CATEGORY_CONVERSATIONS) != 0;
         boolean areChannelsBypassingDnd = (policy.state & Policy.STATE_CHANNELS_BYPASSING_DND) != 0;
         boolean allowSystem =  (policy.priorityCategories & Policy.PRIORITY_CATEGORY_SYSTEM) != 0;
         return !allowReminders && !allowCalls && !allowMessages && !allowEvents
-                && !allowRepeatCallers && !areChannelsBypassingDnd && !allowSystem;
+                && !allowRepeatCallers && !areChannelsBypassingDnd && !allowSystem
+                && !allowConversations;
     }
 
     /**
diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java
index 6e2faa9..87295e1 100644
--- a/core/java/android/service/notification/ZenPolicy.java
+++ b/core/java/android/service/notification/ZenPolicy.java
@@ -41,6 +41,7 @@
     private ArrayList<Integer> mVisualEffects;
     private @PeopleType int mPriorityMessages = PEOPLE_TYPE_UNSET;
     private @PeopleType int mPriorityCalls = PEOPLE_TYPE_UNSET;
+    private @ConversationSenders int mConversationSenders = CONVERSATION_SENDERS_UNSET;
 
     /** @hide */
     @IntDef(prefix = { "PRIORITY_CATEGORY_" }, value = {
@@ -52,6 +53,7 @@
             PRIORITY_CATEGORY_ALARMS,
             PRIORITY_CATEGORY_MEDIA,
             PRIORITY_CATEGORY_SYSTEM,
+            PRIORITY_CATEGORY_CONVERSATIONS,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PriorityCategory {}
@@ -72,6 +74,8 @@
     public static final int PRIORITY_CATEGORY_MEDIA = 6;
     /** @hide */
     public static final int PRIORITY_CATEGORY_SYSTEM = 7;
+    /** @hide */
+    public static final int PRIORITY_CATEGORY_CONVERSATIONS = 8;
 
     /** @hide */
     @IntDef(prefix = { "VISUAL_EFFECT_" }, value = {
@@ -138,6 +142,37 @@
      */
     public static final int PEOPLE_TYPE_NONE = 4;
 
+
+    /** @hide */
+    @IntDef(prefix = { "CONVERSATION_SENDERS_" }, value = {
+            CONVERSATION_SENDERS_UNSET,
+            CONVERSATION_SENDERS_ANYONE,
+            CONVERSATION_SENDERS_IMPORTANT,
+            CONVERSATION_SENDERS_NONE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ConversationSenders {}
+
+    /**
+     * Used to indicate no preference for the type of conversations that can bypass dnd.
+     */
+    public static final int CONVERSATION_SENDERS_UNSET = 0;
+
+    /**
+     * Used to indicate all conversations can bypass dnd.
+     */
+    public static final int CONVERSATION_SENDERS_ANYONE = 1;
+
+    /**
+     * Used to indicate important conversations can bypass dnd.
+     */
+    public static final int CONVERSATION_SENDERS_IMPORTANT = 2;
+
+    /**
+     * Used to indicate no conversations can bypass dnd.
+     */
+    public static final int CONVERSATION_SENDERS_NONE = 3;
+
     /** @hide */
     @IntDef(prefix = { "STATE_" }, value = {
             STATE_UNSET,
@@ -165,11 +200,20 @@
 
     /** @hide */
     public ZenPolicy() {
-        mPriorityCategories = new ArrayList<>(Collections.nCopies(8, 0));
+        mPriorityCategories = new ArrayList<>(Collections.nCopies(9, 0));
         mVisualEffects = new ArrayList<>(Collections.nCopies(7, 0));
     }
 
     /**
+     * Conversation type that can bypass DND.
+     * @return {@link #CONVERSATION_SENDERS_UNSET}, {@link #CONVERSATION_SENDERS_ANYONE},
+     * {@link #CONVERSATION_SENDERS_IMPORTANT}, {@link #CONVERSATION_SENDERS_NONE}.
+     */
+    public @PeopleType int getPriorityConversationSenders() {
+        return mConversationSenders;
+    }
+
+    /**
      * Message senders that can bypass DND.
      * @return {@link #PEOPLE_TYPE_UNSET}, {@link #PEOPLE_TYPE_ANYONE},
      * {@link #PEOPLE_TYPE_CONTACTS}, {@link #PEOPLE_TYPE_STARRED} or {@link #PEOPLE_TYPE_NONE}
@@ -188,6 +232,16 @@
     }
 
     /**
+     * Whether this policy wants to allow conversation notifications
+     * (see {@link NotificationChannel#getConversationId()}) to play sounds and visually appear
+     * or to intercept them when DND is active.
+     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
+     */
+    public @State int getPriorityCategoryConversations() {
+        return mPriorityCategories.get(PRIORITY_CATEGORY_CONVERSATIONS);
+    }
+
+    /**
      * Whether this policy wants to allow notifications with category
      * {@link Notification#CATEGORY_REMINDER} to play sounds and visually appear
      * or to intercept them when DND is active.
@@ -392,6 +446,7 @@
             }
             mZenPolicy.mPriorityMessages = PEOPLE_TYPE_ANYONE;
             mZenPolicy.mPriorityCalls = PEOPLE_TYPE_ANYONE;
+            mZenPolicy.mConversationSenders = CONVERSATION_SENDERS_ANYONE;
             return this;
         }
 
@@ -408,6 +463,7 @@
             }
             mZenPolicy.mPriorityMessages = PEOPLE_TYPE_NONE;
             mZenPolicy.mPriorityCalls = PEOPLE_TYPE_NONE;
+            mZenPolicy.mConversationSenders = CONVERSATION_SENDERS_NONE;
             return this;
         }
 
@@ -443,6 +499,8 @@
                 mZenPolicy.mPriorityMessages = STATE_UNSET;
             } else if (category == PRIORITY_CATEGORY_CALLS) {
                 mZenPolicy.mPriorityCalls = STATE_UNSET;
+            } else if (category == PRIORITY_CATEGORY_CONVERSATIONS) {
+                mZenPolicy.mConversationSenders = STATE_UNSET;
             }
 
             return this;
@@ -479,6 +537,31 @@
         }
 
         /**
+         * Whether to allow conversation notifications
+         * (see {@link NotificationChannel#setConversationId(String, String)})
+         * that match audienceType to play sounds and visually appear or to intercept
+         * them when DND is active.
+         * @param audienceType callers that are allowed to bypass DND
+         */
+        public @NonNull  Builder allowConversations(@ConversationSenders int audienceType) {
+            if (audienceType == STATE_UNSET) {
+                return unsetPriorityCategory(PRIORITY_CATEGORY_CONVERSATIONS);
+            }
+
+            if (audienceType == CONVERSATION_SENDERS_NONE) {
+                mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_CONVERSATIONS, STATE_DISALLOW);
+            } else if (audienceType == CONVERSATION_SENDERS_ANYONE
+                    || audienceType == CONVERSATION_SENDERS_IMPORTANT) {
+                mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_CONVERSATIONS, STATE_ALLOW);
+            } else {
+                return this;
+            }
+
+            mZenPolicy.mConversationSenders = audienceType;
+            return this;
+        }
+
+        /**
          * Whether to allow notifications with category {@link Notification#CATEGORY_MESSAGE}
          * that match audienceType to play sounds and visually appear or to intercept
          * them when DND is active.
@@ -537,7 +620,6 @@
             return this;
         }
 
-
         /**
          * Whether to allow notifications with category {@link Notification#CATEGORY_ALARM}
          * to play sounds and visually appear or to intercept them when DND is active.
@@ -712,6 +794,7 @@
         dest.writeList(mVisualEffects);
         dest.writeInt(mPriorityCalls);
         dest.writeInt(mPriorityMessages);
+        dest.writeInt(mConversationSenders);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<ZenPolicy> CREATOR =
@@ -723,6 +806,7 @@
             policy.mVisualEffects = source.readArrayList(Integer.class.getClassLoader());
             policy.mPriorityCalls = source.readInt();
             policy.mPriorityMessages = source.readInt();
+            policy.mConversationSenders = source.readInt();
             return policy;
         }
 
@@ -738,8 +822,10 @@
                 .append('{')
                 .append("priorityCategories=[").append(priorityCategoriesToString())
                 .append("], visualEffects=[").append(visualEffectsToString())
-                .append("], priorityCalls=").append(peopleTypeToString(mPriorityCalls))
-                .append(", priorityMessages=").append(peopleTypeToString(mPriorityMessages))
+                .append("], priorityCallsSenders=").append(peopleTypeToString(mPriorityCalls))
+                .append(", priorityMessagesSenders=").append(peopleTypeToString(mPriorityMessages))
+                .append(", priorityConversationSenders=").append(
+                        conversationTypeToString(mConversationSenders))
                 .append('}')
                 .toString();
     }
@@ -811,6 +897,8 @@
                 return "media";
             case PRIORITY_CATEGORY_SYSTEM:
                 return "system";
+            case PRIORITY_CATEGORY_CONVERSATIONS:
+                return "convs";
         }
         return null;
     }
@@ -843,6 +931,23 @@
         return "invalidPeopleType{" + peopleType + "}";
     }
 
+    /**
+     * @hide
+     */
+    public static String conversationTypeToString(@ConversationSenders int conversationType) {
+        switch (conversationType) {
+            case CONVERSATION_SENDERS_ANYONE:
+                return "anyone";
+            case CONVERSATION_SENDERS_IMPORTANT:
+                return "important";
+            case CONVERSATION_SENDERS_NONE:
+                return "none";
+            case CONVERSATION_SENDERS_UNSET:
+                return "unset";
+        }
+        return "invalidConversationType{" + conversationType + "}";
+    }
+
     @Override
     public boolean equals(Object o) {
         if (!(o instanceof ZenPolicy)) return false;
@@ -852,12 +957,14 @@
         return Objects.equals(other.mPriorityCategories, mPriorityCategories)
                 && Objects.equals(other.mVisualEffects, mVisualEffects)
                 && other.mPriorityCalls == mPriorityCalls
-                && other.mPriorityMessages == mPriorityMessages;
+                && other.mPriorityMessages == mPriorityMessages
+                && other.mConversationSenders == mConversationSenders;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mPriorityCategories, mVisualEffects, mPriorityCalls, mPriorityMessages);
+        return Objects.hash(mPriorityCategories, mVisualEffects, mPriorityCalls, mPriorityMessages,
+                mConversationSenders);
     }
 
     private @ZenPolicy.State int getZenPolicyPriorityCategoryState(@PriorityCategory int
@@ -879,6 +986,8 @@
                 return getPriorityCategoryMedia();
             case PRIORITY_CATEGORY_SYSTEM:
                 return getPriorityCategorySystem();
+            case PRIORITY_CATEGORY_CONVERSATIONS:
+                return getPriorityCategoryConversations();
         }
         return -1;
     }
@@ -953,6 +1062,9 @@
                 } else if (category == PRIORITY_CATEGORY_CALLS
                         && mPriorityCalls < policyToApply.mPriorityCalls) {
                     mPriorityCalls = policyToApply.mPriorityCalls;
+                } else if (category == PRIORITY_CATEGORY_CONVERSATIONS
+                        && mConversationSenders < policyToApply.mConversationSenders) {
+                    mConversationSenders = policyToApply.mConversationSenders;
                 }
             }
         }
diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml
index 6cf6a82..9110661 100644
--- a/core/res/res/xml/default_zen_mode_config.xml
+++ b/core/res/res/xml/default_zen_mode_config.xml
@@ -18,9 +18,10 @@
 -->
 
 <!-- Default configuration for zen mode.  See android.service.notification.ZenModeConfig. -->
-<zen version="8">
+<zen version="9">
     <allow alarms="true" media="true" system="false" calls="true" callsFrom="2" messages="false"
-           reminders="false" events="false" repeatCallers="true" />
+            reminders="false" events="false" repeatCallers="true" conversations="true"
+            conversationsFrom="2"/>
     <automatic ruleId="EVENTS_DEFAULT_RULE" enabled="false" snoozing="false" name="Event" zen="1"
                component="android/com.android.server.notification.EventConditionProvider"
                conditionId="condition://android/event?userId=-10000&amp;calendar=&amp;reply=1"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1f13f8d..a44e109 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1812,16 +1812,16 @@
     <string name="demote">Mark this notification as not a conversation</string>
 
     <!-- [CHAR LIMIT=100] Mark this conversation as a favorite -->
-    <string name="notification_conversation_favorite">Favorite</string>
+    <string name="notification_conversation_favorite">Mark as important</string>
 
     <!-- [CHAR LIMIT=100] Unmark this conversation as a favorite -->
-    <string name="notification_conversation_unfavorite">Unfavorite</string>
+    <string name="notification_conversation_unfavorite">Mark as unimportant</string>
 
     <!-- [CHAR LIMIT=100] Mute this conversation -->
-    <string name="notification_conversation_mute">Mute</string>
+    <string name="notification_conversation_mute">Silence</string>
 
     <!-- [CHAR LIMIT=100] Umute this conversation -->
-    <string name="notification_conversation_unmute">Unmute</string>
+    <string name="notification_conversation_unmute">Alerting</string>
 
     <!-- [CHAR LIMIT=100] Show notification as bubble -->
     <string name="notification_conversation_bubble">Show as bubble</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index 6045524..bb0681c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -280,7 +280,7 @@
 
         Button favorite = findViewById(R.id.fave);
         favorite.setOnClickListener(mOnFavoriteClick);
-        if (mNotificationChannel.canBypassDnd()) {
+        if (mNotificationChannel.isImportantConversation()) {
             favorite.setText(R.string.notification_conversation_unfavorite);
             favorite.setCompoundDrawablesRelative(
                     mContext.getDrawable(R.drawable.ic_star), null, null, null);
@@ -621,8 +621,8 @@
                         }
                         break;
                     case ACTION_FAVORITE:
-                        // TODO: extend beyond DND
-                        mChannelToUpdate.setBypassDnd(!mChannelToUpdate.canBypassDnd());
+                        mChannelToUpdate.setImportantConversation(
+                                !mChannelToUpdate.isImportantConversation());
                         break;
                     case ACTION_MUTE:
                         if (mChannelToUpdate.getImportance() == IMPORTANCE_UNSPECIFIED
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 20a089f..f080d67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -655,13 +655,13 @@
                 ArgumentCaptor.forClass(NotificationChannel.class);
         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
                 anyString(), anyInt(), captor.capture());
-        assertTrue(captor.getValue().canBypassDnd());
+        assertTrue(captor.getValue().isImportantConversation());
     }
 
     @Test
     public void testFavorite_unfavorite() throws Exception {
-        mNotificationChannel.setBypassDnd(true);
-        mConversationChannel.setBypassDnd(true);
+        mNotificationChannel.setImportantConversation(true);
+        mConversationChannel.setImportantConversation(true);
 
         mNotificationInfo.bindNotification(
                 mShortcutManager,
@@ -688,7 +688,7 @@
                 ArgumentCaptor.forClass(NotificationChannel.class);
         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
                 anyString(), anyInt(), captor.capture());
-        assertFalse(captor.getValue().canBypassDnd());
+        assertFalse(captor.getValue().isImportantConversation());
     }
 
     @Test
diff --git a/services/core/java/com/android/server/notification/BadgeExtractor.java b/services/core/java/com/android/server/notification/BadgeExtractor.java
index d91d541..af8baa5 100644
--- a/services/core/java/com/android/server/notification/BadgeExtractor.java
+++ b/services/core/java/com/android/server/notification/BadgeExtractor.java
@@ -43,9 +43,9 @@
             if (DBG) Slog.d(TAG, "missing config");
             return null;
         }
-        boolean userWantsBadges = mConfig.badgingEnabled(record.sbn.getUser());
+        boolean userWantsBadges = mConfig.badgingEnabled(record.getSbn().getUser());
         boolean appCanShowBadge =
-                mConfig.canShowBadge(record.sbn.getPackageName(), record.sbn.getUid());
+                mConfig.canShowBadge(record.getSbn().getPackageName(), record.getSbn().getUid());
         if (!userWantsBadges || !appCanShowBadge) {
             record.setShowBadge(false);
         } else {
diff --git a/services/core/java/com/android/server/notification/BubbleExtractor.java b/services/core/java/com/android/server/notification/BubbleExtractor.java
index e59bf16..c9c8042 100644
--- a/services/core/java/com/android/server/notification/BubbleExtractor.java
+++ b/services/core/java/com/android/server/notification/BubbleExtractor.java
@@ -42,7 +42,7 @@
             return null;
         }
         boolean appCanShowBubble =
-                mConfig.areBubblesAllowed(record.sbn.getPackageName(), record.sbn.getUid());
+                mConfig.areBubblesAllowed(record.getSbn().getPackageName(), record.getSbn().getUid());
         if (!mConfig.bubblesEnabled() || !appCanShowBubble) {
             record.setAllowBubble(false);
         } else {
diff --git a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
index 0e14364..83ca699 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
@@ -15,10 +15,8 @@
 */
 package com.android.server.notification;
 
-import android.app.Notification;
 import android.app.NotificationChannel;
 import android.content.Context;
-import android.util.FeatureFlagUtils;
 import android.util.Slog;
 
 /**
@@ -47,9 +45,9 @@
             return null;
         }
         NotificationChannel updatedChannel = mConfig.getConversationNotificationChannel(
-                record.sbn.getPackageName(),
-                record.sbn.getUid(), record.getChannel().getId(),
-                record.sbn.getShortcutId(mContext), true, false);
+                record.getSbn().getPackageName(),
+                record.getSbn().getUid(), record.getChannel().getId(),
+                record.getSbn().getShortcutId(mContext), true, false);
         record.updateNotificationChannel(updatedChannel);
 
         return null;
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index a7e40cb..29b5e81 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -122,8 +122,8 @@
             return -1 * Integer.compare(leftPackagePriority, rightPackagePriority);
         }
 
-        final int leftPriority = left.sbn.getNotification().priority;
-        final int rightPriority = right.sbn.getNotification().priority;
+        final int leftPriority = left.getSbn().getNotification().priority;
+        final int rightPriority = right.getSbn().getNotification().priority;
         if (leftPriority != rightPriority) {
             // by priority, high to low
             return -1 * Integer.compare(leftPriority, rightPriority);
@@ -169,7 +169,7 @@
     }
 
     protected boolean isImportantMessaging(NotificationRecord record) {
-        return mMessagingUtil.isImportantMessaging(record.sbn, record.getImportance());
+        return mMessagingUtil.isImportantMessaging(record.getSbn(), record.getImportance());
     }
 
     private boolean isOngoing(NotificationRecord record) {
@@ -183,7 +183,7 @@
 
     private boolean isCall(NotificationRecord record) {
         return record.isCategory(Notification.CATEGORY_CALL)
-                && isDefaultPhoneApp(record.sbn.getPackageName());
+                && isDefaultPhoneApp(record.getSbn().getPackageName());
     }
 
     private boolean isDefaultPhoneApp(String pkg) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 68cc014..f6276fb 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -684,14 +684,14 @@
         if (summary == null) {
             return;
         }
-        int oldFlags = summary.sbn.getNotification().flags;
+        int oldFlags = summary.getSbn().getNotification().flags;
         if (needsOngoingFlag) {
-            summary.sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+            summary.getSbn().getNotification().flags |= FLAG_ONGOING_EVENT;
         } else {
-            summary.sbn.getNotification().flags &= ~FLAG_ONGOING_EVENT;
+            summary.getSbn().getNotification().flags &= ~FLAG_ONGOING_EVENT;
         }
 
-        if (summary.sbn.getNotification().flags != oldFlags) {
+        if (summary.getSbn().getNotification().flags != oldFlags) {
             mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground));
         }
     }
@@ -917,7 +917,7 @@
                         r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now),
                         nv.rank, nv.count);
 
-                StatusBarNotification sbn = r.sbn;
+                StatusBarNotification sbn = r.getSbn();
                 cancelNotification(callingUid, callingPid, sbn.getPackageName(), sbn.getTag(),
                         sbn.getId(), Notification.FLAG_AUTO_CANCEL,
                         FLAG_FOREGROUND_SERVICE, false, r.getUserId(),
@@ -959,7 +959,7 @@
                 nv.recycle();
                 reportUserInteraction(r);
                 mAssistants.notifyAssistantActionClicked(
-                        r.sbn, actionIndex, action, generatedByAssistant);
+                        r.getSbn(), actionIndex, action, generatedByAssistant);
             }
         }
 
@@ -1044,7 +1044,7 @@
                         reportSeen(r);
                     }
                     r.setVisibility(true, nv.rank, nv.count);
-                    mAssistants.notifyAssistantVisibilityChangedLocked(r.sbn, true);
+                    mAssistants.notifyAssistantVisibilityChangedLocked(r.getSbn(), true);
                     boolean isHun = (nv.location
                             == NotificationVisibility.NotificationLocation.LOCATION_FIRST_HEADS_UP);
                     // hasBeenVisiblyExpanded must be called after updating the expansion state of
@@ -1063,7 +1063,7 @@
                     NotificationRecord r = mNotificationsByKey.get(nv.key);
                     if (r == null) continue;
                     r.setVisibility(false, nv.rank, nv.count);
-                    mAssistants.notifyAssistantVisibilityChangedLocked(r.sbn, false);
+                    mAssistants.notifyAssistantVisibilityChangedLocked(r.getSbn(), false);
                     nv.recycle();
                 }
             }
@@ -1090,7 +1090,8 @@
                         r.recordExpanded();
                         reportUserInteraction(r);
                     }
-                    mAssistants.notifyAssistantExpansionChangedLocked(r.sbn, userAction, expanded);
+                    mAssistants.notifyAssistantExpansionChangedLocked(
+                            r.getSbn(), userAction, expanded);
                 }
             }
         }
@@ -1106,7 +1107,7 @@
                             .setCategory(MetricsEvent.NOTIFICATION_DIRECT_REPLY_ACTION)
                             .setType(MetricsEvent.TYPE_ACTION));
                     reportUserInteraction(r);
-                    mAssistants.notifyAssistantNotificationDirectReplyLocked(r.sbn);
+                    mAssistants.notifyAssistantNotificationDirectReplyLocked(r.getSbn());
                 }
             }
         }
@@ -1150,7 +1151,7 @@
                     // Treat clicking on a smart reply as a user interaction.
                     reportUserInteraction(r);
                     mAssistants.notifyAssistantSuggestedReplySent(
-                            r.sbn, reply, r.getSuggestionsGeneratedByAssistant());
+                            r.getSbn(), reply, r.getSuggestionsGeneratedByAssistant());
                 }
             }
         }
@@ -1170,7 +1171,7 @@
             synchronized (mNotificationLock) {
                 NotificationRecord r = mNotificationsByKey.get(key);
                 if (r != null) {
-                    final StatusBarNotification n = r.sbn;
+                    final StatusBarNotification n = r.getSbn();
                     final int callingUid = n.getUid();
                     final String pkg = n.getPackageName();
                     applyFlagBubble(r, pkg, callingUid, null /* oldEntry */, isBubble);
@@ -1372,9 +1373,9 @@
                     record = findNotificationByKeyLocked(intent.getStringExtra(EXTRA_KEY));
                 }
                 if (record != null) {
-                    cancelNotification(record.sbn.getUid(), record.sbn.getInitialPid(),
-                            record.sbn.getPackageName(), record.sbn.getTag(),
-                            record.sbn.getId(), 0,
+                    cancelNotification(record.getSbn().getUid(), record.getSbn().getInitialPid(),
+                            record.getSbn().getPackageName(), record.getSbn().getTag(),
+                            record.getSbn().getId(), 0,
                             FLAG_FOREGROUND_SERVICE, true, record.getUserId(),
                             REASON_TIMEOUT, null);
                 }
@@ -1637,7 +1638,7 @@
                 synchronized (mNotificationLock) {
                     NotificationRecord r = mNotificationsByKey.get(bubbleKey);
                     if (r != null) {
-                        final StatusBarNotification n = r.sbn;
+                        final StatusBarNotification n = r.getSbn();
                         final int callingUid = n.getUid();
                         final String pkg = n.getPackageName();
                         applyFlagBubble(r, pkg, callingUid, null /* oldEntry */, isAppForeground);
@@ -1780,7 +1781,7 @@
                 if (mNotificationsByKey.containsKey(posted.getKey())) {
                     count--;
                 }
-                if (posted.sbn.isGroup() && posted.getNotification().isGroupSummary()) {
+                if (posted.getSbn().isGroup() && posted.getNotification().isGroupSummary()) {
                     count--;
                 }
             }
@@ -1802,8 +1803,8 @@
     @VisibleForTesting
     void addNotification(NotificationRecord r) {
         mNotificationList.add(r);
-        mNotificationsByKey.put(r.sbn.getKey(), r);
-        if (r.sbn.isGroup()) {
+        mNotificationsByKey.put(r.getSbn().getKey(), r);
+        if (r.getSbn().isGroup()) {
             mSummaryByGroupKey.put(r.getGroupKey(), r);
         }
     }
@@ -2059,9 +2060,9 @@
                     if (DBG) {
                         Slog.d(TAG, "Reposting " + r.getKey());
                     }
-                    enqueueNotificationInternal(r.sbn.getPackageName(), r.sbn.getOpPkg(),
-                            r.sbn.getUid(), r.sbn.getInitialPid(), r.sbn.getTag(), r.sbn.getId(),
-                            r.sbn.getNotification(), userId);
+                    enqueueNotificationInternal(r.getSbn().getPackageName(), r.getSbn().getOpPkg(),
+                            r.getSbn().getUid(), r.getSbn().getInitialPid(), r.getSbn().getTag(),
+                            r.getSbn().getId(),  r.getSbn().getNotification(), userId);
                 } catch (Exception e) {
                     Slog.e(TAG, "Cannot un-snooze notification", e);
                 }
@@ -2201,7 +2202,7 @@
                 String pkg;
                 synchronized (mNotificationLock) {
                     NotificationRecord r = mNotificationsByKey.get(key);
-                    pkg = r != null && r.sbn != null ? r.sbn.getPackageName() : null;
+                    pkg = r != null && r.getSbn() != null ? r.getSbn().getPackageName() : null;
                 }
                 boolean isAppForeground = pkg != null
                         && mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
@@ -2209,7 +2210,7 @@
                     NotificationRecord r = mNotificationsByKey.get(key);
                     if (r == null) return;
                     updateAutobundledSummaryFlags(r.getUser().getIdentifier(),
-                            r.sbn.getPackageName(), needsOngoingFlag, isAppForeground);
+                            r.getSbn().getPackageName(), needsOngoingFlag, isAppForeground);
                 }
             }
         });
@@ -2280,7 +2281,8 @@
         final long updatedSuppressedEffects = calculateSuppressedEffects();
         if (updatedSuppressedEffects == mZenModeHelper.getSuppressedEffects()) return;
         final List<ComponentName> suppressors = getSuppressors();
-        ZenLog.traceEffectsSuppressorChanged(mEffectsSuppressors, suppressors, updatedSuppressedEffects);
+        ZenLog.traceEffectsSuppressorChanged(
+                mEffectsSuppressors, suppressors, updatedSuppressedEffects);
         mEffectsSuppressors = suppressors;
         mZenModeHelper.setSuppressedEffects(updatedSuppressedEffects);
         sendRegisteredOnlyBroadcast(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
@@ -2486,6 +2488,18 @@
         scheduleInterruptionFilterChanged(interruptionFilter);
     }
 
+    int correctCategory(int requestedCategoryList, int categoryType,
+            int currentCategoryList) {
+        if ((requestedCategoryList & categoryType) != 0
+                && (currentCategoryList & categoryType) == 0) {
+            requestedCategoryList &= ~categoryType;
+        } else if ((requestedCategoryList & categoryType) == 0
+                && (currentCategoryList & categoryType) != 0){
+            requestedCategoryList |= categoryType;
+        }
+        return requestedCategoryList;
+    }
+
     @VisibleForTesting
     INotificationManager getBinderService() {
         return INotificationManager.Stub.asInterface(mService);
@@ -2498,8 +2512,8 @@
     @GuardedBy("mNotificationLock")
     protected void reportSeen(NotificationRecord r) {
         if (!r.isProxied()) {
-            mAppUsageStats.reportEvent(r.sbn.getPackageName(),
-                    getRealUserId(r.sbn.getUserId()),
+            mAppUsageStats.reportEvent(r.getSbn().getPackageName(),
+                    getRealUserId(r.getSbn().getUserId()),
                     UsageEvents.Event.NOTIFICATION_SEEN);
         }
     }
@@ -2574,18 +2588,18 @@
     @GuardedBy("mNotificationLock")
     protected void maybeRecordInterruptionLocked(NotificationRecord r) {
         if (r.isInterruptive() && !r.hasRecordedInterruption()) {
-            mAppUsageStats.reportInterruptiveNotification(r.sbn.getPackageName(),
+            mAppUsageStats.reportInterruptiveNotification(r.getSbn().getPackageName(),
                     r.getChannel().getId(),
-                    getRealUserId(r.sbn.getUserId()));
+                    getRealUserId(r.getSbn().getUserId()));
             mHistoryManager.addNotification(new HistoricalNotification.Builder()
-                    .setPackage(r.sbn.getPackageName())
-                    .setUid(r.sbn.getUid())
+                    .setPackage(r.getSbn().getPackageName())
+                    .setUid(r.getSbn().getUid())
                     .setChannelId(r.getChannel().getId())
                     .setChannelName(r.getChannel().getName().toString())
                     .setPostedTimeMs(System.currentTimeMillis())
                     .setTitle(getHistoryTitle(r.getNotification()))
                     .setText(getHistoryText(
-                            r.sbn.getPackageContext(getContext()), r.getNotification()))
+                            r.getSbn().getPackageContext(getContext()), r.getNotification()))
                     .setIcon(r.getNotification().getSmallIcon())
                     .build());
             r.setRecordedInterruption(true);
@@ -2632,8 +2646,8 @@
      * @param r notification record
      */
     protected void reportUserInteraction(NotificationRecord r) {
-        mAppUsageStats.reportEvent(r.sbn.getPackageName(),
-                getRealUserId(r.sbn.getUserId()),
+        mAppUsageStats.reportEvent(r.getSbn().getPackageName(),
+                getRealUserId(r.getSbn().getUserId()),
                 UsageEvents.Event.USER_INTERACTION);
     }
 
@@ -3509,7 +3523,7 @@
                     tmp = new StatusBarNotification[mNotificationList.size()];
                     final int N = mNotificationList.size();
                     for (int i=0; i<N; i++) {
-                        tmp[i] = mNotificationList.get(i).sbn;
+                        tmp[i] = mNotificationList.get(i).getSbn();
                     }
                 }
             }
@@ -3541,13 +3555,13 @@
                 final int N = mNotificationList.size();
                 for (int i = 0; i < N; i++) {
                     StatusBarNotification sbn = sanitizeSbn(pkg, userId,
-                            mNotificationList.get(i).sbn);
+                            mNotificationList.get(i).getSbn());
                     if (sbn != null) {
                         map.put(sbn.getKey(), sbn);
                     }
                 }
                 for(NotificationRecord snoozed: mSnoozeHelper.getSnoozed(userId, pkg)) {
-                    StatusBarNotification sbn = sanitizeSbn(pkg, userId, snoozed.sbn);
+                    StatusBarNotification sbn = sanitizeSbn(pkg, userId, snoozed.getSbn());
                     if (sbn != null) {
                         map.put(sbn.getKey(), sbn);
                     }
@@ -3555,7 +3569,7 @@
                 final int M = mEnqueuedNotifications.size();
                 for (int i = 0; i < M; i++) {
                     StatusBarNotification sbn = sanitizeSbn(pkg, userId,
-                            mEnqueuedNotifications.get(i).sbn);
+                            mEnqueuedNotifications.get(i).getSbn());
                     if (sbn != null) {
                         map.put(sbn.getKey(), sbn); // pending update overwrites existing post here
                     }
@@ -3673,15 +3687,15 @@
                         for (int i = 0; i < N; i++) {
                             NotificationRecord r = mNotificationsByKey.get(keys[i]);
                             if (r == null) continue;
-                            final int userId = r.sbn.getUserId();
+                            final int userId = r.getSbn().getUserId();
                             if (userId != info.userid && userId != UserHandle.USER_ALL &&
                                     !mUserProfiles.isCurrentProfile(userId)) {
                                 throw new SecurityException("Disallowed call from listener: "
                                         + info.service);
                             }
                             cancelNotificationFromListenerLocked(info, callingUid, callingPid,
-                                    r.sbn.getPackageName(), r.sbn.getTag(), r.sbn.getId(),
-                                    userId);
+                                    r.getSbn().getPackageName(), r.getSbn().getTag(),
+                                    r.getSbn().getId(), userId);
                         }
                     } else {
                         cancelAllLocked(callingUid, callingPid, info.userid,
@@ -3741,7 +3755,7 @@
                     for (int i = 0; i < n; i++) {
                         NotificationRecord r = mNotificationsByKey.get(keys[i]);
                         if (r == null) continue;
-                        final int userId = r.sbn.getUserId();
+                        final int userId = r.getSbn().getUserId();
                         if (userId != info.userid && userId != UserHandle.USER_ALL
                                 && !mUserProfiles.isCurrentProfile(userId)) {
                             throw new SecurityException("Disallowed call from listener: "
@@ -3891,7 +3905,7 @@
                             ? mNotificationsByKey.get(keys[i])
                             : mNotificationList.get(i);
                     if (r == null) continue;
-                    StatusBarNotification sbn = r.sbn;
+                    StatusBarNotification sbn = r.getSbn();
                     if (!isVisibleToListener(sbn, info)) continue;
                     StatusBarNotification sbnToSend =
                             (trim == TRIM_FULL) ? sbn : sbn.cloneLight();
@@ -3921,7 +3935,7 @@
                 for (int i=0; i < N; i++) {
                     final NotificationRecord r = snoozedRecords.get(i);
                     if (r == null) continue;
-                    StatusBarNotification sbn = r.sbn;
+                    StatusBarNotification sbn = r.getSbn();
                     if (!isVisibleToListener(sbn, info)) continue;
                     StatusBarNotification sbnToSend =
                             (trim == TRIM_FULL) ? sbn : sbn.cloneLight();
@@ -4096,7 +4110,8 @@
             Objects.requireNonNull(packageName, "Package name is null");
             enforceSystemOrSystemUI("removeAutomaticZenRules");
 
-            return mZenModeHelper.removeAutomaticZenRules(packageName, "removeAutomaticZenRules");
+            return mZenModeHelper.removeAutomaticZenRules(packageName,
+                    packageName + "|removeAutomaticZenRules");
         }
 
         @Override
@@ -4411,11 +4426,20 @@
                             policy.priorityCallSenders, policy.priorityMessageSenders,
                             policy.suppressedVisualEffects);
                 }
+                if (applicationInfo.targetSdkVersion < Build.VERSION_CODES.R) {
+                    int priorityCategories = correctCategory(policy.priorityCategories,
+                            Policy.PRIORITY_CATEGORY_CONVERSATIONS,
+                            currPolicy.priorityCategories);
+
+                    policy = new Policy(priorityCategories,
+                            policy.priorityCallSenders, policy.priorityMessageSenders,
+                            policy.suppressedVisualEffects, currPolicy.priorityConversationSenders);
+                }
                 int newVisualEffects = calculateSuppressedVisualEffects(
                             policy, currPolicy, applicationInfo.targetSdkVersion);
                 policy = new Policy(policy.priorityCategories,
                         policy.priorityCallSenders, policy.priorityMessageSenders,
-                        newVisualEffects);
+                        newVisualEffects, policy.priorityConversationSenders);
                 ZenLog.traceSetNotificationPolicy(pkg, applicationInfo.targetSdkVersion, policy);
                 mZenModeHelper.setNotificationPolicy(policy);
             } catch (RemoteException e) {
@@ -4424,6 +4448,8 @@
             }
         }
 
+
+
         @Override
         public List<String> getEnabledNotificationListenerPackages() {
             checkCallerIsSystem();
@@ -4637,8 +4663,8 @@
             Objects.requireNonNull(user);
             verifyPrivilegedListener(token, user, true);
 
-            return mPreferencesHelper.getNotificationChannels(pkg, getUidForPackageAndUser(pkg, user),
-                    false /* includeDeleted */);
+            return mPreferencesHelper.getNotificationChannels(pkg,
+                    getUidForPackageAndUser(pkg, user), false /* includeDeleted */);
         }
 
         @Override
@@ -4830,7 +4856,7 @@
         if (r == null) {
             return;
         }
-        if (r.sbn.getOverrideGroupKey() == null) {
+        if (r.getSbn().getOverrideGroupKey() == null) {
             addAutoGroupAdjustment(r, GroupHelper.AUTOGROUP_KEY);
             EventLogTags.writeNotificationAutogrouped(key);
             mRankingHandler.requestSort();
@@ -4843,7 +4869,7 @@
         if (r == null) {
             return;
         }
-        if (r.sbn.getOverrideGroupKey() != null) {
+        if (r.getSbn().getOverrideGroupKey() != null) {
             addAutoGroupAdjustment(r, null);
             EventLogTags.writeNotificationUnautogrouped(key);
             mRankingHandler.requestSort();
@@ -4853,8 +4879,8 @@
     private void addAutoGroupAdjustment(NotificationRecord r, String overrideGroupKey) {
         Bundle signals = new Bundle();
         signals.putString(Adjustment.KEY_GROUP_KEY, overrideGroupKey);
-        Adjustment adjustment =
-                new Adjustment(r.sbn.getPackageName(), r.getKey(), signals, "", r.sbn.getUserId());
+        Adjustment adjustment = new Adjustment(r.getSbn().getPackageName(), r.getKey(), signals, "",
+                r.getSbn().getUserId());
         r.addAdjustment(adjustment);
     }
 
@@ -4890,7 +4916,7 @@
                 // adjustment will post a summary if needed.
                 return;
             }
-            final StatusBarNotification adjustedSbn = notificationRecord.sbn;
+            final StatusBarNotification adjustedSbn = notificationRecord.getSbn();
             userId = adjustedSbn.getUser().getIdentifier();
             ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
             if (summaries == null) {
@@ -4938,7 +4964,8 @@
             }
         }
         if (summaryRecord != null && checkDisqualifyingFeatures(userId, MY_UID,
-                summaryRecord.sbn.getId(), summaryRecord.sbn.getTag(), summaryRecord, true)) {
+                summaryRecord.getSbn().getId(), summaryRecord.getSbn().getTag(), summaryRecord,
+                true)) {
             mHandler.post(new EnqueueNotificationRunnable(userId, summaryRecord, isAppForeground));
         }
     }
@@ -4999,14 +5026,14 @@
             int N = mNotificationList.size();
             for (int i = 0; i < N; i++) {
                 final NotificationRecord nr = mNotificationList.get(i);
-                if (filter.filtered && !filter.matches(nr.sbn)) continue;
+                if (filter.filtered && !filter.matches(nr.getSbn())) continue;
                 nr.dump(proto, NotificationServiceDumpProto.RECORDS, filter.redact,
                         NotificationRecordProto.POSTED);
             }
             N = mEnqueuedNotifications.size();
             for (int i = 0; i < N; i++) {
                 final NotificationRecord nr = mEnqueuedNotifications.get(i);
-                if (filter.filtered && !filter.matches(nr.sbn)) continue;
+                if (filter.filtered && !filter.matches(nr.getSbn())) continue;
                 nr.dump(proto, NotificationServiceDumpProto.RECORDS, filter.redact,
                         NotificationRecordProto.ENQUEUED);
             }
@@ -5014,7 +5041,7 @@
             N = snoozed.size();
             for (int i = 0; i < N; i++) {
                 final NotificationRecord nr = snoozed.get(i);
-                if (filter.filtered && !filter.matches(nr.sbn)) continue;
+                if (filter.filtered && !filter.matches(nr.getSbn())) continue;
                 nr.dump(proto, NotificationServiceDumpProto.RECORDS, filter.redact,
                         NotificationRecordProto.SNOOZED);
             }
@@ -5075,7 +5102,7 @@
                 pw.println("  Notification List:");
                 for (int i = 0; i < N; i++) {
                     final NotificationRecord nr = mNotificationList.get(i);
-                    if (filter.filtered && !filter.matches(nr.sbn)) continue;
+                    if (filter.filtered && !filter.matches(nr.getSbn())) continue;
                     nr.dump(pw, "    ", getContext(), filter.redact);
                 }
                 pw.println("  ");
@@ -5155,7 +5182,7 @@
                         pw.println("  Enqueued Notification List:");
                         for (int i = 0; i < N; i++) {
                             final NotificationRecord nr = mEnqueuedNotifications.get(i);
-                            if (filter.filtered && !filter.matches(nr.sbn)) continue;
+                            if (filter.filtered && !filter.matches(nr.getSbn())) continue;
                             nr.dump(pw, "    ", getContext(), filter.redact);
                         }
                         pw.println("  ");
@@ -5281,7 +5308,7 @@
             if (r == null) {
                 return;
             }
-            StatusBarNotification sbn = r.sbn;
+            StatusBarNotification sbn = r.getSbn();
             // NoMan adds flags FLAG_NO_CLEAR and FLAG_ONGOING_EVENT when it sees
             // FLAG_FOREGROUND_SERVICE. Hence it's not enough to remove
             // FLAG_FOREGROUND_SERVICE, we have to revert to the flags we received
@@ -5312,7 +5339,7 @@
                 // Look for the notification, searching both the posted and enqueued lists.
                 NotificationRecord r = findNotificationLocked(pkg, tag, id, userId);
                 if (r != null) {
-                    if (!Objects.equals(opPkg, r.sbn.getOpPkg())) {
+                    if (!Objects.equals(opPkg, r.getSbn().getOpPkg())) {
                         throw new SecurityException(opPkg + " does not have permission to "
                                 + "cancel a notification they did not post " + tag + " " + id);
                     }
@@ -5442,7 +5469,7 @@
         }
 
         if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r,
-                r.sbn.getOverrideGroupKey() != null)) {
+                r.getSbn().getOverrideGroupKey() != null)) {
             return;
         }
 
@@ -5586,12 +5613,12 @@
             if (shortcutId != null) {
                 // Must track shortcut based bubbles in case the shortcut is removed
                 HashMap<String, String> packageBubbles = mActiveShortcutBubbles.get(
-                        r.sbn.getPackageName());
+                        r.getSbn().getPackageName());
                 if (packageBubbles == null) {
                     packageBubbles = new HashMap<>();
                 }
                 packageBubbles.put(shortcutId, r.getKey());
-                mActiveShortcutBubbles.put(r.sbn.getPackageName(), packageBubbles);
+                mActiveShortcutBubbles.put(r.getSbn().getPackageName(), packageBubbles);
                 if (!mLauncherAppsCallbackRegistered) {
                     mLauncherAppsService.registerCallback(mLauncherAppsCallback, mHandler);
                     mLauncherAppsCallbackRegistered = true;
@@ -5602,12 +5629,12 @@
             if (shortcutId != null) {
                 // No longer track shortcut
                 HashMap<String, String> packageBubbles = mActiveShortcutBubbles.get(
-                        r.sbn.getPackageName());
+                        r.getSbn().getPackageName());
                 if (packageBubbles != null) {
                     packageBubbles.remove(shortcutId);
                 }
                 if (packageBubbles != null && packageBubbles.isEmpty()) {
-                    mActiveShortcutBubbles.remove(r.sbn.getPackageName());
+                    mActiveShortcutBubbles.remove(r.getSbn().getPackageName());
                 }
                 if (mLauncherAppsCallbackRegistered && mActiveShortcutBubbles.isEmpty()) {
                     mLauncherAppsService.unregisterCallback(mLauncherAppsCallback);
@@ -5853,7 +5880,7 @@
      */
     private boolean checkDisqualifyingFeatures(int userId, int uid, int id, String tag,
             NotificationRecord r, boolean isAutogroup) {
-        final String pkg = r.sbn.getPackageName();
+        final String pkg = r.getSbn().getPackageName();
         final boolean isSystemNotification =
                 isUidSystemOrPhone(uid) || ("android".equals(pkg));
         final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);
@@ -5863,7 +5890,7 @@
         if (!isSystemNotification && !isNotificationFromListener) {
             synchronized (mNotificationLock) {
                 final int callingUid = Binder.getCallingUid();
-                if (mNotificationsByKey.get(r.sbn.getKey()) == null
+                if (mNotificationsByKey.get(r.getSbn().getKey()) == null
                         && isCallerInstantApp(callingUid, userId)) {
                     // Ephemeral apps have some special constraints for notifications.
                     // They are not allowed to create new notifications however they are allowed to
@@ -5874,7 +5901,7 @@
                 }
 
                 // rate limit updates that aren't completed progress notifications
-                if (mNotificationsByKey.get(r.sbn.getKey()) != null
+                if (mNotificationsByKey.get(r.getSbn().getKey()) != null
                         && !r.getNotification().hasCompletedProgress()
                         && !isAutogroup) {
 
@@ -5884,7 +5911,7 @@
                         final long now = SystemClock.elapsedRealtime();
                         if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) {
                             Slog.e(TAG, "Package enqueue rate is " + appEnqueueRate
-                                    + ". Shedding " + r.sbn.getKey() + ". package=" + pkg);
+                                    + ". Shedding " + r.getSbn().getKey() + ". package=" + pkg);
                             mLastOverRateLogTime = now;
                         }
                         return false;
@@ -5933,10 +5960,10 @@
         final int N = mNotificationList.size();
         for (int i = 0; i < N; i++) {
             final NotificationRecord existing = mNotificationList.get(i);
-            if (existing.sbn.getPackageName().equals(pkg)
-                    && existing.sbn.getUserId() == userId) {
-                if (existing.sbn.getId() == excludedId
-                        && TextUtils.equals(existing.sbn.getTag(), excludedTag)) {
+            if (existing.getSbn().getPackageName().equals(pkg)
+                    && existing.getSbn().getUserId() == userId) {
+                if (existing.getSbn().getId() == excludedId
+                        && TextUtils.equals(existing.getSbn().getTag(), excludedTag)) {
                     continue;
                 }
                 count++;
@@ -5945,8 +5972,8 @@
         final int M = mEnqueuedNotifications.size();
         for (int i = 0; i < M; i++) {
             final NotificationRecord existing = mEnqueuedNotifications.get(i);
-            if (existing.sbn.getPackageName().equals(pkg)
-                    && existing.sbn.getUserId() == userId) {
+            if (existing.getSbn().getPackageName().equals(pkg)
+                    && existing.getSbn().getUserId() == userId) {
                 count++;
             }
         }
@@ -5965,8 +5992,8 @@
     }
 
     private boolean isBlocked(NotificationRecord r) {
-        final String pkg = r.sbn.getPackageName();
-        final int callingUid = r.sbn.getUid();
+        final String pkg = r.getSbn().getPackageName();
+        final int callingUid = r.getSbn().getUid();
         return mPreferencesHelper.isGroupBlocked(pkg, callingUid, r.getChannel().getGroup())
                 || mPreferencesHelper.getImportance(pkg, callingUid)
                 == NotificationManager.IMPORTANCE_NONE
@@ -5996,10 +6023,11 @@
 
         @GuardedBy("mNotificationLock")
         void snoozeLocked(NotificationRecord r) {
-            if (r.sbn.isGroup()) {
+            if (r.getSbn().isGroup()) {
                 final List<NotificationRecord> groupNotifications =
                         findCurrentAndSnoozedGroupNotificationsLocked(
-                        r.sbn.getPackageName(), r.sbn.getGroupKey(), r.sbn.getUserId());
+                        r.getSbn().getPackageName(),
+                                r.getSbn().getGroupKey(), r.getSbn().getUserId());
                 if (r.getNotification().isGroupSummary()) {
                     // snooze all children
                     for (int i = 0; i < groupNotifications.size(); i++) {
@@ -6010,7 +6038,7 @@
                 } else {
                     // if there is a valid summary for this group, and we are snoozing the only
                     // child, also snooze the summary
-                    if (mSummaryByGroupKey.containsKey(r.sbn.getGroupKey())) {
+                    if (mSummaryByGroupKey.containsKey(r.getSbn().getGroupKey())) {
                         if (groupNotifications.size() == 2) {
                             // snooze summary and the one child
                             for (int i = 0; i < groupNotifications.size(); i++) {
@@ -6041,7 +6069,7 @@
             cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null);
             updateLightsLocked();
             if (mSnoozeCriterionId != null) {
-                mAssistants.notifyAssistantSnoozedLocked(r.sbn, mSnoozeCriterionId);
+                mAssistants.notifyAssistantSnoozedLocked(r.getSbn(), mSnoozeCriterionId);
                 mSnoozeHelper.snooze(r, mSnoozeCriterionId);
             } else {
                 mSnoozeHelper.snooze(r, mDuration);
@@ -6172,10 +6200,10 @@
                 final Long snoozeAt =
                         mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
                                 r.getUser().getIdentifier(),
-                                r.sbn.getPackageName(), r.sbn.getKey());
+                                r.getSbn().getPackageName(), r.getSbn().getKey());
                 final long currentTime = System.currentTimeMillis();
                 if (snoozeAt.longValue() > currentTime) {
-                    (new SnoozeNotificationRunnable(r.sbn.getKey(),
+                    (new SnoozeNotificationRunnable(r.getSbn().getKey(),
                             snoozeAt.longValue() - currentTime, null)).snoozeLocked(r);
                     return;
                 }
@@ -6183,9 +6211,9 @@
                 final String contextId =
                         mSnoozeHelper.getSnoozeContextForUnpostedNotification(
                                 r.getUser().getIdentifier(),
-                                r.sbn.getPackageName(), r.sbn.getKey());
+                                r.getSbn().getPackageName(), r.getSbn().getKey());
                 if (contextId != null) {
-                    (new SnoozeNotificationRunnable(r.sbn.getKey(),
+                    (new SnoozeNotificationRunnable(r.getSbn().getKey(),
                             0, contextId)).snoozeLocked(r);
                     return;
                 }
@@ -6193,7 +6221,7 @@
                 mEnqueuedNotifications.add(r);
                 scheduleTimeoutLocked(r);
 
-                final StatusBarNotification n = r.sbn;
+                final StatusBarNotification n = r.getSbn();
                 if (DBG) Slog.d(TAG, "EnqueueNotificationRunnable.run for: " + n.getKey());
                 NotificationRecord old = mNotificationsByKey.get(n.getKey());
                 if (old != null) {
@@ -6291,20 +6319,20 @@
                     }
 
                     final boolean isPackageSuspended =
-                            isPackagePausedOrSuspended(r.sbn.getPackageName(), r.getUid());
+                            isPackagePausedOrSuspended(r.getSbn().getPackageName(), r.getUid());
                     r.setHidden(isPackageSuspended);
                     if (isPackageSuspended) {
                         mUsageStats.registerSuspendedByAdmin(r);
                     }
                     NotificationRecord old = mNotificationsByKey.get(key);
-                    final StatusBarNotification n = r.sbn;
+                    final StatusBarNotification n = r.getSbn();
                     final Notification notification = n.getNotification();
 
                     // Make sure the SBN has an instance ID for statsd logging.
-                    if (old == null || old.sbn.getInstanceId() == null) {
+                    if (old == null || old.getSbn().getInstanceId() == null) {
                         n.setInstanceId(mNotificationInstanceIdSequence.newInstanceId());
                     } else {
-                        n.setInstanceId(old.sbn.getInstanceId());
+                        n.setInstanceId(old.getSbn().getInstanceId());
                     }
 
                     int index = indexOfNotificationLocked(n.getKey());
@@ -6344,7 +6372,7 @@
                     }
 
                     if (notification.getSmallIcon() != null) {
-                        StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
+                        StatusBarNotification oldSbn = (old != null) ? old.getSbn() : null;
                         mListeners.notifyPostedLocked(r, old);
                         if ((oldSbn == null || !Objects.equals(oldSbn.getGroup(), n.getGroup()))
                                 && !isCritical(r)) {
@@ -6358,7 +6386,7 @@
                         } else if (oldSbn != null) {
                             final NotificationRecord finalRecord = r;
                             mHandler.post(() -> mGroupHelper.onNotificationUpdated(
-                                    finalRecord.sbn, hasAutoGroupSummaryLocked(n)));
+                                    finalRecord.getSbn(), hasAutoGroupSummaryLocked(n)));
                         }
                     } else {
                         Slog.e(TAG, "Not posting notification without small icon: " + notification);
@@ -6405,7 +6433,7 @@
     @VisibleForTesting
     protected boolean isVisuallyInterruptive(NotificationRecord old, NotificationRecord r) {
         // Ignore summary updates because we don't display most of the information.
-        if (r.sbn.isGroup() && r.sbn.getNotification().isGroupSummary()) {
+        if (r.getSbn().isGroup() && r.getSbn().getNotification().isGroupSummary()) {
             if (DEBUG_INTERRUPTIVENESS) {
                 Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is not interruptive: summary");
@@ -6429,8 +6457,8 @@
             return false;
         }
 
-        Notification oldN = old.sbn.getNotification();
-        Notification newN = r.sbn.getNotification();
+        Notification oldN = old.getSbn().getNotification();
+        Notification newN = r.getSbn().getNotification();
         if (oldN.extras == null || newN.extras == null) {
             if (DEBUG_INTERRUPTIVENESS) {
                 Slog.v(TAG, "INTERRUPTIVENESS: "
@@ -6441,7 +6469,7 @@
 
         // Ignore visual interruptions from foreground services because users
         // consider them one 'session'. Count them for everything else.
-        if ((r.sbn.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0) {
+        if ((r.getSbn().getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0) {
             if (DEBUG_INTERRUPTIVENESS) {
                 Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is not interruptive: foreground service");
@@ -6555,7 +6583,7 @@
     @GuardedBy("mNotificationLock")
     private void handleGroupedNotificationLocked(NotificationRecord r, NotificationRecord old,
             int callingUid, int callingPid) {
-        StatusBarNotification sbn = r.sbn;
+        StatusBarNotification sbn = r.getSbn();
         Notification n = sbn.getNotification();
         if (n.isGroupSummary() && !sbn.isAppGroup())  {
             // notifications without a group shouldn't be a summary, otherwise autobundling can
@@ -6566,8 +6594,8 @@
         String group = sbn.getGroupKey();
         boolean isSummary = n.isGroupSummary();
 
-        Notification oldN = old != null ? old.sbn.getNotification() : null;
-        String oldGroup = old != null ? old.sbn.getGroupKey() : null;
+        Notification oldN = old != null ? old.getSbn().getNotification() : null;
+        String oldGroup = old != null ? old.getSbn().getGroupKey() : null;
         boolean oldIsSummary = old != null && oldN.isGroupSummary();
 
         if (oldIsSummary) {
@@ -6624,7 +6652,7 @@
         boolean beep = false;
         boolean blink = false;
 
-        final Notification notification = record.sbn.getNotification();
+        final Notification notification = record.getSbn().getNotification();
         final String key = record.getKey();
 
         // Should this notification make noise, vibe, or use the LED?
@@ -6642,7 +6670,7 @@
         // If the notification will appear in the status bar, it should send an accessibility
         // event
         if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
-            sendAccessibilityEvent(notification, record.sbn.getPackageName());
+            sendAccessibilityEvent(notification, record.getSbn().getPackageName());
             sentAccessibilityEvent = true;
         }
 
@@ -6664,7 +6692,7 @@
                 boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
                 if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
                     if (!sentAccessibilityEvent) {
-                        sendAccessibilityEvent(notification, record.sbn.getPackageName());
+                        sendAccessibilityEvent(notification, record.getSbn().getPackageName());
                         sentAccessibilityEvent = true;
                     }
                     if (DBG) Slog.v(TAG, "Interrupting!");
@@ -6719,7 +6747,7 @@
         final int buzzBeepBlink = (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0);
         if (buzzBeepBlink > 0) {
             // Ignore summary updates because we don't display most of the information.
-            if (record.sbn.isGroup() && record.sbn.getNotification().isGroupSummary()) {
+            if (record.getSbn().isGroup() && record.getSbn().getNotification().isGroupSummary()) {
                 if (DEBUG_INTERRUPTIVENESS) {
                     Slog.v(TAG, "INTERRUPTIVENESS: "
                             + record.getKey() + " is not interruptive: summary");
@@ -6774,7 +6802,7 @@
             return false;
         }
         // Suppressed because another notification in its group handles alerting
-        if (record.sbn.isGroup() && record.getNotification().suppressAlertingDueToGrouping()) {
+        if (record.getSbn().isGroup() && record.getNotification().suppressAlertingDueToGrouping()) {
             return false;
         }
         // not if in call or the screen's on
@@ -6806,14 +6834,14 @@
         }
 
         // Suppressed because another notification in its group handles alerting
-        if (record.sbn.isGroup()) {
+        if (record.getSbn().isGroup()) {
             if (notification.suppressAlertingDueToGrouping()) {
                 return true;
             }
         }
 
         // Suppressed for being too recently noisy
-        final String pkg = record.sbn.getPackageName();
+        final String pkg = record.getSbn().getPackageName();
         if (mUsageStats.isAlertRateLimited(pkg)) {
             Slog.e(TAG, "Muting recently noisy " + record.getKey());
             return true;
@@ -6854,7 +6882,7 @@
                 if (player != null) {
                     if (DBG) Slog.v(TAG, "Playing sound " + soundUri
                             + " with attributes " + record.getAudioAttributes());
-                    player.playAsync(soundUri, record.sbn.getUser(), looping,
+                    player.playAsync(soundUri, record.getSbn().getUser(), looping,
                             record.getAudioAttributes());
                     return true;
                 }
@@ -6897,15 +6925,16 @@
                     // so need to check the notification still valide for vibrate.
                     synchronized (mNotificationLock) {
                         if (mNotificationsByKey.get(record.getKey()) != null) {
-                            mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+                            mVibrator.vibrate(record.getSbn().getUid(), record.getSbn().getOpPkg(),
                                     effect, "Notification (delayed)", record.getAudioAttributes());
                         } else {
-                            Slog.e(TAG, "No vibration for canceled notification : " + record.getKey());
+                            Slog.e(TAG, "No vibration for canceled notification : "
+                                    + record.getKey());
                         }
                     }
                 }).start();
             } else {
-                mVibrator.vibrate(record.sbn.getUid(), record.sbn.getPackageName(),
+                mVibrator.vibrate(record.getSbn().getUid(), record.getSbn().getPackageName(),
                         effect, "Notification", record.getAudioAttributes());
             }
             return true;
@@ -7388,7 +7417,7 @@
         if ((recordInList = findNotificationByListLocked(mNotificationList, r.getKey()))
                 != null) {
             mNotificationList.remove(recordInList);
-            mNotificationsByKey.remove(recordInList.sbn.getKey());
+            mNotificationsByKey.remove(recordInList.getSbn().getKey());
             wasPosted = true;
         }
         while ((recordInList = findNotificationByListLocked(mEnqueuedNotifications, r.getKey()))
@@ -7429,7 +7458,7 @@
                 } catch (PendingIntent.CanceledException ex) {
                     // do nothing - there's no relevant way to recover, and
                     //     no reason to let this propagate
-                    Slog.w(TAG, "canceled PendingIntent for " + r.sbn.getPackageName(), ex);
+                    Slog.w(TAG, "canceled PendingIntent for " + r.getSbn().getPackageName(), ex);
                 }
             }
         }
@@ -7445,7 +7474,7 @@
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
-                        mGroupHelper.onNotificationRemoved(r.sbn);
+                        mGroupHelper.onNotificationRemoved(r.getSbn());
                     }
                 });
             }
@@ -7501,13 +7530,15 @@
         if (groupSummary != null && groupSummary.getKey().equals(canceledKey)) {
             mSummaryByGroupKey.remove(groupKey);
         }
-        final ArrayMap<String, String> summaries = mAutobundledSummaries.get(r.sbn.getUserId());
-        if (summaries != null && r.sbn.getKey().equals(summaries.get(r.sbn.getPackageName()))) {
-            summaries.remove(r.sbn.getPackageName());
+        final ArrayMap<String, String> summaries =
+                mAutobundledSummaries.get(r.getSbn().getUserId());
+        if (summaries != null && r.getSbn().getKey().equals(
+                summaries.get(r.getSbn().getPackageName()))) {
+            summaries.remove(r.getSbn().getPackageName());
         }
 
         // Save it for users of getHistoricalNotifications()
-        mArchive.record(r.sbn);
+        mArchive.record(r.getSbn());
 
         final long now = System.currentTimeMillis();
         final LogMaker logMaker = r.getItemLogMaker()
@@ -7756,7 +7787,7 @@
             if (!flagChecker.apply(r.getFlags())) {
                 continue;
             }
-            if (pkg != null && !r.sbn.getPackageName().equals(pkg)) {
+            if (pkg != null && !r.getSbn().getPackageName().equals(pkg)) {
                 continue;
             }
             if (channelId != null && !channelId.equals(r.getChannel().getId())) {
@@ -7852,7 +7883,7 @@
             return;
         }
 
-        String pkg = r.sbn.getPackageName();
+        String pkg = r.getSbn().getPackageName();
 
         if (pkg == null) {
             if (DBG) Slog.e(TAG, "No package for group summary: " + r.getKey());
@@ -7869,12 +7900,12 @@
     private void cancelGroupChildrenByListLocked(ArrayList<NotificationRecord> notificationList,
             NotificationRecord parentNotification, int callingUid, int callingPid,
             String listenerName, boolean sendDelete, boolean wasPosted, FlagChecker flagChecker) {
-        final String pkg = parentNotification.sbn.getPackageName();
+        final String pkg = parentNotification.getSbn().getPackageName();
         final int userId = parentNotification.getUserId();
         final int reason = REASON_GROUP_SUMMARY_CANCELED;
         for (int i = notificationList.size() - 1; i >= 0; i--) {
             final NotificationRecord childR = notificationList.get(i);
-            final StatusBarNotification childSbn = childR.sbn;
+            final StatusBarNotification childSbn = childR.getSbn();
             if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) &&
                     childR.getGroupKey().equals(parentNotification.getGroupKey())
                     && (childR.getFlags() & FLAG_FOREGROUND_SERVICE) == 0
@@ -7952,7 +7983,7 @@
         for (int i = 0; i < len; i++) {
             NotificationRecord r = list.get(i);
             if (notificationMatchesUserId(r, userId) && r.getGroupKey().equals(groupKey)
-                    && r.sbn.getPackageName().equals(pkg)) {
+                    && r.getSbn().getPackageName().equals(pkg)) {
                 records.add(r);
             }
         }
@@ -7993,8 +8024,9 @@
         final int len = list.size();
         for (int i = 0; i < len; i++) {
             NotificationRecord r = list.get(i);
-            if (notificationMatchesUserId(r, userId) && r.sbn.getId() == id &&
-                    TextUtils.equals(r.sbn.getTag(), tag) && r.sbn.getPackageName().equals(pkg)) {
+            if (notificationMatchesUserId(r, userId) && r.getSbn().getId() == id &&
+                    TextUtils.equals(r.getSbn().getTag(), tag)
+                    && r.getSbn().getPackageName().equals(pkg)) {
                 return r;
             }
         }
@@ -8008,8 +8040,9 @@
         final int len = list.size();
         for (int i = 0; i < len; i++) {
             NotificationRecord r = list.get(i);
-            if (notificationMatchesUserId(r, userId) && r.sbn.getId() == id &&
-                    TextUtils.equals(r.sbn.getTag(), tag) && r.sbn.getPackageName().equals(pkg)) {
+            if (notificationMatchesUserId(r, userId) && r.getSbn().getId() == id &&
+                    TextUtils.equals(r.getSbn().getTag(), tag)
+                    && r.getSbn().getPackageName().equals(pkg)) {
                 matching.add(r);
             }
         }
@@ -8047,7 +8080,7 @@
             int numNotifications = mNotificationList.size();
             for (int i = 0; i < numNotifications; i++) {
                 NotificationRecord rec = mNotificationList.get(i);
-                if (pkgList.contains(rec.sbn.getPackageName())) {
+                if (pkgList.contains(rec.getSbn().getPackageName())) {
                     rec.setHidden(true);
                     changedNotifications.add(rec);
                 }
@@ -8065,7 +8098,7 @@
             int numNotifications = mNotificationList.size();
             for (int i = 0; i < numNotifications; i++) {
                 NotificationRecord rec = mNotificationList.get(i);
-                if (pkgList.contains(rec.sbn.getPackageName())) {
+                if (pkgList.contains(rec.getSbn().getPackageName())) {
                     rec.setHidden(false);
                     changedNotifications.add(rec);
                 }
@@ -8264,10 +8297,10 @@
 
         for (int i = 0; i < N; i++) {
             NotificationRecord record = mNotificationList.get(i);
-            if (!isVisibleToListener(record.sbn, info)) {
+            if (!isVisibleToListener(record.getSbn(), info)) {
                 continue;
             }
-            final String key = record.sbn.getKey();
+            final String key = record.getSbn().getKey();
             final NotificationListenerService.Ranking ranking =
                     new NotificationListenerService.Ranking();
             ranking.populate(
@@ -8278,7 +8311,7 @@
                     record.getSuppressedVisualEffects(),
                     record.getImportance(),
                     record.getImportanceExplanation(),
-                    record.sbn.getOverrideGroupKey(),
+                    record.getSbn().getOverrideGroupKey(),
                     record.getChannel(),
                     record.getPeopleOverride(),
                     record.getSnoozeCriteria(),
@@ -8550,7 +8583,7 @@
             for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
                 ArrayList<String> keys = new ArrayList<>(records.size());
                 for (NotificationRecord r : records) {
-                    boolean sbnVisible = isVisibleToListener(r.sbn, info)
+                    boolean sbnVisible = isVisibleToListener(r.getSbn(), info)
                             && info.isSameUser(r.getUserId());
                     if (sbnVisible) {
                         keys.add(r.getKey());
@@ -8638,7 +8671,7 @@
             if (debug) {
                 Slog.v(TAG, "onNotificationEnqueuedLocked() called with: r = [" + r + "]");
             }
-            final StatusBarNotification sbn = r.sbn;
+            final StatusBarNotification sbn = r.getSbn();
             notifyAssistantLocked(
                     sbn,
                     true /* sameUserOnly */,
@@ -8978,8 +9011,8 @@
         private void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
                 boolean notifyAllListeners) {
             // Lazily initialized snapshots of the notification.
-            StatusBarNotification sbn = r.sbn;
-            StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
+            StatusBarNotification sbn = r.getSbn();
+            StatusBarNotification oldSbn = (old != null) ? old.getSbn() : null;
             TrimCache trimCache = new TrimCache(sbn);
 
             for (final ManagedServiceInfo info : getServices()) {
@@ -9039,7 +9072,7 @@
         @GuardedBy("mNotificationLock")
         public void notifyRemovedLocked(NotificationRecord r, int reason,
                 NotificationStats notificationStats) {
-            final StatusBarNotification sbn = r.sbn;
+            final StatusBarNotification sbn = r.getSbn();
 
             // make a copy in case changes are made to the underlying Notification object
             // NOTE: this copy is lightweight: it doesn't include heavyweight parts of the
@@ -9103,7 +9136,7 @@
                 if (isHiddenRankingUpdate && serviceInfo.targetSdkVersion >=
                         Build.VERSION_CODES.P) {
                     for (NotificationRecord rec : changedHiddenNotifications) {
-                        if (isVisibleToListener(rec.sbn, serviceInfo)) {
+                        if (isVisibleToListener(rec.getSbn(), serviceInfo)) {
                             notifyThisListener = true;
                             break;
                         }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 660d574..4785da9 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -91,7 +91,7 @@
     static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
     // the period after which a notification is updated where it can make sound
     private static final int MAX_SOUND_DELAY_MS = 2000;
-    final StatusBarNotification sbn;
+    private final StatusBarNotification sbn;
     IActivityManager mAm;
     UriGrantsManagerInternal mUgmInternal;
     final int mTargetSdkVersion;
@@ -229,7 +229,7 @@
     }
 
     private Uri calculateSound() {
-        final Notification n = sbn.getNotification();
+        final Notification n = getSbn().getNotification();
 
         // No notification sounds on tv
         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
@@ -265,7 +265,7 @@
         if (mPreChannelsNotification
                 && (getChannel().getUserLockedFields()
                 & NotificationChannel.USER_LOCKED_LIGHTS) == 0) {
-            final Notification notification = sbn.getNotification();
+            final Notification notification = getSbn().getNotification();
             if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0) {
                 light = new Light(notification.ledARGB, notification.ledOnMS,
                         notification.ledOffMS);
@@ -296,7 +296,7 @@
         if (mPreChannelsNotification
                 && (getChannel().getUserLockedFields()
                 & NotificationChannel.USER_LOCKED_VIBRATION) == 0) {
-            final Notification notification = sbn.getNotification();
+            final Notification notification = getSbn().getNotification();
             final boolean useDefaultVibrate =
                     (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
             if (useDefaultVibrate) {
@@ -309,7 +309,7 @@
     }
 
     private AudioAttributes calculateAttributes() {
-        final Notification n = sbn.getNotification();
+        final Notification n = getSbn().getNotification();
         AudioAttributes attributes = getChannel().getAudioAttributes();
         if (attributes == null) {
             attributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
@@ -335,7 +335,7 @@
     }
 
     private int calculateInitialImportance() {
-        final Notification n = sbn.getNotification();
+        final Notification n = getSbn().getNotification();
         int importance = getChannel().getImportance();  // Post-channels notifications use this
         mInitialImportanceExplanationCode = getChannel().hasUserSetImportance()
                 ? MetricsEvent.IMPORTANCE_EXPLANATION_USER
@@ -406,31 +406,31 @@
         mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
         mCreationTimeMs = previous.mCreationTimeMs;
         mVisibleSinceMs = previous.mVisibleSinceMs;
-        if (previous.sbn.getOverrideGroupKey() != null && !sbn.isAppGroup()) {
-            sbn.setOverrideGroupKey(previous.sbn.getOverrideGroupKey());
+        if (previous.getSbn().getOverrideGroupKey() != null && !getSbn().isAppGroup()) {
+            getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
         }
         // Don't copy importance information or mGlobalSortKey, recompute them.
     }
 
-    public Notification getNotification() { return sbn.getNotification(); }
-    public int getFlags() { return sbn.getNotification().flags; }
-    public UserHandle getUser() { return sbn.getUser(); }
-    public String getKey() { return sbn.getKey(); }
+    public Notification getNotification() { return getSbn().getNotification(); }
+    public int getFlags() { return getSbn().getNotification().flags; }
+    public UserHandle getUser() { return getSbn().getUser(); }
+    public String getKey() { return getSbn().getKey(); }
     /** @deprecated Use {@link #getUser()} instead. */
-    public int getUserId() { return sbn.getUserId(); }
-    public int getUid() { return sbn.getUid(); }
+    public int getUserId() { return getSbn().getUserId(); }
+    public int getUid() { return getSbn().getUid(); }
 
     void dump(ProtoOutputStream proto, long fieldId, boolean redact, int state) {
         final long token = proto.start(fieldId);
 
-        proto.write(NotificationRecordProto.KEY, sbn.getKey());
+        proto.write(NotificationRecordProto.KEY, getSbn().getKey());
         proto.write(NotificationRecordProto.STATE, state);
         if (getChannel() != null) {
             proto.write(NotificationRecordProto.CHANNEL_ID, getChannel().getId());
         }
         proto.write(NotificationRecordProto.CAN_SHOW_LIGHT, getLight() != null);
         proto.write(NotificationRecordProto.CAN_VIBRATE, getVibration() != null);
-        proto.write(NotificationRecordProto.FLAGS, sbn.getNotification().flags);
+        proto.write(NotificationRecordProto.FLAGS, getSbn().getNotification().flags);
         proto.write(NotificationRecordProto.GROUP_KEY, getGroupKey());
         proto.write(NotificationRecordProto.IMPORTANCE, getImportance());
         if (getSound() != null) {
@@ -439,8 +439,8 @@
         if (getAudioAttributes() != null) {
             getAudioAttributes().dumpDebug(proto, NotificationRecordProto.AUDIO_ATTRIBUTES);
         }
-        proto.write(NotificationRecordProto.PACKAGE, sbn.getPackageName());
-        proto.write(NotificationRecordProto.DELEGATE_PACKAGE, sbn.getOpPkg());
+        proto.write(NotificationRecordProto.PACKAGE, getSbn().getPackageName());
+        proto.write(NotificationRecordProto.DELEGATE_PACKAGE, getSbn().getOpPkg());
 
         proto.end(token);
     }
@@ -452,15 +452,15 @@
     }
 
     void dump(PrintWriter pw, String prefix, Context baseContext, boolean redact) {
-        final Notification notification = sbn.getNotification();
+        final Notification notification = getSbn().getNotification();
         pw.println(prefix + this);
         prefix = prefix + "  ";
-        pw.println(prefix + "uid=" + sbn.getUid() + " userId=" + sbn.getUserId());
-        pw.println(prefix + "opPkg=" + sbn.getOpPkg());
+        pw.println(prefix + "uid=" + getSbn().getUid() + " userId=" + getSbn().getUserId());
+        pw.println(prefix + "opPkg=" + getSbn().getOpPkg());
         pw.println(prefix + "icon=" + notification.getSmallIcon());
         pw.println(prefix + "flags=0x" + Integer.toHexString(notification.flags));
         pw.println(prefix + "pri=" + notification.priority);
-        pw.println(prefix + "key=" + sbn.getKey());
+        pw.println(prefix + "key=" + getSbn().getKey());
         pw.println(prefix + "seen=" + mStats.hasSeen());
         pw.println(prefix + "groupKey=" + getGroupKey());
         pw.println(prefix + "fullscreenIntent=" + notification.fullScreenIntent);
@@ -594,9 +594,9 @@
                 "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s importance=%d key=%s" +
                         ": %s)",
                 System.identityHashCode(this),
-                this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(),
-                this.sbn.getTag(), this.mImportance, this.sbn.getKey(),
-                this.sbn.getNotification());
+                this.getSbn().getPackageName(), this.getSbn().getUser(), this.getSbn().getId(),
+                this.getSbn().getTag(), this.mImportance, this.getSbn().getKey(),
+                this.getSbn().getNotification());
     }
 
     public boolean hasAdjustment(String key) {
@@ -936,7 +936,7 @@
     private long calculateRankingTimeMs(long previousRankingTimeMs) {
         Notification n = getNotification();
         // Take developer provided 'when', unless it's in the future.
-        if (n.when != 0 && n.when <= sbn.getPostTime()) {
+        if (n.when != 0 && n.when <= getSbn().getPostTime()) {
             return n.when;
         }
         // If we've ranked a previous instance with a timestamp, inherit it. This case is
@@ -944,7 +944,7 @@
         if (previousRankingTimeMs > 0) {
             return previousRankingTimeMs;
         }
-        return sbn.getPostTime();
+        return getSbn().getPostTime();
     }
 
     public void setGlobalSortKey(String globalSortKey) {
@@ -977,11 +977,11 @@
     }
 
     public String getGroupKey() {
-        return sbn.getGroupKey();
+        return getSbn().getGroupKey();
     }
 
     public void setOverrideGroupKey(String overrideGroupKey) {
-        sbn.setOverrideGroupKey(overrideGroupKey);
+        getSbn().setOverrideGroupKey(overrideGroupKey);
     }
 
     public NotificationChannel getChannel() {
@@ -1202,7 +1202,7 @@
      * Returns whether this notification was posted by a secondary app
      */
     public boolean isProxied() {
-        return !Objects.equals(sbn.getPackageName(), sbn.getOpPkg());
+        return !Objects.equals(getSbn().getPackageName(), getSbn().getOpPkg());
     }
 
     /**
@@ -1245,7 +1245,7 @@
         if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
 
         // We can't grant Uri permissions from system
-        final int sourceUid = sbn.getUid();
+        final int sourceUid = getSbn().getUid();
         if (sourceUid == android.os.Process.SYSTEM_UID) return;
 
         final long ident = Binder.clearCallingIdentity();
@@ -1274,7 +1274,7 @@
     }
 
     public LogMaker getLogMaker(long now) {
-        LogMaker lm = sbn.getLogMaker()
+        LogMaker lm = getSbn().getLogMaker()
                 .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE, mImportance)
                 .addTaggedData(MetricsEvent.NOTIFICATION_SINCE_CREATE_MILLIS, getLifespanMs(now))
                 .addTaggedData(MetricsEvent.NOTIFICATION_SINCE_UPDATE_MILLIS, getFreshnessMs(now))
@@ -1351,6 +1351,10 @@
         return true;
     }
 
+    StatusBarNotification getSbn() {
+        return sbn;
+    }
+
     @VisibleForTesting
     static final class Light {
         public final int color;
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index 9bbc3924..8d8511f 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -88,12 +88,12 @@
                 return true;
             }
 
-            return !(Objects.equals(r.sbn.getChannelIdLogTag(), old.sbn.getChannelIdLogTag())
-                    && Objects.equals(r.sbn.getGroupLogTag(), old.sbn.getGroupLogTag())
-                    && (r.sbn.getNotification().isGroupSummary()
-                        == old.sbn.getNotification().isGroupSummary())
-                    && Objects.equals(r.sbn.getNotification().category,
-                        old.sbn.getNotification().category)
+            return !(Objects.equals(r.getSbn().getChannelIdLogTag(), old.getSbn().getChannelIdLogTag())
+                    && Objects.equals(r.getSbn().getGroupLogTag(), old.getSbn().getGroupLogTag())
+                    && (r.getSbn().getNotification().isGroupSummary()
+                        == old.getSbn().getNotification().isGroupSummary())
+                    && Objects.equals(r.getSbn().getNotification().category,
+                        old.getSbn().getNotification().category)
                     && (r.getImportance() == old.getImportance()));
         }
 
@@ -106,7 +106,7 @@
          * @return hash code for the notification style class, or 0 if none exists.
          */
         public int getStyle() {
-            return getStyle(r.sbn.getNotification().extras);
+            return getStyle(r.getSbn().getNotification().extras);
         }
 
         private int getStyle(@Nullable Bundle extras) {
@@ -120,7 +120,7 @@
         }
 
         int getNumPeople() {
-            return getNumPeople(r.sbn.getNotification().extras);
+            return getNumPeople(r.getSbn().getNotification().extras);
         }
 
         private int getNumPeople(@Nullable Bundle extras) {
@@ -140,7 +140,7 @@
         }
 
         int getInstanceId() {
-            return (r.sbn.getInstanceId() == null ? 0 : r.sbn.getInstanceId().getId());
+            return (r.getSbn().getInstanceId() == null ? 0 : r.getSbn().getInstanceId().getId());
         }
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index 00b4c2b..f43ce76 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -34,15 +34,15 @@
         StatsLog.write(StatsLog.NOTIFICATION_REPORTED,
                 /* int32 event_id = 1 */ p.getUiEvent().getId(),
                 /* int32 uid = 2 */ r.getUid(),
-                /* string package_name = 3 */ r.sbn.getPackageName(),
+                /* string package_name = 3 */ r.getSbn().getPackageName(),
                 /* int32 instance_id = 4 */ p.getInstanceId(),
-                /* int32 notification_id = 5 */ r.sbn.getId(),
-                /* string notification_tag = 6 */ r.sbn.getTag(),
-                /* string channel_id = 7 */ r.sbn.getChannelIdLogTag(),
-                /* string group_id = 8 */ r.sbn.getGroupLogTag(),
+                /* int32 notification_id = 5 */ r.getSbn().getId(),
+                /* string notification_tag = 6 */ r.getSbn().getTag(),
+                /* string channel_id = 7 */ r.getSbn().getChannelIdLogTag(),
+                /* string group_id = 8 */ r.getSbn().getGroupLogTag(),
                 /* int32 group_instance_id = 9 */ 0, // TODO generate and fill instance ids
-                /* bool is_group_summary = 10 */ r.sbn.getNotification().isGroupSummary(),
-                /* string category = 11 */ r.sbn.getNotification().category,
+                /* bool is_group_summary = 10 */ r.getSbn().getNotification().isGroupSummary(),
+                /* string category = 11 */ r.getSbn().getNotification().category,
                 /* int32 style = 12 */ p.getStyle(),
                 /* int32 num_people = 13 */ p.getNumPeople(),
                 /* int32 position = 14 */ position,
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index d1fe0d9..b42fe92 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -276,7 +276,7 @@
 
     // Locked by this.
     private AggregatedStats[] getAggregatedStatsLocked(NotificationRecord record) {
-        return getAggregatedStatsLocked(record.sbn.getPackageName());
+        return getAggregatedStatsLocked(record.getSbn().getPackageName());
     }
 
     // Locked by this.
@@ -1142,7 +1142,7 @@
                     long nowMs = System.currentTimeMillis();
                     switch (msg.what) {
                         case MSG_POST:
-                            writeEvent(r.sbn.getPostTime(), EVENT_TYPE_POST, r);
+                            writeEvent(r.getSbn().getPostTime(), EVENT_TYPE_POST, r);
                             break;
                         case MSG_CLICK:
                             writeEvent(nowMs, EVENT_TYPE_CLICK, r);
@@ -1287,7 +1287,7 @@
 
         private void writeEvent(long eventTimeMs, int eventType, NotificationRecord r) {
             ContentValues cv = new ContentValues();
-            cv.put(COL_EVENT_USER_ID, r.sbn.getUser().getIdentifier());
+            cv.put(COL_EVENT_USER_ID, r.getSbn().getUser().getIdentifier());
             cv.put(COL_EVENT_TIME, eventTimeMs);
             cv.put(COL_EVENT_TYPE, eventType);
             putNotificationIdentifiers(r, cv);
@@ -1324,16 +1324,16 @@
         }
 
         private static void putNotificationIdentifiers(NotificationRecord r, ContentValues outCv) {
-            outCv.put(COL_KEY, r.sbn.getKey());
-            outCv.put(COL_PKG, r.sbn.getPackageName());
+            outCv.put(COL_KEY, r.getSbn().getKey());
+            outCv.put(COL_PKG, r.getSbn().getPackageName());
         }
 
         private static void putNotificationDetails(NotificationRecord r, ContentValues outCv) {
-            outCv.put(COL_NOTIFICATION_ID, r.sbn.getId());
-            if (r.sbn.getTag() != null) {
-                outCv.put(COL_TAG, r.sbn.getTag());
+            outCv.put(COL_NOTIFICATION_ID, r.getSbn().getId());
+            if (r.getSbn().getTag() != null) {
+                outCv.put(COL_TAG, r.getSbn().getTag());
             }
-            outCv.put(COL_WHEN_MS, r.sbn.getPostTime());
+            outCv.put(COL_WHEN_MS, r.getSbn().getPostTime());
             outCv.put(COL_FLAGS, r.getNotification().flags);
             final int before = r.stats.requestedImportance;
             final int after = r.getImportance();
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index b0c1863..fe39322 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1380,7 +1380,8 @@
                 policy.priorityCategories, policy.priorityCallSenders,
                 policy.priorityMessageSenders, policy.suppressedVisualEffects,
                 (areChannelsBypassingDnd ? NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND
-                        : 0)));
+                        : 0),
+                policy.priorityConversationSenders));
     }
 
     public boolean areChannelsBypassingDnd() {
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index 9e32d0e..661297a 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -166,7 +166,7 @@
             ArrayMap<String, NotificationRecord> packages =
                     mSnoozedNotifications.get(userId).get(pkg);
             for (int i = 0; i < packages.size(); i++) {
-                String currentGroupKey = packages.valueAt(i).sbn.getGroup();
+                String currentGroupKey = packages.valueAt(i).getSbn().getGroup();
                 if (currentGroupKey.equals(groupKey)) {
                     records.add(packages.valueAt(i));
                 }
@@ -223,7 +223,7 @@
      * Snoozes a notification and schedules an alarm to repost at that time.
      */
     protected void snooze(NotificationRecord record, long duration) {
-        String pkg = record.sbn.getPackageName();
+        String pkg = record.getSbn().getPackageName();
         String key = record.getKey();
         int userId = record.getUser().getIdentifier();
 
@@ -242,7 +242,7 @@
         int userId = record.getUser().getIdentifier();
         if (contextId != null) {
             synchronized (mPersistedSnoozedNotificationsWithContext) {
-                storeRecord(record.sbn.getPackageName(), record.getKey(),
+                storeRecord(record.getSbn().getPackageName(), record.getKey(),
                         userId, mPersistedSnoozedNotificationsWithContext, contextId);
             }
         }
@@ -254,9 +254,9 @@
         if (DEBUG) {
             Slog.d(TAG, "Snoozing " + record.getKey());
         }
-        storeRecord(record.sbn.getPackageName(), record.getKey(),
+        storeRecord(record.getSbn().getPackageName(), record.getKey(),
                 userId, mSnoozedNotifications, record);
-        mPackages.put(record.getKey(), record.sbn.getPackageName());
+        mPackages.put(record.getKey(), record.getSbn().getPackageName());
         mUsers.put(record.getKey(), userId);
     }
 
@@ -308,7 +308,7 @@
             if (recordsForPkg != null) {
                 final Set<Map.Entry<String, NotificationRecord>> records = recordsForPkg.entrySet();
                 for (Map.Entry<String, NotificationRecord> record : records) {
-                    final StatusBarNotification sbn = record.getValue().sbn;
+                    final StatusBarNotification sbn = record.getValue().getSbn();
                     if (Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
                         record.getValue().isCanceled = true;
                         return true;
@@ -369,7 +369,7 @@
         if (records == null) {
             return;
         }
-        ArrayMap<String, NotificationRecord> pkgRecords = records.get(record.sbn.getPackageName());
+        ArrayMap<String, NotificationRecord> pkgRecords = records.get(record.getSbn().getPackageName());
         if (pkgRecords == null) {
             return;
         }
@@ -420,7 +420,7 @@
                     int N = recordsByKey.size();
                     for (int i = 0; i < N; i++) {
                         final NotificationRecord potentialGroupSummary = recordsByKey.valueAt(i);
-                        if (potentialGroupSummary.sbn.isGroup()
+                        if (potentialGroupSummary.getSbn().isGroup()
                                 && potentialGroupSummary.getNotification().isGroupSummary()
                                 && groupKey.equals(potentialGroupSummary.getGroupKey())) {
                             groupSummaryKey = potentialGroupSummary.getKey();
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index 6045f6c..4d19855 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -17,6 +17,7 @@
 package com.android.server.notification;
 
 import static android.provider.Settings.Global.ZEN_MODE_OFF;
+import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -106,8 +107,8 @@
     }
 
     private static Bundle extras(NotificationRecord record) {
-        return record != null && record.sbn != null && record.sbn.getNotification() != null
-                ? record.sbn.getNotification().extras : null;
+        return record != null && record.getSbn() != null && record.getSbn().getNotification() != null
+                ? record.getSbn().getNotification().extras : null;
     }
 
     protected void recordCall(NotificationRecord record) {
@@ -125,8 +126,8 @@
         }
         // Make an exception to policy for the notification saying that policy has changed
         if (NotificationManager.Policy.areAllVisualEffectsSuppressed(policy.suppressedVisualEffects)
-                && "android".equals(record.sbn.getPackageName())
-                && SystemMessageProto.SystemMessage.NOTE_ZEN_UPGRADE == record.sbn.getId()) {
+                && "android".equals(record.getSbn().getPackageName())
+                && SystemMessageProto.SystemMessage.NOTE_ZEN_UPGRADE == record.getSbn().getId()) {
             ZenLog.traceNotIntercepted(record, "systemDndChangedNotification");
             return false;
         }
@@ -156,25 +157,6 @@
                     }
                     return false;
                 }
-                if (isCall(record)) {
-                    if (policy.allowRepeatCallers()
-                            && REPEAT_CALLERS.isRepeat(mContext, extras(record))) {
-                        ZenLog.traceNotIntercepted(record, "repeatCaller");
-                        return false;
-                    }
-                    if (!policy.allowCalls()) {
-                        ZenLog.traceIntercepted(record, "!allowCalls");
-                        return true;
-                    }
-                    return shouldInterceptAudience(policy.allowCallsFrom(), record);
-                }
-                if (isMessage(record)) {
-                    if (!policy.allowMessages()) {
-                        ZenLog.traceIntercepted(record, "!allowMessages");
-                        return true;
-                    }
-                    return shouldInterceptAudience(policy.allowMessagesFrom(), record);
-                }
                 if (isEvent(record)) {
                     if (!policy.allowEvents()) {
                         ZenLog.traceIntercepted(record, "!allowEvents");
@@ -203,6 +185,41 @@
                     }
                     return false;
                 }
+                if (isConversation(record)) {
+                    if (policy.allowConversations()) {
+                        if (policy.priorityConversationSenders == CONVERSATION_SENDERS_ANYONE) {
+                            ZenLog.traceNotIntercepted(record, "conversationAnyone");
+                            return false;
+                        } else if (policy.priorityConversationSenders
+                                == NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT
+                                && record.getChannel().isImportantConversation()) {
+                            ZenLog.traceNotIntercepted(record, "conversationMatches");
+                            return false;
+                        }
+                    }
+                    // if conversations aren't allowed record might still be allowed thanks
+                    // to call or message metadata, so don't return yet
+                }
+                if (isCall(record)) {
+                    if (policy.allowRepeatCallers()
+                            && REPEAT_CALLERS.isRepeat(mContext, extras(record))) {
+                        ZenLog.traceNotIntercepted(record, "repeatCaller");
+                        return false;
+                    }
+                    if (!policy.allowCalls()) {
+                        ZenLog.traceIntercepted(record, "!allowCalls");
+                        return true;
+                    }
+                    return shouldInterceptAudience(policy.allowCallsFrom(), record);
+                }
+                if (isMessage(record)) {
+                    if (!policy.allowMessages()) {
+                        ZenLog.traceIntercepted(record, "!allowMessages");
+                        return true;
+                    }
+                    return shouldInterceptAudience(policy.allowMessagesFrom(), record);
+                }
+
                 ZenLog.traceIntercepted(record, "!priority");
                 return true;
             default:
@@ -245,7 +262,7 @@
     }
 
     public boolean isCall(NotificationRecord record) {
-        return record != null && (isDefaultPhoneApp(record.sbn.getPackageName())
+        return record != null && (isDefaultPhoneApp(record.getSbn().getPackageName())
                 || record.isCategory(Notification.CATEGORY_CALL));
     }
 
@@ -273,7 +290,11 @@
     }
 
     protected boolean isMessage(NotificationRecord record) {
-        return mMessagingUtil.isMessaging(record.sbn);
+        return mMessagingUtil.isMessaging(record.getSbn());
+    }
+
+    protected boolean isConversation(NotificationRecord record) {
+        return record.isConversation();
     }
 
     private static boolean audienceMatches(int source, float contactAffinity) {
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 696d2ea..3b564c3 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -641,9 +641,11 @@
     }
 
     public void dump(PrintWriter pw, String prefix) {
-        pw.print(prefix); pw.print("mZenMode=");
+        pw.print(prefix);
+        pw.print("mZenMode=");
         pw.println(Global.zenModeToString(mZenMode));
-        pw.print("mConsolidatedPolicy=" + mConsolidatedPolicy.toString());
+        pw.print(prefix);
+        pw.println("mConsolidatedPolicy=" + mConsolidatedPolicy.toString());
         final int N = mConfigs.size();
         for (int i = 0; i < N; i++) {
             dump(pw, prefix, "mConfigs[u=" + mConfigs.keyAt(i) + "]", mConfigs.valueAt(i));
@@ -665,13 +667,17 @@
             return;
         }
         pw.printf("allow(alarms=%b,media=%b,system=%b,calls=%b,callsFrom=%s,repeatCallers=%b,"
-                + "messages=%b,messagesFrom=%s,events=%b,reminders=%b)\n",
+                + "messages=%b,messagesFrom=%s,conversations=%b,conversationsFrom=%s,"
+                        + "events=%b,reminders=%b)\n",
                 config.allowAlarms, config.allowMedia, config.allowSystem,
                 config.allowCalls, ZenModeConfig.sourceToString(config.allowCallsFrom),
                 config.allowRepeatCallers, config.allowMessages,
                 ZenModeConfig.sourceToString(config.allowMessagesFrom),
+                config.allowConversations,
+                ZenPolicy.conversationTypeToString(config.allowConversationsFrom),
                 config.allowEvents, config.allowReminders);
-        pw.printf(" disallow(visualEffects=%s)\n", config.suppressedVisualEffects);
+        pw.print(prefix);
+        pw.printf("  disallow(visualEffects=%s)\n", config.suppressedVisualEffects);
         pw.print(prefix); pw.print("  manualRule="); pw.println(config.manualRule);
         if (config.automaticRules.isEmpty()) return;
         final int N = config.automaticRules.size();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
index d16c232a..47ad831 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
@@ -97,7 +97,7 @@
         NotificationChannel updatedChannel =
                 new NotificationChannel("a", "", IMPORTANCE_HIGH);
         when(mConfig.getConversationNotificationChannel(
-                any(), anyInt(), eq("a"), eq(r.sbn.getShortcutId(mContext)), eq(true), eq(false)))
+                any(), anyInt(), eq("a"), eq(r.getSbn().getShortcutId(mContext)), eq(true), eq(false)))
                 .thenReturn(updatedChannel);
 
         assertNull(extractor.process(r));
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 2cf5eae..bcdc283 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -30,6 +30,9 @@
 import static android.app.NotificationManager.IMPORTANCE_MAX;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
@@ -679,8 +682,9 @@
         NotificationRecord nrBubble = generateMessageBubbleNotifRecord(true /* addMetadata */,
                 mTestNotificationChannel, 1 /* id */, "tag", groupKey, false /* isSummary */);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrBubble.sbn.getTag(),
-                nrBubble.sbn.getId(), nrBubble.sbn.getNotification(), nrBubble.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrBubble.getSbn().getTag(),
+                nrBubble.getSbn().getId(), nrBubble.getSbn().getNotification(),
+                nrBubble.getSbn().getUserId());
         waitForIdle();
 
         // Make sure we are a bubble
@@ -692,8 +696,9 @@
         NotificationRecord nrPlain = generateMessageBubbleNotifRecord(false /* addMetadata */,
                 mTestNotificationChannel, 2 /* id */, "tag", groupKey, false /* isSummary */);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrPlain.sbn.getTag(),
-                nrPlain.sbn.getId(), nrPlain.sbn.getNotification(), nrPlain.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrPlain.getSbn().getTag(),
+                nrPlain.getSbn().getId(), nrPlain.getSbn().getNotification(),
+                nrPlain.getSbn().getUserId());
         waitForIdle();
 
         notifsAfter = mBinderService.getActiveNotifications(PKG);
@@ -706,8 +711,9 @@
         if (summaryAutoCancel) {
             nrSummary.getNotification().flags |= FLAG_AUTO_CANCEL;
         }
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrSummary.sbn.getTag(),
-                nrSummary.sbn.getId(), nrSummary.sbn.getNotification(), nrSummary.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrSummary.getSbn().getTag(),
+                nrSummary.getSbn().getId(), nrSummary.getSbn().getNotification(),
+                nrSummary.getSbn().getUserId());
         waitForIdle();
 
         notifsAfter = mBinderService.getActiveNotifications(PKG);
@@ -886,7 +892,7 @@
 
         mBinderService.createNotificationChannels(
                 PKG, new ParceledListSlice(Arrays.asList(channel)));
-        final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(channel).getSbn();
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testBlockedNotifications_blockedChannel",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -904,7 +910,7 @@
         mBinderService.createNotificationChannels(
                 PKG, new ParceledListSlice(Arrays.asList(channel)));
 
-        final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(channel).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -933,7 +939,7 @@
         assertEquals(IMPORTANCE_NONE, mBinderService.getNotificationChannel(
                 PKG, mContext.getUserId(), PKG, channel.getId()).getImportance());
 
-        StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
+        StatusBarNotification sbn = generateNotificationRecord(channel).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -955,7 +961,7 @@
         assertEquals(IMPORTANCE_NONE, mBinderService.getNotificationChannel(
                 PKG, mContext.getUserId(), PKG, channel.getId()).getImportance());
 
-        sbn = generateNotificationRecord(channel).sbn;
+        sbn = generateNotificationRecord(channel).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testEnqueuedBlockedNotifications_userBlockedChannelForegroundService",
@@ -989,7 +995,7 @@
 
         mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
 
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testEnqueuedBlockedNotifications_blockedApp",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -1003,7 +1009,7 @@
 
         mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
 
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testEnqueuedBlockedNotifications_blockedAppForegroundService",
@@ -1026,7 +1032,7 @@
         int id = 0;
         for (String category: categories) {
             final StatusBarNotification sbn =
-                    generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
+                    generateNotificationRecord(mTestNotificationChannel, ++id, "", false).getSbn();
             sbn.getNotification().category = category;
             mBinderService.enqueueNotificationWithTag(PKG, PKG,
                     "testEnqueuedRestrictedNotifications_asSystem",
@@ -1051,7 +1057,7 @@
         int id = 0;
         for (String category: categories) {
             final StatusBarNotification sbn =
-                    generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
+                    generateNotificationRecord(mTestNotificationChannel, ++id, "", false).getSbn();
             sbn.getNotification().category = category;
             mBinderService.enqueueNotificationWithTag(PKG, PKG,
                     "testEnqueuedRestrictedNotifications_notAutomotive",
@@ -1074,7 +1080,7 @@
                 Notification.CATEGORY_CAR_WARNING,
                 Notification.CATEGORY_CAR_INFORMATION);
         for (String category: categories) {
-            final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+            final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
             sbn.getNotification().category = category;
             try {
                 mBinderService.enqueueNotificationWithTag(PKG, PKG,
@@ -1102,7 +1108,7 @@
         Bundle bundle = new Bundle();
         bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         NotificationManagerService.PostNotificationRunnable runnable =
@@ -1137,11 +1143,11 @@
         assertNull(call.old);
         assertEquals(0, call.position);
         assertEquals(0, call.buzzBeepBlink);
-        assertEquals(PKG, call.r.sbn.getPackageName());
-        assertEquals(0, call.r.sbn.getId());
-        assertEquals(tag, call.r.sbn.getTag());
-        assertNotNull(call.r.sbn.getInstanceId());
-        assertEquals(0, call.r.sbn.getInstanceId().getId());
+        assertEquals(PKG, call.r.getSbn().getPackageName());
+        assertEquals(0, call.r.getSbn().getId());
+        assertEquals(tag, call.r.getSbn().getTag());
+        assertNotNull(call.r.getSbn().getInstanceId());
+        assertEquals(0, call.r.getSbn().getInstanceId().getId());
     }
 
     @Test
@@ -1163,14 +1169,14 @@
         assertEquals(
                 NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED,
                 mNotificationRecordLogger.get(0).getUiEvent());
-        assertEquals(0, mNotificationRecordLogger.get(0).r.sbn.getInstanceId().getId());
+        assertEquals(0, mNotificationRecordLogger.get(0).r.getSbn().getInstanceId().getId());
 
         assertTrue(mNotificationRecordLogger.get(1).shouldLog());
         assertEquals(
                 NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_UPDATED,
                 mNotificationRecordLogger.get(1).getUiEvent());
         // Instance ID doesn't change on update of an active notification
-        assertEquals(0, mNotificationRecordLogger.get(1).r.sbn.getInstanceId().getId());
+        assertEquals(0, mNotificationRecordLogger.get(1).r.getSbn().getInstanceId().getId());
     }
 
     @Test
@@ -1204,14 +1210,14 @@
         assertEquals(
                 NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED,
                 mNotificationRecordLogger.get(0).getUiEvent());
-        assertEquals(0, mNotificationRecordLogger.get(0).r.sbn.getInstanceId().getId());
+        assertEquals(0, mNotificationRecordLogger.get(0).r.getSbn().getInstanceId().getId());
 
         assertTrue(mNotificationRecordLogger.get(1).shouldLog());
         assertEquals(
                 NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED,
                 mNotificationRecordLogger.get(1).getUiEvent());
         // New instance ID because notification was canceled before re-post
-        assertEquals(1, mNotificationRecordLogger.get(1).r.sbn.getInstanceId().getId());
+        assertEquals(1, mNotificationRecordLogger.get(1).r.getSbn().getInstanceId().getId());
     }
 
     @Test
@@ -1252,7 +1258,7 @@
     @Test
     public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
         NotificationRecord r = generateNotificationRecord(null);
-        final StatusBarNotification sbn = r.sbn;
+        final StatusBarNotification sbn = r.getSbn();
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelNotificationsFromListenerImmediatelyAfterEnqueue",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -1266,7 +1272,7 @@
 
     @Test
     public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelAllNotificationsImmediatelyAfterEnqueue",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -1281,7 +1287,7 @@
     @Test
     public void testCancelImmediatelyAfterEnqueueNotifiesListeners_ForegroundServiceFlag()
             throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags =
                 Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
@@ -1299,14 +1305,14 @@
 
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testUserInitiatedClearAll_noLeak",
-                n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
+                n.getSbn().getId(), n.getSbn().getNotification(), n.getSbn().getUserId());
         waitForIdle();
 
         mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
                 n.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(n.sbn.getPackageName());
+                mBinderService.getActiveNotifications(n.getSbn().getPackageName());
         assertEquals(0, notifs.length);
         assertEquals(0, mService.getNotificationRecordCount());
         ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
@@ -1323,20 +1329,22 @@
 
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelAllNotificationsCancelsChildren",
-                parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
+                parent.getSbn().getId(), parent.getSbn().getNotification(),
+                parent.getSbn().getUserId());
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelAllNotificationsCancelsChildren",
-                child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
+                child.getSbn().getId(), child.getSbn().getNotification(),
+                child.getSbn().getUserId());
         waitForIdle();
 
-        mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId());
+        mBinderService.cancelAllNotifications(PKG, parent.getSbn().getUserId());
         waitForIdle();
         assertEquals(0, mService.getNotificationRecordCount());
     }
 
     @Test
     public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         for (int i = 0; i < 10; i++) {
             mBinderService.enqueueNotificationWithTag(PKG, PKG,
                     "testCancelAllNotificationsMultipleEnqueuedDoesNotCrash",
@@ -1360,20 +1368,22 @@
         // fully post parent notification
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
-                parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
+                parent.getSbn().getId(), parent.getSbn().getNotification(),
+                parent.getSbn().getUserId());
         waitForIdle();
 
         // enqueue the child several times
         for (int i = 0; i < 10; i++) {
             mBinderService.enqueueNotificationWithTag(PKG, PKG,
                     "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
-                    child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
+                    child.getSbn().getId(), child.getSbn().getNotification(),
+                    child.getSbn().getUserId());
         }
         // make the parent a child, which will cancel the child notification
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
-                parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
-                parentAsChild.sbn.getUserId());
+                parentAsChild.getSbn().getId(), parentAsChild.getSbn().getNotification(),
+                parentAsChild.getSbn().getUserId());
         waitForIdle();
 
         assertEquals(0, mService.getNotificationRecordCount());
@@ -1390,7 +1400,7 @@
         mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
         mService.updateAutobundledSummaryFlags(0, "pkg", true, false);
 
-        assertTrue(summary.sbn.isOngoing());
+        assertTrue(summary.getSbn().isOngoing());
     }
 
     @Test
@@ -1406,12 +1416,12 @@
 
         mService.updateAutobundledSummaryFlags(0, "pkg", false, false);
 
-        assertFalse(summary.sbn.isOngoing());
+        assertFalse(summary.getSbn().isOngoing());
     }
 
     @Test
     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelAllNotifications_IgnoreForegroundService",
@@ -1426,7 +1436,7 @@
 
     @Test
     public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelAllNotifications_IgnoreOtherPackages",
@@ -1441,7 +1451,7 @@
 
     @Test
     public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelAllNotifications_NullPkgRemovesAll",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -1455,7 +1465,7 @@
 
     @Test
     public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelAllNotifications_NullPkgIgnoresUserAllNotifications",
                 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
@@ -1470,7 +1480,7 @@
 
     @Test
     public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testAppInitiatedCancelAllNotifications_CancelsNoClearFlag",
@@ -1492,7 +1502,7 @@
                 notif.getUserId(), 0, null);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(notif.sbn.getPackageName());
+                mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
         assertEquals(0, notifs.length);
     }
 
@@ -1507,7 +1517,7 @@
                 notif.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(notif.sbn.getPackageName());
+                mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
         assertEquals(1, notifs.length);
     }
 
@@ -1529,7 +1539,7 @@
         mService.getBinderService().cancelNotificationsFromListener(null, null);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(1, notifs.length);
     }
 
@@ -1552,7 +1562,7 @@
                 parent.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(1, notifs.length);
     }
 
@@ -1577,7 +1587,7 @@
 
     @Test
     public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags =
                 Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
@@ -1611,7 +1621,7 @@
         mService.getBinderService().cancelNotificationsFromListener(null, null);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(0, notifs.length);
     }
 
@@ -1631,12 +1641,12 @@
         mService.addNotification(child);
         mService.addNotification(child2);
         mService.addNotification(newGroup);
-        String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
-                child2.sbn.getKey(), newGroup.sbn.getKey()};
+        String[] keys = {parent.getSbn().getKey(), child.getSbn().getKey(),
+                child2.getSbn().getKey(), newGroup.getSbn().getKey()};
         mService.getBinderService().cancelNotificationsFromListener(null, keys);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(1, notifs.length);
     }
 
@@ -1659,7 +1669,7 @@
                 parent.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(0, notifs.length);
     }
 
@@ -1675,31 +1685,33 @@
         final NotificationRecord group2 = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group2", true);
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
-                group2.sbn.getId(), group2.sbn.getNotification(), group2.sbn.getUserId());
+                group2.getSbn().getId(), group2.getSbn().getNotification(),
+                group2.getSbn().getUserId());
         waitForIdle();
 
         // should not be returned
         final NotificationRecord nonGroup = generateNotificationRecord(
                 mTestNotificationChannel, 3, null, false);
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
-                nonGroup.sbn.getId(), nonGroup.sbn.getNotification(), nonGroup.sbn.getUserId());
+                nonGroup.getSbn().getId(), nonGroup.getSbn().getNotification(),
+                nonGroup.getSbn().getUserId());
         waitForIdle();
 
         // same group, child, should be returned
         final NotificationRecord group1Child = generateNotificationRecord(
                 mTestNotificationChannel, 4, "group1", false);
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
-                group1Child.sbn.getId(),
-                group1Child.sbn.getNotification(), group1Child.sbn.getUserId());
+                group1Child.getSbn().getId(),
+                group1Child.getSbn().getNotification(), group1Child.getSbn().getUserId());
         waitForIdle();
 
         List<NotificationRecord> inGroup1 =
                 mService.findGroupNotificationsLocked(PKG, group1.getGroupKey(),
-                        group1.sbn.getUserId());
+                        group1.getSbn().getUserId());
         assertEquals(3, inGroup1.size());
         for (NotificationRecord record : inGroup1) {
             assertTrue(record.getGroupKey().equals(group1.getGroupKey()));
-            assertTrue(record.sbn.getId() == 1 || record.sbn.getId() == 4);
+            assertTrue(record.getSbn().getId() == 1 || record.getSbn().getId() == 4);
         }
     }
 
@@ -1713,7 +1725,7 @@
                 Notification.FLAG_ONGOING_EVENT, true, notif.getUserId(), 0, null);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(notif.sbn.getPackageName());
+                mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
         assertEquals(0, notifs.length);
     }
 
@@ -1733,18 +1745,18 @@
         mService.addNotification(child);
         mService.addNotification(child2);
         mService.addNotification(newGroup);
-        String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
-                child2.sbn.getKey(), newGroup.sbn.getKey()};
+        String[] keys = {parent.getSbn().getKey(), child.getSbn().getKey(),
+                child2.getSbn().getKey(), newGroup.getSbn().getKey()};
         mService.getBinderService().cancelNotificationsFromListener(null, keys);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(0, notifs.length);
     }
 
     @Test
     public void testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag",
@@ -1766,7 +1778,7 @@
                 notif.getUserId(), 0, null);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(notif.sbn.getPackageName());
+                mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
         assertEquals(0, notifs.length);
     }
 
@@ -1781,7 +1793,7 @@
                 notif.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(notif.sbn.getPackageName());
+                mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
         assertEquals(1, notifs.length);
     }
 
@@ -1803,7 +1815,7 @@
         mService.getBinderService().cancelNotificationsFromListener(null, null);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(1, notifs.length);
     }
 
@@ -1823,12 +1835,12 @@
         mService.addNotification(child);
         mService.addNotification(child2);
         mService.addNotification(newGroup);
-        String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
-                child2.sbn.getKey(), newGroup.sbn.getKey()};
+        String[] keys = {parent.getSbn().getKey(), child.getSbn().getKey(),
+                child2.getSbn().getKey(), newGroup.getSbn().getKey()};
         mService.getBinderService().cancelNotificationsFromListener(null, keys);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(0, notifs.length);
     }
 
@@ -1851,7 +1863,7 @@
                 parent.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+                mBinderService.getActiveNotifications(parent.getSbn().getPackageName());
         assertEquals(1, notifs.length);
     }
 
@@ -1985,7 +1997,8 @@
     public void testUpdateGroupNotifyCreatorBlock() throws Exception {
         NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
+        when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()),
+                eq(PKG), anyInt()))
                 .thenReturn(existing);
 
         NotificationChannelGroup updated = new NotificationChannelGroup("id", "name");
@@ -2008,7 +2021,8 @@
         NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
         existing.setBlocked(true);
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
+        when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()),
+                eq(PKG), anyInt()))
                 .thenReturn(existing);
 
         mBinderService.updateNotificationChannelGroupForPackage(
@@ -2028,7 +2042,8 @@
     public void testUpdateGroupNoNotifyCreatorOtherChanges() throws Exception {
         NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
+        when(mPreferencesHelper.getNotificationChannelGroup(
+                eq(existing.getId()), eq(PKG), anyInt()))
                 .thenReturn(existing);
 
         mBinderService.updateNotificationChannelGroupForPackage(
@@ -2487,7 +2502,7 @@
     public void testSnoozeRunnable_snoozeGroupChild_onlyChildOfSummary() throws Exception {
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
-        assertTrue(parent.sbn.getNotification().isGroupSummary());
+        assertTrue(parent.getSbn().getNotification().isGroupSummary());
         final NotificationRecord child = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group", false);
         mService.addNotification(parent);
@@ -2523,7 +2538,8 @@
                 mTestNotificationChannel, 2, "group", false);
 
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostNonGroup_noUnsnoozing",
-                child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
+                child.getSbn().getId(), child.getSbn().getNotification(),
+                child.getSbn().getUserId());
         waitForIdle();
 
         verify(mSnoozeHelper, times(1)).repostGroupSummary(
@@ -2536,7 +2552,8 @@
                 mTestNotificationChannel, 2, null, false);
 
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostNonGroup_noUnsnoozing",
-                record.sbn.getId(), record.sbn.getNotification(), record.sbn.getUserId());
+                record.getSbn().getId(), record.getSbn().getNotification(),
+                record.getSbn().getUserId());
         waitForIdle();
 
         verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
@@ -2548,7 +2565,8 @@
                 mTestNotificationChannel, 2, "group", true);
 
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostGroupSummary_noUnsnoozing",
-                parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
+                parent.getSbn().getId(), parent.getSbn().getNotification(),
+                parent.getSbn().getUserId());
         waitForIdle();
 
         verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
@@ -2967,11 +2985,11 @@
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         NotificationRecord posted = mService.findNotificationLocked(
-                PKG, nr.sbn.getTag(), nr.sbn.getId(), nr.sbn.getUserId());
+                PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
 
         assertFalse(posted.getNotification().isColorized());
     }
@@ -2990,7 +3008,7 @@
             NotificationRecord r =
                     generateNotificationRecord(mTestNotificationChannel, i, null, false);
             mService.addNotification(r);
-            sampleTagToExclude = r.sbn.getTag();
+            sampleTagToExclude = r.getSbn().getTag();
             sampleIdToExclude = i;
         }
 
@@ -3226,7 +3244,8 @@
 
         StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9,
                 "testBumpFGImportance_noChannelChangePreOApp",
-                Binder.getCallingUid(), 0, nb.build(), new UserHandle(Binder.getCallingUid()), null, 0);
+                Binder.getCallingUid(), 0, nb.build(), new UserHandle(Binder.getCallingUid()), null,
+                0);
 
         mBinderService.enqueueNotificationWithTag(sbn.getPackageName(), sbn.getOpPkg(),
                 sbn.getTag(), sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -3264,7 +3283,7 @@
 
         mService.mNotificationDelegate.onNotificationDirectReplied(r.getKey());
         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasDirectReplied());
-        verify(mAssistants).notifyAssistantNotificationDirectReplyLocked(eq(r.sbn));
+        verify(mAssistants).notifyAssistantNotificationDirectReplyLocked(eq(r.getSbn()));
     }
 
     @Test
@@ -3274,12 +3293,14 @@
 
         mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, true,
                 NOTIFICATION_LOCATION_UNKNOWN);
-        verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.sbn), eq(true), eq((true)));
+        verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.getSbn()), eq(true),
+                eq((true)));
         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
 
         mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, false,
                 NOTIFICATION_LOCATION_UNKNOWN);
-        verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.sbn), eq(true), eq((false)));
+        verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.getSbn()), eq(true),
+                eq((false)));
         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
     }
 
@@ -3291,13 +3312,14 @@
         mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, true,
                 NOTIFICATION_LOCATION_UNKNOWN);
         assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
-        verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.sbn), eq(false), eq((true)));
+        verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.getSbn()), eq(false),
+                eq((true)));
 
         mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, false,
                 NOTIFICATION_LOCATION_UNKNOWN);
         assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
         verify(mAssistants).notifyAssistantExpansionChangedLocked(
-                eq(r.sbn), eq(false), eq((false)));
+                eq(r.getSbn()), eq(false), eq((false)));
     }
 
     @Test
@@ -3317,11 +3339,11 @@
         final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 1, 2, true);
         mService.mNotificationDelegate.onNotificationVisibilityChanged(
                 new NotificationVisibility[] {nv}, new NotificationVisibility[]{});
-        verify(mAssistants).notifyAssistantVisibilityChangedLocked(eq(r.sbn), eq(true));
+        verify(mAssistants).notifyAssistantVisibilityChangedLocked(eq(r.getSbn()), eq(true));
         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
         mService.mNotificationDelegate.onNotificationVisibilityChanged(
                 new NotificationVisibility[] {}, new NotificationVisibility[]{nv});
-        verify(mAssistants).notifyAssistantVisibilityChangedLocked(eq(r.sbn), eq(false));
+        verify(mAssistants).notifyAssistantVisibilityChangedLocked(eq(r.getSbn()), eq(false));
         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
     }
 
@@ -3331,8 +3353,8 @@
         mService.addNotification(r);
 
         final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
-        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
-                r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD,
+        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.getSbn().getTag(),
+                r.getSbn().getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD,
                 NotificationStats.DISMISS_SENTIMENT_POSITIVE, nv);
         waitForIdle();
 
@@ -3345,8 +3367,8 @@
         mService.addNotification(r);
 
         final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
-        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
-                r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD,
+        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.getSbn().getTag(),
+                r.getSbn().getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD,
                 NotificationStats.DISMISS_SENTIMENT_NEGATIVE, nv);
         waitForIdle();
 
@@ -3368,7 +3390,7 @@
         signals.putInt(Adjustment.KEY_USER_SENTIMENT,
                 USER_SENTIMENT_NEGATIVE);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyAdjustmentFromAssistant(null, adjustment);
 
         waitForIdle();
@@ -3387,7 +3409,7 @@
         Bundle signals = new Bundle();
         signals.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
         mBinderService.applyAdjustmentFromAssistant(null, adjustment);
 
@@ -3410,7 +3432,7 @@
         signals.putInt(Adjustment.KEY_USER_SENTIMENT,
                 USER_SENTIMENT_NEGATIVE);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         assertEquals(USER_SENTIMENT_NEGATIVE, r.getUserSentiment());
@@ -3428,7 +3450,7 @@
         Bundle signals = new Bundle();
         signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         assertEquals(IMPORTANCE_LOW, r.getImportance());
@@ -3447,7 +3469,7 @@
         signals.putInt(Adjustment.KEY_USER_SENTIMENT,
                 USER_SENTIMENT_NEGATIVE);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         assertEquals(USER_SENTIMENT_NEUTRAL, r.getUserSentiment());
@@ -3467,7 +3489,7 @@
         signals.putInt(Adjustment.KEY_USER_SENTIMENT,
                 USER_SENTIMENT_NEGATIVE);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyAdjustmentFromAssistant(null, adjustment);
 
         waitForIdle();
@@ -3485,7 +3507,7 @@
         signals.putInt(Adjustment.KEY_USER_SENTIMENT,
                 USER_SENTIMENT_NEGATIVE);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         waitForIdle();
@@ -3503,7 +3525,7 @@
         signals.putInt(Adjustment.KEY_USER_SENTIMENT,
                 USER_SENTIMENT_NEGATIVE);
         Adjustment adjustment = new Adjustment(
-                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         assertEquals(USER_SENTIMENT_NEGATIVE, r.getUserSentiment());
@@ -4073,7 +4095,7 @@
         ArgumentCaptor<List<NotificationRecord>> captorHide = ArgumentCaptor.forClass(List.class);
         verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
         assertEquals(1, captorHide.getValue().size());
-        assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName());
+        assertEquals("a", captorHide.getValue().get(0).getSbn().getPackageName());
 
         // on broadcast, unhide the package
         mService.simulatePackageDistractionBroadcast(
@@ -4081,7 +4103,7 @@
         ArgumentCaptor<List<NotificationRecord>> captorUnhide = ArgumentCaptor.forClass(List.class);
         verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
         assertEquals(1, captorUnhide.getValue().size());
-        assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName());
+        assertEquals("a", captorUnhide.getValue().get(0).getSbn().getPackageName());
     }
 
     @Test
@@ -4102,8 +4124,8 @@
         // should be called only once.
         verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
         assertEquals(2, captorHide.getValue().size());
-        assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName());
-        assertEquals("b", captorHide.getValue().get(1).sbn.getPackageName());
+        assertEquals("a", captorHide.getValue().get(0).getSbn().getPackageName());
+        assertEquals("b", captorHide.getValue().get(1).getSbn().getPackageName());
 
         // on broadcast, unhide the package
         mService.simulatePackageDistractionBroadcast(
@@ -4113,8 +4135,8 @@
         // should be called only once.
         verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
         assertEquals(2, captorUnhide.getValue().size());
-        assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName());
-        assertEquals("b", captorUnhide.getValue().get(1).sbn.getPackageName());
+        assertEquals("a", captorUnhide.getValue().get(0).getSbn().getPackageName());
+        assertEquals("b", captorUnhide.getValue().get(1).getSbn().getPackageName());
     }
 
     @Test
@@ -4400,7 +4422,7 @@
         ai.uid = -1;
         when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())).thenReturn(ai);
 
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         try {
             mInternalService.enqueueNotification(notReal, "android", 0, 0,
                     "testPostFromAndroidForNonExistentPackage",
@@ -4421,7 +4443,7 @@
         when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())).thenReturn(ai);
 
         // unlike the post case, ignore instead of throwing
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
 
         mInternalService.cancelNotification(notReal, "android", 0, 0, "tag",
                 sbn.getId(), sbn.getUserId());
@@ -4452,7 +4474,7 @@
         mService.addEnqueuedNotification(r);
 
         mInternalService.removeForegroundServiceFlagFromNotification(
-                PKG, r.sbn.getId(), r.sbn.getUserId());
+                PKG, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -4471,7 +4493,7 @@
         mService.addNotification(r);
 
         mInternalService.removeForegroundServiceFlagFromNotification(
-                PKG, r.sbn.getId(), r.sbn.getUserId());
+                PKG, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -4596,7 +4618,7 @@
                 r.getKey(), replyIndex, reply, NOTIFICATION_LOCATION_UNKNOWN,
                 modifiedBeforeSending);
         verify(mAssistants).notifyAssistantSuggestedReplySent(
-                eq(r.sbn), eq(reply), eq(generatedByAssistant));
+                eq(r.getSbn()), eq(reply), eq(generatedByAssistant));
     }
 
     @Test
@@ -4615,7 +4637,7 @@
                 10, 10, r.getKey(), actionIndex, action, notificationVisibility,
                 generatedByAssistant);
         verify(mAssistants).notifyAssistantActionClicked(
-                eq(r.sbn), eq(actionIndex), eq(action), eq(generatedByAssistant));
+                eq(r.getSbn()), eq(actionIndex), eq(action), eq(generatedByAssistant));
     }
 
     @Test
@@ -4688,13 +4710,13 @@
         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         mService.addNotification(r);
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, r.sbn.getId(),
-                r.sbn.getTag(), mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, r.getSbn().getId(),
+                r.getSbn().getTag(), mUid, 0,
                 new Notification.Builder(mContext, mTestNotificationChannel.getId()).build(),
                 new UserHandle(mUid), null, 0);
         NotificationRecord update = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
         mService.addEnqueuedNotification(update);
-        assertNull(update.sbn.getNotification().getSmallIcon());
+        assertNull(update.getSbn().getNotification().getSmallIcon());
 
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(update.getKey());
@@ -4866,15 +4888,15 @@
         NotificationRecord nr =
                 generateMessageBubbleNotifRecord(mTestNotificationChannel, "testFlagBubble");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
         assertEquals(1, notifs.length);
         assertTrue((notifs[0].getNotification().flags & FLAG_BUBBLE) != 0);
         assertTrue(mService.getNotificationRecord(
-                nr.sbn.getKey()).getNotification().isBubbleNotification());
+                nr.getSbn().getKey()).getNotification().isBubbleNotification());
     }
 
     @Test
@@ -4885,15 +4907,15 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                         "testFlagBubble_noFlag_appNotAllowed");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
         assertEquals(1, notifs.length);
         assertEquals((notifs[0].getNotification().flags & FLAG_BUBBLE), 0);
         assertFalse(mService.getNotificationRecord(
-                nr.sbn.getKey()).getNotification().isBubbleNotification());
+                nr.getSbn().getKey()).getNotification().isBubbleNotification());
     }
 
     @Test
@@ -4912,16 +4934,16 @@
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         // Say we're foreground
-        when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
+        when(mActivityManager.getPackageImportance(nr.getSbn().getPackageName())).thenReturn(
                 IMPORTANCE_FOREGROUND);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // if notif isn't configured properly it doesn't get to bubble just because app is
         // foreground.
         assertFalse(mService.getNotificationRecord(
-                nr.sbn.getKey()).getNotification().isBubbleNotification());
+                nr.getSbn().getKey()).getNotification().isBubbleNotification());
     }
 
     @Test
@@ -4932,13 +4954,13 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testFlagBubbleNotifs_flag_messaging");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // yes allowed, yes messaging, yes bubble
         assertTrue(mService.getNotificationRecord(
-                nr.sbn.getKey()).getNotification().isBubbleNotification());
+                nr.getSbn().getKey()).getNotification().isBubbleNotification());
     }
 
     @Test
@@ -4968,8 +4990,8 @@
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // yes phone call, yes person, yes foreground service, yes bubble
@@ -5001,8 +5023,8 @@
                 nb.build(), new UserHandle(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // yes phone call, yes person, NO foreground service, no bubble
@@ -5032,8 +5054,8 @@
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // yes phone call, yes foreground service, BUT NO person, no bubble
@@ -5067,8 +5089,8 @@
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // yes person, yes foreground service, BUT NO call, no bubble
@@ -5085,13 +5107,13 @@
                 "testFlagBubbleNotifs_noFlag_messaging_appNotAllowed");
 
         // Post the notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // not allowed, no bubble
         assertFalse(mService.getNotificationRecord(
-                nr.sbn.getKey()).getNotification().isBubbleNotification());
+                nr.getSbn().getKey()).getNotification().isBubbleNotification());
     }
 
     @Test
@@ -5109,13 +5131,13 @@
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         // Post the notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // no bubble metadata, no bubble
         assertFalse(mService.getNotificationRecord(
-                nr.sbn.getKey()).getNotification().isBubbleNotification());
+                nr.getSbn().getKey()).getNotification().isBubbleNotification());
     }
 
     @Test
@@ -5127,13 +5149,13 @@
                 "testFlagBubbleNotifs_noFlag_messaging_channelNotAllowed");
 
         // Post the notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // channel not allowed, no bubble
         assertFalse(mService.getNotificationRecord(
-                nr.sbn.getKey()).getNotification().isBubbleNotification());
+                nr.getSbn().getKey()).getNotification().isBubbleNotification());
     }
 
     @Test
@@ -5199,7 +5221,7 @@
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // yes phone call, yes person, yes foreground service, but channel not allowed, no bubble
@@ -5210,10 +5232,10 @@
     @Test
     public void testCancelAllNotifications_cancelsBubble() throws Exception {
         final NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel);
-        nr.sbn.getNotification().flags |= FLAG_BUBBLE;
+        nr.getSbn().getNotification().flags |= FLAG_BUBBLE;
         mService.addNotification(nr);
 
-        mBinderService.cancelAllNotifications(PKG, nr.sbn.getUserId());
+        mBinderService.cancelAllNotifications(PKG, nr.getSbn().getUserId());
         waitForIdle();
 
         StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
@@ -5224,12 +5246,13 @@
     @Test
     public void testAppCancelNotifications_cancelsBubbles() throws Exception {
         final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel);
-        nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE;
+        nrBubble.getSbn().getNotification().flags |= FLAG_BUBBLE;
 
         // Post the notification
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testAppCancelNotifications_cancelsBubbles",
-                nrBubble.sbn.getId(), nrBubble.sbn.getNotification(), nrBubble.sbn.getUserId());
+                nrBubble.getSbn().getId(), nrBubble.getSbn().getNotification(),
+                nrBubble.getSbn().getUserId());
         waitForIdle();
 
         StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
@@ -5237,8 +5260,8 @@
         assertEquals(1, mService.getNotificationRecordCount());
 
         mBinderService.cancelNotificationWithTag(PKG, PKG,
-                "testAppCancelNotifications_cancelsBubbles", nrBubble.sbn.getId(),
-                nrBubble.sbn.getUserId());
+                "testAppCancelNotifications_cancelsBubbles", nrBubble.getSbn().getId(),
+                nrBubble.getSbn().getUserId());
         waitForIdle();
 
         StatusBarNotification[] notifs2 = mBinderService.getActiveNotifications(PKG);
@@ -5250,7 +5273,7 @@
     public void testCancelAllNotificationsFromListener_ignoresBubbles() throws Exception {
         final NotificationRecord nrNormal = generateNotificationRecord(mTestNotificationChannel);
         final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel);
-        nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE;
+        nrBubble.getSbn().getNotification().flags |= FLAG_BUBBLE;
 
         mService.addNotification(nrNormal);
         mService.addNotification(nrBubble);
@@ -5267,12 +5290,12 @@
     public void testCancelNotificationsFromListener_ignoresBubbles() throws Exception {
         final NotificationRecord nrNormal = generateNotificationRecord(mTestNotificationChannel);
         final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel);
-        nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE;
+        nrBubble.getSbn().getNotification().flags |= FLAG_BUBBLE;
 
         mService.addNotification(nrNormal);
         mService.addNotification(nrBubble);
 
-        String[] keys = {nrNormal.sbn.getKey(), nrBubble.sbn.getKey()};
+        String[] keys = {nrNormal.getSbn().getKey(), nrBubble.getSbn().getKey()};
         mService.getBinderService().cancelNotificationsFromListener(null, keys);
         waitForIdle();
 
@@ -5308,7 +5331,7 @@
         Bundle signals = new Bundle();
         signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         signals.putInt(KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
-        Adjustment adjustment = new Adjustment(r.sbn.getPackageName(), r.getKey(), signals,
+        Adjustment adjustment = new Adjustment(r.getSbn().getPackageName(), r.getKey(), signals,
                "", r.getUser().getIdentifier());
 
         mBinderService.applyAdjustmentFromAssistant(null, adjustment);
@@ -5391,8 +5414,8 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testNotificationBubbleChanged_false");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // Reset as this is called when the notif is first sent
@@ -5421,8 +5444,8 @@
         // Notif that is not a bubble
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
                 1, null, false);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // Would be a normal notification because wouldn't have met requirements to bubble
@@ -5432,9 +5455,9 @@
 
         // Update the notification to be message style / meet bubble requirements
         NotificationRecord nr2 = generateMessageBubbleNotifRecord(mTestNotificationChannel,
-                nr.sbn.getTag());
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr2.sbn.getTag(),
-                nr2.sbn.getId(), nr2.sbn.getNotification(), nr2.sbn.getUserId());
+                nr.getSbn().getTag());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr2.getSbn().getTag(),
+                nr2.getSbn().getId(), nr2.getSbn().getNotification(), nr2.getSbn().getUserId());
         waitForIdle();
 
         // Reset as this is called when the notif is first sent
@@ -5457,8 +5480,8 @@
 
         // Notif that is not a bubble
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // Reset as this is called when the notif is first sent
@@ -5485,11 +5508,11 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "tag");
 
         // Bubbles are allowed!
-        setUpPrefsForBubbles(PKG, nr.sbn.getUserId(), true /* global */,
+        setUpPrefsForBubbles(PKG, nr.getSbn().getUserId(), true /* global */,
                 true /* app */, true /* channel */);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // NOT suppressed
@@ -5523,7 +5546,7 @@
     public void testGrantInlineReplyUriPermission_recordExists() throws Exception {
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, 0);
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // A notification exists for the given record
@@ -5535,12 +5558,13 @@
         Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1);
 
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
-                nr.getKey(), uri, nr.sbn.getUser(), nr.sbn.getPackageName(), nr.sbn.getUid());
+                nr.getKey(), uri, nr.getSbn().getUser(), nr.getSbn().getPackageName(),
+                nr.getSbn().getUid());
 
         // Grant permission called for the UID of SystemUI under the target user ID
         verify(mUgm, times(1)).grantUriPermissionFromOwner(any(),
-                eq(nr.sbn.getUid()), eq(nr.sbn.getPackageName()), eq(uri), anyInt(), anyInt(),
-                eq(nr.sbn.getUserId()));
+                eq(nr.getSbn().getUid()), eq(nr.getSbn().getPackageName()), eq(uri), anyInt(),
+                anyInt(), eq(nr.getSbn().getUserId()));
     }
 
     @Test
@@ -5556,12 +5580,13 @@
         int uid = 0; // sysui on primary user
 
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
-                nr.getKey(), uri, nr.sbn.getUser(), nr.sbn.getPackageName(), nr.sbn.getUid());
+                nr.getKey(), uri, nr.getSbn().getUser(), nr.getSbn().getPackageName(),
+                nr.getSbn().getUid());
 
         // Grant permission still called if no NotificationRecord exists for the given key
         verify(mUgm, times(1)).grantUriPermissionFromOwner(any(),
-                eq(nr.sbn.getUid()), eq(nr.sbn.getPackageName()), eq(uri), anyInt(), anyInt(),
-                eq(nr.sbn.getUserId()));
+                eq(nr.getSbn().getUid()), eq(nr.getSbn().getPackageName()), eq(uri), anyInt(),
+                anyInt(), eq(nr.getSbn().getUserId()));
     }
 
     @Test
@@ -5570,7 +5595,7 @@
         NotificationRecord nr =
                 generateNotificationRecord(mTestNotificationChannel, UserHandle.USER_ALL);
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // A notification exists for the given record
@@ -5582,12 +5607,13 @@
         Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1);
 
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
-                nr.getKey(), uri, nr.sbn.getUser(), nr.sbn.getPackageName(), nr.sbn.getUid());
+                nr.getKey(), uri, nr.getSbn().getUser(), nr.getSbn().getPackageName(),
+                nr.getSbn().getUid());
 
         // Target user for the grant is USER_ALL instead of USER_SYSTEM
         verify(mUgm, times(1)).grantUriPermissionFromOwner(any(),
-                eq(nr.sbn.getUid()), eq(nr.sbn.getPackageName()), eq(uri), anyInt(), anyInt(),
-                eq(UserHandle.USER_SYSTEM));
+                eq(nr.getSbn().getUid()), eq(nr.getSbn().getPackageName()), eq(uri), anyInt(),
+                anyInt(), eq(UserHandle.USER_SYSTEM));
     }
 
     @Test
@@ -5597,7 +5623,7 @@
         NotificationRecord nr =
                 generateNotificationRecord(mTestNotificationChannel, otherUserId);
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // A notification exists for the given record
@@ -5620,11 +5646,11 @@
                 .thenReturn(otherUserUid);
 
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
-                nr.getKey(), uri, nr.sbn.getUser(), nr.sbn.getPackageName(), uid);
+                nr.getKey(), uri, nr.getSbn().getUser(), nr.getSbn().getPackageName(), uid);
 
         // Target user for the grant is USER_ALL instead of USER_SYSTEM
         verify(mUgm, times(1)).grantUriPermissionFromOwner(any(),
-                eq(otherUserUid), eq(nr.sbn.getPackageName()), eq(uri), anyInt(), anyInt(),
+                eq(otherUserUid), eq(nr.getSbn().getPackageName()), eq(uri), anyInt(), anyInt(),
                 eq(otherUserId));
     }
 
@@ -5638,15 +5664,18 @@
 
         // create an inline record with two uris in it
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
-                nr.getKey(), uri1, nr.sbn.getUser(), nr.sbn.getPackageName(), nr.sbn.getUid());
+                nr.getKey(), uri1, nr.getSbn().getUser(), nr.getSbn().getPackageName(),
+                nr.getSbn().getUid());
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
-                nr.getKey(), uri2, nr.sbn.getUser(), nr.sbn.getPackageName(), nr.sbn.getUid());
+                nr.getKey(), uri2, nr.getSbn().getUser(), nr.getSbn().getPackageName(),
+                nr.getSbn().getUid());
 
         InlineReplyUriRecord record = mService.mInlineReplyRecordsByKey.get(nr.getKey());
         assertNotNull(record); // record exists
         assertEquals(record.getUris().size(), 2); // record has two uris in it
 
-        mService.mNotificationDelegate.clearInlineReplyUriPermissions(nr.getKey(), nr.sbn.getUid());
+        mService.mNotificationDelegate.clearInlineReplyUriPermissions(nr.getKey(),
+                nr.getSbn().getUid());
 
         // permissionOwner destroyed
         verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(
@@ -5659,7 +5688,8 @@
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, 0);
         reset(mPackageManager);
 
-        mService.mNotificationDelegate.clearInlineReplyUriPermissions(nr.getKey(), nr.sbn.getUid());
+        mService.mNotificationDelegate.clearInlineReplyUriPermissions(nr.getKey(),
+                nr.getSbn().getUid());
 
         // no permissionOwner destroyed
         verify(mUgmInternal, times(0)).revokeUriPermissionFromOwner(
@@ -5677,12 +5707,14 @@
 
         // create an inline record a uri in it
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
-                nr.getKey(), uri1, nr.sbn.getUser(), nr.sbn.getPackageName(), nr.sbn.getUid());
+                nr.getKey(), uri1, nr.getSbn().getUser(), nr.getSbn().getPackageName(),
+                nr.getSbn().getUid());
 
         InlineReplyUriRecord record = mService.mInlineReplyRecordsByKey.get(nr.getKey());
         assertNotNull(record); // record exists
 
-        mService.mNotificationDelegate.clearInlineReplyUriPermissions(nr.getKey(), nr.sbn.getUid());
+        mService.mNotificationDelegate.clearInlineReplyUriPermissions(
+                nr.getKey(), nr.getSbn().getUid());
 
         // permissionOwner destroyed for USER_SYSTEM, not USER_ALL
         verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(
@@ -5700,8 +5732,8 @@
         // Notification that would typically bubble
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testNotificationBubbles_disabled_lowRamDevice");
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // But we wouldn't be a bubble because the device is low ram & all bubbles are disabled.
@@ -5781,20 +5813,20 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testNotificationBubbles_flagAutoExpandForeground_fails_notForeground");
         // Modify metadata flags
-        nr.sbn.getNotification().getBubbleMetadata().setFlags(
+        nr.getSbn().getNotification().getBubbleMetadata().setFlags(
                 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE
                         | Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION);
 
         // Ensure we're not foreground
-        when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
+        when(mActivityManager.getPackageImportance(nr.getSbn().getPackageName())).thenReturn(
                 IMPORTANCE_VISIBLE);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // yes allowed, yes messaging, yes bubble
-        Notification notif = mService.getNotificationRecord(nr.sbn.getKey()).getNotification();
+        Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification();
         assertTrue(notif.isBubbleNotification());
 
         // Our flags should have failed since we're not foreground
@@ -5811,20 +5843,20 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testNotificationBubbles_flagAutoExpandForeground_succeeds_foreground");
         // Modify metadata flags
-        nr.sbn.getNotification().getBubbleMetadata().setFlags(
+        nr.getSbn().getNotification().getBubbleMetadata().setFlags(
                 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE
                         | Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION);
 
         // Ensure we are in the foreground
-        when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
+        when(mActivityManager.getPackageImportance(nr.getSbn().getPackageName())).thenReturn(
                 IMPORTANCE_FOREGROUND);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // yes allowed, yes messaging, yes bubble
-        Notification notif = mService.getNotificationRecord(nr.sbn.getKey()).getNotification();
+        Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification();
         assertTrue(notif.isBubbleNotification());
 
         // Our flags should have passed since we are foreground
@@ -5857,8 +5889,8 @@
         when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
 
         // Test: Send the bubble notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // Verify:
@@ -5867,7 +5899,7 @@
         verify(mLauncherApps, times(1)).registerCallback(launcherAppsCallback.capture(), any());
 
         // yes allowed, yes messaging w/shortcut, yes bubble
-        Notification notif = mService.getNotificationRecord(nr.sbn.getKey()).getNotification();
+        Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification();
         assertTrue(notif.isBubbleNotification());
 
         // Test: Remove the shortcut
@@ -5880,7 +5912,7 @@
         verify(mLauncherApps, times(1)).unregisterCallback(launcherAppsCallback.getValue());
 
         // We're no longer a bubble
-        Notification notif2 = mService.getNotificationRecord(nr.sbn.getKey()).getNotification();
+        Notification notif2 = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification();
         assertFalse(notif2.isBubbleNotification());
     }
 
@@ -5896,8 +5928,9 @@
         // Dismiss summary
         final NotificationVisibility nv = NotificationVisibility.obtain(nrSummary.getKey(), 1, 2,
                 true);
-        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, nrSummary.sbn.getTag(),
-                nrSummary.sbn.getId(), nrSummary.getUserId(), nrSummary.getKey(),
+        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG,
+                nrSummary.getSbn().getTag(),
+                nrSummary.getSbn().getId(), nrSummary.getUserId(), nrSummary.getKey(),
                 NotificationStats.DISMISSAL_SHADE,
                 NotificationStats.DISMISS_SENTIMENT_NEUTRAL, nv);
         waitForIdle();
@@ -6007,8 +6040,8 @@
     public void testNotificationHistory_addNoisyNotification() throws Exception {
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
                 null /* tvExtender */);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
-                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         verify(mHistoryManager, times(1)).addNotification(any());
@@ -6090,4 +6123,48 @@
         assertNull(mBinderService.getConversationNotificationChannel(
                 PKG, 0, PKG, callsParent.getId(), false, conversationId));
     }
+
+    @Test
+    public void testCorrectCategory_systemOn_appCannotTurnOff() {
+        int requested = 0;
+        int system = PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS;
+
+        int actual = mService.correctCategory(requested, PRIORITY_CATEGORY_CONVERSATIONS,
+                system);
+
+        assertEquals(PRIORITY_CATEGORY_CONVERSATIONS, actual);
+    }
+
+    @Test
+    public void testCorrectCategory_systemOff_appTurnOff_noChanges() {
+        int requested = PRIORITY_CATEGORY_CALLS;
+        int system = PRIORITY_CATEGORY_CALLS;
+
+        int actual = mService.correctCategory(requested, PRIORITY_CATEGORY_CONVERSATIONS,
+                system);
+
+        assertEquals(PRIORITY_CATEGORY_CALLS, actual);
+    }
+
+    @Test
+    public void testCorrectCategory_systemOn_appTurnOn_noChanges() {
+        int requested = PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS;
+        int system = PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS;
+
+        int actual = mService.correctCategory(requested, PRIORITY_CATEGORY_CONVERSATIONS,
+                system);
+
+        assertEquals(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS, actual);
+    }
+
+    @Test
+    public void testCorrectCategory_systemOff_appCannotTurnOn() {
+        int requested = PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS;
+        int system = PRIORITY_CATEGORY_CALLS;
+
+        int actual = mService.correctCategory(requested, PRIORITY_CATEGORY_CONVERSATIONS,
+                system);
+
+        assertEquals(PRIORITY_CATEGORY_CALLS, actual);
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index c1c74da..bb84b04 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -171,7 +171,7 @@
                 .thenReturn(SOUND_URI);
 
         mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
-                NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
+                NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
         resetZenModeHelper();
@@ -1430,7 +1430,7 @@
         // start notification policy off with mAreChannelsBypassingDnd = true, but
         // RankingHelper should change to false
         mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
-                NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
+                NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
         assertFalse(mHelper.areChannelsBypassingDnd());
@@ -1441,7 +1441,7 @@
     @Test
     public void testSetupNewZenModeHelper_cannotBypass() {
         // start notification policy off with mAreChannelsBypassingDnd = false
-        mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0);
+        mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
         assertFalse(mHelper.areChannelsBypassingDnd());
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 8774b63..5018166 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -140,7 +140,7 @@
                 .thenReturn(SOUND_URI);
 
         mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
-                NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
+                NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         mHelper = new RankingHelper(getContext(), mHandler, mConfig, mMockZenModeHelper,
                 mUsageStats, new String[] {ImportanceExtractor.class.getName()});
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 5841e59..3186d53 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -169,11 +169,11 @@
     public void testCleanupContextShouldRemovePersistedRecord() {
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
         mSnoozeHelper.snooze(r, "context");
-        mSnoozeHelper.cleanupPersistedContext(r.sbn.getKey());
+        mSnoozeHelper.cleanupPersistedContext(r.getSbn().getKey());
         assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
                 r.getUser().getIdentifier(),
-                r.sbn.getPackageName(),
-                r.sbn.getKey()
+                r.getSbn().getPackageName(),
+                r.getSbn().getKey()
         ));
     }
 
@@ -201,7 +201,7 @@
         long actualSnoozedUntilDuration = captor.getValue() - SystemClock.elapsedRealtime();
         assertTrue(Math.abs(actualSnoozedUntilDuration - 1000) < 250);
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
     }
 
     @Test
@@ -211,7 +211,7 @@
         verify(mAm, never()).setExactAndAllowWhileIdle(
                 anyInt(), anyLong(), any(PendingIntent.class));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
     }
 
     @Test
@@ -221,17 +221,17 @@
         mSnoozeHelper.snooze(r, 1000);
         mSnoozeHelper.snooze(r2 , 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
 
-        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.sbn.getPackageName(), "one", 1);
+        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), "one", 1);
         // 2 = one for each snooze, above, zero for the cancel.
         verify(mAm, times(2)).cancel(any(PendingIntent.class));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
     }
 
     @Test
@@ -243,21 +243,21 @@
         mSnoozeHelper.snooze(r2, 1000);
         mSnoozeHelper.snooze(r3, 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_ALL, r3.sbn.getPackageName(), r3.getKey()));
+                UserHandle.USER_ALL, r3.getSbn().getPackageName(), r3.getKey()));
 
         mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, false);
         // 3 = once for each snooze above (3), only.
         verify(mAm, times(3)).cancel(any(PendingIntent.class));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_ALL, r3.sbn.getPackageName(), r3.getKey()));
+                UserHandle.USER_ALL, r3.getSbn().getPackageName(), r3.getKey()));
     }
 
     @Test
@@ -269,21 +269,21 @@
         mSnoozeHelper.snooze(r2, 1000);
         mSnoozeHelper.snooze(r3, 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey()));
+                UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
 
         mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, "pkg2");
         // 3 = once for each snooze above (3), only.
         verify(mAm, times(3)).cancel(any(PendingIntent.class));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey()));
+                UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
     }
 
     @Test
@@ -291,12 +291,12 @@
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
         mSnoozeHelper.snooze(r, 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
 
-        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.sbn.getPackageName(), "one", 1);
+        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), "one", 1);
 
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
     }
 
     @Test
@@ -306,11 +306,11 @@
         mSnoozeHelper.snooze(r, 1000);
         mSnoozeHelper.snooze(r2 , 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
 
-        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.sbn.getPackageName(), "one", 1);
+        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), "one", 1);
 
         mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
         verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r);
@@ -507,18 +507,18 @@
         mSnoozeHelper.snooze(r, 1000);
         mSnoozeHelper.snooze(r2, 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
 
         // clear data
         mSnoozeHelper.clearData(UserHandle.USER_SYSTEM, "pkg");
 
         // nothing snoozed; alarms canceled
         assertFalse(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertFalse(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
         // twice for initial snooze, twice for canceling the snooze
         verify(mAm, times(4)).cancel(any(PendingIntent.class));
     }
@@ -533,21 +533,21 @@
         mSnoozeHelper.snooze(r2, 1000);
         mSnoozeHelper.snooze(r3, 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_ALL, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey()));
+                UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
 
         // clear data
         mSnoozeHelper.clearData(UserHandle.USER_SYSTEM, "pkg");
 
         assertFalse(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_ALL, r2.sbn.getPackageName(), r2.getKey()));
+                UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
-                UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey()));
+                UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
         // once for each initial snooze, once for canceling one snooze
         verify(mAm, times(4)).cancel(any(PendingIntent.class));
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index b654764..f7b435e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -91,6 +91,7 @@
         int priorityCategories = originalPolicy.priorityCategories;
         int priorityCallSenders = originalPolicy.priorityCallSenders;
         int priorityMessageSenders = originalPolicy.priorityMessageSenders;
+        int priorityConversationsSenders = originalPolicy.priorityConversationSenders;
         int suppressedVisualEffects = originalPolicy.suppressedVisualEffects;
         priorityCategories |= Policy.PRIORITY_CATEGORY_ALARMS;
         priorityCategories |= Policy.PRIORITY_CATEGORY_REMINDERS;
@@ -99,7 +100,7 @@
         suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT;
 
         Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders,
-                priorityMessageSenders, suppressedVisualEffects, 0);
+                priorityMessageSenders, suppressedVisualEffects, 0, priorityConversationsSenders);
 
         assertEquals(expectedPolicy, config.toNotificationPolicy(zenPolicy));
     }
@@ -235,6 +236,8 @@
         config.areChannelsBypassingDnd = false;
         config.allowCallsFrom = ZenModeConfig.SOURCE_ANYONE;
         config.allowMessagesFrom = ZenModeConfig.SOURCE_ANYONE;
+        config.allowConversations = true;
+        config.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
 
         config.suppressedVisualEffects = 0;
         return config;
@@ -252,6 +255,8 @@
         config.allowReminders = false;
         config.allowEvents = false;
         config.areChannelsBypassingDnd = false;
+        config.allowConversations = false;
+        config.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_NONE;
 
         config.suppressedVisualEffects = 0;
         return config;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
index 32f389a..fb15088 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
@@ -16,6 +16,16 @@
 
 package com.android.server.notification;
 
+import static android.app.Notification.CATEGORY_CALL;
+import static android.app.Notification.CATEGORY_MESSAGE;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
 import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
 import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
@@ -31,11 +41,10 @@
 
 import android.app.Notification;
 import android.app.NotificationChannel;
-import android.app.NotificationManager;
 import android.app.NotificationManager.Policy;
 import android.media.AudioAttributes;
+import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
-import android.service.notification.ZenModeConfig;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -76,6 +85,16 @@
         return new NotificationRecord(mContext, sbn, c);
     }
 
+    private NotificationRecord getConversationRecord(NotificationChannel c,
+            StatusBarNotification sbn) {
+        NotificationRecord r = mock(NotificationRecord.class);
+        when(r.getCriticality()).thenReturn(CriticalNotificationExtractor.NORMAL);
+        when(r.getSbn()).thenReturn(sbn);
+        when(r.getChannel()).thenReturn(c);
+        when(r.isConversation()).thenReturn(true);
+        return r;
+    }
+
     @Test
     public void testIsMessage() {
         NotificationRecord r = getNotificationRecord();
@@ -97,14 +116,14 @@
         assertTrue(mZenModeFiltering.isAlarm(r));
 
         r = getNotificationRecord();
-        r.sbn.getNotification().category = Notification.CATEGORY_ALARM;
+        r.getSbn().getNotification().category = Notification.CATEGORY_ALARM;
         assertTrue(mZenModeFiltering.isAlarm(r));
     }
 
     @Test
     public void testIsAlarm_wrongCategory() {
         NotificationRecord r = getNotificationRecord();
-        r.sbn.getNotification().category = Notification.CATEGORY_CALL;
+        r.getSbn().getNotification().category = CATEGORY_CALL;
         assertFalse(mZenModeFiltering.isAlarm(r));
     }
 
@@ -121,10 +140,10 @@
     @Test
     public void testSuppressDNDInfo_yes_VisEffectsAllowed() {
         NotificationRecord r = getNotificationRecord();
-        when(r.sbn.getPackageName()).thenReturn("android");
-        when(r.sbn.getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE);
+        when(r.getSbn().getPackageName()).thenReturn("android");
+        when(r.getSbn().getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE);
         Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects()
-                - SUPPRESSED_EFFECT_STATUS_BAR);
+                - SUPPRESSED_EFFECT_STATUS_BAR, 0);
 
         assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
     }
@@ -132,9 +151,9 @@
     @Test
     public void testSuppressDNDInfo_yes_WrongId() {
         NotificationRecord r = getNotificationRecord();
-        when(r.sbn.getPackageName()).thenReturn("android");
-        when(r.sbn.getId()).thenReturn(SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION);
-        Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects());
+        when(r.getSbn().getPackageName()).thenReturn("android");
+        when(r.getSbn().getId()).thenReturn(SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION);
+        Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects(), 0);
 
         assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
     }
@@ -142,9 +161,9 @@
     @Test
     public void testSuppressDNDInfo_yes_WrongPackage() {
         NotificationRecord r = getNotificationRecord();
-        when(r.sbn.getPackageName()).thenReturn("android2");
-        when(r.sbn.getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE);
-        Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects());
+        when(r.getSbn().getPackageName()).thenReturn("android2");
+        when(r.getSbn().getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE);
+        Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects(), 0);
 
         assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
     }
@@ -152,9 +171,9 @@
     @Test
     public void testSuppressDNDInfo_no() {
         NotificationRecord r = getNotificationRecord();
-        when(r.sbn.getPackageName()).thenReturn("android");
-        when(r.sbn.getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE);
-        Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects());
+        when(r.getSbn().getPackageName()).thenReturn("android");
+        when(r.getSbn().getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE);
+        Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects(), 0);
 
         assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
         assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_ALARMS, policy, r));
@@ -164,7 +183,7 @@
     @Test
     public void testSuppressAnything_yes_ZenModeOff() {
         NotificationRecord r = getNotificationRecord();
-        when(r.sbn.getPackageName()).thenReturn("bananas");
+        when(r.getSbn().getPackageName()).thenReturn("bananas");
         Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects());
 
         assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_OFF, policy, r));
@@ -174,12 +193,120 @@
     public void testSuppressAnything_bypass_ZenModeOn() {
         NotificationRecord r = getNotificationRecord();
         r.setCriticality(CriticalNotificationExtractor.CRITICAL);
-        when(r.sbn.getPackageName()).thenReturn("bananas");
-        Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects());
+        when(r.getSbn().getPackageName()).thenReturn("bananas");
+        Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects(), 0);
 
         assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_NO_INTERRUPTIONS, policy, r));
 
         r.setCriticality(CriticalNotificationExtractor.CRITICAL_LOW);
         assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_NO_INTERRUPTIONS, policy, r));
     }
+
+    @Test
+    public void testConversation_allAllowed() {
+        Notification n = new Notification.Builder(mContext, "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n,
+                UserHandle.SYSTEM, null, 0);
+
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.setConversationId("parent", "me, work");
+
+        NotificationRecord r = getConversationRecord(channel, sbn);
+        when(r.isConversation()).thenReturn(true);
+
+        Policy policy = new Policy(
+                PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_ANYONE);
+
+        assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
+    }
+
+    @Test
+    public void testConversation_importantAllowed_isImportant() {
+        Notification n = new Notification.Builder(mContext, "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n,
+                UserHandle.SYSTEM, null, 0);
+
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.setConversationId("parent", "me, work");
+        channel.setImportantConversation(true);
+
+        NotificationRecord r = getConversationRecord(channel, sbn);
+
+        Policy policy = new Policy(
+                PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_IMPORTANT);
+
+        assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
+    }
+
+    @Test
+    public void testConversation_importantAllowed_isNotImportant() {
+        Notification n = new Notification.Builder(mContext, "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n,
+                UserHandle.SYSTEM, null, 0);
+
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.setConversationId("parent", "me, work");
+
+        NotificationRecord r = getConversationRecord(channel, sbn);
+
+        Policy policy = new Policy(
+                PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_IMPORTANT);
+
+        assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
+    }
+
+    @Test
+    public void testConversation_noneAllowed_notCallOrMsg() {
+        Notification n = new Notification.Builder(mContext, "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n,
+                UserHandle.SYSTEM, null, 0);
+
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.setConversationId("parent", "me, work");
+
+        NotificationRecord r = getConversationRecord(channel, sbn);
+
+        Policy policy =
+                new Policy(PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+        assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
+    }
+
+    @Test
+    public void testConversation_noneAllowed_callAllowed() {
+        Notification n = new Notification.Builder(mContext, "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n,
+                UserHandle.SYSTEM, null, 0);
+
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.setConversationId("parent", "me, work");
+
+        NotificationRecord r = getConversationRecord(channel, sbn);
+        when(r.isCategory(CATEGORY_CALL)).thenReturn(true);
+
+        Policy policy =
+                new Policy(PRIORITY_CATEGORY_CALLS,
+                        PRIORITY_SENDERS_ANY, 0, 0, CONVERSATION_SENDERS_NONE);
+
+        assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
+    }
+
+    @Test
+    public void testConversation_noneAllowed_msgAllowed() {
+        when(mMessagingUtil.isMessaging(any())).thenReturn(true);
+        Notification n = new Notification.Builder(mContext, "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n,
+                UserHandle.SYSTEM, null, 0);
+
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.setConversationId("parent", "me, work");
+
+        NotificationRecord r = getConversationRecord(channel, sbn);
+
+        Policy policy =
+                new Policy(PRIORITY_CATEGORY_MESSAGES,
+                        0, PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_NONE);
+
+        assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 99771b9..bc2766c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -142,7 +142,8 @@
                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
                 + "visualScreenOff=\"true\" alarms=\"true\" "
-                + "media=\"true\" system=\"false\" />\n"
+                + "media=\"true\" system=\"false\" conversations=\"true\""
+                + " conversationsFrom=\"2\"/>\n"
                 + "<automatic ruleId=\"" + EVENTS_DEFAULT_RULE_ID
                 + "\" enabled=\"false\" snoozing=\"false\""
                 + " name=\"Event\" zen=\"1\""
@@ -218,7 +219,7 @@
     public void testZenOff_NoMuteApplied() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_OFF;
         mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0);
+                Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         doNothing().when(mZenModeHelperSpy).applyRestrictions(eq(false), anyBoolean(), anyInt());
@@ -232,7 +233,7 @@
     public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0);
+                Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
 
         mZenModeHelperSpy.applyRestrictions();
         verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false,
@@ -244,7 +245,7 @@
     @Test
     public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
         verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
                 AudioAttributes.USAGE_ALARM);
@@ -260,7 +261,7 @@
     public void testTotalSilence() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
         mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0);
+                Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         // Total silence will silence alarms, media and system noises (but not vibrations)
@@ -281,7 +282,7 @@
     @Test
     public void testAlarmsOnly_alarmMediaMuteNotApplied() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         // Alarms only mode will not silence alarms
@@ -304,7 +305,7 @@
     @Test
     public void testAlarmsOnly_callsMuteApplied() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         // Alarms only mode will silence calls despite priority-mode config
@@ -318,7 +319,7 @@
     public void testAlarmsOnly_allZenConfigToggledCannotBypass_alarmMuteNotApplied() {
         // Only audio attributes with SUPPRESIBLE_NEVER can bypass
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
@@ -330,7 +331,7 @@
         // Only audio attributes with SUPPRESIBLE_NEVER can bypass
         // with special case USAGE_ASSISTANCE_SONIFICATION
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         for (int usage : AudioAttributes.SDK_USAGES) {
@@ -352,7 +353,7 @@
     public void testApplyRestrictions_whitelist_priorityOnlyMode() {
         mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
         mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         for (int usage : AudioAttributes.SDK_USAGES) {
@@ -367,7 +368,7 @@
     public void testApplyRestrictions_whitelist_alarmsOnlyMode() {
         mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
         mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_ALARMS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         for (int usage : AudioAttributes.SDK_USAGES) {
@@ -382,7 +383,7 @@
     public void testApplyRestrictions_whitelist_totalSilenceMode() {
         mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
         mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_NO_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.applyRestrictions();
 
         for (int usage : AudioAttributes.SDK_USAGES) {
@@ -401,7 +402,7 @@
         Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
         Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0);
         mZenModeHelperSpy.mIsBootComplete = true;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
+        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
         mZenModeHelperSpy.setZenModeSetting(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
 
         verify(mZenModeHelperSpy, times(1)).createZenUpgradeNotification();
@@ -452,7 +453,8 @@
         mZenModeHelperSpy.mConfig.allowCalls = false;
         mZenModeHelperSpy.mConfig.allowMessages = false;
         mZenModeHelperSpy.mConfig.allowEvents = false;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
+        mZenModeHelperSpy.mConfig.allowRepeatCallers = false;
+        mZenModeHelperSpy.mConfig.allowConversations = false;
 
         // 2. apply priority only zen - verify ringer is unchanged
         mZenModeHelperSpy.applyZenToRingerMode();
@@ -509,7 +511,8 @@
         mZenModeHelperSpy.mConfig.allowCalls = false;
         mZenModeHelperSpy.mConfig.allowMessages = false;
         mZenModeHelperSpy.mConfig.allowEvents = false;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
+        mZenModeHelperSpy.mConfig.allowRepeatCallers = false;
+        mZenModeHelperSpy.mConfig.allowConversations = false;
         ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted =
                 mZenModeHelperSpy.new RingerModeDelegate();
 
@@ -694,7 +697,9 @@
         mZenModeHelperSpy.mConfig.allowCalls = true;
         mZenModeHelperSpy.mConfig.allowMessages = true;
         mZenModeHelperSpy.mConfig.allowEvents = true;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
+        mZenModeHelperSpy.mConfig.allowRepeatCallers = true;
+        mZenModeHelperSpy.mConfig.allowConversations = true;
+        mZenModeHelperSpy.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
         mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
         mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
         mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
@@ -716,7 +721,9 @@
         mZenModeHelperSpy.mConfig.allowCalls = true;
         mZenModeHelperSpy.mConfig.allowMessages = true;
         mZenModeHelperSpy.mConfig.allowEvents = true;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
+        mZenModeHelperSpy.mConfig.allowRepeatCallers = true;
+        mZenModeHelperSpy.mConfig.allowConversations = true;
+        mZenModeHelperSpy.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
         mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
         mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
         mZenModeHelperSpy.mConfig.manualRule.zenMode =