diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java index 21b7d25d2ebec..accfc875956ca 100644 --- a/core/java/com/android/internal/notification/SystemNotificationChannels.java +++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java @@ -59,7 +59,6 @@ public class SystemNotificationChannels { VIRTUAL_KEYBOARD, context.getString(R.string.notification_channel_virtual_keyboard), NotificationManager.IMPORTANCE_LOW); - keyboard.setBypassDnd(true); keyboard.setBlockableSystem(true); channelsList.add(keyboard); @@ -76,7 +75,6 @@ public class SystemNotificationChannels { SECURITY, context.getString(R.string.notification_channel_security), NotificationManager.IMPORTANCE_LOW); - security.setBypassDnd(true); channelsList.add(security); final NotificationChannel car = new NotificationChannel( @@ -84,7 +82,6 @@ public class SystemNotificationChannels { context.getString(R.string.notification_channel_car_mode), NotificationManager.IMPORTANCE_LOW); car.setBlockableSystem(true); - car.setBypassDnd(true); channelsList.add(car); channelsList.add(newAccountChannel(context)); @@ -93,7 +90,6 @@ public class SystemNotificationChannels { DEVELOPER, context.getString(R.string.notification_channel_developer), NotificationManager.IMPORTANCE_LOW); - developer.setBypassDnd(true); developer.setBlockableSystem(true); channelsList.add(developer); @@ -101,21 +97,18 @@ public class SystemNotificationChannels { UPDATES, context.getString(R.string.notification_channel_updates), NotificationManager.IMPORTANCE_LOW); - updates.setBypassDnd(true); channelsList.add(updates); final NotificationChannel network = new NotificationChannel( NETWORK_STATUS, context.getString(R.string.notification_channel_network_status), NotificationManager.IMPORTANCE_LOW); - network.setBypassDnd(true); channelsList.add(network); final NotificationChannel networkAlertsChannel = new NotificationChannel( NETWORK_ALERTS, context.getString(R.string.notification_channel_network_alerts), NotificationManager.IMPORTANCE_HIGH); - networkAlertsChannel.setBypassDnd(true); networkAlertsChannel.setBlockableSystem(true); channelsList.add(networkAlertsChannel); @@ -124,42 +117,36 @@ public class SystemNotificationChannels { context.getString(R.string.notification_channel_network_available), NotificationManager.IMPORTANCE_LOW); networkAvailable.setBlockableSystem(true); - networkAvailable.setBypassDnd(true); channelsList.add(networkAvailable); final NotificationChannel vpn = new NotificationChannel( VPN, context.getString(R.string.notification_channel_vpn), NotificationManager.IMPORTANCE_LOW); - vpn.setBypassDnd(true); channelsList.add(vpn); final NotificationChannel deviceAdmin = new NotificationChannel( DEVICE_ADMIN, context.getString(R.string.notification_channel_device_admin), NotificationManager.IMPORTANCE_LOW); - deviceAdmin.setBypassDnd(true); channelsList.add(deviceAdmin); final NotificationChannel alertsChannel = new NotificationChannel( ALERTS, context.getString(R.string.notification_channel_alerts), NotificationManager.IMPORTANCE_DEFAULT); - alertsChannel.setBypassDnd(true); channelsList.add(alertsChannel); final NotificationChannel retail = new NotificationChannel( RETAIL_MODE, context.getString(R.string.notification_channel_retail_mode), NotificationManager.IMPORTANCE_LOW); - retail.setBypassDnd(true); channelsList.add(retail); final NotificationChannel usb = new NotificationChannel( USB, context.getString(R.string.notification_channel_usb), NotificationManager.IMPORTANCE_MIN); - usb.setBypassDnd(true); channelsList.add(usb); NotificationChannel foregroundChannel = new NotificationChannel( @@ -167,7 +154,6 @@ public class SystemNotificationChannels { context.getString(R.string.notification_channel_foreground_service), NotificationManager.IMPORTANCE_LOW); foregroundChannel.setBlockableSystem(true); - foregroundChannel.setBypassDnd(true); channelsList.add(foregroundChannel); NotificationChannel heavyWeightChannel = new NotificationChannel( @@ -179,19 +165,16 @@ public class SystemNotificationChannels { .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT) .build()); - heavyWeightChannel.setBypassDnd(true); channelsList.add(heavyWeightChannel); NotificationChannel systemChanges = new NotificationChannel(SYSTEM_CHANGES, context.getString(R.string.notification_channel_system_changes), NotificationManager.IMPORTANCE_LOW); - systemChanges.setBypassDnd(true); channelsList.add(systemChanges); NotificationChannel dndChanges = new NotificationChannel(DO_NOT_DISTURB, context.getString(R.string.notification_channel_do_not_disturb), NotificationManager.IMPORTANCE_LOW); - dndChanges.setBypassDnd(true); channelsList.add(dndChanges); nm.createNotificationChannels(channelsList); @@ -208,12 +191,10 @@ public class SystemNotificationChannels { } private static NotificationChannel newAccountChannel(Context context) { - final NotificationChannel acct = new NotificationChannel( + return new NotificationChannel( ACCOUNT, context.getString(R.string.notification_channel_account), NotificationManager.IMPORTANCE_LOW); - acct.setBypassDnd(true); - return acct; } private SystemNotificationChannels() {} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 87e6608a576a8..42c774ee0c5c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -179,11 +179,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private NotificationGuts mGuts; private NotificationData.Entry mEntry; private StatusBarNotification mStatusBarNotification; - /** - * Whether or not this row represents a system notification. Note that if this is {@code null}, - * that means we were either unable to retrieve the info or have yet to retrieve the info. - */ - private Boolean mIsSystemNotification; private String mAppName; private boolean mIsHeadsUp; private boolean mLastChronometerRunning = true; @@ -426,7 +421,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * once per notification as the packageInfo can't technically change for a notification row. */ private void cacheIsSystemNotification() { - if (mIsSystemNotification == null) { + if (mEntry != null && mEntry.mIsSystemNotification == null) { if (mSystemNotificationAsyncTask.getStatus() == AsyncTask.Status.PENDING) { // Run async task once, only if it hasn't already been executed. Note this is // executed in serial - no need to parallelize this small task. @@ -445,16 +440,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView // If the SystemNotifAsyncTask hasn't finished running or retrieved a value, we'll try once // again, but in-place on the main thread this time. This should rarely ever get called. - if (mIsSystemNotification == null) { + if (mEntry != null && mEntry.mIsSystemNotification == null) { if (DEBUG) { Log.d(TAG, "Retrieving isSystemNotification on main thread"); } mSystemNotificationAsyncTask.cancel(true /* mayInterruptIfRunning */); - mIsSystemNotification = isSystemNotification(mContext, mStatusBarNotification); + mEntry.mIsSystemNotification = isSystemNotification(mContext, mStatusBarNotification); } - if (!isNonblockable && mIsSystemNotification != null) { - if (mIsSystemNotification) { + if (!isNonblockable && mEntry != null && mEntry.mIsSystemNotification != null) { + if (mEntry.mIsSystemNotification) { if (mEntry.channel != null && !mEntry.channel.isBlockableSystem()) { isNonblockable = true; @@ -2875,7 +2870,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView @Override protected void onPostExecute(Boolean result) { - mIsSystemNotification = result; + if (mEntry != null) { + mEntry.mIsSystemNotification = result; + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index ab46b39a4ca34..37d92d92edfcf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -103,6 +103,12 @@ public class NotificationData { public ArraySet mActiveAppOps = new ArraySet<>(3); public CharSequence headsUpStatusBarText; public CharSequence headsUpStatusBarTextPublic; + /** + * Whether or not this row represents a system notification. Note that if this is + * {@code null}, that means we were either unable to retrieve the info or have yet to + * retrieve the info. + */ + public Boolean mIsSystemNotification; public Entry(StatusBarNotification n) { this.key = n.getKey(); @@ -435,31 +441,31 @@ public class NotificationData { return Ranking.VISIBILITY_NO_OVERRIDE; } - public boolean shouldSuppressFullScreenIntent(StatusBarNotification sbn) { - return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_FULL_SCREEN_INTENT); + public boolean shouldSuppressFullScreenIntent(Entry entry) { + return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_FULL_SCREEN_INTENT); } - public boolean shouldSuppressPeek(StatusBarNotification sbn) { - return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_PEEK); + public boolean shouldSuppressPeek(Entry entry) { + return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_PEEK); } - public boolean shouldSuppressStatusBar(StatusBarNotification sbn) { - return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_STATUS_BAR); + public boolean shouldSuppressStatusBar(Entry entry) { + return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_STATUS_BAR); } - public boolean shouldSuppressAmbient(StatusBarNotification sbn) { - return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_AMBIENT); + public boolean shouldSuppressAmbient(Entry entry) { + return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_AMBIENT); } - public boolean shouldSuppressNotificationList(StatusBarNotification sbn) { - return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_NOTIFICATION_LIST); + public boolean shouldSuppressNotificationList(Entry entry) { + return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_NOTIFICATION_LIST); } - private boolean shouldSuppressVisualEffect(StatusBarNotification sbn, int effect) { - if (isExemptFromDndVisualSuppression(sbn)) { + private boolean shouldSuppressVisualEffect(Entry entry, int effect) { + if (isExemptFromDndVisualSuppression(entry)) { return false; } - String key = sbn.getKey(); + String key = entry.key; if (mRankingMap != null) { getRanking(key, mTmpRanking); return (mTmpRanking.getSuppressedVisualEffects() & effect) != 0; @@ -467,11 +473,15 @@ public class NotificationData { return false; } - protected boolean isExemptFromDndVisualSuppression(StatusBarNotification sbn) { - if ((sbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) { + protected boolean isExemptFromDndVisualSuppression(Entry entry) { + if ((entry.notification.getNotification().flags + & Notification.FLAG_FOREGROUND_SERVICE) != 0) { return true; } - if (sbn.getNotification().isMediaNotification()) { + if (entry.notification.getNotification().isMediaNotification()) { + return true; + } + if (entry.mIsSystemNotification != null && entry.mIsSystemNotification) { return true; } return false; @@ -564,9 +574,8 @@ public class NotificationData { final int N = mEntries.size(); for (int i = 0; i < N; i++) { Entry entry = mEntries.valueAt(i); - StatusBarNotification sbn = entry.notification; - if (shouldFilterOut(sbn)) { + if (shouldFilterOut(entry)) { continue; } @@ -578,10 +587,10 @@ public class NotificationData { } /** - * @param sbn * @return true if this notification should NOT be shown right now */ - public boolean shouldFilterOut(StatusBarNotification sbn) { + public boolean shouldFilterOut(Entry entry) { + final StatusBarNotification sbn = entry.notification; if (!(mEnvironment.isDeviceProvisioned() || showNotificationEvenIfUnprovisioned(sbn))) { return true; @@ -598,11 +607,11 @@ public class NotificationData { return true; } - if (mEnvironment.isDozing() && shouldSuppressAmbient(sbn)) { + if (mEnvironment.isDozing() && shouldSuppressAmbient(entry)) { return true; } - if (!mEnvironment.isDozing() && shouldSuppressNotificationList(sbn)) { + if (!mEnvironment.isDozing() && shouldSuppressNotificationList(entry)) { return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java index 849cfdd9f7504..6437a3a4e89bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java @@ -300,12 +300,12 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. updateNotifications(); } - private boolean shouldSuppressFullScreenIntent(StatusBarNotification sbn) { + private boolean shouldSuppressFullScreenIntent(NotificationData.Entry entry) { if (mPresenter.isDeviceInVrMode()) { return true; } - return mNotificationData.shouldSuppressFullScreenIntent(sbn); + return mNotificationData.shouldSuppressFullScreenIntent(entry); } private void inflateViews(NotificationData.Entry entry, ViewGroup parent) { @@ -692,7 +692,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. NotificationData.Entry shadeEntry = createNotificationViews(notification); boolean isHeadsUped = shouldPeek(shadeEntry); if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) { - if (shouldSuppressFullScreenIntent(notification)) { + if (shouldSuppressFullScreenIntent(shadeEntry)) { if (DEBUG) { Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + key); } @@ -848,7 +848,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. return false; } - if (mNotificationData.shouldFilterOut(sbn)) { + if (mNotificationData.shouldFilterOut(entry)) { if (DEBUG) Log.d(TAG, "No peeking: filtered notification: " + sbn.getKey()); return false; } @@ -862,13 +862,13 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. return false; } - if (!mPresenter.isDozing() && mNotificationData.shouldSuppressPeek(sbn)) { + if (!mPresenter.isDozing() && mNotificationData.shouldSuppressPeek(entry)) { if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey()); return false; } // Peeking triggers an ambient display pulse, so disable peek is ambient is active - if (mPresenter.isDozing() && mNotificationData.shouldSuppressAmbient(sbn)) { + if (mPresenter.isDozing() && mNotificationData.shouldSuppressAmbient(entry)) { if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey()); return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index 6bc19ea69be72..b043100d7b08a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -156,8 +156,7 @@ public class NotificationIconAreaController implements DarkReceiver { } // showAmbient == show in shade but not shelf - if (!showAmbient && mEntryManager.getNotificationData().shouldSuppressStatusBar( - entry.notification)) { + if (!showAmbient && mEntryManager.getNotificationData().shouldSuppressStatusBar(entry)) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java index 7a9cdfd85645f..67fa049d688ff 100644 --- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java +++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java @@ -51,19 +51,16 @@ public class NotificationChannels extends SystemUI { .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT) .build()); batteryChannel.setBlockableSystem(true); - batteryChannel.setBypassDnd(true); final NotificationChannel alerts = new NotificationChannel( ALERTS, context.getString(R.string.notification_channel_alerts), NotificationManager.IMPORTANCE_HIGH); - alerts.setBypassDnd(true); final NotificationChannel general = new NotificationChannel( GENERAL, context.getString(R.string.notification_channel_general), NotificationManager.IMPORTANCE_MIN); - general.setBypassDnd(true); final NotificationChannel storage = new NotificationChannel( STORAGE, @@ -71,7 +68,6 @@ public class NotificationChannels extends SystemUI { isTv(context) ? NotificationManager.IMPORTANCE_DEFAULT : NotificationManager.IMPORTANCE_LOW); - storage.setBypassDnd(true); final NotificationChannel hint = new NotificationChannel( HINTS, @@ -119,7 +115,6 @@ public class NotificationChannels extends SystemUI { screenshotChannel.setSound(Uri.parse(""), // silent new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); - screenshotChannel.setBypassDnd(true); screenshotChannel.setBlockableSystem(true); if (legacySS != null) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java index 5ec77acfa7283..d3c3746761aad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java @@ -210,7 +210,7 @@ public class NotificationDataTest extends SysuiTestCase { bundle.putStringArray(Notification.EXTRA_FOREGROUND_APPS, new String[] {"something"}); sbn.getNotification().extras = bundle; - assertTrue(mNotificationData.shouldFilterOut(mRow.getEntry().notification)); + assertTrue(mNotificationData.shouldFilterOut(mRow.getEntry())); } @Test @@ -223,17 +223,17 @@ public class NotificationDataTest extends SysuiTestCase { when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true); when(mFsc.isSystemAlertNotification(any())).thenReturn(true); - assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification)); + assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry())); when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true); when(mFsc.isSystemAlertNotification(any())).thenReturn(false); - assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification)); + assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry())); when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false); when(mFsc.isSystemAlertNotification(any())).thenReturn(false); - assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification)); + assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry())); } @Test @@ -241,7 +241,7 @@ public class NotificationDataTest extends SysuiTestCase { when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true); // missing extra - assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification)); + assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry())); StatusBarNotification sbn = mRow.getEntry().notification; Bundle bundle = new Bundle(); @@ -249,7 +249,7 @@ public class NotificationDataTest extends SysuiTestCase { sbn.getNotification().extras = bundle; // extra missing values - assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification)); + assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry())); } @Test @@ -262,11 +262,13 @@ public class NotificationDataTest extends SysuiTestCase { // test should filter out hidden notifications: // hidden when(mMockStatusBarNotification.getKey()).thenReturn(TEST_HIDDEN_NOTIFICATION_KEY); - assertTrue(mNotificationData.shouldFilterOut(mMockStatusBarNotification)); + NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification); + assertTrue(mNotificationData.shouldFilterOut(entry)); // not hidden when(mMockStatusBarNotification.getKey()).thenReturn("not hidden"); - assertFalse(mNotificationData.shouldFilterOut(mMockStatusBarNotification)); + entry = new NotificationData.Entry(mMockStatusBarNotification); + assertFalse(mNotificationData.shouldFilterOut(entry)); } @Test @@ -276,9 +278,10 @@ public class NotificationDataTest extends SysuiTestCase { TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY); Notification n = mMockStatusBarNotification.getNotification(); n.flags = Notification.FLAG_FOREGROUND_SERVICE; + NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification); - assertTrue(mNotificationData.isExemptFromDndVisualSuppression(mMockStatusBarNotification)); - assertFalse(mNotificationData.shouldSuppressAmbient(mMockStatusBarNotification)); + assertTrue(mNotificationData.isExemptFromDndVisualSuppression(entry)); + assertFalse(mNotificationData.shouldSuppressAmbient(entry)); } @Test @@ -291,9 +294,22 @@ public class NotificationDataTest extends SysuiTestCase { nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class))); n = nb.build(); when(mMockStatusBarNotification.getNotification()).thenReturn(n); + NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification); - assertTrue(mNotificationData.isExemptFromDndVisualSuppression(mMockStatusBarNotification)); - assertFalse(mNotificationData.shouldSuppressAmbient(mMockStatusBarNotification)); + assertTrue(mNotificationData.isExemptFromDndVisualSuppression(entry)); + assertFalse(mNotificationData.shouldSuppressAmbient(entry)); + } + + @Test + public void testIsExemptFromDndVisualSuppression_system() { + initStatusBarNotification(false); + when(mMockStatusBarNotification.getKey()).thenReturn( + TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY); + NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification); + entry.mIsSystemNotification = true; + + assertTrue(mNotificationData.isExemptFromDndVisualSuppression(entry)); + assertFalse(mNotificationData.shouldSuppressAmbient(entry)); } private void initStatusBarNotification(boolean allowDuringSetup) {