Loading packages/SystemUI/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1455,6 +1455,9 @@ Hints that the user's only option is to block all of the app's notifications. --> <string name="notification_default_channel_desc">This app doesn\'t have notification categories</string> <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. --> <string name="notification_unblockable_desc">Notifications from this app can\'t be turned off</string> <!-- Notification: Control panel: Label that shows how many channels this application has defined, describing the current notification channel as "1 out of n notification categories from this app". --> <plurals name="notification_num_channels_desc"> Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java +30 −20 Original line number Diff line number Diff line Loading @@ -154,9 +154,32 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G } } boolean nonBlockable = false; try { final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) { final int numChannels = mNotificationChannels.size(); for (int i = 0; i < numChannels; i++) { final NotificationChannel notificationChannel = mNotificationChannels.get(i); // If any of the system channels is not blockable, the bundle is nonblockable if (!notificationChannel.isBlockableSystem()) { nonBlockable = true; break; } } } } catch (PackageManager.NameNotFoundException e) { // unlikely. } if (nonBlockablePkgs != null) { nonBlockable |= nonBlockablePkgs.contains(pkg); } String channelsDescText; mNumChannelsView = findViewById(R.id.num_channels_desc); if (mIsSingleDefaultChannel) { if (nonBlockable) { channelsDescText = mContext.getString(R.string.notification_unblockable_desc); } else if (mIsSingleDefaultChannel) { channelsDescText = mContext.getString(R.string.notification_default_channel_desc); } else { switch (mNotificationChannels.size()) { Loading Loading @@ -188,8 +211,9 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G // Multiple channels don't use a channel name for the title. channelNameText = mContext.getString(R.string.notification_num_channels, mNotificationChannels.size()); } else if (mIsSingleDefaultChannel) { // If this is the default channel, don't use our channel-specific text. } else if (mIsSingleDefaultChannel || nonBlockable) { // If this is the default channel or the app is unblockable, // don't use our channel-specific text. channelNameText = mContext.getString(R.string.notification_header_default_channel); } else { channelNameText = mSingleNotificationChannel.getName(); Loading Loading @@ -218,19 +242,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G groupDividerView.setVisibility(View.GONE); } boolean nonBlockable = false; try { final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); nonBlockable = Utils.isSystemPackage(getResources(), pm, pkgInfo) && (mSingleNotificationChannel == null || !mSingleNotificationChannel.isBlockableSystem()); } catch (PackageManager.NameNotFoundException e) { // unlikely. } if (nonBlockablePkgs != null) { nonBlockable |= nonBlockablePkgs.contains(pkg); } bindButtons(nonBlockable); // Top-level importance group Loading @@ -246,12 +257,11 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G (View view) -> { onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF); }); if (numTotalChannels > 1) { settingsButton.setText(R.string.notification_all_categories); } else { if (numTotalChannels <= 1 || nonBlockable) { settingsButton.setText(R.string.notification_more_settings); } else { settingsButton.setText(R.string.notification_all_categories); } } else { settingsButton.setVisibility(View.GONE); } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -231,6 +231,17 @@ public class NotificationInfoTest extends SysuiTestCase { textView.getText()); } @Test public void testBindNotification_UnblockablePackageDoesNotUseChannelName() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), mNotificationChannel.getImportance(), mSbn, null, null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name); assertEquals(mContext.getString(R.string.notification_header_default_channel), textView.getText()); } @Test public void testBindNotification_DefaultChannelUsesNameWhenMoreThanOneChannelExists() throws Exception { Loading Loading @@ -331,6 +342,21 @@ public class NotificationInfoTest extends SysuiTestCase { assertEquals(getStringById(R.string.notification_all_categories), settingsButton.getText()); } @Test public void testBindNotification_SettingsTextWithMultipleChannelsForUnblockableApp() throws Exception { when(mMockINotificationManager.getNumNotificationChannelsForPackage( eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), mNotificationChannel.getImportance(), mSbn, (View v, NotificationChannel c, int appUid) -> { }, null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); final TextView settingsButton = (TextView) mNotificationInfo.findViewById(R.id.more_settings); assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText()); } @Test public void testBindNotification_SetsOnClickListenerForDone() throws Exception { final CountDownLatch latch = new CountDownLatch(1); Loading Loading @@ -501,6 +527,19 @@ public class NotificationInfoTest extends SysuiTestCase { assertEquals(numChannelsView.getVisibility(), View.GONE); } @Test public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), mNotificationChannel.getImportance(), mSbn, null, null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); final TextView numChannelsView = (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc); assertEquals(View.VISIBLE, numChannelsView.getVisibility()); assertEquals(mContext.getString(R.string.notification_unblockable_desc), numChannelsView.getText()); } @Test @UiThreadTest public void testBindNotification_ChannelDisabledTextShowsForDefaultChannel() Loading Loading
packages/SystemUI/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1455,6 +1455,9 @@ Hints that the user's only option is to block all of the app's notifications. --> <string name="notification_default_channel_desc">This app doesn\'t have notification categories</string> <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. --> <string name="notification_unblockable_desc">Notifications from this app can\'t be turned off</string> <!-- Notification: Control panel: Label that shows how many channels this application has defined, describing the current notification channel as "1 out of n notification categories from this app". --> <plurals name="notification_num_channels_desc"> Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java +30 −20 Original line number Diff line number Diff line Loading @@ -154,9 +154,32 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G } } boolean nonBlockable = false; try { final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) { final int numChannels = mNotificationChannels.size(); for (int i = 0; i < numChannels; i++) { final NotificationChannel notificationChannel = mNotificationChannels.get(i); // If any of the system channels is not blockable, the bundle is nonblockable if (!notificationChannel.isBlockableSystem()) { nonBlockable = true; break; } } } } catch (PackageManager.NameNotFoundException e) { // unlikely. } if (nonBlockablePkgs != null) { nonBlockable |= nonBlockablePkgs.contains(pkg); } String channelsDescText; mNumChannelsView = findViewById(R.id.num_channels_desc); if (mIsSingleDefaultChannel) { if (nonBlockable) { channelsDescText = mContext.getString(R.string.notification_unblockable_desc); } else if (mIsSingleDefaultChannel) { channelsDescText = mContext.getString(R.string.notification_default_channel_desc); } else { switch (mNotificationChannels.size()) { Loading Loading @@ -188,8 +211,9 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G // Multiple channels don't use a channel name for the title. channelNameText = mContext.getString(R.string.notification_num_channels, mNotificationChannels.size()); } else if (mIsSingleDefaultChannel) { // If this is the default channel, don't use our channel-specific text. } else if (mIsSingleDefaultChannel || nonBlockable) { // If this is the default channel or the app is unblockable, // don't use our channel-specific text. channelNameText = mContext.getString(R.string.notification_header_default_channel); } else { channelNameText = mSingleNotificationChannel.getName(); Loading Loading @@ -218,19 +242,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G groupDividerView.setVisibility(View.GONE); } boolean nonBlockable = false; try { final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); nonBlockable = Utils.isSystemPackage(getResources(), pm, pkgInfo) && (mSingleNotificationChannel == null || !mSingleNotificationChannel.isBlockableSystem()); } catch (PackageManager.NameNotFoundException e) { // unlikely. } if (nonBlockablePkgs != null) { nonBlockable |= nonBlockablePkgs.contains(pkg); } bindButtons(nonBlockable); // Top-level importance group Loading @@ -246,12 +257,11 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G (View view) -> { onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF); }); if (numTotalChannels > 1) { settingsButton.setText(R.string.notification_all_categories); } else { if (numTotalChannels <= 1 || nonBlockable) { settingsButton.setText(R.string.notification_more_settings); } else { settingsButton.setText(R.string.notification_all_categories); } } else { settingsButton.setVisibility(View.GONE); } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -231,6 +231,17 @@ public class NotificationInfoTest extends SysuiTestCase { textView.getText()); } @Test public void testBindNotification_UnblockablePackageDoesNotUseChannelName() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), mNotificationChannel.getImportance(), mSbn, null, null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name); assertEquals(mContext.getString(R.string.notification_header_default_channel), textView.getText()); } @Test public void testBindNotification_DefaultChannelUsesNameWhenMoreThanOneChannelExists() throws Exception { Loading Loading @@ -331,6 +342,21 @@ public class NotificationInfoTest extends SysuiTestCase { assertEquals(getStringById(R.string.notification_all_categories), settingsButton.getText()); } @Test public void testBindNotification_SettingsTextWithMultipleChannelsForUnblockableApp() throws Exception { when(mMockINotificationManager.getNumNotificationChannelsForPackage( eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), mNotificationChannel.getImportance(), mSbn, (View v, NotificationChannel c, int appUid) -> { }, null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); final TextView settingsButton = (TextView) mNotificationInfo.findViewById(R.id.more_settings); assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText()); } @Test public void testBindNotification_SetsOnClickListenerForDone() throws Exception { final CountDownLatch latch = new CountDownLatch(1); Loading Loading @@ -501,6 +527,19 @@ public class NotificationInfoTest extends SysuiTestCase { assertEquals(numChannelsView.getVisibility(), View.GONE); } @Test public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), mNotificationChannel.getImportance(), mSbn, null, null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); final TextView numChannelsView = (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc); assertEquals(View.VISIBLE, numChannelsView.getVisibility()); assertEquals(mContext.getString(R.string.notification_unblockable_desc), numChannelsView.getText()); } @Test @UiThreadTest public void testBindNotification_ChannelDisabledTextShowsForDefaultChannel() Loading