Merge "Exempt some notis from DND visual suppression" into pi-dev am: a000724a83
am: 94c5dd2157

Change-Id: I0ad56197659cfc945dc9d78ceb32406e271e8cae
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 402d9fdd..4b6ab64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -18,25 +18,21 @@
 
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
 
+import android.Manifest;
 import android.app.AppGlobals;
-import android.app.AppOpsManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
+import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.Context;
 import android.graphics.drawable.Icon;
-import android.os.AsyncTask;
-import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.SnoozeCriterion;
@@ -46,10 +42,8 @@
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.RemoteViews;
-import android.Manifest;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.Dependency;
@@ -454,47 +448,44 @@
         return Ranking.VISIBILITY_NO_OVERRIDE;
     }
 
-    public boolean shouldSuppressFullScreenIntent(String key) {
+    public boolean shouldSuppressFullScreenIntent(StatusBarNotification sbn) {
+        return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
+    }
+
+    public boolean shouldSuppressPeek(StatusBarNotification sbn) {
+        return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_PEEK);
+    }
+
+    public boolean shouldSuppressStatusBar(StatusBarNotification sbn) {
+        return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_STATUS_BAR);
+    }
+
+    public boolean shouldSuppressAmbient(StatusBarNotification sbn) {
+        return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_AMBIENT);
+    }
+
+    public boolean shouldSuppressNotificationList(StatusBarNotification sbn) {
+        return shouldSuppressVisualEffect(sbn, SUPPRESSED_EFFECT_NOTIFICATION_LIST);
+    }
+
+    private boolean shouldSuppressVisualEffect(StatusBarNotification sbn, int effect) {
+        if (isExemptFromDndVisualSuppression(sbn)) {
+            return false;
+        }
+        String key = sbn.getKey();
         if (mRankingMap != null) {
             getRanking(key, mTmpRanking);
-            return (mTmpRanking.getSuppressedVisualEffects()
-                    & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) != 0;
+            return (mTmpRanking.getSuppressedVisualEffects() & effect) != 0;
         }
         return false;
     }
 
