diff options
4 files changed, 195 insertions, 203 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 48cc03221124..abf3da45d0cb 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -49,10 +49,6 @@ import static android.app.Notification.FLAG_ONLY_ALERT_ONCE; import static android.app.Notification.FLAG_PROMOTED_ONGOING; import static android.app.Notification.FLAG_USER_INITIATED_JOB; import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT; -import static android.app.NotificationChannel.NEWS_ID; -import static android.app.NotificationChannel.PROMOTIONS_ID; -import static android.app.NotificationChannel.RECS_ID; -import static android.app.NotificationChannel.SOCIAL_MEDIA_ID; import static android.app.NotificationChannel.SYSTEM_RESERVED_IDS; import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED; import static android.app.NotificationManager.ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED; @@ -108,9 +104,7 @@ import static android.os.UserHandle.USER_NULL; import static android.os.UserHandle.USER_SYSTEM; import static android.service.notification.Adjustment.KEY_TYPE; import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION; -import static android.service.notification.Adjustment.TYPE_NEWS; import static android.service.notification.Adjustment.TYPE_PROMOTION; -import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA; import static android.service.notification.Flags.callstyleCallbackApi; import static android.service.notification.Flags.notificationClassification; import static android.service.notification.Flags.notificationForceGrouping; @@ -6924,21 +6918,19 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") @Nullable + @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) private NotificationChannel getClassificationChannelLocked(NotificationRecord r, Bundle adjustments) { int type = adjustments.getInt(KEY_TYPE); - if (TYPE_NEWS == type) { - return mPreferencesHelper.getNotificationChannel( - r.getSbn().getPackageName(), r.getUid(), NEWS_ID, false); - } else if (TYPE_PROMOTION == type) { - return mPreferencesHelper.getNotificationChannel( - r.getSbn().getPackageName(), r.getUid(), PROMOTIONS_ID, false); - } else if (TYPE_SOCIAL_MEDIA == type) { - return mPreferencesHelper.getNotificationChannel( - r.getSbn().getPackageName(), r.getUid(), SOCIAL_MEDIA_ID, false); - } else if (TYPE_CONTENT_RECOMMENDATION == type) { - return mPreferencesHelper.getNotificationChannel( - r.getSbn().getPackageName(), r.getUid(), RECS_ID, false); + if (type >= TYPE_PROMOTION && type <= TYPE_CONTENT_RECOMMENDATION) { + NotificationChannel channel = mPreferencesHelper.getReservedChannel( + r.getSbn().getPackageName(), r.getUid(), type); + if (channel == null) { + channel = mPreferencesHelper.createReservedChannel( + r.getSbn().getPackageName(), r.getUid(), type); + handleSavePolicyFile(); + } + return channel; } return null; } diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 964a5d002bf2..d26a5aa5491f 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -17,6 +17,7 @@ package com.android.server.notification; import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; +import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID; import static android.app.NotificationChannel.NEWS_ID; import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID; import static android.app.NotificationChannel.PROMOTIONS_ID; @@ -32,6 +33,10 @@ import static android.app.NotificationManager.IMPORTANCE_MAX; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import static android.os.UserHandle.USER_SYSTEM; +import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION; +import static android.service.notification.Adjustment.TYPE_NEWS; +import static android.service.notification.Adjustment.TYPE_PROMOTION; +import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA; import static android.service.notification.Flags.notificationClassification; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES; @@ -66,6 +71,7 @@ import android.os.Process; import android.os.UserHandle; import android.permission.PermissionManager; import android.provider.Settings; +import android.service.notification.Adjustment; import android.service.notification.ConversationChannelWrapper; import android.service.notification.NotificationListenerService; import android.service.notification.RankingHelperProto; @@ -549,10 +555,6 @@ public class PreferencesHelper implements RankingConfig { Slog.e(TAG, "createDefaultChannelIfNeededLocked - Exception: " + e); } - if (notificationClassification()) { - addReservedChannelsLocked(r); - } - if (r.uid == UNKNOWN_UID) { if (Flags.persistIncompleteRestoreData()) { r.userId = userId; @@ -587,7 +589,7 @@ public class PreferencesHelper implements RankingConfig { private boolean deleteDefaultChannelIfNeededLocked(PackagePreferences r) throws PackageManager.NameNotFoundException { - if (!r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) { + if (!r.channels.containsKey(DEFAULT_CHANNEL_ID)) { // Not present return false; } @@ -598,7 +600,7 @@ public class PreferencesHelper implements RankingConfig { } // Remove Default Channel. - r.channels.remove(NotificationChannel.DEFAULT_CHANNEL_ID); + r.channels.remove(DEFAULT_CHANNEL_ID); return true; } @@ -609,8 +611,8 @@ public class PreferencesHelper implements RankingConfig { return false; } - if (r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) { - r.channels.get(NotificationChannel.DEFAULT_CHANNEL_ID).setName(mContext.getString( + if (r.channels.containsKey(DEFAULT_CHANNEL_ID)) { + r.channels.get(DEFAULT_CHANNEL_ID).setName(mContext.getString( com.android.internal.R.string.default_notification_channel_label)); return false; } @@ -623,7 +625,7 @@ public class PreferencesHelper implements RankingConfig { // Create Default Channel NotificationChannel channel; channel = new NotificationChannel( - NotificationChannel.DEFAULT_CHANNEL_ID, + DEFAULT_CHANNEL_ID, mContext.getString(R.string.default_notification_channel_label), r.importance); channel.setBypassDnd(r.priority == Notification.PRIORITY_MAX); @@ -642,38 +644,25 @@ public class PreferencesHelper implements RankingConfig { return true; } - private void addReservedChannelsLocked(PackagePreferences p) { - if (!p.channels.containsKey(NotificationChannel.PROMOTIONS_ID)) { - NotificationChannel channel = new NotificationChannel( - NotificationChannel.PROMOTIONS_ID, - mContext.getString(R.string.promotional_notification_channel_label), - IMPORTANCE_LOW); - p.channels.put(channel.getId(), channel); - } - - if (!p.channels.containsKey(NotificationChannel.RECS_ID)) { - NotificationChannel channel = new NotificationChannel( - NotificationChannel.RECS_ID, - mContext.getString(R.string.recs_notification_channel_label), - IMPORTANCE_LOW); - p.channels.put(channel.getId(), channel); - } - - if (!p.channels.containsKey(NotificationChannel.NEWS_ID)) { - NotificationChannel channel = new NotificationChannel( - NotificationChannel.NEWS_ID, - mContext.getString(R.string.news_notification_channel_label), - IMPORTANCE_LOW); - p.channels.put(channel.getId(), channel); - } - - if (!p.channels.containsKey(NotificationChannel.SOCIAL_MEDIA_ID)) { - NotificationChannel channel = new NotificationChannel( - NotificationChannel.SOCIAL_MEDIA_ID, - mContext.getString(R.string.social_notification_channel_label), - IMPORTANCE_LOW); - p.channels.put(channel.getId(), channel); + private NotificationChannel addReservedChannelLocked(PackagePreferences p, String channelId) { + String label = ""; + switch (channelId) { + case PROMOTIONS_ID: + label = mContext.getString(R.string.promotional_notification_channel_label); + break; + case RECS_ID: + label = mContext.getString(R.string.recs_notification_channel_label); + break; + case NEWS_ID: + label = mContext.getString(R.string.news_notification_channel_label); + break; + case SOCIAL_MEDIA_ID: + label = mContext.getString(R.string.social_notification_channel_label); + break; } + NotificationChannel channel = new NotificationChannel(channelId, label, IMPORTANCE_LOW); + p.channels.put(channelId, channel); + return channel; } public void writeXml(TypedXmlSerializer out, boolean forBackup, int userId) throws IOException { @@ -1078,7 +1067,7 @@ public class PreferencesHelper implements RankingConfig { if (channel.getGroup() != null && !r.groups.containsKey(channel.getGroup())) { throw new IllegalArgumentException("NotificationChannelGroup doesn't exist"); } - if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(channel.getId())) { + if (DEFAULT_CHANNEL_ID.equals(channel.getId())) { throw new IllegalArgumentException("Reserved id"); } // Only the user can update bundle channel settings @@ -1411,6 +1400,54 @@ public class PreferencesHelper implements RankingConfig { } } + private @Nullable String getChannelIdForBundleType(@Adjustment.Types int type) { + switch (type) { + case TYPE_CONTENT_RECOMMENDATION: + return RECS_ID; + case TYPE_NEWS: + return NEWS_ID; + case TYPE_PROMOTION: + return PROMOTIONS_ID; + case TYPE_SOCIAL_MEDIA: + return SOCIAL_MEDIA_ID; + } + return null; + } + + @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) + public NotificationChannel getReservedChannel(String pkg, int uid, + @Adjustment.Types int type) { + if (!notificationClassification()) { + return null; + } + Objects.requireNonNull(pkg); + String channelId = getChannelIdForBundleType(type); + if (channelId == null) { + return null; + } + NotificationChannel channel = + getConversationNotificationChannel(pkg, uid, channelId, null, true, false); + return channel; + } + + @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) + public NotificationChannel createReservedChannel(String pkg, int uid, + @Adjustment.Types int type) { + if (!notificationClassification()) { + return null; + } + Objects.requireNonNull(pkg); + PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid); + if (r == null) { + return null; + } + String channelId = getChannelIdForBundleType(type); + if (channelId == null) { + return null; + } + return addReservedChannelLocked(r, channelId); + } + @Override public NotificationChannel getNotificationChannel(String pkg, int uid, String channelId, boolean includeDeleted) { @@ -1429,7 +1466,7 @@ public class PreferencesHelper implements RankingConfig { return null; } if (channelId == null) { - channelId = NotificationChannel.DEFAULT_CHANNEL_ID; + channelId = DEFAULT_CHANNEL_ID; } NotificationChannel channel = null; if (conversationId != null) { @@ -1540,7 +1577,7 @@ public class PreferencesHelper implements RankingConfig { int N = r.channels.size() - 1; for (int i = N; i >= 0; i--) { String key = r.channels.keyAt(i); - if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(key)) { + if (!DEFAULT_CHANNEL_ID.equals(key)) { r.channels.remove(key); } } @@ -1658,10 +1695,7 @@ public class PreferencesHelper implements RankingConfig { && (activeChannelFilter == null || (includeBlocked && nc.getImportance() == IMPORTANCE_NONE) || activeChannelFilter.contains(nc.getId())) - && !PROMOTIONS_ID.equals(nc.getId()) - && !NEWS_ID.equals(nc.getId()) - && !SOCIAL_MEDIA_ID.equals(nc.getId()) - && !RECS_ID.equals(nc.getId()); + && !SYSTEM_RESERVED_IDS.contains(nc.getId()); if (includeChannel) { if (nc.getGroup() != null) { if (r.groups.get(nc.getGroup()) != null) { @@ -1924,9 +1958,23 @@ public class PreferencesHelper implements RankingConfig { public boolean onlyHasDefaultChannel(String pkg, int uid) { synchronized (mLock) { PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid); - if (r.channels.size() == (notificationClassification() ? 5 : 1) - && r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) { - return true; + if (r.channels.containsKey(DEFAULT_CHANNEL_ID)) { + if (r.channels.size() == 1) { + return true; + } + if (notificationClassification()) { + if (r.channels.size() <= 5) { + for (NotificationChannel c : r.channels.values()) { + if (!SYSTEM_RESERVED_IDS.contains(c.getId()) && + !DEFAULT_CHANNEL_ID.equals(c.getId())) { + return false; + } + return true; + } + } else { + return false; + } + } } return false; } @@ -2744,9 +2792,9 @@ public class PreferencesHelper implements RankingConfig { PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i); if (UserHandle.getUserId(PackagePreferences.uid) == userId) { if (PackagePreferences.channels.containsKey( - NotificationChannel.DEFAULT_CHANNEL_ID)) { + DEFAULT_CHANNEL_ID)) { PackagePreferences.channels.get( - NotificationChannel.DEFAULT_CHANNEL_ID).setName( + DEFAULT_CHANNEL_ID).setName( context.getResources().getString( R.string.default_notification_channel_label)); } 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 e845d80b412a..dec7f09f2da4 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -45,6 +45,9 @@ import static android.app.Notification.GROUP_ALERT_CHILDREN; import static android.app.Notification.VISIBILITY_PRIVATE; import static android.app.NotificationChannel.NEWS_ID; import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID; +import static android.app.NotificationChannel.PROMOTIONS_ID; +import static android.app.NotificationChannel.RECS_ID; +import static android.app.NotificationChannel.SOCIAL_MEDIA_ID; import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED; import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; @@ -98,7 +101,10 @@ import static android.service.notification.Adjustment.KEY_IMPORTANCE; import static android.service.notification.Adjustment.KEY_TEXT_REPLIES; import static android.service.notification.Adjustment.KEY_TYPE; import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; +import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION; import static android.service.notification.Adjustment.TYPE_NEWS; +import static android.service.notification.Adjustment.TYPE_PROMOTION; +import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA; import static android.service.notification.Condition.SOURCE_CONTEXT; import static android.service.notification.Condition.SOURCE_USER_ACTION; import static android.service.notification.Condition.STATE_TRUE; @@ -16767,6 +16773,24 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { r.applyAdjustments(); assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID); + + signals.putInt(KEY_TYPE, TYPE_PROMOTION); + mBinderService.applyAdjustmentFromAssistant(null, adjustment); + waitForIdle(); + r.applyAdjustments(); + assertThat(r.getChannel().getId()).isEqualTo(PROMOTIONS_ID); + + signals.putInt(KEY_TYPE, TYPE_SOCIAL_MEDIA); + mBinderService.applyAdjustmentFromAssistant(null, adjustment); + waitForIdle(); + r.applyAdjustments(); + assertThat(r.getChannel().getId()).isEqualTo(SOCIAL_MEDIA_ID); + + signals.putInt(KEY_TYPE, TYPE_CONTENT_RECOMMENDATION); + mBinderService.applyAdjustmentFromAssistant(null, adjustment); + waitForIdle(); + r.applyAdjustments(); + assertThat(r.getChannel().getId()).isEqualTo(RECS_ID); } @Test @@ -17066,7 +17090,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAppCannotUseReservedBundleChannels() throws Exception { - mBinderService.getBubblePreferenceForPackage(mPkg, mUid); + mService.mPreferencesHelper.createReservedChannel(mPkg, mUid, TYPE_NEWS); NotificationChannel news = mBinderService.getNotificationChannel( mPkg, mContext.getUserId(), mPkg, NEWS_ID); assertThat(news).isNotNull(); 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 36fa1b82fe69..1a1da0f6d408 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -54,6 +54,11 @@ import static android.media.AudioAttributes.USAGE_NOTIFICATION; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_SYSTEM; import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; +import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION; +import static android.service.notification.Adjustment.TYPE_NEWS; +import static android.service.notification.Adjustment.TYPE_OTHER; +import static android.service.notification.Adjustment.TYPE_PROMOTION; +import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA; import static android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION; import static android.service.notification.Flags.notificationClassification; @@ -640,6 +645,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { NotificationChannel updateNews = null; if (notificationClassification()) { + mHelper.createReservedChannel(PKG_N_MR1, UID_N_MR1, TYPE_NEWS); // change one of the reserved bundle channels to ensure changes are persisted across // boot updateNews = mHelper.getNotificationChannel( @@ -1210,22 +1216,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" " + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble" + "=\"false\" uid=\"10002\">\n" - + (notificationClassification() ? "<channel id=\"android.app.social\" " - + "name=\"Social\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"id\" name=\"name\" importance=\"2\" " + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" " - + "importance=\"2\" sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "</package>\n" + "<package name=\"com.example.n_mr1\" show_badge=\"true\" " + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" " @@ -1233,10 +1226,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "=\"false\" uid=\"10001\">\n" + "<channelGroup id=\"1\" name=\"bye\" blocked=\"false\" locked=\"0\" />\n" + "<channelGroup id=\"2\" name=\"hello\" blocked=\"false\" locked=\"0\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.social\" " - + "name=\"Social\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"id1\" name=\"name1\" importance=\"4\" show_badge=\"true\" " + "orig_imp=\"4\" />\n" + "<channel id=\"id2\" name=\"name2\" desc=\"descriptions for all\" " @@ -1246,15 +1235,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" vibration_enabled=\"true\" show_badge=\"true\" " + "orig_imp=\"4\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" " - + "importance=\"2\" sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"miscellaneous\" name=\"Uncategorized\" " + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" @@ -1321,22 +1301,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" " + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble" + "=\"false\">\n" - + (notificationClassification() ? "<channel id=\"android.app.social\" " - + "name=\"Social\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"id\" name=\"name\" importance=\"2\" " + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" " - + "importance=\"2\" sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "</package>\n" // Importance default because on in permission helper + "<package name=\"com.example.n_mr1\" importance=\"3\" show_badge=\"true\" " @@ -1345,10 +1312,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "=\"false\">\n" + "<channelGroup id=\"1\" name=\"bye\" blocked=\"false\" locked=\"0\" />\n" + "<channelGroup id=\"2\" name=\"hello\" blocked=\"false\" locked=\"0\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.social\" " - + "name=\"Social\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"id1\" name=\"name1\" importance=\"4\" show_badge=\"true\" " + "orig_imp=\"4\" />\n" + "<channel id=\"id2\" name=\"name2\" desc=\"descriptions for all\" " @@ -1358,15 +1321,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" vibration_enabled=\"true\" show_badge=\"true\" " + "orig_imp=\"4\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" " - + "importance=\"2\" sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"miscellaneous\" name=\"Uncategorized\" " + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" @@ -1433,22 +1387,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" " + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble" + "=\"false\">\n" - + (notificationClassification() ? "<channel id=\"android.app.social\" " - + "name=\"Social\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"id\" name=\"name\" importance=\"2\" " + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" " - + "importance=\"2\" sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "</package>\n" // Importance 0 because missing from permission helper + "<package name=\"com.example.n_mr1\" importance=\"0\" show_badge=\"true\" " @@ -1457,10 +1398,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "=\"false\">\n" + "<channelGroup id=\"1\" name=\"bye\" blocked=\"false\" locked=\"0\" />\n" + "<channelGroup id=\"2\" name=\"hello\" blocked=\"false\" locked=\"0\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.social\" " - + "name=\"Social\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"id1\" name=\"name1\" importance=\"4\" show_badge=\"true\" " + "orig_imp=\"4\" />\n" + "<channel id=\"id2\" name=\"name2\" desc=\"descriptions for all\" " @@ -1470,15 +1407,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" vibration_enabled=\"true\" show_badge=\"true\" " + "orig_imp=\"4\" />\n" - + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" " - + "importance=\"2\" sound=\"content://settings/system/notification_sound\" " - + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" - + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" " - + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " - + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "") + "<channel id=\"miscellaneous\" name=\"Uncategorized\" " + "sound=\"content://settings/system/notification_sound\" usage=\"5\" " + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" @@ -2183,10 +2111,10 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testUpdate_preUpgrade_updatesAppFields() throws Exception { assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); - assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1)); + assertEquals(Notification.PRIORITY_DEFAULT, + mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1)); assertEquals(VISIBILITY_NO_OVERRIDE, mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1)); @@ -2549,7 +2477,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { List<NotificationChannel> channels = mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false, true).getList(); // Default channel + non-deleted channel + system defaults - assertEquals(notificationClassification() ? 6 : 2, channels.size()); + assertEquals(2, channels.size()); for (NotificationChannel nc : channels) { if (channel2.getId().equals(nc.getId())) { compareChannels(channel2, nc); @@ -2559,7 +2487,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { // Returns deleted channels too channels = mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true, true).getList(); // Includes system channel(s) - assertEquals(notificationClassification() ? 7 : 3, channels.size()); + assertEquals(3, channels.size()); for (NotificationChannel nc : channels) { if (channel2.getId().equals(nc.getId())) { compareChannels(channelMap.get(nc.getId()), nc); @@ -3036,7 +2964,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testOnlyHasDefaultChannel() throws Exception { assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1)); assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O)); @@ -3047,6 +2974,18 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test + @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) + public void testOnlyHasDefaultChannel_bundleExists() throws Exception { + mHelper.createReservedChannel(PKG_N_MR1, UID_N_MR1, TYPE_NEWS); + assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1)); + assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O)); + + mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false, + UID_N_MR1, false); + assertFalse(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1)); + } + + @Test public void testCreateDeletedChannel() throws Exception { long[] vibration = new long[]{100, 67, 145, 156}; NotificationChannel channel = @@ -3315,7 +3254,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { // user 0 records remain for (int i = 0; i < user0Uids.length; i++) { - assertEquals(notificationClassification() ? 5 : 1, + assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, user0Uids[i], false, true) .getList().size()); } @@ -3346,7 +3285,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertFalse(mHelper.onPackagesChanged(false, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{UID_N_MR1})); - assertEquals(notificationClassification() ? 6 : 2, + assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false, true) .getList().size()); } @@ -3420,7 +3359,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testRecordDefaults() throws Exception { assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); - assertEquals(notificationClassification() ? 5 : 1, + assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false, true) .getList().size()); } @@ -3659,9 +3598,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false, UID_N_MR1, false); } - if (notificationClassification()) { - numChannels += 4; - } expectedChannels.put(pkgName, numChannels); } @@ -4883,10 +4819,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testTooManyChannels() { int numToCreate = NOTIFICATION_CHANNEL_COUNT_LIMIT; - if (notificationClassification()) { - // reserved channels lower limit - numToCreate -= 4; - } for (int i = 0; i < numToCreate; i++) { NotificationChannel channel = new NotificationChannel(String.valueOf(i), String.valueOf(i), NotificationManager.IMPORTANCE_HIGH); @@ -4907,10 +4839,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testTooManyChannels_xml() throws Exception { int numToCreate = NOTIFICATION_CHANNEL_COUNT_LIMIT; - if (notificationClassification()) { - // reserved channels lower limit - numToCreate -= 4; - } String extraChannel = "EXTRA"; String extraChannel1 = "EXTRA1"; @@ -5928,9 +5856,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { ArrayList<StatsEvent> events = new ArrayList<>(); mHelper.pullPackageChannelPreferencesStats(events); - assertEquals("expected number of events", - notificationClassification() ? 7 : 3, - events.size()); + assertEquals("expected number of events", 3, events.size()); for (StatsEvent ev : events) { // all of these events should be of PackageNotificationChannelPreferences type, // and therefore we expect the atom to have this field. @@ -5971,17 +5897,11 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false, UID_O, false); List<String> channels = new LinkedList<>(Arrays.asList("a", "b", "c")); - if (notificationClassification()) { - channels.add(NEWS_ID); - channels.add(PROMOTIONS_ID); - channels.add(SOCIAL_MEDIA_ID); - channels.add(RECS_ID); - } ArrayList<StatsEvent> events = new ArrayList<>(); mHelper.pullPackageChannelPreferencesStats(events); - assertEquals("total events", notificationClassification() ? 7 : 3, events.size()); + assertEquals("total events", 3, events.size()); for (StatsEvent ev : events) { AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev); assertTrue(atom.hasPackageNotificationChannelPreferences()); @@ -6015,7 +5935,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.pullPackageChannelPreferencesStats(events); // In this case, we want to check the properties of the conversation channel (not parent) - assertEquals("total events", notificationClassification() ? 6 : 2, events.size()); + assertEquals("total events", 2, events.size()); for (StatsEvent ev : events) { AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev); assertTrue(atom.hasPackageNotificationChannelPreferences()); @@ -6047,9 +5967,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { ArrayList<StatsEvent> events = new ArrayList<>(); mHelper.pullPackageChannelPreferencesStats(events); - assertEquals("total events", - notificationClassification() ? 6 : 2, - events.size()); + assertEquals("total events", 2, events.size()); for (StatsEvent ev : events) { AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev); assertTrue(atom.hasPackageNotificationChannelPreferences()); @@ -6080,9 +5998,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { ArrayList<StatsEvent> events = new ArrayList<>(); mHelper.pullPackageChannelPreferencesStats(events); - assertEquals("total events", - notificationClassification() ? 6 : 2, - events.size()); + assertEquals("total events", 2, events.size()); for (StatsEvent ev : events) { AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev); assertTrue(atom.hasPackageNotificationChannelPreferences()); @@ -6367,8 +6283,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testGetNotificationChannels_omitBundleChannels() { - // do something that triggers settings creation for an app - mHelper.setShowBadge(PKG_O, UID_O, true); + mHelper.createReservedChannel(PKG_O, UID_O, TYPE_NEWS); assertThat(mHelper.getNotificationChannels(PKG_O, UID_O, true, false).getList()).isEmpty(); } @@ -6376,18 +6291,34 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testNotificationBundles() { - // do something that triggers settings creation for an app - mHelper.setShowBadge(PKG_O, UID_O, true); - - // verify 4 reserved channels are created + mHelper.createReservedChannel(PKG_O, UID_O, TYPE_NEWS); assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, NEWS_ID, false).getImportance()) .isEqualTo(IMPORTANCE_LOW); - assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, PROMOTIONS_ID, false) - .getImportance()).isEqualTo(IMPORTANCE_LOW); - assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, SOCIAL_MEDIA_ID, false) - .getImportance()).isEqualTo(IMPORTANCE_LOW); + assertThat(mHelper.getNotificationChannels(PKG_O, UID_O, true, true).getList().size()) + .isEqualTo(1); + + mHelper.createReservedChannel(PKG_O, UID_O, TYPE_SOCIAL_MEDIA); + assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, SOCIAL_MEDIA_ID, false). + getImportance()).isEqualTo(IMPORTANCE_LOW); + assertThat(mHelper.getNotificationChannels(PKG_O, UID_O, true, true).getList().size()) + .isEqualTo(2); + + mHelper.createReservedChannel(PKG_O, UID_O, TYPE_CONTENT_RECOMMENDATION); assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, RECS_ID, false).getImportance()) .isEqualTo(IMPORTANCE_LOW); + assertThat(mHelper.getNotificationChannels(PKG_O, UID_O, true, true).getList().size()) + .isEqualTo(3); + + mHelper.createReservedChannel(PKG_O, UID_O, TYPE_PROMOTION); + assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, PROMOTIONS_ID, false) + .getImportance()).isEqualTo(IMPORTANCE_LOW); + assertThat(mHelper.getNotificationChannels(PKG_O, UID_O, true, true).getList().size()) + .isEqualTo(4); + + // only the first 4 types are created; no others + mHelper.createReservedChannel(PKG_O, UID_O, TYPE_OTHER); + assertThat(mHelper.getNotificationChannels(PKG_O, UID_O, true, true).getList().size()) + .isEqualTo(4); } @Test @@ -6417,8 +6348,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testNotificationBundles_appsCannotUpdate() { - // do something that triggers settings creation for an app - mHelper.setShowBadge(PKG_O, UID_O, true); + mHelper.createReservedChannel(PKG_O, UID_O, TYPE_NEWS); NotificationChannel fromApp = new NotificationChannel(NEWS_ID, "The best channel", IMPORTANCE_HIGH); @@ -6431,8 +6361,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testNotificationBundles_osCanAllowToBypassDnd() { - // do something that triggers settings creation for an app - mHelper.setShowBadge(PKG_O, UID_O, true); + mHelper.createReservedChannel(PKG_O, UID_O, TYPE_NEWS); NotificationChannel fromApp = new NotificationChannel(NEWS_ID, "The best channel", IMPORTANCE_HIGH); @@ -6442,18 +6371,17 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testUnDeleteBundleChannelsOnLoadIfNotUserChange() throws Exception { - mHelper.setShowBadge(PKG_P, UID_P, true); // the public create/update methods should prevent this, so take advantage of the fact that // the object is in the same process - mHelper.getNotificationChannel(PKG_P, UID_P, SOCIAL_MEDIA_ID, true).setDeleted(true); + mHelper.createReservedChannel(PKG_N_MR1, UID_N_MR1, TYPE_SOCIAL_MEDIA).setDeleted(true); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false, UserHandle.USER_ALL, SOCIAL_MEDIA_ID); loadStreamXml(baos, false, UserHandle.USER_ALL); - assertThat(mXmlHelper.getNotificationChannel(PKG_P, UID_P, SOCIAL_MEDIA_ID, true). - isDeleted()).isFalse(); + assertThat(mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, SOCIAL_MEDIA_ID, true) + .isDeleted()).isFalse(); } @Test |