RankingHelperTest.java revision 60315337024c9ab7dc81f269c676bb8fc17e0700
16b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown/*
26b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * Copyright (C) 2014 The Android Open Source Project
36b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown *
46b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
56b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * you may not use this file except in compliance with the License.
66b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * You may obtain a copy of the License at
76b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown *
86b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
96b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown *
106b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * Unless required by applicable law or agreed to in writing, software
116b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
126b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * See the License for the specific language governing permissions and
146b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * limitations under the License.
156b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown */
166b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownpackage com.android.server.notification;
176b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
186b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static android.app.NotificationManager.IMPORTANCE_DEFAULT;
196b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static android.app.NotificationManager.IMPORTANCE_HIGH;
206b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static android.app.NotificationManager.IMPORTANCE_LOW;
216b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
22061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brownimport static junit.framework.Assert.assertNull;
23061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brownimport static junit.framework.Assert.fail;
246b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
256b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.json.JSONArray;
266b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.json.JSONObject;
276b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.junit.Before;
286b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.junit.Test;
296b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.junit.runner.RunWith;
306b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
316b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport com.android.internal.util.FastXmlSerializer;
326b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
336b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.mockito.Mock;
346b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.mockito.MockitoAnnotations;
356b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.xmlpull.v1.XmlPullParser;
366b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport org.xmlpull.v1.XmlSerializer;
376b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
386b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.app.Notification;
396b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.app.NotificationChannelGroup;
4049ed71db425c5054e3ad9526496a7e116c89556bJeff Brownimport android.content.Context;
4149ed71db425c5054e3ad9526496a7e116c89556bJeff Brownimport android.app.NotificationChannel;
426b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.app.NotificationManager;
436b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.content.pm.ApplicationInfo;
446b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.content.pm.PackageManager;
456b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.graphics.Color;
466b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.media.AudioAttributes;
476b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.net.Uri;
486b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.os.Build;
496b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.os.UserHandle;
506b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.service.notification.StatusBarNotification;
516b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.support.test.InstrumentationRegistry;
526b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.support.test.runner.AndroidJUnit4;
536b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.test.suitebuilder.annotation.SmallTest;
5449ed71db425c5054e3ad9526496a7e116c89556bJeff Brownimport android.util.ArrayMap;
556b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.util.Xml;
566b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
576b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.io.BufferedInputStream;
586b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.io.BufferedOutputStream;
596b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.io.ByteArrayInputStream;
606b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.io.ByteArrayOutputStream;
616b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.util.ArrayList;
626b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.util.Arrays;
636b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.util.HashMap;
646b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.util.List;
656b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.util.Map;
666b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.util.Objects;
676b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport java.util.concurrent.ThreadLocalRandom;
686b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
696b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static org.junit.Assert.assertEquals;
706b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static org.junit.Assert.assertFalse;
716b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static org.junit.Assert.assertNotNull;
726b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static org.junit.Assert.assertTrue;
736b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static org.mockito.Matchers.anyInt;
746b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static org.mockito.Matchers.anyString;
756b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static org.mockito.Matchers.eq;
766b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport static org.mockito.Mockito.when;
776b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
786b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown@SmallTest
7949ed71db425c5054e3ad9526496a7e116c89556bJeff Brown@RunWith(AndroidJUnit4.class)
806b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownpublic class RankingHelperTest {
816b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private static final String PKG = "com.android.server.notification";
826b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private static final int UID = 0;
836b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private static final String UPDATED_PKG = "updatedPkg";
846b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private static final int UID2 = 1111111;
856b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private static final String TEST_CHANNEL_ID = "test_channel_id";
866b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
876b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Mock NotificationUsageStats mUsageStats;
886b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Mock RankingHandler mHandler;
896b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Mock PackageManager mPm;
906b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
916b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private Notification mNotiGroupGSortA;
926b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private Notification mNotiGroupGSortB;
936b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private Notification mNotiNoGroup;
946b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private Notification mNotiNoGroup2;
956b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private Notification mNotiNoGroupSortA;
966b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private NotificationRecord mRecordGroupGSortA;
976b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private NotificationRecord mRecordGroupGSortB;
986b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private NotificationRecord mRecordNoGroup;
996b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private NotificationRecord mRecordNoGroup2;
1006b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private NotificationRecord mRecordNoGroupSortA;
1016b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private RankingHelper mHelper;
1026b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private AudioAttributes mAudioAttributes;
1036b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1046b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private Context getContext() {
1056b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        return InstrumentationRegistry.getTargetContext();
1066b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
1076b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1086b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Before
1096b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void setUp() throws Exception {
11049ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        MockitoAnnotations.initMocks(this);
1116b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        UserHandle user = UserHandle.ALL;
1126b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1136b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper = new RankingHelper(getContext(), mPm, mHandler, mUsageStats,
1146b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                new String[] {ImportanceExtractor.class.getName()});
1156b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1166b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mNotiGroupGSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
1176b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setContentTitle("A")
1186b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setGroup("G")
1196b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setSortKey("A")
1206b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setWhen(1205)
1216b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .build();
1226b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
1236b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                "package", "package", 1, null, 0, 0, mNotiGroupGSortA, user,
1246b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                null, System.currentTimeMillis()), getDefaultChannel());
1256b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1266b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mNotiGroupGSortB = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
1276b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setContentTitle("B")
1286b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setGroup("G")
1296b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setSortKey("B")
1306b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setWhen(1200)
1316b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .build();
1326b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
1336b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                "package", "package", 1, null, 0, 0, mNotiGroupGSortB, user,
1346b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                null, System.currentTimeMillis()), getDefaultChannel());
1356b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1366b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mNotiNoGroup = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
1376b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setContentTitle("C")
1386b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setWhen(1201)
1396b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .build();
1406b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
14149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown                "package", "package", 1, null, 0, 0, mNotiNoGroup, user,
1426b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                null, System.currentTimeMillis()), getDefaultChannel());
1436b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1446b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mNotiNoGroup2 = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
1456b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setContentTitle("D")
1466b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setWhen(1202)
1476b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .build();
1486b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
1496b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                "package", "package", 1, null, 0, 0, mNotiNoGroup2, user,
1506b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                null, System.currentTimeMillis()), getDefaultChannel());
1516b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1526b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mNotiNoGroupSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
1536b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setContentTitle("E")
15449ed71db425c5054e3ad9526496a7e116c89556bJeff Brown                .setWhen(1201)
1556b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setSortKey("A")
1566b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .build();
1576b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
1586b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                "package", "package", 1, null, 0, 0, mNotiNoGroupSortA, user,
1596b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                null, System.currentTimeMillis()), getDefaultChannel());
1606b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1616b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mAudioAttributes = new AudioAttributes.Builder()
1626b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
1636b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
1646b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
1656b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                .build();
1666b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1676b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        final ApplicationInfo legacy = new ApplicationInfo();
1686b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1696b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        final ApplicationInfo upgrade = new ApplicationInfo();
1706b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
1716b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
1726b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
1736b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
1746b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
1756b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1766b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private NotificationChannel getDefaultChannel() {
1776b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
1786b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                IMPORTANCE_LOW);
1796b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
1806b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1816b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, boolean forBackup,
1826b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            String... channelIds)
1836b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            throws Exception {
1846b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        XmlSerializer serializer = new FastXmlSerializer();
1856b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1866b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
1876b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        serializer.startDocument(null, true);
1889a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        serializer.startTag(null, "ranking");
1896b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.writeXml(serializer, forBackup);
1906b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        serializer.endTag(null, "ranking");
1916b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        serializer.endDocument();
1926b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        serializer.flush();
1936b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1949a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        for (String channelId : channelIds) {
1956b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
1966b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        }
1976b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        return baos;
1986b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
1996b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2009a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    private void loadStreamXml(ByteArrayOutputStream stream) throws Exception {
2016b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        XmlPullParser parser = Xml.newPullParser();
2026b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(stream.toByteArray())),
2036b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                null);
2046b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        parser.nextTag();
2056b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.readXml(parser, false);
2069a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    }
2076b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2086b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
2096b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getId(), actual.getId());
2106b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getName(), actual.getName());
2116b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getDescription(), actual.getDescription());
2129a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
2136b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
2146b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getImportance(), actual.getImportance());
2156b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
2166b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getSound(), actual.getSound());
2176b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
2189a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
2196b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getGroup(), actual.getGroup());
2206b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
2216b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getLightColor(), actual.getLightColor());
2226b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
2236b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2249a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
2256b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getId(), actual.getId());
2266b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(expected.getName(), actual.getName());
22749ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    }
2286b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2296b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Test
2306b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testFindAfterRankingWithASplitGroup() throws Exception {
2319a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
2326b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordGroupGSortA);
2336b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordGroupGSortB);
2346b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordNoGroup);
2356b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordNoGroupSortA);
2366b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.sort(notificationList);
2379a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0);
2386b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0);
2396b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0);
2406b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0);
2416b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
2426b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2439a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
2446b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testSortShouldNotThrowWithPlainNotifications() throws Exception {
2456b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
2466b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordNoGroup);
2476b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordNoGroup2);
2486b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.sort(notificationList);
2496b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
2506b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2519a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
252cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown    public void testSortShouldNotThrowOneSorted() throws Exception {
2536b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
2546b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordNoGroup);
2556b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordNoGroupSortA);
2566b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.sort(notificationList);
2576b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
2586b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2596b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Test
2606b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testSortShouldNotThrowOneNotification() throws Exception {
2616b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
2626b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordNoGroup);
2636b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.sort(notificationList);
2646b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
2656b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2669a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
2676b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testSortShouldNotThrowOneSortKey() throws Exception {
2686b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
2696b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        notificationList.add(mRecordGroupGSortB);
2706b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.sort(notificationList);
2716b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
2729a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
2736b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Test
2746b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testSortShouldNotThrowOnEmptyList() throws Exception {
2756b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
2766b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.sort(notificationList);
2776b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
2789a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
2796b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Test
2806b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testChannelXml() throws Exception {
2816b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
2826b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
2836b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        NotificationChannel channel1 =
2849a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
2856b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        NotificationChannel channel2 =
2866b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
28749ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        channel2.setDescription("descriptions for all");
28849ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
2896b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        channel2.enableLights(true);
2906b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        channel2.setBypassDnd(true);
2916b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
2929a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel2.enableVibration(true);
2936b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        channel2.setGroup(ncg.getId());
2946b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
2956b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        channel2.setLightColor(Color.BLUE);
2966b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
2976b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
2989a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
2996b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel1, true);
3006b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel2, false);
3016b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3026b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.setShowBadge(PKG, UID, true);
3036b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3049a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
3056b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                channel2.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
3066b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
3076b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3086b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        loadStreamXml(baos);
3096b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3109a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertTrue(mHelper.canShowBadge(PKG, UID));
3116b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
3126b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        compareChannels(channel2,
3136b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
3146b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertNotNull(mHelper.getNotificationChannel(
3156b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false));
3169a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
3176b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        List<NotificationChannelGroup> actualGroups =
3186b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                mHelper.getNotificationChannelGroups(PKG, UID, false).getList();
3196b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        boolean foundNcg = false;
3206b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        for (NotificationChannelGroup actual : actualGroups) {
3216b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            if (ncg.getId().equals(actual.getId())) {
3229a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                foundNcg = true;
3236b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                compareGroups(ncg, actual);
3246b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            } else if (ncg2.getId().equals(actual.getId())) {
3256b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                compareGroups(ncg2, actual);
3266b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            }
3276b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        }
3289a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertTrue(foundNcg);
3296b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3306b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        boolean foundChannel2Group = false;
3316b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        for (NotificationChannelGroup actual : actualGroups) {
3326b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
333061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown                foundChannel2Group = true;
334061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown                break;
3356b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            }
3369a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        }
3376b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertTrue(foundChannel2Group);
3386b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
3396b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3406b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Test
3416b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testChannelXml_backup() throws Exception {
3429a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
3436b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
3446b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        NotificationChannel channel1 =
3456b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
3466b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        NotificationChannel channel2 =
3476b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
3489a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        NotificationChannel channel3 =
3496b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
3506b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        channel3.setGroup(ncg.getId());
3516b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3526b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
3536b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
3549a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel1, true);
3556b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel2, false);
3566b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel3, true);
3576b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3586b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.deleteNotificationChannel(PKG, UID, channel1.getId());
3596b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.deleteNotificationChannelGroup(PKG, UID, ncg.getId());
3609a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
3616b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3626b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
3636b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
3646b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
3656b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3669a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        XmlPullParser parser = Xml.newPullParser();
3676b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
3686b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                null);
3696b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        parser.nextTag();
3706b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.readXml(parser, true);
3716b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3729a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertNull(mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
3736b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertNull(mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
3746b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG, UID));
3756b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        //assertEquals(ncg2, mHelper.getNotificationChannelGroup(ncg2.getId(), PKG, UID));
3766b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
3776b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
3789a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
3796b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Test
3806b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
3816b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        NotificationChannel channel1 =
3826b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_DEFAULT);
3836b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3849a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel1, true);
3856b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3866b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
3876b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                NotificationChannel.DEFAULT_CHANNEL_ID);
3886b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3896b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        loadStreamXml(baos);
3909a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
3916b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        final NotificationChannel updated = mHelper.getNotificationChannel(PKG, UID,
3926b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                NotificationChannel.DEFAULT_CHANNEL_ID, false);
3936b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
3946b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertFalse(updated.canBypassDnd());
3956b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
3969a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(0, updated.getUserLockedFields());
3976b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
3986b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3996b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Test
4006b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
4019a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        NotificationChannel channel1 =
4026b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_MIN);
4036b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel1, true);
4046b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
4056b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
4069a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                NotificationChannel.DEFAULT_CHANNEL_ID, false);
4076b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
4086b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.updateNotificationChannel(PKG, UID, defaultChannel);
4096b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
4106b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
4119a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                NotificationChannel.DEFAULT_CHANNEL_ID);
4126b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
4136b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        loadStreamXml(baos);
4146b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
4156b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
4169a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
4176b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    }
4186b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
4196b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    @Test
4206b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
4219a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        final String preupgradeXml = "<ranking version=\"1\">\n"
4226b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                + "<package name=\"" + PKG
4236b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
4246b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
4256b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID + "\" />\n"
4269a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                + "<package name=\"" + UPDATED_PKG + "\" uid=\"" + UID2 + "\" visibility=\""
4276b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                + Notification.VISIBILITY_PRIVATE + "\" />\n"
4286b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                + "</ranking>";
4296b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        XmlPullParser parser = Xml.newPullParser();
4306b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
4316b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                null);
4329a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        parser.nextTag();
4336b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        mHelper.readXml(parser, false);
4346b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
4356b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        final NotificationChannel updated1 =
4366b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            mHelper.getNotificationChannel(PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
4379a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
4386b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertTrue(updated1.canBypassDnd());
4396b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
4406b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
4416b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                | NotificationChannel.USER_LOCKED_PRIORITY
4426b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                | NotificationChannel.USER_LOCKED_VISIBILITY,
4436b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                updated1.getUserLockedFields());
4446b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
4456b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        // STOPSHIP - this should be reversed after the STOPSHIP is removed in the tested code.
446061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        // No Default Channel created for updated packages
447061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        // assertEquals(null, mHelper.getNotificationChannel(UPDATED_PKG, UID2,
448061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        //         NotificationChannel.DEFAULT_CHANNEL_ID, false));
449061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        assertTrue(mHelper.getNotificationChannel(UPDATED_PKG, UID2,
4509a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                NotificationChannel.DEFAULT_CHANNEL_ID, false) != null);
451061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown    }
452061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown
453061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown    @Test
454061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown    public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
4559a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
456061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown                PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
457061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        assertTrue(defaultChannel != null);
458061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        ByteArrayOutputStream baos =
459061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown                writeXmlAndPurge(PKG, UID, false, NotificationChannel.DEFAULT_CHANNEL_ID);
4609a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        // Load package at higher sdk.
461061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        final ApplicationInfo upgraded = new ApplicationInfo();
462061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
463061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
464061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        loadStreamXml(baos);
4659a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
466061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        // STOPSHIP - this should be reversed after the STOPSHIP is removed in the tested code.
467061cf758841dfc972be3f0ec4857762fafe49aa6Jeff Brown        // Default Channel should be gone.
46849ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        // assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
46949ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        //         NotificationChannel.DEFAULT_CHANNEL_ID, false));
47049ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        assertTrue(mHelper.getNotificationChannel(UPDATED_PKG, UID2,
47149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown                NotificationChannel.DEFAULT_CHANNEL_ID, false) != null);
47249ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    }
4739a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
4749a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
4759a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
4769a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.createNotificationChannel(PKG, UID,
4779a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
4789a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
4799a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
4800648d2c4ce2ca4709382cc5e8bf78d07843b7373Michael Wright
4819a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        // Load package at higher sdk.
4829a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        final ApplicationInfo upgraded = new ApplicationInfo();
4839a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
4849a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
4859a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        loadStreamXml(baos);
4869a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
4879a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        // Default Channel should be gone.
4880648d2c4ce2ca4709382cc5e8bf78d07843b7373Michael Wright        assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
4899a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                NotificationChannel.DEFAULT_CHANNEL_ID, false));
4909a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    }
4919a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
4929a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
4939a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    public void testCreateChannel_blocked() throws Exception {
4949a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.setImportance(PKG, UID, NotificationManager.IMPORTANCE_NONE);
4959a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
4960648d2c4ce2ca4709382cc5e8bf78d07843b7373Michael Wright        mHelper.createNotificationChannel(PKG, UID,
4979a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
4989a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    }
4999a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5009a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5019a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
5029a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    public void testUpdate() throws Exception {
5039a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        // no fields locked by user
5049a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        final NotificationChannel channel =
5059a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
5069a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
5079a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.enableLights(true);
5089a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setBypassDnd(true);
5099a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
5109a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5119a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel, false);
5129a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5139a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        // same id, try to update all fields
5149a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        final NotificationChannel channel2 =
5159a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
5169a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
5179a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel2.enableLights(false);
5189a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel2.setBypassDnd(false);
5199a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
5209a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5219a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.updateNotificationChannel(PKG, UID, channel2);
5229a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5239a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        // all fields should be changed
5249a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel.getId(), false));
5259a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    }
5269a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5279a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
5280648d2c4ce2ca4709382cc5e8bf78d07843b7373Michael Wright    public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
5299a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(null, mHelper.getNotificationChannel(PKG, UID, "garbage", false));
5309a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    }
5319a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5329a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
5339a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    public void testCreateChannel_CannotChangeHiddenFields() throws Exception {
5349a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        final NotificationChannel channel =
5359a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
5369a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
5379a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.enableLights(true);
5389a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setBypassDnd(true);
5399a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
5409a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setShowBadge(true);
5419a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        int lockMask = 0;
5429a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
5439a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown            lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
5449a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        }
5459a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.lockFields(lockMask);
5469a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5479a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel, true);
5489a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5499a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        NotificationChannel savedChannel =
5509a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
5519a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5529a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(channel.getName(), savedChannel.getName());
5539a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
5549a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertFalse(savedChannel.canBypassDnd());
5559a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
5569a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
5579a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    }
5589a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5599a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
5609a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    public void testCreateChannel_CannotChangeHiddenFieldsAssistant() throws Exception {
5619a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        final NotificationChannel channel =
5629a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
5639a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
5649a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.enableLights(true);
5659a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setBypassDnd(true);
5669a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
5679a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setShowBadge(true);
5689a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        int lockMask = 0;
5699a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
5709a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown            lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
5719a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        }
5729a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.lockFields(lockMask);
5739a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5749a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.createNotificationChannel(PKG, UID, channel, true);
5759a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5769a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        NotificationChannel savedChannel =
5779a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
5789a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5799a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(channel.getName(), savedChannel.getName());
5809a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
5819a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertFalse(savedChannel.canBypassDnd());
5829a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
5839a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
5849a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    }
5859a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5869a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
5879a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    public void testDeleteNonExistentChannel() throws Exception {
5889a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        mHelper.deleteNotificationChannelGroup(PKG, UID, "does not exist");
5899a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    }
5909a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown
5919a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    @Test
5929a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown    public void testGetDeletedChannel() throws Exception {
5939a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        NotificationChannel channel =
5949a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
5959a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
5969a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.enableLights(true);
5979a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setBypassDnd(true);
5989a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
5999a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.enableVibration(true);
6009a2bbf680e3b5b98051b9f2913ab6bd31b77f79aJeff Brown        channel.setVibrationPattern(new long[]{100, 67, 145, 156});
60149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
602        mHelper.createNotificationChannel(PKG, UID, channel, true);
603        mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
604
605        // Does not return deleted channel
606        NotificationChannel response =
607                mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
608        assertNull(response);
609
610        // Returns deleted channel
611        response = mHelper.getNotificationChannel(PKG, UID, channel.getId(), true);
612        compareChannels(channel, response);
613        assertTrue(response.isDeleted());
614    }
615
616    @Test
617    public void testGetDeletedChannels() throws Exception {
618        Map<String, NotificationChannel> channelMap = new HashMap<>();
619        NotificationChannel channel =
620                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
621        channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
622        channel.enableLights(true);
623        channel.setBypassDnd(true);
624        channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
625        channel.enableVibration(true);
626        channel.setVibrationPattern(new long[]{100, 67, 145, 156});
627        channelMap.put(channel.getId(), channel);
628        NotificationChannel channel2 =
629                new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
630        channelMap.put(channel2.getId(), channel2);
631        mHelper.createNotificationChannel(PKG, UID, channel, true);
632        mHelper.createNotificationChannel(PKG, UID, channel2, true);
633
634        mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
635
636        // Returns only non-deleted channels
637        List<NotificationChannel> channels =
638                mHelper.getNotificationChannels(PKG, UID, false).getList();
639        assertEquals(2, channels.size());   // Default channel + non-deleted channel
640        for (NotificationChannel nc : channels) {
641            if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
642                compareChannels(channel2, nc);
643            }
644        }
645
646        // Returns deleted channels too
647        channels = mHelper.getNotificationChannels(PKG, UID, true).getList();
648        assertEquals(3, channels.size());               // Includes default channel
649        for (NotificationChannel nc : channels) {
650            if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
651                compareChannels(channelMap.get(nc.getId()), nc);
652            }
653        }
654    }
655
656    @Test
657    public void testGetDeletedChannelCount() throws Exception {
658        NotificationChannel channel =
659                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
660        NotificationChannel channel2 =
661                new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
662        NotificationChannel channel3 =
663                new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
664        mHelper.createNotificationChannel(PKG, UID, channel, true);
665        mHelper.createNotificationChannel(PKG, UID, channel2, true);
666        mHelper.createNotificationChannel(PKG, UID, channel3, true);
667
668        mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
669        mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
670
671        assertEquals(2, mHelper.getDeletedChannelCount(PKG, UID));
672        assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID2));
673    }
674
675    @Test
676    public void testCreateDeletedChannel() throws Exception {
677        long[] vibration = new long[]{100, 67, 145, 156};
678        NotificationChannel channel =
679                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
680        channel.setVibrationPattern(vibration);
681
682        mHelper.createNotificationChannel(PKG, UID, channel, true);
683        mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
684
685        NotificationChannel newChannel = new NotificationChannel(
686                channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
687        newChannel.setVibrationPattern(new long[]{100});
688
689        mHelper.createNotificationChannel(PKG, UID, newChannel, true);
690
691        // No long deleted, using old settings
692        compareChannels(channel,
693                mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
694    }
695
696    @Test
697    public void testCreateChannel_defaultChannelId() throws Exception {
698        try {
699            mHelper.createNotificationChannel(PKG, UID, new NotificationChannel(
700                    NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true);
701            fail("Allowed to create default channel");
702        } catch (IllegalArgumentException e) {
703            // pass
704        }
705    }
706
707    @Test
708    public void testCreateChannel_alreadyExists() throws Exception {
709        long[] vibration = new long[]{100, 67, 145, 156};
710        NotificationChannel channel =
711                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
712        channel.setVibrationPattern(vibration);
713
714        mHelper.createNotificationChannel(PKG, UID, channel, true);
715
716        NotificationChannel newChannel = new NotificationChannel(
717                channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
718        newChannel.setVibrationPattern(new long[]{100});
719
720        mHelper.createNotificationChannel(PKG, UID, newChannel, true);
721
722        // Old settings not overridden
723        compareChannels(channel,
724                mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
725    }
726
727    @Test
728    public void testCreateChannel_addMissingSound() throws Exception {
729        final NotificationChannel channel =
730                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
731        mHelper.createNotificationChannel(PKG, UID, channel, true);
732        assertNotNull(mHelper.getNotificationChannel(
733                PKG, UID, channel.getId(), false).getSound());
734    }
735
736    @Test
737    public void testCreateChannel_noOverrideSound() throws Exception {
738        Uri sound = new Uri.Builder().scheme("test").build();
739        final NotificationChannel channel = new NotificationChannel("id2", "name2",
740                 NotificationManager.IMPORTANCE_DEFAULT);
741        channel.setSound(sound, mAudioAttributes);
742        mHelper.createNotificationChannel(PKG, UID, channel, true);
743        assertEquals(sound, mHelper.getNotificationChannel(
744                PKG, UID, channel.getId(), false).getSound());
745    }
746
747    @Test
748    public void testPermanentlyDeleteChannels() throws Exception {
749        NotificationChannel channel1 =
750                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
751        NotificationChannel channel2 =
752                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
753
754        mHelper.createNotificationChannel(PKG, UID, channel1, true);
755        mHelper.createNotificationChannel(PKG, UID, channel2, false);
756
757        mHelper.permanentlyDeleteNotificationChannels(PKG, UID);
758
759        // Only default channel remains
760        assertEquals(1, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
761    }
762
763    @Test
764    public void testDeleteGroup() throws Exception {
765        NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
766        NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
767        NotificationChannel nonGroupedNonDeletedChannel =
768                new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
769        NotificationChannel groupedButNotDeleted =
770                new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
771        groupedButNotDeleted.setGroup("not");
772        NotificationChannel groupedAndDeleted =
773                new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
774        groupedAndDeleted.setGroup("totally");
775
776        mHelper.createNotificationChannelGroup(PKG, UID, notDeleted, true);
777        mHelper.createNotificationChannelGroup(PKG, UID, deleted, true);
778        mHelper.createNotificationChannel(PKG, UID, nonGroupedNonDeletedChannel, true);
779        mHelper.createNotificationChannel(PKG, UID, groupedAndDeleted, true);
780        mHelper.createNotificationChannel(PKG, UID, groupedButNotDeleted, true);
781
782        mHelper.deleteNotificationChannelGroup(PKG, UID, deleted.getId());
783
784        assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG, UID));
785        assertNotNull(mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG, UID));
786
787        assertNull(mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), false));
788        compareChannels(groupedAndDeleted,
789                mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), true));
790
791        compareChannels(groupedButNotDeleted,
792                mHelper.getNotificationChannel(PKG, UID, groupedButNotDeleted.getId(), false));
793        compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
794                PKG, UID, nonGroupedNonDeletedChannel.getId(), false));
795
796        // notDeleted
797        assertEquals(1, mHelper.getNotificationChannelGroups(PKG, UID).size());
798    }
799
800    @Test
801    public void testOnPackageChanged_packageRemoval() throws Exception {
802        // Deleted
803        NotificationChannel channel1 =
804                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
805        mHelper.createNotificationChannel(PKG, UID, channel1, true);
806
807        mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
808
809        assertEquals(0, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
810
811        // Not deleted
812        mHelper.createNotificationChannel(PKG, UID, channel1, true);
813
814        mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
815        assertEquals(2, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
816    }
817
818    @Test
819    public void testOnPackageChanged_packageRemoval_importance() throws Exception {
820        mHelper.setImportance(PKG, UID, NotificationManager.IMPORTANCE_HIGH);
821
822        mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
823
824        assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
825    }
826
827    @Test
828    public void testOnPackageChanged_packageRemoval_groups() throws Exception {
829        NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
830        mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
831        NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
832        mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
833
834        mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
835
836        assertEquals(0, mHelper.getNotificationChannelGroups(PKG, UID, true).getList().size());
837    }
838
839    @Test
840    public void testRecordDefaults() throws Exception {
841        assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
842        assertEquals(true, mHelper.canShowBadge(PKG, UID));
843        assertEquals(1, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
844    }
845
846    @Test
847    public void testCreateGroup() throws Exception {
848        NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
849        mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
850        assertEquals(ncg, mHelper.getNotificationChannelGroups(PKG, UID).iterator().next());
851    }
852
853    @Test
854    public void testCannotCreateChannel_badGroup() throws Exception {
855        NotificationChannel channel1 =
856                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
857        channel1.setGroup("garbage");
858        try {
859            mHelper.createNotificationChannel(PKG, UID, channel1, true);
860            fail("Created a channel with a bad group");
861        } catch (IllegalArgumentException e) {
862        }
863    }
864
865    @Test
866    public void testCannotCreateChannel_goodGroup() throws Exception {
867        NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
868        mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
869        NotificationChannel channel1 =
870                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
871        channel1.setGroup(ncg.getId());
872        mHelper.createNotificationChannel(PKG, UID, channel1, true);
873
874        assertEquals(ncg.getId(),
875                mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false).getGroup());
876    }
877
878    @Test
879    public void testGetChannelGroups() throws Exception {
880        NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
881        mHelper.createNotificationChannelGroup(PKG, UID, unused, true);
882        NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
883        mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
884        NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
885        mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
886
887        NotificationChannel channel1 =
888                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
889        channel1.setGroup(ncg.getId());
890        mHelper.createNotificationChannel(PKG, UID, channel1, true);
891        NotificationChannel channel1a =
892                new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
893        channel1a.setGroup(ncg.getId());
894        mHelper.createNotificationChannel(PKG, UID, channel1a, true);
895
896        NotificationChannel channel2 =
897                new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
898        channel2.setGroup(ncg2.getId());
899        mHelper.createNotificationChannel(PKG, UID, channel2, true);
900
901        NotificationChannel channel3 =
902                new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
903        mHelper.createNotificationChannel(PKG, UID, channel3, true);
904
905        List<NotificationChannelGroup> actual =
906                mHelper.getNotificationChannelGroups(PKG, UID, true).getList();
907        assertEquals(3, actual.size());
908        for (NotificationChannelGroup group : actual) {
909            if (group.getId() == null) {
910                assertEquals(2, group.getChannels().size()); // misc channel too
911                assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
912                        || channel3.getId().equals(group.getChannels().get(1).getId()));
913            } else if (group.getId().equals(ncg.getId())) {
914                assertEquals(2, group.getChannels().size());
915                if (group.getChannels().get(0).getId().equals(channel1.getId())) {
916                    assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
917                } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
918                    assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
919                } else {
920                    fail("expected channel not found");
921                }
922            } else if (group.getId().equals(ncg2.getId())) {
923                assertEquals(1, group.getChannels().size());
924                assertEquals(channel2.getId(), group.getChannels().get(0).getId());
925            }
926        }
927    }
928
929    @Test
930    public void testGetChannelGroups_noSideEffects() throws Exception {
931        NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
932        mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
933
934        NotificationChannel channel1 =
935                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
936        channel1.setGroup(ncg.getId());
937        mHelper.createNotificationChannel(PKG, UID, channel1, true);
938        mHelper.getNotificationChannelGroups(PKG, UID, true).getList();
939
940        channel1.setImportance(IMPORTANCE_LOW);
941        mHelper.updateNotificationChannel(PKG, UID, channel1);
942
943        List<NotificationChannelGroup> actual =
944                mHelper.getNotificationChannelGroups(PKG, UID, true).getList();
945
946        assertEquals(2, actual.size());
947        for (NotificationChannelGroup group : actual) {
948            if (Objects.equals(group.getId(), ncg.getId())) {
949                assertEquals(1, group.getChannels().size());
950            }
951        }
952    }
953
954    @Test
955    public void testCreateChannel_updateName() throws Exception {
956        NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
957        mHelper.createNotificationChannel(PKG, UID, nc, true);
958        NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
959        assertEquals("hello", actual.getName());
960
961        nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
962        mHelper.createNotificationChannel(PKG, UID, nc, true);
963
964        actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
965        assertEquals("goodbye", actual.getName());
966        assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
967    }
968
969    @Test
970    public void testDumpChannelsJson() throws Exception {
971        final ApplicationInfo upgrade = new ApplicationInfo();
972        upgrade.targetSdkVersion = Build.VERSION_CODES.O;
973        try {
974            when(mPm.getApplicationInfoAsUser(
975                    anyString(), anyInt(), anyInt())).thenReturn(upgrade);
976        } catch (PackageManager.NameNotFoundException e) {
977        }
978        ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
979        int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
980        for (int i = 0; i < numPackages; i++) {
981            String pkgName = "pkg" + i;
982            int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
983            for (int j = 0; j < numChannels; j++) {
984                mHelper.createNotificationChannel(pkgName, UID,
985                        new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true);
986            }
987            expectedChannels.put(pkgName, numChannels);
988        }
989
990        // delete the first channel of the first package
991        String pkg = expectedChannels.keyAt(0);
992        mHelper.deleteNotificationChannel("pkg" + 0, UID, "0");
993        // dump should not include deleted channels
994        int count = expectedChannels.get(pkg);
995        expectedChannels.put(pkg, count - 1);
996
997        JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
998        assertEquals(numPackages, actual.length());
999        for (int i = 0; i < numPackages; i++) {
1000            JSONObject object = actual.getJSONObject(i);
1001            assertTrue(expectedChannels.containsKey(object.get("packageName")));
1002            assertEquals(expectedChannels.get(object.get("packageName")).intValue() + 1,
1003                    object.getInt("channelCount"));
1004        }
1005    }
1006}
1007