Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b1cbfce authored by Matías Hernández's avatar Matías Hernández Committed by Android (Google) Code Review
Browse files

Merge "Compare small and large icons as part of isVisuallyInterruptive()" into udc-dev

parents ddc3a0e9 716cf15b
Loading
Loading
Loading
Loading
+38 −28
Original line number Diff line number Diff line
@@ -3266,6 +3266,43 @@ public class Notification implements Parcelable
        return false;
    }
    /**
     * @hide
     */
    public static boolean areIconsDifferent(Notification first, Notification second) {
        return areIconsMaybeDifferent(first.getSmallIcon(), second.getSmallIcon())
                || areIconsMaybeDifferent(first.getLargeIcon(), second.getLargeIcon());
    }
    /**
     * Note that we aren't actually comparing the contents of the bitmaps here; this is only a
     * cursory inspection. We will not return false negatives, but false positives are likely.
     */
    private static boolean areIconsMaybeDifferent(Icon a, Icon b) {
        if (a == b) {
            return false;
        }
        if (a == null || b == null) {
            return true;
        }
        if (a.sameAs(b)) {
            return false;
        }
        final int aType = a.getType();
        if (aType != b.getType()) {
            return true;
        }
        if (aType == Icon.TYPE_BITMAP || aType == Icon.TYPE_ADAPTIVE_BITMAP) {
            final Bitmap aBitmap = a.getBitmap();
            final Bitmap bBitmap = b.getBitmap();
            return aBitmap.getWidth() != bBitmap.getWidth()
                    || aBitmap.getHeight() != bBitmap.getHeight()
                    || aBitmap.getConfig() != bBitmap.getConfig()
                    || aBitmap.getGenerationId() != bBitmap.getGenerationId();
        }
        return true;
    }
    /**
     * @hide
     */
@@ -7643,8 +7680,6 @@ public class Notification implements Parcelable
        /**
         * @hide
         * Note that we aren't actually comparing the contents of the bitmaps here, so this
         * is only doing a cursory inspection. Bitmaps of equal size will appear the same.
         */
        @Override
        public boolean areNotificationsVisiblyDifferent(Style other) {
@@ -7652,32 +7687,7 @@ public class Notification implements Parcelable
                return true;
            }
            BigPictureStyle otherS = (BigPictureStyle) other;
            return areIconsObviouslyDifferent(getBigPicture(), otherS.getBigPicture());
        }
        private static boolean areIconsObviouslyDifferent(Icon a, Icon b) {
            if (a == b) {
                return false;
            }
            if (a == null || b == null) {
                return true;
            }
            if (a.sameAs(b)) {
                return false;
            }
            final int aType = a.getType();
            if (aType != b.getType()) {
                return true;
            }
            if (aType == Icon.TYPE_BITMAP || aType == Icon.TYPE_ADAPTIVE_BITMAP) {
                final Bitmap aBitmap = a.getBitmap();
                final Bitmap bBitmap = b.getBitmap();
                return aBitmap.getWidth() != bBitmap.getWidth()
                        || aBitmap.getHeight() != bBitmap.getHeight()
                        || aBitmap.getConfig() != bBitmap.getConfig()
                        || aBitmap.getGenerationId() != bBitmap.getGenerationId();
            }
            return true;
            return areIconsMaybeDifferent(getBigPicture(), otherS.getBigPicture());
        }
    }