-    public boolean shouldSuppressPeek(String key) {
-        if (mRankingMap != null) {
-            getRanking(key, mTmpRanking);
-            return (mTmpRanking.getSuppressedVisualEffects()
-                    & SUPPRESSED_EFFECT_PEEK) != 0;
+    protected boolean isExemptFromDndVisualSuppression(StatusBarNotification sbn) {
+        if ((sbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+            return true;
         }
-        return false;
-    }
-
-    public boolean shouldSuppressStatusBar(String key) {
-        if (mRankingMap != null) {
-            getRanking(key, mTmpRanking);
-            return (mTmpRanking.getSuppressedVisualEffects()
-                    & SUPPRESSED_EFFECT_STATUS_BAR) != 0;
-        }
-        return false;
-    }
-
-    public boolean shouldSuppressAmbient(String key) {
-        if (mRankingMap != null) {
-            getRanking(key, mTmpRanking);
-            return (mTmpRanking.getSuppressedVisualEffects()
-                    & SUPPRESSED_EFFECT_AMBIENT) != 0;
-        }
-        return false;
-    }
-
-    public boolean shouldSuppressNotificationList(String key) {
-        if (mRankingMap != null) {
-            getRanking(key, mTmpRanking);
-            return (mTmpRanking.getSuppressedVisualEffects()
-                    & SUPPRESSED_EFFECT_NOTIFICATION_LIST) != 0;
+        if (sbn.getNotification().isMediaNotification()) {
+            return true;
         }
         return false;
     }
@@ -620,11 +611,11 @@
             return true;
         }
 
-        if (mEnvironment.isDozing() && shouldSuppressAmbient(sbn.getKey())) {
+        if (mEnvironment.isDozing() && shouldSuppressAmbient(sbn)) {
             return true;
         }
 
-        if (!mEnvironment.isDozing() && shouldSuppressNotificationList(sbn.getKey())) {
+        if (!mEnvironment.isDozing() && shouldSuppressNotificationList(sbn)) {
             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 7a7cc99..45df450 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
@@ -299,12 +299,12 @@
         updateNotifications();
     }
 
-    private boolean shouldSuppressFullScreenIntent(String key) {
+    private boolean shouldSuppressFullScreenIntent(StatusBarNotification sbn) {
         if (mPresenter.isDeviceInVrMode()) {
             return true;
         }
 
-        return mNotificationData.shouldSuppressFullScreenIntent(key);
+        return mNotificationData.shouldSuppressFullScreenIntent(sbn);
     }
 
     private void inflateViews(NotificationData.Entry entry, ViewGroup parent) {
@@ -690,7 +690,7 @@
         NotificationData.Entry shadeEntry = createNotificationViews(notification);
         boolean isHeadsUped = shouldPeek(shadeEntry);
         if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
-            if (shouldSuppressFullScreenIntent(key)) {
+            if (shouldSuppressFullScreenIntent(notification)) {
                 if (DEBUG) {
                     Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + key);
                 }
@@ -846,13 +846,13 @@
             return false;
         }
 
-        if (!mPresenter.isDozing() && mNotificationData.shouldSuppressPeek(sbn.getKey())) {
+        if (!mPresenter.isDozing() && mNotificationData.shouldSuppressPeek(sbn)) {
             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.getKey())) {
+        if (mPresenter.isDozing() && mNotificationData.shouldSuppressAmbient(sbn)) {
             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 9063dea..b6a11f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -150,7 +150,7 @@
 
         // showAmbient == show in shade but not shelf
         if (!showAmbient && mEntryManager.getNotificationData().shouldSuppressStatusBar(
-                entry.key)) {
+                entry.notification)) {
             return false;
         }
 
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 c437021..5e27fde 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
@@ -35,6 +35,7 @@
 import android.app.NotificationChannel;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.media.session.MediaSession;
 import android.os.Bundle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
@@ -61,6 +62,7 @@
     private static final int UID_NORMAL = 123;
     private static final int UID_ALLOW_DURING_SETUP = 456;
     private static final String TEST_HIDDEN_NOTIFICATION_KEY = "testHiddenNotificationKey";
+    private static final String TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY = "exempt";
 
     private final StatusBarNotification mMockStatusBarNotification =
             mock(StatusBarNotification.class);
@@ -275,6 +277,7 @@
 
     @Test
     public void testShouldFilterHiddenNotifications() {
+        initStatusBarNotification(false);
         // setup
         when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
         when(mFsc.isSystemAlertNotification(any())).thenReturn(false);
@@ -289,6 +292,33 @@
         assertFalse(mNotificationData.shouldFilterOut(mMockStatusBarNotification));
     }
 
+    @Test
+    public void testIsExemptFromDndVisualSuppression_foreground() {
+        initStatusBarNotification(false);
+        when(mMockStatusBarNotification.getKey()).thenReturn(
+                TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY);
+        Notification n = mMockStatusBarNotification.getNotification();
+        n.flags = Notification.FLAG_FOREGROUND_SERVICE;
+
+        assertTrue(mNotificationData.isExemptFromDndVisualSuppression(mMockStatusBarNotification));
+        assertFalse(mNotificationData.shouldSuppressAmbient(mMockStatusBarNotification));
+    }
+
+    @Test
+    public void testIsExemptFromDndVisualSuppression_media() {
+        initStatusBarNotification(false);
+        when(mMockStatusBarNotification.getKey()).thenReturn(
+                TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY);
+        Notification n = mMockStatusBarNotification.getNotification();
+        Notification.Builder nb = Notification.Builder.recoverBuilder(mContext, n);
+        nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
+        n = nb.build();
+        when(mMockStatusBarNotification.getNotification()).thenReturn(n);
+
+        assertTrue(mNotificationData.isExemptFromDndVisualSuppression(mMockStatusBarNotification));
+        assertFalse(mNotificationData.shouldSuppressAmbient(mMockStatusBarNotification));
+    }
+
     private void initStatusBarNotification(boolean allowDuringSetup) {
         Bundle bundle = new Bundle();
         bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup);
@@ -318,6 +348,13 @@
                         outRanking.getImportance(), outRanking.getImportanceExplanation(),
                         outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
                         outRanking.canShowBadge(), outRanking.getUserSentiment(), true);
+            } else if (key.equals(TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY)) {
+                outRanking.populate(key, outRanking.getRank(),
+                        outRanking.matchesInterruptionFilter(),
+                        outRanking.getVisibilityOverride(), 255,
+                        outRanking.getImportance(), outRanking.getImportanceExplanation(),
+                        outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
+                        outRanking.canShowBadge(), outRanking.getUserSentiment(), true);
             } else {
                 outRanking.populate(key, outRanking.getRank(),
                         outRanking.matchesInterruptionFilter(),