Loading core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -4311,6 +4311,10 @@ (default 2MB) --> <integer name="config_notificationStripRemoteViewSizeBytes">5000000</integer> <!-- List of packages that can use the Conversation space for their category messages notifications until they target R --> <string-array name="config_notificationMsgPkgsAllowedAsConvos" translatable="false"/> <!-- Contains a blacklist of apps that should not get pre-installed carrier app permission grants, even if the UICC claims that the app should be privileged. See b/138150105 --> <string-array name="config_restrictedPreinstalledCarrierApps" translatable="false"/> Loading core/res/res/values/symbols.xml +2 −0 Original line number Diff line number Diff line Loading @@ -4031,4 +4031,6 @@ <java-symbol type="string" name="config_overlayableConfigurator" /> <java-symbol type="array" name="config_overlayableConfiguratorTargets" /> <java-symbol type="array" name="config_notificationMsgPkgsAllowedAsConvos" /> </resources> services/core/java/com/android/server/notification/NotificationManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -530,6 +531,7 @@ public class NotificationManagerService extends SystemService { private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable(); private NotificationRecordLogger mNotificationRecordLogger; private InstanceIdSequence mNotificationInstanceIdSequence; private Set<String> mMsgPkgsAllowedAsConvos = new HashSet(); static class Archive { final SparseArray<Boolean> mEnabled; Loading Loading @@ -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; } Loading Loading @@ -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(); Loading services/core/java/com/android/server/notification/NotificationRecord.java +17 −7 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 // user kicked it out of convo space if (mChannel.isDemoted() || mAppDemotedFromConvo) { return false; } if (mChannel.isDemoted()) { // NAS kicked it out of notification space if (mIsNotConversationOverride) { return false; } if (mIsNotConversationOverride) { 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) { Loading @@ -1410,9 +1423,6 @@ public final class NotificationRecord { if (mHasSentValidMsg && mShortcutInfo == null) { return false; } if (mAppDemotedFromConvo) { return false; } return true; } Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +52 −0 Original line number Diff line number Diff line Loading @@ -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()); } } Loading
core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -4311,6 +4311,10 @@ (default 2MB) --> <integer name="config_notificationStripRemoteViewSizeBytes">5000000</integer> <!-- List of packages that can use the Conversation space for their category messages notifications until they target R --> <string-array name="config_notificationMsgPkgsAllowedAsConvos" translatable="false"/> <!-- Contains a blacklist of apps that should not get pre-installed carrier app permission grants, even if the UICC claims that the app should be privileged. See b/138150105 --> <string-array name="config_restrictedPreinstalledCarrierApps" translatable="false"/> Loading
core/res/res/values/symbols.xml +2 −0 Original line number Diff line number Diff line Loading @@ -4031,4 +4031,6 @@ <java-symbol type="string" name="config_overlayableConfigurator" /> <java-symbol type="array" name="config_overlayableConfiguratorTargets" /> <java-symbol type="array" name="config_notificationMsgPkgsAllowedAsConvos" /> </resources>
services/core/java/com/android/server/notification/NotificationManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -530,6 +531,7 @@ public class NotificationManagerService extends SystemService { private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable(); private NotificationRecordLogger mNotificationRecordLogger; private InstanceIdSequence mNotificationInstanceIdSequence; private Set<String> mMsgPkgsAllowedAsConvos = new HashSet(); static class Archive { final SparseArray<Boolean> mEnabled; Loading Loading @@ -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; } Loading Loading @@ -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(); Loading
services/core/java/com/android/server/notification/NotificationRecord.java +17 −7 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 // user kicked it out of convo space if (mChannel.isDemoted() || mAppDemotedFromConvo) { return false; } if (mChannel.isDemoted()) { // NAS kicked it out of notification space if (mIsNotConversationOverride) { return false; } if (mIsNotConversationOverride) { 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) { Loading @@ -1410,9 +1423,6 @@ public final class NotificationRecord { if (mHasSentValidMsg && mShortcutInfo == null) { return false; } if (mAppDemotedFromConvo) { return false; } return true; } Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +52 −0 Original line number Diff line number Diff line Loading @@ -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()); } }