+63 −1
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.annotation.Nullable;
import android.app.Notification.CallStyle;
import android.content.Context;
import android.content.Intent;
import android.content.LocusId;
@@ -1038,6 +1037,69 @@ public class NotificationTest {
        Assert.assertEquals("dismiss", new Notification.WearableExtender(before).getDismissalId());
    }

    @Test
    public void areIconsDifferent_sameSmallIcon_false() {
        Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build();
        Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(1).build();

        assertThat(Notification.areIconsDifferent(n1, n2)).isFalse();
    }

    @Test
    public void areIconsDifferent_differentSmallIcon_true() {
        Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build();
        Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(2).build();

        assertThat(Notification.areIconsDifferent(n1, n2)).isTrue();
    }

    @Test
    public void areIconsDifferent_sameLargeIcon_false() {
        Icon icon1 = Icon.createWithContentUri("uri");
        Icon icon2 = Icon.createWithContentUri("uri");
        Notification n1 = new Notification.Builder(mContext, "test")
                .setSmallIcon(1).setLargeIcon(icon1).build();
        Notification n2 = new Notification.Builder(mContext, "test")
                .setSmallIcon(1).setLargeIcon(icon2).build();

        // Note that this will almost certainly not happen for Icons created from Bitmaps, since
        // their serialization/deserialization of Bitmaps (app -> system_process) results in a
        // different getGenerationId() value. :(
        assertThat(Notification.areIconsDifferent(n1, n2)).isFalse();
    }

    @Test
    public void areIconsDifferent_differentLargeIcon_true() {
        Icon icon1 = Icon.createWithContentUri("uri1");
        Icon icon2 = Icon.createWithContentUri("uri2");
        Notification n1 = new Notification.Builder(mContext, "test")
                .setSmallIcon(1).setLargeIcon(icon1).build();
        Notification n2 = new Notification.Builder(mContext, "test")
                .setSmallIcon(2).setLargeIcon(icon2).build();

        assertThat(Notification.areIconsDifferent(n1, n2)).isTrue();
    }

    @Test
    public void areIconsDifferent_addedLargeIcon_true() {
        Icon icon = Icon.createWithContentUri("uri");
        Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build();
        Notification n2 = new Notification.Builder(mContext, "test")
                .setSmallIcon(2).setLargeIcon(icon).build();

        assertThat(Notification.areIconsDifferent(n1, n2)).isTrue();
    }

    @Test
    public void areIconsDifferent_removedLargeIcon_true() {
        Icon icon = Icon.createWithContentUri("uri");
        Notification n1 = new Notification.Builder(mContext, "test")
                .setSmallIcon(1).setLargeIcon(icon).build();
        Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(2).build();

        assertThat(Notification.areIconsDifferent(n1, n2)).isTrue();
    }

    @Test
    public void testStyleChangeVisiblyDifferent_noStyles() {
        Notification.Builder n1 = new Notification.Builder(mContext, "test");
+10 −9
Original line number Diff line number Diff line
@@ -7803,7 +7803,8 @@ public class NotificationManagerService extends SystemService {
     */
    @GuardedBy("mNotificationLock")
    @VisibleForTesting
    protected boolean isVisuallyInterruptive(NotificationRecord old, NotificationRecord r) {
    protected boolean isVisuallyInterruptive(@Nullable NotificationRecord old,
            @NonNull NotificationRecord r) {
        // Ignore summary updates because we don't display most of the information.
        if (r.getSbn().isGroup() && r.getSbn().getNotification().isGroupSummary()) {
            if (DEBUG_INTERRUPTIVENESS) {
@@ -7821,14 +7822,6 @@ public class NotificationManagerService extends SystemService {
            return true;
        }
        if (r == null) {
            if (DEBUG_INTERRUPTIVENESS) {
                Slog.v(TAG, "INTERRUPTIVENESS: "
                        +  r.getKey() + " is not interruptive: null");
            }
            return false;
        }
        Notification oldN = old.getSbn().getNotification();
        Notification newN = r.getSbn().getNotification();
        if (oldN.extras == null || newN.extras == null) {
@@ -7886,6 +7879,14 @@ public class NotificationManagerService extends SystemService {
            return true;
        }
        if (Notification.areIconsDifferent(oldN, newN)) {
            if (DEBUG_INTERRUPTIVENESS) {
                Slog.v(TAG, "INTERRUPTIVENESS: "
                        +  r.getKey() + " is interruptive: icons differ");
            }
            return true;
        }
        // Fields below are invisible to bubbles.
        if (r.canBubble()) {
            if (DEBUG_INTERRUPTIVENESS) {
+51 −0
Original line number Diff line number Diff line
@@ -5840,6 +5840,57 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertFalse(mService.isVisuallyInterruptive(null, r2));
    }

    @Test
    public void testVisualDifference_sameImages() {
        Icon large = Icon.createWithResource(mContext, 1);
        Notification n1 = new Notification.Builder(mContext, "channel")
                .setSmallIcon(1).setLargeIcon(large).build();
        Notification n2 = new Notification.Builder(mContext, "channel")
                .setSmallIcon(1).setLargeIcon(large).build();

        NotificationRecord r1 = notificationToRecord(n1);
        NotificationRecord r2 = notificationToRecord(n2);

        assertThat(mService.isVisuallyInterruptive(r1, r2)).isFalse();
    }

    @Test
    public void testVisualDifference_differentSmallImage() {
        Icon large = Icon.createWithResource(mContext, 1);
        Notification n1 = new Notification.Builder(mContext, "channel")
                .setSmallIcon(1).setLargeIcon(large).build();
        Notification n2 = new Notification.Builder(mContext, "channel")
                .setSmallIcon(2).setLargeIcon(large).build();

        NotificationRecord r1 = notificationToRecord(n1);
        NotificationRecord r2 = notificationToRecord(n2);

        assertThat(mService.isVisuallyInterruptive(r1, r2)).isTrue();
    }

    @Test
    public void testVisualDifference_differentLargeImage() {
        Icon large1 = Icon.createWithResource(mContext, 1);
        Icon large2 = Icon.createWithResource(mContext, 2);
        Notification n1 = new Notification.Builder(mContext, "channel")
                .setSmallIcon(1).setLargeIcon(large1).build();
        Notification n2 = new Notification.Builder(mContext, "channel")
                .setSmallIcon(1).setLargeIcon(large2).build();

        NotificationRecord r1 = notificationToRecord(n1);
        NotificationRecord r2 = notificationToRecord(n2);

        assertThat(mService.isVisuallyInterruptive(r1, r2)).isTrue();
    }

    private NotificationRecord notificationToRecord(Notification n) {
        return new NotificationRecord(
                mContext,
                new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0, n,
                        UserHandle.getUserHandleForUid(mUid), null, 0),
                mock(NotificationChannel.class));
    }

    @Test
    public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
        // post 2 notification from this package