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());
+ }
}