Merge "more precise definition for undecorated remoteviews" into qt-qpr1-dev am: 90387eb27f

Change-Id: I118196d4578af0d0c2cf426068a288dd82731aba
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 3c2169a..c46aad9 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -1289,6 +1289,18 @@
         return getLogMaker().setCategory(MetricsEvent.NOTIFICATION_ITEM);
     }
 
+    public boolean hasUndecoratedRemoteView() {
+        Notification notification = getNotification();
+        Class<? extends Notification.Style> style = notification.getNotificationStyle();
+        boolean hasDecoratedStyle = style != null
+                && (Notification.DecoratedCustomViewStyle.class.equals(style)
+                || Notification.DecoratedMediaCustomViewStyle.class.equals(style));
+        boolean hasCustomRemoteView = notification.contentView != null
+                || notification.bigContentView != null
+                || notification.headsUpContentView != null;
+        return hasCustomRemoteView && !hasDecoratedStyle;
+    }
+
     @VisibleForTesting
     static final class Light {
         public final int color;
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index ba7820e..fbf9934 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -150,7 +150,7 @@
             stats.numPostedByApp++;
             stats.updateInterarrivalEstimate(now);
             stats.countApiUse(notification);
-            stats.numUndecoratedRemoteViews += (isUndecoratedRemoteView(notification) ? 1 : 0);
+            stats.numUndecoratedRemoteViews += (notification.hasUndecoratedRemoteView() ? 1 : 0);
         }
         releaseAggregatedStatsLocked(aggregatedStatsArray);
         if (ENABLE_SQLITE_LOG) {
@@ -159,13 +159,6 @@
     }
 
     /**
-     * Does this notification use RemoveViews without a platform decoration?
-     */
-    protected static boolean isUndecoratedRemoteView(NotificationRecord notification) {
-        return (notification.getNotification().getNotificationStyle() == null);
-    }
-
-    /**
      * Called when a notification has been updated.
      */
     public synchronized void registerUpdatedByApp(NotificationRecord notification,
@@ -1287,7 +1280,7 @@
             } else {
                 putPosttimeVisibility(r, cv);
             }
-            cv.put(COL_UNDECORATED, (isUndecoratedRemoteView(r) ? 1 : 0));
+            cv.put(COL_UNDECORATED, (r.hasUndecoratedRemoteView() ? 1 : 0));
             SQLiteDatabase db = mHelper.getWritableDatabase();
             if (db.insert(TAB_LOG, null, cv) < 0) {
                 Log.wtf(TAG, "Error while trying to insert values: " + cv);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index 7c22350..fab6b7f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -52,11 +52,13 @@
 import android.media.AudioAttributes;
 import android.metrics.LogMaker;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.Adjustment;
 import android.service.notification.StatusBarNotification;
+import android.widget.RemoteViews;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -114,7 +116,9 @@
 
         when(mMockContext.getResources()).thenReturn(getContext().getResources());
         when(mMockContext.getPackageManager()).thenReturn(mPm);
-        when(mMockContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
+        ApplicationInfo appInfo = new ApplicationInfo();
+        appInfo.targetSdkVersion = Build.VERSION_CODES.O;
+        when(mMockContext.getApplicationInfo()).thenReturn(appInfo);
     }
 
     private StatusBarNotification getNotification(String pkg, boolean noisy, boolean defaultSound,
@@ -168,6 +172,28 @@
         return new StatusBarNotification(pkg, pkg, id1, tag1, uid, uid, n, mUser, null, uid);
     }
 
+    private StatusBarNotification getStyledNotification(boolean customContent, boolean customBig,
+            boolean customHeadsUp, Notification.Style style) {
+        final Builder builder = new Builder(mMockContext)
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+        if (style != null) {
+            builder.setStyle(style);
+        }
+        if (customContent) {
+            builder.setCustomContentView(mock(RemoteViews.class));
+        }
+        if (customBig) {
+            builder.setCustomBigContentView(mock(RemoteViews.class));
+        }
+        if (customHeadsUp) {
+            builder.setCustomHeadsUpContentView(mock(RemoteViews.class));
+        }
+
+        Notification n = builder.build();
+        return new StatusBarNotification(pkg, pkg, id1, tag1, uid, uid, n, mUser, null, uid);
+    }
+
     //
     // Tests
     //
@@ -999,4 +1025,74 @@
 
         assertEquals(IMPORTANCE_LOW, record.getImportance());
     }
+
+    @Test
+    public void testHasUndecoratedRemoteViews_NoRemoteViews() {
+        StatusBarNotification sbn = getStyledNotification(false, false, false, null);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertFalse("false positive detection", record.hasUndecoratedRemoteView());
+    }
+
+    @Test
+    public void testHasUndecoratedRemoteViews_NoRemoteViewsWithStyle() {
+        StatusBarNotification sbn = getStyledNotification(false, false, false,
+                new Notification.BigPictureStyle());
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertFalse("false positive detection", record.hasUndecoratedRemoteView());
+    }
+
+    @Test
+    public void testHasUndecoratedRemoteViews_UndecoratedContent() {
+        StatusBarNotification sbn = getStyledNotification(true, false, false, null);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertTrue("false negative detection", record.hasUndecoratedRemoteView());
+    }
+
+
+    @Test
+    public void testHasUndecoratedRemoteViews_UndecoratedBig() {
+        StatusBarNotification sbn = getStyledNotification(false, true, false, null);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertTrue("false negative detection", record.hasUndecoratedRemoteView());
+    }
+
+
+    @Test
+    public void testHasUndecoratedRemoteViews_UndecoratedHeadsup() {
+        StatusBarNotification sbn = getStyledNotification(false, false, true, null);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertTrue("false negative detection", record.hasUndecoratedRemoteView());
+    }
+
+    @Test
+    public void testHasUndecoratedRemoteViews_DecoratedRemoteViews() {
+        StatusBarNotification sbn = getStyledNotification(true, true, true,
+                new Notification.DecoratedCustomViewStyle());
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertFalse("false positive detection", record.hasUndecoratedRemoteView());
+    }
+
+    @Test
+    public void testHasUndecoratedRemoteViews_DecoratedMediaRemoteViews() {
+        StatusBarNotification sbn = getStyledNotification(true, true, true,
+                new Notification.DecoratedMediaCustomViewStyle());
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertFalse("false positive detection", record.hasUndecoratedRemoteView());
+    }
+
+    @Test
+    public void testHasUndecoratedRemoteViews_UndecoratedWrongStyle() {
+        StatusBarNotification sbn = getStyledNotification(true, true, true,
+                new Notification.BigPictureStyle());
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertTrue("false negative detection", record.hasUndecoratedRemoteView());
+    }
 }