RankingHelperTest.java revision baff400fa5a93d157934818982fcf534327f9830
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.notification;
17
18import static junit.framework.Assert.fail;
19
20import org.junit.Before;
21import org.junit.Test;
22import org.junit.runner.RunWith;
23
24import com.android.internal.util.FastXmlSerializer;
25
26import org.mockito.Mock;
27import org.mockito.MockitoAnnotations;
28import org.xmlpull.v1.XmlPullParser;
29import org.xmlpull.v1.XmlSerializer;
30
31import android.app.Notification;
32import android.content.Context;
33import android.app.NotificationChannel;
34import android.app.NotificationManager;
35import android.content.pm.ApplicationInfo;
36import android.content.pm.PackageManager;
37import android.net.Uri;
38import android.os.Build;
39import android.os.UserHandle;
40import android.service.notification.StatusBarNotification;
41import android.support.test.InstrumentationRegistry;
42import android.support.test.runner.AndroidJUnit4;
43import android.test.suitebuilder.annotation.SmallTest;
44import android.util.Xml;
45
46import java.io.BufferedInputStream;
47import java.io.BufferedOutputStream;
48import java.io.ByteArrayInputStream;
49import java.io.ByteArrayOutputStream;
50import java.util.ArrayList;
51import java.util.Arrays;
52
53import static org.junit.Assert.assertEquals;
54import static org.junit.Assert.assertFalse;
55import static org.junit.Assert.assertNotNull;
56import static org.junit.Assert.assertTrue;
57import static org.mockito.Matchers.anyInt;
58import static org.mockito.Matchers.eq;
59import static org.mockito.Mockito.when;
60
61@SmallTest
62@RunWith(AndroidJUnit4.class)
63public class RankingHelperTest {
64    @Mock NotificationUsageStats mUsageStats;
65    @Mock RankingHandler handler;
66    @Mock PackageManager mPm;
67
68    private Notification mNotiGroupGSortA;
69    private Notification mNotiGroupGSortB;
70    private Notification mNotiNoGroup;
71    private Notification mNotiNoGroup2;
72    private Notification mNotiNoGroupSortA;
73    private NotificationRecord mRecordGroupGSortA;
74    private NotificationRecord mRecordGroupGSortB;
75    private NotificationRecord mRecordNoGroup;
76    private NotificationRecord mRecordNoGroup2;
77    private NotificationRecord mRecordNoGroupSortA;
78    private RankingHelper mHelper;
79    private final String pkg = "com.android.server.notification";
80    private final int uid = 0;
81    private final String pkg2 = "pkg2";
82    private final int uid2 = 1111111;
83
84    private Context getContext() {
85        return InstrumentationRegistry.getTargetContext();
86    }
87
88    @Before
89    public void setUp() {
90        MockitoAnnotations.initMocks(this);
91        UserHandle user = UserHandle.ALL;
92
93        mHelper = new RankingHelper(getContext(), mPm, handler, mUsageStats,
94                new String[] {ImportanceExtractor.class.getName()});
95
96        mNotiGroupGSortA = new Notification.Builder(getContext())
97                .setContentTitle("A")
98                .setGroup("G")
99                .setSortKey("A")
100                .setWhen(1205)
101                .build();
102        mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
103                "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiGroupGSortA, user,
104                null, System.currentTimeMillis()));
105
106        mNotiGroupGSortB = new Notification.Builder(getContext())
107                .setContentTitle("B")
108                .setGroup("G")
109                .setSortKey("B")
110                .setWhen(1200)
111                .build();
112        mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
113                "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiGroupGSortB, user,
114                null, System.currentTimeMillis()));
115
116        mNotiNoGroup = new Notification.Builder(getContext())
117                .setContentTitle("C")
118                .setWhen(1201)
119                .build();
120        mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
121                "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroup, user,
122                null, System.currentTimeMillis()));
123
124        mNotiNoGroup2 = new Notification.Builder(getContext())
125                .setContentTitle("D")
126                .setWhen(1202)
127                .build();
128        mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
129                "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroup2, user,
130                null, System.currentTimeMillis()));
131
132        mNotiNoGroupSortA = new Notification.Builder(getContext())
133                .setContentTitle("E")
134                .setWhen(1201)
135                .setSortKey("A")
136                .build();
137        mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
138                "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroupSortA, user,
139                null, System.currentTimeMillis()));
140
141        final ApplicationInfo legacy = new ApplicationInfo();
142        legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
143        final ApplicationInfo upgrade = new ApplicationInfo();
144        upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
145        try {
146            when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(legacy);
147            when(mPm.getApplicationInfoAsUser(eq(pkg2), anyInt(), anyInt())).thenReturn(upgrade);
148        } catch (PackageManager.NameNotFoundException e) {}
149    }
150
151    private NotificationChannel getDefaultChannel() {
152        return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
153                NotificationManager.IMPORTANCE_LOW);
154    }
155
156    private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, String... channelIds)
157            throws Exception {
158        XmlSerializer serializer = new FastXmlSerializer();
159        ByteArrayOutputStream baos = new ByteArrayOutputStream();
160        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
161        serializer.startDocument(null, true);
162        serializer.startTag(null, "ranking");
163        mHelper.writeXml(serializer, false);
164        serializer.endTag(null, "ranking");
165        serializer.endDocument();
166        serializer.flush();
167
168        for (String channelId : channelIds) {
169            mHelper.deleteNotificationChannel(pkg, uid, channelId);
170        }
171        return baos;
172    }
173
174    private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
175        assertEquals(expected.getId(), actual.getId());
176        assertEquals(expected.getName(), actual.getName());
177        assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
178        assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
179        assertEquals(expected.getImportance(), actual.getImportance());
180        assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
181        assertEquals(expected.getSound(), actual.getSound());
182        assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
183        assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
184    }
185
186    @Test
187    public void testFindAfterRankingWithASplitGroup() throws Exception {
188        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
189        notificationList.add(mRecordGroupGSortA);
190        notificationList.add(mRecordGroupGSortB);
191        notificationList.add(mRecordNoGroup);
192        notificationList.add(mRecordNoGroupSortA);
193        mHelper.sort(notificationList);
194        assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0);
195        assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0);
196        assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0);
197        assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0);
198    }
199
200    @Test
201    public void testSortShouldNotThrowWithPlainNotifications() throws Exception {
202        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
203        notificationList.add(mRecordNoGroup);
204        notificationList.add(mRecordNoGroup2);
205        mHelper.sort(notificationList);
206    }
207
208    @Test
209    public void testSortShouldNotThrowOneSorted() throws Exception {
210        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
211        notificationList.add(mRecordNoGroup);
212        notificationList.add(mRecordNoGroupSortA);
213        mHelper.sort(notificationList);
214    }
215
216    @Test
217    public void testSortShouldNotThrowOneNotification() throws Exception {
218        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
219        notificationList.add(mRecordNoGroup);
220        mHelper.sort(notificationList);
221    }
222
223    @Test
224    public void testSortShouldNotThrowOneSortKey() throws Exception {
225        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
226        notificationList.add(mRecordGroupGSortB);
227        mHelper.sort(notificationList);
228    }
229
230    @Test
231    public void testSortShouldNotThrowOnEmptyList() throws Exception {
232        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
233        mHelper.sort(notificationList);
234    }
235
236    @Test
237    public void testChannelXml() throws Exception {
238        NotificationChannel channel1 =
239                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
240        NotificationChannel channel2 =
241                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
242        channel2.setSound(new Uri.Builder().scheme("test").build());
243        channel2.setLights(true);
244        channel2.setBypassDnd(true);
245        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
246        channel2.enableVibration(true);
247        channel2.setVibrationPattern(new long[] {100, 67, 145, 156});
248
249        mHelper.createNotificationChannel(pkg, uid, channel1, false);
250        mHelper.createNotificationChannel(pkg, uid, channel2, false);
251
252        ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(), channel2.getId(),
253                NotificationChannel.DEFAULT_CHANNEL_ID);
254
255        mHelper.deleteNotificationChannel(pkg, uid, channel1.getId());
256        mHelper.deleteNotificationChannel(pkg, uid, channel2.getId());
257        mHelper.deleteNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
258
259        XmlPullParser parser = Xml.newPullParser();
260        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
261                null);
262        parser.nextTag();
263        mHelper.readXml(parser, false);
264
265        assertEquals(channel1, mHelper.getNotificationChannel(pkg, uid, channel1.getId()));
266        compareChannels(channel2, mHelper.getNotificationChannel(pkg, uid, channel2.getId()));
267        assertNotNull(
268                mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID));
269    }
270
271    @Test
272    public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
273        NotificationChannel channel1 =
274                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_DEFAULT);
275
276        mHelper.createNotificationChannel(pkg, uid, channel1, true);
277
278        ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(),
279                NotificationChannel.DEFAULT_CHANNEL_ID);
280
281        XmlPullParser parser = Xml.newPullParser();
282        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
283                null);
284        parser.nextTag();
285        mHelper.readXml(parser, false);
286
287        final NotificationChannel updated =
288                mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
289        assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
290        assertFalse(updated.canBypassDnd());
291        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,updated.getLockscreenVisibility());
292        assertEquals(0, updated.getUserLockedFields());
293    }
294
295    @Test
296    public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
297         NotificationChannel channel1 =
298                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_MIN);
299        mHelper.createNotificationChannel(pkg, uid, channel1, true);
300
301        final NotificationChannel defaultChannel =
302                mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
303        defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
304        mHelper.updateNotificationChannel(pkg, uid, defaultChannel);
305
306        ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(),
307                NotificationChannel.DEFAULT_CHANNEL_ID);
308
309        XmlPullParser parser = Xml.newPullParser();
310        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
311                null);
312        parser.nextTag();
313        mHelper.readXml(parser, false);
314
315        assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
316                pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID).getImportance());
317    }
318
319    @Test
320    public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
321        final String preupgradeXml = "<ranking version=\"1\">\n"
322             + "<package name=\"" + pkg + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
323            + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
324            + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + uid + "\" />\n"
325            + "<package name=\"" + pkg2 + "\" uid=\"" + uid2 + "\" visibility=\""
326            + Notification.VISIBILITY_PRIVATE + "\" />\n"
327            + "</ranking>";
328        XmlPullParser parser = Xml.newPullParser();
329        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
330            null);
331        parser.nextTag();
332        mHelper.readXml(parser, false);
333
334        final NotificationChannel updated1 =
335            mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
336        assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
337        assertTrue(updated1.canBypassDnd());
338        assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
339        assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
340            | NotificationChannel.USER_LOCKED_PRIORITY
341            | NotificationChannel.USER_LOCKED_VISIBILITY, updated1.getUserLockedFields());
342
343        final NotificationChannel updated2 =
344            mHelper.getNotificationChannel(pkg2, uid2, NotificationChannel.DEFAULT_CHANNEL_ID);
345        // clamped
346        assertEquals(NotificationManager.IMPORTANCE_LOW, updated2.getImportance());
347        assertFalse(updated2.canBypassDnd());
348        assertEquals(Notification.VISIBILITY_PRIVATE, updated2.getLockscreenVisibility());
349        assertEquals(NotificationChannel.USER_LOCKED_VISIBILITY, updated2.getUserLockedFields());
350    }
351
352    @Test
353    public void testCreateChannel_blocked() throws Exception {
354        mHelper.setImportance(pkg, uid, NotificationManager.IMPORTANCE_NONE);
355
356        try {
357            mHelper.createNotificationChannel(pkg, uid,
358                    new NotificationChannel(pkg, "", NotificationManager.IMPORTANCE_LOW), true);
359            fail("Channel creation should fail");
360        } catch (IllegalArgumentException e) {
361            // pass
362        }
363    }
364
365    @Test
366    public void testUpdate_userLockedImportance() throws Exception {
367        // all fields locked by user
368        final NotificationChannel channel =
369            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
370        channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
371
372        mHelper.createNotificationChannel(pkg, uid, channel, false);
373
374        // same id, try to update
375        final NotificationChannel channel2 =
376            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
377
378        mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2);
379
380        // no fields should be changed
381        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
382    }
383
384    @Test
385    public void testUpdate_userLockedVisibility() throws Exception {
386        // all fields locked by user
387        final NotificationChannel channel =
388            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
389        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
390        channel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
391
392        mHelper.createNotificationChannel(pkg, uid, channel, false);
393
394        // same id, try to update
395        final NotificationChannel channel2 =
396            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
397        channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
398
399        mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2);
400
401        // no fields should be changed
402        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
403    }
404
405    @Test
406    public void testUpdate_userLockedVibration() throws Exception {
407        // all fields locked by user
408        final NotificationChannel channel =
409            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
410        channel.setLights(false);
411        channel.lockFields(NotificationChannel.USER_LOCKED_VIBRATION);
412
413        mHelper.createNotificationChannel(pkg, uid, channel, false);
414
415        // same id, try to update
416        final NotificationChannel channel2 =
417            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
418        channel2.enableVibration(true);
419        channel2.setVibrationPattern(new long[] {100});
420
421        mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2);
422
423        // no fields should be changed
424        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
425    }
426
427    @Test
428    public void testUpdate_userLockedLights() throws Exception {
429        // all fields locked by user
430        final NotificationChannel channel =
431            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
432        channel.setLights(false);
433        channel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
434
435        mHelper.createNotificationChannel(pkg, uid, channel, false);
436
437        // same id, try to update
438        final NotificationChannel channel2 =
439            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
440        channel2.setLights(true);
441
442        mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2);
443
444        // no fields should be changed
445        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
446    }
447
448    @Test
449    public void testUpdate_userLockedPriority() throws Exception {
450        // all fields locked by user
451        final NotificationChannel channel =
452            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
453        channel.setBypassDnd(true);
454        channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
455
456        mHelper.createNotificationChannel(pkg, uid, channel, false);
457
458        // same id, try to update all fields
459        final NotificationChannel channel2 =
460            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
461        channel2.setBypassDnd(false);
462
463        mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2);
464
465        // no fields should be changed
466        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
467    }
468
469    @Test
470    public void testUpdate_userLockedRingtone() throws Exception {
471        // all fields locked by user
472        final NotificationChannel channel =
473            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
474        channel.setSound(new Uri.Builder().scheme("test").build());
475        channel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
476
477        mHelper.createNotificationChannel(pkg, uid, channel, false);
478
479        // same id, try to update all fields
480        final NotificationChannel channel2 =
481            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
482        channel2.setSound(new Uri.Builder().scheme("test2").build());
483
484        mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2);
485
486        // no fields should be changed
487        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
488    }
489
490    @Test
491    public void testUpdate_userLockedAllowed() throws Exception {
492        final NotificationChannel channel =
493                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
494        channel.setAllowed(true);
495        channel.lockFields(NotificationChannel.USER_LOCKED_ALLOWED);
496
497        mHelper.createNotificationChannel(pkg, uid, channel, false);
498
499        final NotificationChannel channel2 =
500                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
501        channel2.setAllowed(false);
502
503        mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2);
504
505        // no fields should be changed
506        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
507    }
508
509    @Test
510    public void testUpdate_userLockedBadge() throws Exception {
511        final NotificationChannel channel =
512                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
513        channel.setShowBadge(true);
514        channel.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE);
515
516        mHelper.createNotificationChannel(pkg, uid, channel, false);
517
518        final NotificationChannel channel2 =
519                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
520        channel2.setShowBadge(false);
521
522        mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2);
523
524        // no fields should be changed
525        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
526    }
527
528    @Test
529    public void testUpdate() throws Exception {
530        // no fields locked by user
531        final NotificationChannel channel =
532                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
533        channel.setSound(new Uri.Builder().scheme("test").build());
534        channel.setLights(true);
535        channel.setBypassDnd(true);
536        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
537
538        mHelper.createNotificationChannel(pkg, uid, channel, false);
539
540        // same id, try to update all fields
541        final NotificationChannel channel2 =
542                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
543        channel2.setSound(new Uri.Builder().scheme("test2").build());
544        channel2.setLights(false);
545        channel2.setBypassDnd(false);
546        channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
547
548        mHelper.updateNotificationChannel(pkg, uid, channel2);
549
550        // all fields should be changed
551        assertEquals(channel2, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
552    }
553
554    @Test
555    public void testGetChannelWithFallback() throws Exception {
556        NotificationChannel channel =
557                mHelper.getNotificationChannelWithFallback(pkg, uid, "garbage");
558        assertEquals(NotificationChannel.DEFAULT_CHANNEL_ID, channel.getId());
559    }
560
561    @Test
562    public void testCreateChannel_CannotChangeHiddenFields() throws Exception {
563        final NotificationChannel channel =
564                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
565        channel.setSound(new Uri.Builder().scheme("test").build());
566        channel.setLights(true);
567        channel.setBypassDnd(true);
568        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
569        channel.setShowBadge(true);
570        channel.setAllowed(false);
571        int lockMask = 0;
572        for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
573            lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
574        }
575        channel.lockFields(lockMask);
576
577        mHelper.createNotificationChannel(pkg, uid, channel, true);
578
579        NotificationChannel savedChannel =
580                mHelper.getNotificationChannel(pkg, uid, channel.getId());
581
582        assertEquals(channel.getName(), savedChannel.getName());
583        assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
584        assertFalse(savedChannel.canBypassDnd());
585        assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
586        assertFalse(savedChannel.canShowBadge());
587    }
588
589    @Test
590    public void testCreateChannel_CannotChangeHiddenFieldsAssistant() throws Exception {
591        final NotificationChannel channel =
592                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
593        channel.setSound(new Uri.Builder().scheme("test").build());
594        channel.setLights(true);
595        channel.setBypassDnd(true);
596        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
597        channel.setShowBadge(true);
598        channel.setAllowed(false);
599        int lockMask = 0;
600        for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
601            lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
602        }
603        channel.lockFields(lockMask);
604
605        mHelper.createNotificationChannel(pkg, uid, channel, true);
606
607        NotificationChannel savedChannel =
608                mHelper.getNotificationChannel(pkg, uid, channel.getId());
609
610        assertEquals(channel.getName(), savedChannel.getName());
611        assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
612        assertFalse(savedChannel.canBypassDnd());
613        assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
614        assertFalse(savedChannel.canShowBadge());
615    }
616}
617