diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9959de8aa6452..00eae80c8669a 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4311,6 +4311,10 @@ (default 2MB) --> 5000000 + + + diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 61a65249a464f..d282ccded069d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4030,4 +4030,6 @@ + + diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 86e8734177f04..86d2e63975dbe 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -292,6 +292,7 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -530,6 +531,7 @@ public class NotificationManagerService extends SystemService { private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable(); private NotificationRecordLogger mNotificationRecordLogger; private InstanceIdSequence mNotificationInstanceIdSequence; + private Set mMsgPkgsAllowedAsConvos = new HashSet(); static class Archive { final SparseArray mEnabled; @@ -2042,6 +2044,9 @@ public class NotificationManagerService extends SystemService { mStripRemoteViewsSizeBytes = getContext().getResources().getInteger( com.android.internal.R.integer.config_notificationStripRemoteViewSizeBytes); + mMsgPkgsAllowedAsConvos = Set.of( + getContext().getResources().getStringArray( + com.android.internal.R.array.config_notificationMsgPkgsAllowedAsConvos)); mStatsManager = statsManager; } @@ -5683,6 +5688,7 @@ public class NotificationManagerService extends SystemService { r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid)); r.setPostSilently(postSilently); r.setFlagBubbleRemoved(false); + r.setPkgAllowedAsConvo(mMsgPkgsAllowedAsConvos.contains(pkg)); if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) { final boolean fgServiceShown = channel.isFgServiceShown(); diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index c10782242faa1..bae02ac75f0a2 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -190,6 +190,7 @@ public final class NotificationRecord { private boolean mPostSilently; private boolean mHasSentValidMsg; private boolean mAppDemotedFromConvo; + private boolean mPkgAllowedAsConvo; /** * Whether this notification (and its channels) should be considered user locked. Used in * conjunction with user sentiment calculation. @@ -1387,21 +1388,33 @@ public final class NotificationRecord { mAppDemotedFromConvo = userDemoted; } + public void setPkgAllowedAsConvo(boolean allowedAsConvo) { + mPkgAllowedAsConvo = allowedAsConvo; + } + /** * Whether this notification is a conversation notification. */ public boolean isConversation() { Notification notification = getNotification(); - if (!Notification.MessagingStyle.class.equals(notification.getNotificationStyle())) { - // very common; don't bother logging - return false; - } - if (mChannel.isDemoted()) { + // user kicked it out of convo space + if (mChannel.isDemoted() || mAppDemotedFromConvo) { return false; } + // NAS kicked it out of notification space if (mIsNotConversationOverride) { return false; } + if (!Notification.MessagingStyle.class.equals(notification.getNotificationStyle())) { + // some non-msgStyle notifs can temporarily appear in the conversation space if category + // is right + if (mPkgAllowedAsConvo && mTargetSdkVersion < Build.VERSION_CODES.R + && Notification.CATEGORY_MESSAGE.equals(getNotification().category)) { + return true; + } + return false; + } + if (mTargetSdkVersion >= Build.VERSION_CODES.R && Notification.MessagingStyle.class.equals(notification.getNotificationStyle()) && mShortcutInfo == null) { @@ -1410,9 +1423,6 @@ public final class NotificationRecord { if (mHasSentValidMsg && mShortcutInfo == null) { return false; } - if (mAppDemotedFromConvo) { - return false; - } return true; } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java index 6df3c7b69d15a..976f40896b78f 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java @@ -1191,4 +1191,56 @@ public class NotificationRecordTest extends UiServiceTestCase { assertFalse(record.isConversation()); } + + @Test + public void isConversation_pkgAllowed_isMsgType() { + StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */, + true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */, + false /* lights */, false /* defaultLights */, null /* group */); + sbn.getNotification().category = Notification.CATEGORY_MESSAGE; + NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel); + + record.setPkgAllowedAsConvo(true); + + assertTrue(record.isConversation()); + } + + @Test + public void isConversation_pkgAllowed_isMNotsgType() { + StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */, + true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */, + false /* lights */, false /* defaultLights */, null /* group */); + sbn.getNotification().category = Notification.CATEGORY_ALARM; + NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel); + + record.setPkgAllowedAsConvo(true); + + assertFalse(record.isConversation()); + } + + @Test + public void isConversation_pkgNotAllowed_isMsgType() { + StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */, + true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */, + false /* lights */, false /* defaultLights */, null /* group */); + sbn.getNotification().category = Notification.CATEGORY_MESSAGE; + NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel); + + record.setPkgAllowedAsConvo(false); + + assertFalse(record.isConversation()); + } + + @Test + public void isConversation_pkgAllowed_isMsgType_targetsR() { + StatusBarNotification sbn = getNotification(PKG_R, true /* noisy */, + true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */, + false /* lights */, false /* defaultLights */, null /* group */); + sbn.getNotification().category = Notification.CATEGORY_MESSAGE; + NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel); + + record.setPkgAllowedAsConvo(true); + + assertFalse(record.isConversation()); + } }