blob: 98c6ec42207fed3485620a4352144f1c52d33e42 [file] [log] [blame]
Chris Wren1031c972014-07-23 13:11:45 +00001/*
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
Julia Reynoldsd373d782017-03-03 13:32:57 -050018import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
Julia Reynolds03fa85d2017-03-06 15:14:50 -050019import static android.app.NotificationManager.IMPORTANCE_HIGH;
Julia Reynolds74856c42017-02-08 14:47:23 -050020import static android.app.NotificationManager.IMPORTANCE_LOW;
Julia Reynolds3e50bf62017-05-24 16:33:32 -040021import static android.app.NotificationManager.IMPORTANCE_MAX;
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -040022import static android.app.NotificationManager.IMPORTANCE_NONE;
Julia Reynoldsfa04e142017-04-23 13:32:01 -040023import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
Julia Reynolds74856c42017-02-08 14:47:23 -050024
Julia Reynolds4036e8d2017-01-13 09:50:05 -050025import static junit.framework.Assert.assertNull;
Julia Reynolds32c97ef2016-11-28 10:47:18 -050026import static junit.framework.Assert.fail;
27
Julia Reynolds3d5b3c72017-11-07 09:04:58 -050028import static org.junit.Assert.assertEquals;
29import static org.junit.Assert.assertFalse;
30import static org.junit.Assert.assertNotNull;
31import static org.junit.Assert.assertTrue;
32import static org.mockito.ArgumentMatchers.any;
33import static org.mockito.Matchers.anyInt;
34import static org.mockito.Matchers.anyString;
35import static org.mockito.Matchers.eq;
Beverlyc36640f2018-05-21 16:14:15 -040036import static org.mockito.Mockito.atLeast;
Julia Reynolds3d5b3c72017-11-07 09:04:58 -050037import static org.mockito.Mockito.mock;
38import static org.mockito.Mockito.never;
Beverlyc36640f2018-05-21 16:14:15 -040039import static org.mockito.Mockito.reset;
Julia Reynolds3d5b3c72017-11-07 09:04:58 -050040import static org.mockito.Mockito.times;
41import static org.mockito.Mockito.verify;
42import static org.mockito.Mockito.when;
43
Chris Wren1031c972014-07-23 13:11:45 +000044import android.app.Notification;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040045import android.app.NotificationChannel;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010046import android.app.NotificationChannelGroup;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040047import android.app.NotificationManager;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010048import android.content.ContentProvider;
49import android.content.Context;
50import android.content.IContentProvider;
Julia Reynolds85769912016-10-25 09:08:57 -040051import android.content.pm.ApplicationInfo;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -040052import android.content.pm.PackageInfo;
Julia Reynolds85769912016-10-25 09:08:57 -040053import android.content.pm.PackageManager;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -040054import android.content.pm.Signature;
Julia Reynolds816797a2017-08-11 15:47:09 -040055import android.content.res.Resources;
Julia Reynolds529e3322017-02-06 08:33:01 -050056import android.graphics.Color;
Julia Reynolds619a69f2017-01-27 15:11:38 -050057import android.media.AudioAttributes;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040058import android.net.Uri;
Julia Reynolds85769912016-10-25 09:08:57 -040059import android.os.Build;
Chris Wren1031c972014-07-23 13:11:45 +000060import android.os.UserHandle;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010061import android.provider.Settings;
Chris Wren89aa2262017-05-05 18:05:56 -040062import android.provider.Settings.Secure;
Chris Wren1031c972014-07-23 13:11:45 +000063import android.service.notification.StatusBarNotification;
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040064import android.support.test.InstrumentationRegistry;
65import android.support.test.runner.AndroidJUnit4;
Chris Wren1031c972014-07-23 13:11:45 +000066import android.test.suitebuilder.annotation.SmallTest;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010067import android.testing.TestableContentResolver;
Julia Reynoldsd373d782017-03-03 13:32:57 -050068import android.util.ArrayMap;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040069import android.util.Xml;
Chris Wren1031c972014-07-23 13:11:45 +000070
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010071import com.android.internal.util.FastXmlSerializer;
Jason Monk74f5e362017-12-06 08:56:33 -050072import com.android.server.UiServiceTestCase;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010073
74import org.json.JSONArray;
75import org.json.JSONObject;
76import org.junit.Before;
77import org.junit.Test;
78import org.junit.runner.RunWith;
79import org.mockito.Mock;
80import org.mockito.MockitoAnnotations;
81import org.xmlpull.v1.XmlPullParser;
82import org.xmlpull.v1.XmlSerializer;
83
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040084import java.io.BufferedInputStream;
85import java.io.BufferedOutputStream;
86import java.io.ByteArrayInputStream;
87import java.io.ByteArrayOutputStream;
Chris Wren1031c972014-07-23 13:11:45 +000088import java.util.ArrayList;
Julia Reynoldsf57de462016-11-23 11:31:46 -050089import java.util.Arrays;
Julia Reynolds4036e8d2017-01-13 09:50:05 -050090import java.util.HashMap;
91import java.util.List;
92import java.util.Map;
Julia Reynolds74856c42017-02-08 14:47:23 -050093import java.util.Objects;
Julia Reynoldsd373d782017-03-03 13:32:57 -050094import java.util.concurrent.ThreadLocalRandom;
Chris Wren1031c972014-07-23 13:11:45 +000095
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040096@SmallTest
97@RunWith(AndroidJUnit4.class)
Jason Monk74f5e362017-12-06 08:56:33 -050098public class RankingHelperTest extends UiServiceTestCase {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -050099 private static final String PKG = "com.android.server.notification";
100 private static final int UID = 0;
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400101 private static final UserHandle USER = UserHandle.of(0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500102 private static final String UPDATED_PKG = "updatedPkg";
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400103 private static final int UID2 = 1111;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400104 private static final String SYSTEM_PKG = "android";
105 private static final int SYSTEM_UID= 1000;
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400106 private static final UserHandle USER2 = UserHandle.of(10);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500107 private static final String TEST_CHANNEL_ID = "test_channel_id";
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100108 private static final String TEST_AUTHORITY = "test";
109 private static final Uri SOUND_URI =
110 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
111 private static final Uri CANONICAL_SOUND_URI =
112 Uri.parse("content://" + TEST_AUTHORITY
113 + "/internal/audio/media/10?title=Test&canonical=1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500114
115 @Mock NotificationUsageStats mUsageStats;
116 @Mock RankingHandler mHandler;
117 @Mock PackageManager mPm;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100118 @Mock IContentProvider mTestIContentProvider;
Julia Reynoldse0b25742017-05-08 12:55:24 -0400119 @Mock Context mContext;
Beverlyc36640f2018-05-21 16:14:15 -0400120 @Mock ZenModeHelper mMockZenModeHelper;
Chris Wren1031c972014-07-23 13:11:45 +0000121
Beverlyc36640f2018-05-21 16:14:15 -0400122 private NotificationManager.Policy mTestNotificationPolicy;
Chris Wren1031c972014-07-23 13:11:45 +0000123 private Notification mNotiGroupGSortA;
124 private Notification mNotiGroupGSortB;
125 private Notification mNotiNoGroup;
126 private Notification mNotiNoGroup2;
127 private Notification mNotiNoGroupSortA;
128 private NotificationRecord mRecordGroupGSortA;
129 private NotificationRecord mRecordGroupGSortB;
130 private NotificationRecord mRecordNoGroup;
131 private NotificationRecord mRecordNoGroup2;
132 private NotificationRecord mRecordNoGroupSortA;
133 private RankingHelper mHelper;
Julia Reynolds619a69f2017-01-27 15:11:38 -0500134 private AudioAttributes mAudioAttributes;
Chris Wren1031c972014-07-23 13:11:45 +0000135
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400136 @Before
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500137 public void setUp() throws Exception {
Chris Wren5eab2b72015-06-16 13:56:22 -0400138 MockitoAnnotations.initMocks(this);
Chris Wren1031c972014-07-23 13:11:45 +0000139 UserHandle user = UserHandle.ALL;
140
Julia Reynolds85769912016-10-25 09:08:57 -0400141 final ApplicationInfo legacy = new ApplicationInfo();
142 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Julia Reynolds1864ff52016-11-02 09:54:47 -0400143 final ApplicationInfo upgrade = new ApplicationInfo();
Dan Sandlere103b782017-05-17 16:07:56 -0700144 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500145 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
146 when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400147 when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500148 when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
Julia Reynoldsf26eb912017-05-22 15:47:06 -0400149 when(mPm.getPackageUidAsUser(eq(UPDATED_PKG), anyInt())).thenReturn(UID2);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400150 when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
151 PackageInfo info = mock(PackageInfo.class);
152 info.signatures = new Signature[] {mock(Signature.class)};
153 when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
154 when(mPm.getPackageInfoAsUser(eq(PKG), anyInt(), anyInt()))
155 .thenReturn(mock(PackageInfo.class));
Julia Reynoldse0b25742017-05-08 12:55:24 -0400156 when(mContext.getResources()).thenReturn(
157 InstrumentationRegistry.getContext().getResources());
Julia Reynolds816797a2017-08-11 15:47:09 -0400158 when(mContext.getContentResolver()).thenReturn(
159 InstrumentationRegistry.getContext().getContentResolver());
Julia Reynoldse0b25742017-05-08 12:55:24 -0400160 when(mContext.getPackageManager()).thenReturn(mPm);
161 when(mContext.getApplicationInfo()).thenReturn(legacy);
Chris Wren89aa2262017-05-05 18:05:56 -0400162 // most tests assume badging is enabled
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100163 TestableContentResolver contentResolver = getContext().getContentResolver();
164 contentResolver.setFallbackToExisting(false);
165 Secure.putIntForUser(contentResolver,
Chris Wren89aa2262017-05-05 18:05:56 -0400166 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID));
Julia Reynoldse0b25742017-05-08 12:55:24 -0400167
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100168 ContentProvider testContentProvider = mock(ContentProvider.class);
169 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
170 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
171
172 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
173 .thenReturn(CANONICAL_SOUND_URI);
174 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
175 .thenReturn(CANONICAL_SOUND_URI);
176 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
177 .thenReturn(SOUND_URI);
178
Beverlyc36640f2018-05-21 16:14:15 -0400179 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
180 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
181 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
182 mHelper = new RankingHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
Julia Reynoldsc861a3d2018-02-15 10:34:49 -0500183 mUsageStats, new String[] {ImportanceExtractor.class.getName()});
Beverlyc36640f2018-05-21 16:14:15 -0400184 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -0400185
Julia Reynoldse0b25742017-05-08 12:55:24 -0400186 mNotiGroupGSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
187 .setContentTitle("A")
188 .setGroup("G")
189 .setSortKey("A")
190 .setWhen(1205)
191 .build();
192 mRecordGroupGSortA = new NotificationRecord(mContext, new StatusBarNotification(
193 PKG, PKG, 1, null, 0, 0, mNotiGroupGSortA, user,
194 null, System.currentTimeMillis()), getDefaultChannel());
195
196 mNotiGroupGSortB = new Notification.Builder(mContext, TEST_CHANNEL_ID)
197 .setContentTitle("B")
198 .setGroup("G")
199 .setSortKey("B")
200 .setWhen(1200)
201 .build();
202 mRecordGroupGSortB = new NotificationRecord(mContext, new StatusBarNotification(
203 PKG, PKG, 1, null, 0, 0, mNotiGroupGSortB, user,
204 null, System.currentTimeMillis()), getDefaultChannel());
205
206 mNotiNoGroup = new Notification.Builder(mContext, TEST_CHANNEL_ID)
207 .setContentTitle("C")
208 .setWhen(1201)
209 .build();
210 mRecordNoGroup = new NotificationRecord(mContext, new StatusBarNotification(
211 PKG, PKG, 1, null, 0, 0, mNotiNoGroup, user,
212 null, System.currentTimeMillis()), getDefaultChannel());
213
214 mNotiNoGroup2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
215 .setContentTitle("D")
216 .setWhen(1202)
217 .build();
218 mRecordNoGroup2 = new NotificationRecord(mContext, new StatusBarNotification(
219 PKG, PKG, 1, null, 0, 0, mNotiNoGroup2, user,
220 null, System.currentTimeMillis()), getDefaultChannel());
221
222 mNotiNoGroupSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
223 .setContentTitle("E")
224 .setWhen(1201)
225 .setSortKey("A")
226 .build();
227 mRecordNoGroupSortA = new NotificationRecord(mContext, new StatusBarNotification(
228 PKG, PKG, 1, null, 0, 0, mNotiNoGroupSortA, user,
229 null, System.currentTimeMillis()), getDefaultChannel());
230
231 mAudioAttributes = new AudioAttributes.Builder()
232 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
233 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
234 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
235 .build();
Chris Wren1031c972014-07-23 13:11:45 +0000236 }
237
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400238 private NotificationChannel getDefaultChannel() {
Julia Reynolds85769912016-10-25 09:08:57 -0400239 return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
Julia Reynolds74856c42017-02-08 14:47:23 -0500240 IMPORTANCE_LOW);
Julia Reynolds85769912016-10-25 09:08:57 -0400241 }
242
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400243 private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, boolean forBackup,
244 String... channelIds)
Julia Reynolds85769912016-10-25 09:08:57 -0400245 throws Exception {
246 XmlSerializer serializer = new FastXmlSerializer();
247 ByteArrayOutputStream baos = new ByteArrayOutputStream();
248 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
249 serializer.startDocument(null, true);
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400250 mHelper.writeXml(serializer, forBackup);
Julia Reynolds85769912016-10-25 09:08:57 -0400251 serializer.endDocument();
252 serializer.flush();
Julia Reynolds85769912016-10-25 09:08:57 -0400253 for (String channelId : channelIds) {
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500254 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
Julia Reynolds85769912016-10-25 09:08:57 -0400255 }
256 return baos;
257 }
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400258
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400259 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore) throws Exception {
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100260 loadByteArrayXml(stream.toByteArray(), forRestore);
261 }
262
263 private void loadByteArrayXml(byte[] byteArray, boolean forRestore) throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500264 XmlPullParser parser = Xml.newPullParser();
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100265 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500266 parser.nextTag();
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400267 mHelper.readXml(parser, forRestore);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500268 }
269
Julia Reynoldsf57de462016-11-23 11:31:46 -0500270 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
271 assertEquals(expected.getId(), actual.getId());
272 assertEquals(expected.getName(), actual.getName());
Julia Reynolds2c891c92017-03-17 14:23:47 -0400273 assertEquals(expected.getDescription(), actual.getDescription());
Julia Reynoldsf57de462016-11-23 11:31:46 -0500274 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
275 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
276 assertEquals(expected.getImportance(), actual.getImportance());
277 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
278 assertEquals(expected.getSound(), actual.getSound());
279 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
280 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
Julia Reynolds59e152e2017-01-25 17:42:53 -0500281 assertEquals(expected.getGroup(), actual.getGroup());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500282 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
Julia Reynolds529e3322017-02-06 08:33:01 -0500283 assertEquals(expected.getLightColor(), actual.getLightColor());
Julia Reynoldsf57de462016-11-23 11:31:46 -0500284 }
285
Julia Reynoldsd5286842017-03-02 15:37:10 -0500286 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
287 assertEquals(expected.getId(), actual.getId());
288 assertEquals(expected.getName(), actual.getName());
Julia Reynolds005c8b92017-08-24 10:35:53 -0400289 assertEquals(expected.getDescription(), actual.getDescription());
290 assertEquals(expected.isBlocked(), actual.isBlocked());
Julia Reynoldsd5286842017-03-02 15:37:10 -0500291 }
292
Julia Reynoldse0b25742017-05-08 12:55:24 -0400293 private NotificationChannel getChannel() {
294 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
295 }
296
Julia Reynolds005c8b92017-08-24 10:35:53 -0400297 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
298 for (NotificationChannel channel : channels) {
299 if (channel.getId().equals(id)) {
300 return channel;
301 }
302 }
303 return null;
304 }
305
Beverlyc36640f2018-05-21 16:14:15 -0400306 private void resetZenModeHelper() {
307 reset(mMockZenModeHelper);
308 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
309 }
310
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400311 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000312 public void testFindAfterRankingWithASplitGroup() throws Exception {
313 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
314 notificationList.add(mRecordGroupGSortA);
315 notificationList.add(mRecordGroupGSortB);
316 notificationList.add(mRecordNoGroup);
317 notificationList.add(mRecordNoGroupSortA);
318 mHelper.sort(notificationList);
319 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0);
320 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0);
321 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0);
322 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0);
323 }
324
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400325 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000326 public void testSortShouldNotThrowWithPlainNotifications() throws Exception {
327 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
328 notificationList.add(mRecordNoGroup);
329 notificationList.add(mRecordNoGroup2);
330 mHelper.sort(notificationList);
331 }
332
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400333 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000334 public void testSortShouldNotThrowOneSorted() throws Exception {
335 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
336 notificationList.add(mRecordNoGroup);
337 notificationList.add(mRecordNoGroupSortA);
338 mHelper.sort(notificationList);
339 }
340
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400341 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000342 public void testSortShouldNotThrowOneNotification() throws Exception {
343 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
344 notificationList.add(mRecordNoGroup);
345 mHelper.sort(notificationList);
346 }
347
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400348 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000349 public void testSortShouldNotThrowOneSortKey() throws Exception {
350 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
351 notificationList.add(mRecordGroupGSortB);
352 mHelper.sort(notificationList);
353 }
354
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400355 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000356 public void testSortShouldNotThrowOnEmptyList() throws Exception {
357 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
358 mHelper.sort(notificationList);
359 }
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400360
361 @Test
362 public void testChannelXml() throws Exception {
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400363 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
Julia Reynolds005c8b92017-08-24 10:35:53 -0400364 ncg.setBlocked(true);
365 ncg.setDescription("group desc");
Julia Reynoldsd5286842017-03-02 15:37:10 -0500366 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
Julia Reynolds85769912016-10-25 09:08:57 -0400367 NotificationChannel channel1 =
368 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
369 NotificationChannel channel2 =
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400370 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds2c891c92017-03-17 14:23:47 -0400371 channel2.setDescription("descriptions for all");
Julia Reynolds619a69f2017-01-27 15:11:38 -0500372 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500373 channel2.enableLights(true);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400374 channel2.setBypassDnd(true);
375 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Julia Reynoldsf57de462016-11-23 11:31:46 -0500376 channel2.enableVibration(true);
Julia Reynolds59e152e2017-01-25 17:42:53 -0500377 channel2.setGroup(ncg.getId());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500378 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds529e3322017-02-06 08:33:01 -0500379 channel2.setLightColor(Color.BLUE);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400380
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500381 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
382 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400383 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
384 mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400385
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500386 mHelper.setShowBadge(PKG, UID, true);
Rohan Shah590e1b22018-04-10 23:48:47 -0400387 mHelper.setAppImportanceLocked(PKG, UID);
Julia Reynolds924eed12017-01-19 09:52:07 -0500388
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500389 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400390 channel2.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500391 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400392
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400393 loadStreamXml(baos, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400394
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500395 assertTrue(mHelper.canShowBadge(PKG, UID));
Rohan Shah590e1b22018-04-10 23:48:47 -0400396 assertTrue(mHelper.getIsAppImportanceLocked(PKG, UID));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500397 assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500398 compareChannels(channel2,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500399 mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynolds74856c42017-02-08 14:47:23 -0500400
401 List<NotificationChannelGroup> actualGroups =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500402 mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -0500403 boolean foundNcg = false;
404 for (NotificationChannelGroup actual : actualGroups) {
405 if (ncg.getId().equals(actual.getId())) {
406 foundNcg = true;
Julia Reynoldsd5286842017-03-02 15:37:10 -0500407 compareGroups(ncg, actual);
408 } else if (ncg2.getId().equals(actual.getId())) {
409 compareGroups(ncg2, actual);
Julia Reynolds74856c42017-02-08 14:47:23 -0500410 }
411 }
412 assertTrue(foundNcg);
413
414 boolean foundChannel2Group = false;
415 for (NotificationChannelGroup actual : actualGroups) {
416 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
417 foundChannel2Group = true;
418 break;
419 }
420 }
421 assertTrue(foundChannel2Group);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400422 }
Julia Reynolds85769912016-10-25 09:08:57 -0400423
424 @Test
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400425 public void testChannelXmlForBackup() throws Exception {
426 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
427 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
428 NotificationChannel channel1 =
429 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
430 NotificationChannel channel2 =
431 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
432 channel2.setDescription("descriptions for all");
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100433 channel2.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400434 channel2.enableLights(true);
435 channel2.setBypassDnd(true);
436 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
437 channel2.enableVibration(false);
438 channel2.setGroup(ncg.getId());
439 channel2.setLightColor(Color.BLUE);
Julia Reynolds745c1542017-05-26 14:43:47 -0400440 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
441 channel3.enableVibration(true);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400442
443 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
444 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400445 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
446 mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
447 mHelper.createNotificationChannel(PKG, UID, channel3, false, false);
448 mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true, false);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400449
450 mHelper.setShowBadge(PKG, UID, true);
451
452 mHelper.setImportance(UPDATED_PKG, UID2, IMPORTANCE_NONE);
453
454 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
Julia Reynolds745c1542017-05-26 14:43:47 -0400455 channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
456 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG, UPDATED_PKG},
457 new int[]{UID, UID2});
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400458
459 mHelper.setShowBadge(UPDATED_PKG, UID2, true);
460
461 loadStreamXml(baos, true);
462
463 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(UPDATED_PKG, UID2));
464 assertTrue(mHelper.canShowBadge(PKG, UID));
465 assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
466 compareChannels(channel2,
467 mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynolds745c1542017-05-26 14:43:47 -0400468 compareChannels(channel3,
469 mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400470
471 List<NotificationChannelGroup> actualGroups =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500472 mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400473 boolean foundNcg = false;
474 for (NotificationChannelGroup actual : actualGroups) {
475 if (ncg.getId().equals(actual.getId())) {
476 foundNcg = true;
477 compareGroups(ncg, actual);
478 } else if (ncg2.getId().equals(actual.getId())) {
479 compareGroups(ncg2, actual);
480 }
481 }
482 assertTrue(foundNcg);
483
484 boolean foundChannel2Group = false;
485 for (NotificationChannelGroup actual : actualGroups) {
486 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
487 foundChannel2Group = true;
488 break;
489 }
490 }
491 assertTrue(foundChannel2Group);
492 }
493
494 @Test
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100495 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
496 NotificationChannel channel =
497 new NotificationChannel("id", "name", IMPORTANCE_LOW);
498 channel.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400499 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100500
501 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
502
503 // Testing that in restore we are given the canonical version
504 loadStreamXml(baos, true);
505 verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
506 }
507
508 @Test
509 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
510 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
511 Uri canonicalBasedOnLocal = localUri.buildUpon()
512 .appendQueryParameter("title", "Test")
513 .appendQueryParameter("canonical", "1")
514 .build();
515 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
516 .thenReturn(canonicalBasedOnLocal);
517 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
518 .thenReturn(localUri);
519 when(mTestIContentProvider.uncanonicalize(any(), eq(canonicalBasedOnLocal)))
520 .thenReturn(localUri);
521
522 NotificationChannel channel =
523 new NotificationChannel("id", "name", IMPORTANCE_LOW);
524 channel.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400525 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100526 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
527
528 loadStreamXml(baos, true);
529
530 NotificationChannel actualChannel = mHelper.getNotificationChannel(
531 PKG, UID, channel.getId(), false);
532 assertEquals(localUri, actualChannel.getSound());
533 }
534
535 @Test
536 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
537 Thread.sleep(3000);
538 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
539 .thenReturn(null);
540 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
541 .thenReturn(null);
542
543 NotificationChannel channel =
544 new NotificationChannel("id", "name", IMPORTANCE_LOW);
545 channel.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400546 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100547 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
548
549 loadStreamXml(baos, true);
550
551 NotificationChannel actualChannel = mHelper.getNotificationChannel(
552 PKG, UID, channel.getId(), false);
553 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
554 }
555
556
557 /**
558 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
559 * handle its restore properly.
560 */
561 @Test
562 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
563 // Not a local uncanonicalized uri, simulating that it fails to exist locally
564 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI))).thenReturn(null);
565 String id = "id";
566 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
567 + "<package name=\"com.android.server.notification\" show_badge=\"true\">\n"
568 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
569 + "sound=\"" + SOUND_URI + "\" "
570 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
571 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
572 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
573 + "</package>\n"
574 + "</ranking>\n";
575
576 loadByteArrayXml(backupWithUncanonicalizedSoundUri.getBytes(), true);
577
578 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG, UID, id, false);
579 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
580 }
581
582 @Test
583 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
584 NotificationChannel channel =
585 new NotificationChannel("id", "name", IMPORTANCE_LOW);
586 channel.setSound(null, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400587 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100588 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
589
590 loadStreamXml(baos, true);
591
592 NotificationChannel actualChannel = mHelper.getNotificationChannel(
593 PKG, UID, channel.getId(), false);
594 assertEquals(null, actualChannel.getSound());
595 }
596
597 @Test
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400598 public void testChannelXml_backup() throws Exception {
599 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
600 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
601 NotificationChannel channel1 =
602 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
603 NotificationChannel channel2 =
604 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
605 NotificationChannel channel3 =
606 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
607 channel3.setGroup(ncg.getId());
608
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500609 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
610 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400611 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
612 mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
613 mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400614
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500615 mHelper.deleteNotificationChannel(PKG, UID, channel1.getId());
616 mHelper.deleteNotificationChannelGroup(PKG, UID, ncg.getId());
617 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400618
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500619 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400620 channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500621 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400622
623 XmlPullParser parser = Xml.newPullParser();
624 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
625 null);
626 parser.nextTag();
627 mHelper.readXml(parser, true);
628
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500629 assertNull(mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
630 assertNull(mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
631 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG, UID));
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000632 //assertEquals(ncg2, mHelper.getNotificationChannelGroup(ncg2.getId(), PKG, UID));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500633 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400634 }
635
636 @Test
Julia Reynolds85769912016-10-25 09:08:57 -0400637 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400638 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
Julia Reynolds85769912016-10-25 09:08:57 -0400639 NotificationChannel.DEFAULT_CHANNEL_ID);
640
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400641 loadStreamXml(baos, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400642
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500643 final NotificationChannel updated = mHelper.getNotificationChannel(PKG, UID,
644 NotificationChannel.DEFAULT_CHANNEL_ID, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400645 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
646 assertFalse(updated.canBypassDnd());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500647 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
Julia Reynolds85769912016-10-25 09:08:57 -0400648 assertEquals(0, updated.getUserLockedFields());
649 }
650
651 @Test
Julia Reynoldsb3a04f02016-11-04 09:08:52 -0400652 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500653 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
654 NotificationChannel.DEFAULT_CHANNEL_ID, false);
655 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400656 mHelper.updateNotificationChannel(PKG, UID, defaultChannel, true);
Julia Reynoldsb3a04f02016-11-04 09:08:52 -0400657
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400658 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
Julia Reynolds85769912016-10-25 09:08:57 -0400659 NotificationChannel.DEFAULT_CHANNEL_ID);
660
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400661 loadStreamXml(baos, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400662
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500663 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
664 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Julia Reynolds85769912016-10-25 09:08:57 -0400665 }
666
Julia Reynolds85769912016-10-25 09:08:57 -0400667 @Test
668 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
Julia Reynolds1864ff52016-11-02 09:54:47 -0400669 final String preupgradeXml = "<ranking version=\"1\">\n"
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500670 + "<package name=\"" + PKG
671 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
Julia Reynolds619a69f2017-01-27 15:11:38 -0500672 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500673 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID + "\" />\n"
674 + "<package name=\"" + UPDATED_PKG + "\" uid=\"" + UID2 + "\" visibility=\""
Julia Reynolds619a69f2017-01-27 15:11:38 -0500675 + Notification.VISIBILITY_PRIVATE + "\" />\n"
676 + "</ranking>";
Julia Reynolds85769912016-10-25 09:08:57 -0400677 XmlPullParser parser = Xml.newPullParser();
Julia Reynolds1864ff52016-11-02 09:54:47 -0400678 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
Julia Reynolds619a69f2017-01-27 15:11:38 -0500679 null);
Julia Reynolds85769912016-10-25 09:08:57 -0400680 parser.nextTag();
681 mHelper.readXml(parser, false);
682
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500683 final NotificationChannel updated1 =
684 mHelper.getNotificationChannel(PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Julia Reynolds1864ff52016-11-02 09:54:47 -0400685 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
686 assertTrue(updated1.canBypassDnd());
687 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
Julia Reynolds85769912016-10-25 09:08:57 -0400688 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
Julia Reynolds619a69f2017-01-27 15:11:38 -0500689 | NotificationChannel.USER_LOCKED_PRIORITY
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500690 | NotificationChannel.USER_LOCKED_VISIBILITY,
691 updated1.getUserLockedFields());
Julia Reynolds1864ff52016-11-02 09:54:47 -0400692
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500693 // No Default Channel created for updated packages
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400694 assertEquals(null, mHelper.getNotificationChannel(UPDATED_PKG, UID2,
695 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500696 }
697
698 @Test
699 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
700 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
701 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
702 assertTrue(defaultChannel != null);
703 ByteArrayOutputStream baos =
704 writeXmlAndPurge(PKG, UID, false, NotificationChannel.DEFAULT_CHANNEL_ID);
705 // Load package at higher sdk.
706 final ApplicationInfo upgraded = new ApplicationInfo();
707 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
708 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400709 loadStreamXml(baos, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500710
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500711 // Default Channel should be gone.
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400712 assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
713 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500714 }
715
716 @Test
717 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
718 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400719 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500720 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
721 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
722
723 // Load package at higher sdk.
724 final ApplicationInfo upgraded = new ApplicationInfo();
725 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
726 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400727 loadStreamXml(baos, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500728
729 // Default Channel should be gone.
730 assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
731 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Julia Reynolds85769912016-10-25 09:08:57 -0400732 }
733
Julia Reynolds85769912016-10-25 09:08:57 -0400734 @Test
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400735 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
736 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
737 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
738 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400739 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400740
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400741 loadStreamXml(baos, false);
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400742
743 // Should still have the newly created channel that wasn't in the xml.
744 assertTrue(mHelper.getNotificationChannel(PKG, UID, "bananas", false) != null);
745 }
746
747 @Test
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500748 public void testCreateChannel_blocked() throws Exception {
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400749 mHelper.setImportance(PKG, UID, IMPORTANCE_NONE);
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500750
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500751 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400752 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500753 }
754
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400755 @Test
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400756 public void testCreateChannel_badImportance() throws Exception {
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400757 try {
758 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400759 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
760 true, false);
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400761 fail("Was allowed to create a channel with invalid importance");
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400762 } catch (IllegalArgumentException e) {
763 // yay
764 }
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400765 try {
766 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400767 new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
768 true, false);
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400769 fail("Was allowed to create a channel with invalid importance");
770 } catch (IllegalArgumentException e) {
771 // yay
772 }
773 try {
774 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400775 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
776 true, false);
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400777 fail("Was allowed to create a channel with invalid importance");
778 } catch (IllegalArgumentException e) {
779 // yay
780 }
781 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400782 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false);
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400783 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400784 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false);
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400785 }
786
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500787
788 @Test
Julia Reynolds85769912016-10-25 09:08:57 -0400789 public void testUpdate() throws Exception {
790 // no fields locked by user
791 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500792 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500793 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500794 channel.enableLights(true);
Julia Reynolds85769912016-10-25 09:08:57 -0400795 channel.setBypassDnd(true);
796 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
797
Julia Reynolds1fe10942018-03-28 12:46:51 -0400798 mHelper.createNotificationChannel(PKG, UID, channel, false, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400799
800 // same id, try to update all fields
801 final NotificationChannel channel2 =
802 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500803 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500804 channel2.enableLights(false);
Julia Reynolds85769912016-10-25 09:08:57 -0400805 channel2.setBypassDnd(false);
806 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
807
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400808 mHelper.updateNotificationChannel(PKG, UID, channel2, true);
Julia Reynolds85769912016-10-25 09:08:57 -0400809
810 // all fields should be changed
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500811 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel.getId(), false));
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400812
813 verify(mHandler, times(1)).requestSort();
Julia Reynolds85769912016-10-25 09:08:57 -0400814 }
815
816 @Test
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400817 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
818 mHelper.setImportance(PKG, UID, IMPORTANCE_UNSPECIFIED);
819 assertTrue(mHelper.canShowBadge(PKG, UID));
820 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
821 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
822 mHelper.getPackageVisibility(PKG, UID));
Rohan Shah590e1b22018-04-10 23:48:47 -0400823 assertFalse(mHelper.getIsAppImportanceLocked(PKG, UID));
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400824
825 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
826 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
827
828 defaultChannel.setShowBadge(false);
829 defaultChannel.setImportance(IMPORTANCE_NONE);
830 defaultChannel.setBypassDnd(true);
831 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
832
Rohan Shah590e1b22018-04-10 23:48:47 -0400833 mHelper.setAppImportanceLocked(PKG, UID);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400834 mHelper.updateNotificationChannel(PKG, UID, defaultChannel, true);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400835
836 // ensure app level fields are changed
837 assertFalse(mHelper.canShowBadge(PKG, UID));
838 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG, UID));
839 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG, UID));
840 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG, UID));
Rohan Shah590e1b22018-04-10 23:48:47 -0400841 assertTrue(mHelper.getIsAppImportanceLocked(PKG, UID));
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400842 }
843
844 @Test
845 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
846 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
847
Julia Reynolds1fe10942018-03-28 12:46:51 -0400848 mHelper.createNotificationChannel(PKG, UID, channel, false, false);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400849 assertTrue(mHelper.canShowBadge(PKG, UID));
850 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
851 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
852 mHelper.getPackageVisibility(PKG, UID));
853
854 channel.setShowBadge(false);
855 channel.setImportance(IMPORTANCE_NONE);
856 channel.setBypassDnd(true);
857 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
858
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400859 mHelper.updateNotificationChannel(PKG, UID, channel, true);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400860
861 // ensure app level fields are not changed
862 assertTrue(mHelper.canShowBadge(PKG, UID));
863 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
864 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
865 mHelper.getPackageVisibility(PKG, UID));
866 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
867 }
868
869 @Test
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500870 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
871 assertEquals(null, mHelper.getNotificationChannel(PKG, UID, "garbage", false));
Julia Reynolds85769912016-10-25 09:08:57 -0400872 }
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500873
874 @Test
875 public void testCreateChannel_CannotChangeHiddenFields() throws Exception {
876 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500877 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500878 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500879 channel.enableLights(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500880 channel.setBypassDnd(true);
881 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
882 channel.setShowBadge(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500883 int lockMask = 0;
884 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
885 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
886 }
887 channel.lockFields(lockMask);
888
Julia Reynolds1fe10942018-03-28 12:46:51 -0400889 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500890
891 NotificationChannel savedChannel =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500892 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500893
894 assertEquals(channel.getName(), savedChannel.getName());
895 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
896 assertFalse(savedChannel.canBypassDnd());
897 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
Julia Reynoldsf35e3972017-01-05 15:41:04 -0500898 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400899
900 verify(mHandler, never()).requestSort();
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500901 }
902
903 @Test
904 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() throws Exception {
905 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500906 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500907 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500908 channel.enableLights(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500909 channel.setBypassDnd(true);
910 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
911 channel.setShowBadge(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500912 int lockMask = 0;
913 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
914 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
915 }
916 channel.lockFields(lockMask);
917
Julia Reynolds1fe10942018-03-28 12:46:51 -0400918 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500919
920 NotificationChannel savedChannel =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500921 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500922
923 assertEquals(channel.getName(), savedChannel.getName());
924 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
925 assertFalse(savedChannel.canBypassDnd());
926 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
Julia Reynoldsf35e3972017-01-05 15:41:04 -0500927 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500928 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500929
930 @Test
Julia Reynoldse0b25742017-05-08 12:55:24 -0400931 public void testClearLockedFields() throws Exception {
932 final NotificationChannel channel = getChannel();
933 mHelper.clearLockedFields(channel);
934 assertEquals(0, channel.getUserLockedFields());
935
936 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
937 | NotificationChannel.USER_LOCKED_IMPORTANCE);
938 mHelper.clearLockedFields(channel);
939 assertEquals(0, channel.getUserLockedFields());
940 }
941
942 @Test
943 public void testLockFields_soundAndVibration() throws Exception {
Julia Reynolds1fe10942018-03-28 12:46:51 -0400944 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400945
946 final NotificationChannel update1 = getChannel();
947 update1.setSound(new Uri.Builder().scheme("test").build(),
948 new AudioAttributes.Builder().build());
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500949 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400950 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500951 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
952 | NotificationChannel.USER_LOCKED_SOUND,
Julia Reynoldse0b25742017-05-08 12:55:24 -0400953 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
954 .getUserLockedFields());
955
956 NotificationChannel update2 = getChannel();
957 update2.enableVibration(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400958 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500959 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
960 | NotificationChannel.USER_LOCKED_SOUND
Julia Reynoldse0b25742017-05-08 12:55:24 -0400961 | NotificationChannel.USER_LOCKED_VIBRATION,
962 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
963 .getUserLockedFields());
964 }
965
966 @Test
967 public void testLockFields_vibrationAndLights() throws Exception {
Julia Reynolds1fe10942018-03-28 12:46:51 -0400968 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400969
970 final NotificationChannel update1 = getChannel();
971 update1.setVibrationPattern(new long[]{7945, 46 ,246});
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400972 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400973 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
974 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
975 .getUserLockedFields());
976
977 final NotificationChannel update2 = getChannel();
978 update2.enableLights(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400979 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400980 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
981 | NotificationChannel.USER_LOCKED_LIGHTS,
982 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
983 .getUserLockedFields());
984 }
985
986 @Test
987 public void testLockFields_lightsAndImportance() throws Exception {
Julia Reynolds1fe10942018-03-28 12:46:51 -0400988 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400989
990 final NotificationChannel update1 = getChannel();
991 update1.setLightColor(Color.GREEN);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400992 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400993 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
994 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
995 .getUserLockedFields());
996
997 final NotificationChannel update2 = getChannel();
998 update2.setImportance(IMPORTANCE_DEFAULT);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400999 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001000 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
1001 | NotificationChannel.USER_LOCKED_IMPORTANCE,
1002 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
1003 .getUserLockedFields());
1004 }
1005
1006 @Test
1007 public void testLockFields_visibilityAndDndAndBadge() throws Exception {
Julia Reynolds1fe10942018-03-28 12:46:51 -04001008 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001009 assertEquals(0,
1010 mHelper.getNotificationChannel(PKG, UID, getChannel().getId(), false)
1011 .getUserLockedFields());
1012
1013 final NotificationChannel update1 = getChannel();
1014 update1.setBypassDnd(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001015 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001016 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
1017 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
1018 .getUserLockedFields());
1019
1020 final NotificationChannel update2 = getChannel();
1021 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001022 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001023 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1024 | NotificationChannel.USER_LOCKED_VISIBILITY,
1025 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
1026 .getUserLockedFields());
1027
1028 final NotificationChannel update3 = getChannel();
1029 update3.setShowBadge(false);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001030 mHelper.updateNotificationChannel(PKG, UID, update3, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001031 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1032 | NotificationChannel.USER_LOCKED_VISIBILITY
1033 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
1034 mHelper.getNotificationChannel(PKG, UID, update3.getId(), false)
1035 .getUserLockedFields());
1036 }
1037
1038 @Test
Julia Reynolds8e0eb372017-03-21 15:04:50 -04001039 public void testDeleteNonExistentChannel() throws Exception {
1040 mHelper.deleteNotificationChannelGroup(PKG, UID, "does not exist");
1041 }
1042
1043 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001044 public void testGetDeletedChannel() throws Exception {
Julia Reynoldse0b25742017-05-08 12:55:24 -04001045 NotificationChannel channel = getChannel();
Julia Reynolds619a69f2017-01-27 15:11:38 -05001046 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -05001047 channel.enableLights(true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001048 channel.setBypassDnd(true);
1049 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1050 channel.enableVibration(true);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001051 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001052
Julia Reynolds1fe10942018-03-28 12:46:51 -04001053 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001054 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001055
1056 // Does not return deleted channel
1057 NotificationChannel response =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001058 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001059 assertNull(response);
1060
1061 // Returns deleted channel
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001062 response = mHelper.getNotificationChannel(PKG, UID, channel.getId(), true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001063 compareChannels(channel, response);
1064 assertTrue(response.isDeleted());
1065 }
1066
1067 @Test
1068 public void testGetDeletedChannels() throws Exception {
1069 Map<String, NotificationChannel> channelMap = new HashMap<>();
1070 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001071 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001072 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -05001073 channel.enableLights(true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001074 channel.setBypassDnd(true);
1075 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1076 channel.enableVibration(true);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001077 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001078 channelMap.put(channel.getId(), channel);
1079 NotificationChannel channel2 =
1080 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1081 channelMap.put(channel2.getId(), channel2);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001082 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1083 mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001084
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001085 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001086
1087 // Returns only non-deleted channels
1088 List<NotificationChannel> channels =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001089 mHelper.getNotificationChannels(PKG, UID, false).getList();
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001090 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1091 for (NotificationChannel nc : channels) {
1092 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1093 compareChannels(channel2, nc);
1094 }
1095 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001096
1097 // Returns deleted channels too
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001098 channels = mHelper.getNotificationChannels(PKG, UID, true).getList();
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001099 assertEquals(3, channels.size()); // Includes default channel
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001100 for (NotificationChannel nc : channels) {
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001101 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1102 compareChannels(channelMap.get(nc.getId()), nc);
1103 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001104 }
1105 }
1106
1107 @Test
Julia Reynolds41103f42017-03-15 11:36:35 -04001108 public void testGetDeletedChannelCount() throws Exception {
1109 NotificationChannel channel =
1110 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1111 NotificationChannel channel2 =
1112 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1113 NotificationChannel channel3 =
Julia Reynoldsf2e499d2018-03-30 10:36:42 -04001114 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001115 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1116 mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
1117 mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
Julia Reynolds41103f42017-03-15 11:36:35 -04001118
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001119 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
1120 mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
Julia Reynolds41103f42017-03-15 11:36:35 -04001121
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001122 assertEquals(2, mHelper.getDeletedChannelCount(PKG, UID));
1123 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID2));
Julia Reynolds41103f42017-03-15 11:36:35 -04001124 }
1125
1126 @Test
Julia Reynoldsf2e499d2018-03-30 10:36:42 -04001127 public void testGetBlockedChannelCount() throws Exception {
1128 NotificationChannel channel =
1129 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1130 NotificationChannel channel2 =
1131 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
1132 NotificationChannel channel3 =
1133 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
1134 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1135 mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
1136 mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
1137
1138 mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
1139
1140 assertEquals(1, mHelper.getBlockedChannelCount(PKG, UID));
1141 assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID2));
1142 }
1143
1144 @Test
Beverly86d076f2018-04-17 14:44:52 -04001145 public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception {
1146 // create notification channel that can't bypass dnd
1147 // expected result: areChannelsBypassingDnd = false
Beverlyc36640f2018-05-21 16:14:15 -04001148 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
Beverly86d076f2018-04-17 14:44:52 -04001149 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
1150 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1151 assertFalse(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001152 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1153 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001154
Beverlyc36640f2018-05-21 16:14:15 -04001155 // create notification channel that can bypass dnd
Beverly86d076f2018-04-17 14:44:52 -04001156 // expected result: areChannelsBypassingDnd = true
1157 NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1158 channel2.setBypassDnd(true);
1159 mHelper.createNotificationChannel(PKG, UID, channel2, true, true);
1160 assertTrue(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001161 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1162 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001163
1164 // delete channels
1165 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
1166 assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
Beverlyc36640f2018-05-21 16:14:15 -04001167 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1168 resetZenModeHelper();
1169
Beverly86d076f2018-04-17 14:44:52 -04001170 mHelper.deleteNotificationChannel(PKG, UID, channel2.getId());
1171 assertFalse(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001172 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1173 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001174 }
1175
1176 @Test
1177 public void testUpdateCanChannelsBypassDnd() throws Exception {
1178 // create notification channel that can't bypass dnd
1179 // expected result: areChannelsBypassingDnd = false
Beverlyc36640f2018-05-21 16:14:15 -04001180 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
Beverly86d076f2018-04-17 14:44:52 -04001181 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
1182 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1183 assertFalse(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001184 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1185 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001186
1187 // update channel so it CAN bypass dnd:
1188 // expected result: areChannelsBypassingDnd = true
1189 channel.setBypassDnd(true);
1190 mHelper.updateNotificationChannel(PKG, UID, channel, true);
1191 assertTrue(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001192 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1193 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001194
1195 // update channel so it can't bypass dnd:
1196 // expected result: areChannelsBypassingDnd = false
1197 channel.setBypassDnd(false);
1198 mHelper.updateNotificationChannel(PKG, UID, channel, true);
1199 assertFalse(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001200 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1201 resetZenModeHelper();
1202 }
1203
1204 @Test
1205 public void testSetupNewZenModeHelper_canBypass() {
1206 // start notification policy off with mAreChannelsBypassingDnd = true, but
1207 // RankingHelper should change to false
1208 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
1209 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
1210 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
1211 mHelper = new RankingHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
1212 mUsageStats, new String[] {ImportanceExtractor.class.getName()});
1213 assertFalse(mHelper.areChannelsBypassingDnd());
1214 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1215 resetZenModeHelper();
1216 }
1217
1218 @Test
1219 public void testSetupNewZenModeHelper_cannotBypass() {
1220 // start notification policy off with mAreChannelsBypassingDnd = false
1221 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0);
1222 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
1223 mHelper = new RankingHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
1224 mUsageStats, new String[] {ImportanceExtractor.class.getName()});
1225 assertFalse(mHelper.areChannelsBypassingDnd());
1226 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1227 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001228 }
1229
1230 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001231 public void testCreateDeletedChannel() throws Exception {
Julia Reynolds619a69f2017-01-27 15:11:38 -05001232 long[] vibration = new long[]{100, 67, 145, 156};
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001233 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001234 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001235 channel.setVibrationPattern(vibration);
1236
Julia Reynolds1fe10942018-03-28 12:46:51 -04001237 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001238 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001239
1240 NotificationChannel newChannel = new NotificationChannel(
1241 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001242 newChannel.setVibrationPattern(new long[]{100});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001243
Julia Reynolds1fe10942018-03-28 12:46:51 -04001244 mHelper.createNotificationChannel(PKG, UID, newChannel, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001245
1246 // No long deleted, using old settings
1247 compareChannels(channel,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001248 mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001249 }
1250
1251 @Test
Julia Reynolds17717f52017-05-09 11:46:06 -04001252 public void testOnlyHasDefaultChannel() throws Exception {
1253 assertTrue(mHelper.onlyHasDefaultChannel(PKG, UID));
1254 assertFalse(mHelper.onlyHasDefaultChannel(UPDATED_PKG, UID2));
1255
Julia Reynolds1fe10942018-03-28 12:46:51 -04001256 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynolds17717f52017-05-09 11:46:06 -04001257 assertFalse(mHelper.onlyHasDefaultChannel(PKG, UID));
1258 }
1259
1260 @Test
Julia Reynolds03fa85d2017-03-06 15:14:50 -05001261 public void testCreateChannel_defaultChannelId() throws Exception {
1262 try {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001263 mHelper.createNotificationChannel(PKG, UID, new NotificationChannel(
Julia Reynolds1fe10942018-03-28 12:46:51 -04001264 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
Julia Reynolds03fa85d2017-03-06 15:14:50 -05001265 fail("Allowed to create default channel");
1266 } catch (IllegalArgumentException e) {
1267 // pass
1268 }
1269 }
1270
1271 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001272 public void testCreateChannel_alreadyExists() throws Exception {
Julia Reynolds619a69f2017-01-27 15:11:38 -05001273 long[] vibration = new long[]{100, 67, 145, 156};
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001274 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001275 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001276 channel.setVibrationPattern(vibration);
1277
Julia Reynolds1fe10942018-03-28 12:46:51 -04001278 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001279
1280 NotificationChannel newChannel = new NotificationChannel(
1281 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001282 newChannel.setVibrationPattern(new long[]{100});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001283
Julia Reynolds1fe10942018-03-28 12:46:51 -04001284 mHelper.createNotificationChannel(PKG, UID, newChannel, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001285
1286 // Old settings not overridden
1287 compareChannels(channel,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001288 mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001289 }
1290
1291 @Test
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001292 public void testCreateChannel_noOverrideSound() throws Exception {
1293 Uri sound = new Uri.Builder().scheme("test").build();
1294 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1295 NotificationManager.IMPORTANCE_DEFAULT);
1296 channel.setSound(sound, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001297 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001298 assertEquals(sound, mHelper.getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001299 PKG, UID, channel.getId(), false).getSound());
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001300 }
1301
1302 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001303 public void testPermanentlyDeleteChannels() throws Exception {
1304 NotificationChannel channel1 =
1305 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1306 NotificationChannel channel2 =
Julia Reynolds74856c42017-02-08 14:47:23 -05001307 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001308
Julia Reynolds1fe10942018-03-28 12:46:51 -04001309 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
1310 mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001311
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001312 mHelper.permanentlyDeleteNotificationChannels(PKG, UID);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001313
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001314 // Only default channel remains
1315 assertEquals(1, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001316 }
1317
1318 @Test
Julia Reynolds9bfba592017-03-15 14:03:55 -04001319 public void testDeleteGroup() throws Exception {
1320 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1321 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1322 NotificationChannel nonGroupedNonDeletedChannel =
1323 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1324 NotificationChannel groupedButNotDeleted =
1325 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1326 groupedButNotDeleted.setGroup("not");
1327 NotificationChannel groupedAndDeleted =
1328 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1329 groupedAndDeleted.setGroup("totally");
1330
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001331 mHelper.createNotificationChannelGroup(PKG, UID, notDeleted, true);
1332 mHelper.createNotificationChannelGroup(PKG, UID, deleted, true);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001333 mHelper.createNotificationChannel(PKG, UID, nonGroupedNonDeletedChannel, true, false);
1334 mHelper.createNotificationChannel(PKG, UID, groupedAndDeleted, true, false);
1335 mHelper.createNotificationChannel(PKG, UID, groupedButNotDeleted, true, false);
Julia Reynolds9bfba592017-03-15 14:03:55 -04001336
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001337 mHelper.deleteNotificationChannelGroup(PKG, UID, deleted.getId());
Julia Reynolds9bfba592017-03-15 14:03:55 -04001338
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001339 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG, UID));
1340 assertNotNull(mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG, UID));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001341
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001342 assertNull(mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001343 compareChannels(groupedAndDeleted,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001344 mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), true));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001345
1346 compareChannels(groupedButNotDeleted,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001347 mHelper.getNotificationChannel(PKG, UID, groupedButNotDeleted.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001348 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001349 PKG, UID, nonGroupedNonDeletedChannel.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001350
1351 // notDeleted
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001352 assertEquals(1, mHelper.getNotificationChannelGroups(PKG, UID).size());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001353
1354 verify(mHandler, never()).requestSort();
Julia Reynolds9bfba592017-03-15 14:03:55 -04001355 }
1356
1357 @Test
Julia Reynolds2e9bf5f2017-05-03 13:23:30 -04001358 public void testOnUserRemoved() throws Exception {
1359 int[] user0Uids = {98, 235, 16, 3782};
1360 int[] user1Uids = new int[user0Uids.length];
1361 for (int i = 0; i < user0Uids.length; i++) {
1362 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1363
1364 final ApplicationInfo legacy = new ApplicationInfo();
1365 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1366 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
1367
1368 // create records with the default channel for all user 0 and user 1 uids
1369 mHelper.getImportance(PKG, user0Uids[i]);
1370 mHelper.getImportance(PKG, user1Uids[i]);
1371 }
1372
1373 mHelper.onUserRemoved(1);
1374
1375 // user 0 records remain
1376 for (int i = 0; i < user0Uids.length; i++) {
1377 assertEquals(1,
1378 mHelper.getNotificationChannels(PKG, user0Uids[i], false).getList().size());
1379 }
1380 // user 1 records are gone
1381 for (int i = 0; i < user1Uids.length; i++) {
1382 assertEquals(0,
1383 mHelper.getNotificationChannels(PKG, user1Uids[i], false).getList().size());
1384 }
1385 }
1386
1387 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001388 public void testOnPackageChanged_packageRemoval() throws Exception {
1389 // Deleted
1390 NotificationChannel channel1 =
1391 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001392 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001393
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001394 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001395
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001396 assertEquals(0, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001397
1398 // Not deleted
Julia Reynolds1fe10942018-03-28 12:46:51 -04001399 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001400
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001401 mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001402 assertEquals(2, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001403 }
Julia Reynolds924eed12017-01-19 09:52:07 -05001404
1405 @Test
Julia Reynolds59e152e2017-01-25 17:42:53 -05001406 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001407 mHelper.setImportance(PKG, UID, NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001408
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001409 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds59e152e2017-01-25 17:42:53 -05001410
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001411 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
Julia Reynolds59e152e2017-01-25 17:42:53 -05001412 }
1413
1414 @Test
1415 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1416 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001417 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001418 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001419 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001420
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001421 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds59e152e2017-01-25 17:42:53 -05001422
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001423 assertEquals(0,
1424 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList().size());
Julia Reynolds59e152e2017-01-25 17:42:53 -05001425 }
1426
1427 @Test
Julia Reynoldsf26eb912017-05-22 15:47:06 -04001428 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1429 // create channel as api 26
Julia Reynolds1fe10942018-03-28 12:46:51 -04001430 mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true, false);
Julia Reynoldsf26eb912017-05-22 15:47:06 -04001431
1432 // install new app version targeting 25
1433 final ApplicationInfo legacy = new ApplicationInfo();
1434 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1435 when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(legacy);
1436 mHelper.onPackagesChanged(
1437 false, UserHandle.USER_SYSTEM, new String[]{UPDATED_PKG}, new int[]{UID2});
1438
1439 // make sure the default channel was readded
1440 //assertEquals(2, mHelper.getNotificationChannels(UPDATED_PKG, UID2, false).getList().size());
1441 assertNotNull(mHelper.getNotificationChannel(
1442 UPDATED_PKG, UID2, NotificationChannel.DEFAULT_CHANNEL_ID, false));
1443 }
1444
1445 @Test
Julia Reynolds924eed12017-01-19 09:52:07 -05001446 public void testRecordDefaults() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001447 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
1448 assertEquals(true, mHelper.canShowBadge(PKG, UID));
1449 assertEquals(1, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
Julia Reynolds924eed12017-01-19 09:52:07 -05001450 }
Julia Reynolds59e152e2017-01-25 17:42:53 -05001451
1452 @Test
1453 public void testCreateGroup() throws Exception {
1454 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001455 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
1456 assertEquals(ncg, mHelper.getNotificationChannelGroups(PKG, UID).iterator().next());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001457 verify(mHandler, never()).requestSort();
Julia Reynolds59e152e2017-01-25 17:42:53 -05001458 }
1459
1460 @Test
1461 public void testCannotCreateChannel_badGroup() throws Exception {
1462 NotificationChannel channel1 =
1463 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1464 channel1.setGroup("garbage");
1465 try {
Julia Reynolds1fe10942018-03-28 12:46:51 -04001466 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001467 fail("Created a channel with a bad group");
Julia Reynolds619a69f2017-01-27 15:11:38 -05001468 } catch (IllegalArgumentException e) {
1469 }
Julia Reynolds59e152e2017-01-25 17:42:53 -05001470 }
1471
1472 @Test
1473 public void testCannotCreateChannel_goodGroup() throws Exception {
1474 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001475 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001476 NotificationChannel channel1 =
1477 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1478 channel1.setGroup(ncg.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001479 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001480
1481 assertEquals(ncg.getId(),
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001482 mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false).getGroup());
Julia Reynolds59e152e2017-01-25 17:42:53 -05001483 }
1484
1485 @Test
1486 public void testGetChannelGroups() throws Exception {
Julia Reynoldsf02562a2017-01-26 13:33:56 -05001487 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001488 mHelper.createNotificationChannelGroup(PKG, UID, unused, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001489 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001490 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001491 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001492 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001493
1494 NotificationChannel channel1 =
1495 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1496 channel1.setGroup(ncg.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001497 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001498 NotificationChannel channel1a =
1499 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1500 channel1a.setGroup(ncg.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001501 mHelper.createNotificationChannel(PKG, UID, channel1a, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001502
1503 NotificationChannel channel2 =
1504 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1505 channel2.setGroup(ncg2.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001506 mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001507
1508 NotificationChannel channel3 =
1509 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001510 mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001511
1512 List<NotificationChannelGroup> actual =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001513 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds59e152e2017-01-25 17:42:53 -05001514 assertEquals(3, actual.size());
Julia Reynolds619a69f2017-01-27 15:11:38 -05001515 for (NotificationChannelGroup group : actual) {
Julia Reynolds59e152e2017-01-25 17:42:53 -05001516 if (group.getId() == null) {
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001517 assertEquals(2, group.getChannels().size()); // misc channel too
1518 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1519 || channel3.getId().equals(group.getChannels().get(1).getId()));
Julia Reynolds59e152e2017-01-25 17:42:53 -05001520 } else if (group.getId().equals(ncg.getId())) {
1521 assertEquals(2, group.getChannels().size());
1522 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1523 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1524 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1525 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1526 } else {
1527 fail("expected channel not found");
1528 }
1529 } else if (group.getId().equals(ncg2.getId())) {
1530 assertEquals(1, group.getChannels().size());
1531 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1532 }
1533 }
1534 }
Julia Reynolds74856c42017-02-08 14:47:23 -05001535
1536 @Test
1537 public void testGetChannelGroups_noSideEffects() throws Exception {
1538 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001539 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds74856c42017-02-08 14:47:23 -05001540
1541 NotificationChannel channel1 =
1542 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1543 channel1.setGroup(ncg.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001544 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001545 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -05001546
1547 channel1.setImportance(IMPORTANCE_LOW);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001548 mHelper.updateNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds74856c42017-02-08 14:47:23 -05001549
1550 List<NotificationChannelGroup> actual =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001551 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -05001552
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001553 assertEquals(2, actual.size());
1554 for (NotificationChannelGroup group : actual) {
1555 if (Objects.equals(group.getId(), ncg.getId())) {
1556 assertEquals(1, group.getChannels().size());
1557 }
1558 }
Julia Reynolds74856c42017-02-08 14:47:23 -05001559 }
Julia Reynoldsd373d782017-03-03 13:32:57 -05001560
1561 @Test
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001562 public void testCreateChannel_updateName() throws Exception {
1563 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001564 mHelper.createNotificationChannel(PKG, UID, nc, true, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001565 NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001566 assertEquals("hello", actual.getName());
1567
1568 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001569 mHelper.createNotificationChannel(PKG, UID, nc, true, false);
Julia Reynoldsd373d782017-03-03 13:32:57 -05001570
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001571 actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001572 assertEquals("goodbye", actual.getName());
1573 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001574
1575 verify(mHandler, times(1)).requestSort();
Julia Reynoldsd373d782017-03-03 13:32:57 -05001576 }
1577
1578 @Test
Julia Reynolds005c8b92017-08-24 10:35:53 -04001579 public void testCreateChannel_addToGroup() throws Exception {
1580 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
1581 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1582 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001583 mHelper.createNotificationChannel(PKG, UID, nc, true, false);
Julia Reynolds005c8b92017-08-24 10:35:53 -04001584 NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
1585 assertNull(actual.getGroup());
1586
1587 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1588 nc.setGroup(group.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001589 mHelper.createNotificationChannel(PKG, UID, nc, true, false);
Julia Reynolds005c8b92017-08-24 10:35:53 -04001590
1591 actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
1592 assertNotNull(actual.getGroup());
1593 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1594
1595 verify(mHandler, times(1)).requestSort();
1596 }
1597
1598 @Test
Julia Reynoldsd373d782017-03-03 13:32:57 -05001599 public void testDumpChannelsJson() throws Exception {
1600 final ApplicationInfo upgrade = new ApplicationInfo();
1601 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
1602 try {
1603 when(mPm.getApplicationInfoAsUser(
1604 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
1605 } catch (PackageManager.NameNotFoundException e) {
1606 }
1607 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
1608 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
1609 for (int i = 0; i < numPackages; i++) {
1610 String pkgName = "pkg" + i;
1611 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
1612 for (int j = 0; j < numChannels; j++) {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001613 mHelper.createNotificationChannel(pkgName, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -04001614 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
Julia Reynoldsd373d782017-03-03 13:32:57 -05001615 }
1616 expectedChannels.put(pkgName, numChannels);
1617 }
1618
1619 // delete the first channel of the first package
1620 String pkg = expectedChannels.keyAt(0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001621 mHelper.deleteNotificationChannel("pkg" + 0, UID, "0");
Julia Reynoldsd373d782017-03-03 13:32:57 -05001622 // dump should not include deleted channels
1623 int count = expectedChannels.get(pkg);
1624 expectedChannels.put(pkg, count - 1);
1625
1626 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
1627 assertEquals(numPackages, actual.length());
1628 for (int i = 0; i < numPackages; i++) {
1629 JSONObject object = actual.getJSONObject(i);
1630 assertTrue(expectedChannels.containsKey(object.get("packageName")));
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -04001631 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
Julia Reynoldsd373d782017-03-03 13:32:57 -05001632 object.getInt("channelCount"));
1633 }
1634 }
Chris Wren89aa2262017-05-05 18:05:56 -04001635
1636 @Test
1637 public void testBadgingOverrideTrue() throws Exception {
1638 Secure.putIntForUser(getContext().getContentResolver(),
1639 Secure.NOTIFICATION_BADGING, 1,
1640 USER.getIdentifier());
1641 mHelper.updateBadgingEnabled(); // would be called by settings observer
1642 assertTrue(mHelper.badgingEnabled(USER));
1643 }
1644
1645 @Test
1646 public void testBadgingOverrideFalse() throws Exception {
1647 Secure.putIntForUser(getContext().getContentResolver(),
1648 Secure.NOTIFICATION_BADGING, 0,
1649 USER.getIdentifier());
1650 mHelper.updateBadgingEnabled(); // would be called by settings observer
1651 assertFalse(mHelper.badgingEnabled(USER));
1652 }
1653
1654 @Test
Chris Wren13f157f2017-05-12 15:02:06 -04001655 public void testBadgingForUserAll() throws Exception {
1656 try {
1657 mHelper.badgingEnabled(UserHandle.ALL);
1658 } catch (Exception e) {
1659 fail("just don't throw");
1660 }
1661 }
1662
1663 @Test
Chris Wren89aa2262017-05-05 18:05:56 -04001664 public void testBadgingOverrideUserIsolation() throws Exception {
1665 Secure.putIntForUser(getContext().getContentResolver(),
1666 Secure.NOTIFICATION_BADGING, 0,
1667 USER.getIdentifier());
1668 Secure.putIntForUser(getContext().getContentResolver(),
1669 Secure.NOTIFICATION_BADGING, 1,
1670 USER2.getIdentifier());
1671 mHelper.updateBadgingEnabled(); // would be called by settings observer
1672 assertFalse(mHelper.badgingEnabled(USER));
1673 assertTrue(mHelper.badgingEnabled(USER2));
1674 }
Julia Reynolds816797a2017-08-11 15:47:09 -04001675
1676 @Test
1677 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
1678 String newLabel = "bananas!";
1679 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
1680 NotificationChannel.DEFAULT_CHANNEL_ID, false);
1681 assertFalse(newLabel.equals(defaultChannel.getName()));
1682
1683 Resources res = mock(Resources.class);
1684 when(mContext.getResources()).thenReturn(res);
1685 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
1686 .thenReturn(newLabel);
1687
1688 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
1689
1690 assertEquals(newLabel, mHelper.getNotificationChannel(PKG, UID,
1691 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
1692 }
Julia Reynolds005c8b92017-08-24 10:35:53 -04001693
1694 @Test
1695 public void testIsGroupBlocked_noGroup() throws Exception {
1696 assertFalse(mHelper.isGroupBlocked(PKG, UID, null));
1697
1698 assertFalse(mHelper.isGroupBlocked(PKG, UID, "non existent group"));
1699 }
1700
1701 @Test
1702 public void testIsGroupBlocked_notBlocked() throws Exception {
1703 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1704 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1705
1706 assertFalse(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1707 }
1708
1709 @Test
1710 public void testIsGroupBlocked_blocked() throws Exception {
1711 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1712 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1713 group.setBlocked(true);
1714 mHelper.createNotificationChannelGroup(PKG, UID, group, false);
1715
1716 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1717 }
1718
1719 @Test
1720 public void testIsGroup_appCannotResetBlock() throws Exception {
1721 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1722 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1723 NotificationChannelGroup group2 = group.clone();
1724 group2.setBlocked(true);
1725 mHelper.createNotificationChannelGroup(PKG, UID, group2, false);
1726 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1727
1728 NotificationChannelGroup group3 = group.clone();
1729 group3.setBlocked(false);
1730 mHelper.createNotificationChannelGroup(PKG, UID, group3, true);
1731 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1732 }
1733
1734 @Test
1735 public void testGetNotificationChannelGroupWithChannels() throws Exception {
1736 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
1737 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
1738 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1739 mHelper.createNotificationChannelGroup(PKG, UID, other, true);
1740
1741 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
1742 a.setGroup(group.getId());
1743 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
1744 b.setGroup(other.getId());
1745 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
1746 c.setGroup(group.getId());
1747 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
1748
Julia Reynolds1fe10942018-03-28 12:46:51 -04001749 mHelper.createNotificationChannel(PKG, UID, a, true, false);
1750 mHelper.createNotificationChannel(PKG, UID, b, true, false);
1751 mHelper.createNotificationChannel(PKG, UID, c, true, false);
1752 mHelper.createNotificationChannel(PKG, UID, d, true, false);
Julia Reynolds005c8b92017-08-24 10:35:53 -04001753 mHelper.deleteNotificationChannel(PKG, UID, c.getId());
1754
1755 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
1756 PKG, UID, group.getId(), true);
1757 assertEquals(2, retrieved.getChannels().size());
1758 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
1759 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
1760
1761 retrieved = mHelper.getNotificationChannelGroupWithChannels(
1762 PKG, UID, group.getId(), false);
1763 assertEquals(1, retrieved.getChannels().size());
1764 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
1765 }
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001766
1767 @Test
Julia Reynolds7f6681d2018-05-01 12:28:56 -04001768 public void testAndroidPkgCannotBypassDnd_creation() {
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001769 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1770 test.setBypassDnd(true);
1771
Julia Reynolds1fe10942018-03-28 12:46:51 -04001772 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001773
Julia Reynolds7f6681d2018-05-01 12:28:56 -04001774 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001775 .canBypassDnd());
1776 }
1777
1778 @Test
Julia Reynolds1fe10942018-03-28 12:46:51 -04001779 public void testDndPkgCanBypassDnd_creation() {
1780 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1781 test.setBypassDnd(true);
1782
1783 mHelper.createNotificationChannel(PKG, UID, test, true, true);
1784
1785 assertTrue(mHelper.getNotificationChannel(PKG, UID, "A", false).canBypassDnd());
1786 }
1787
1788 @Test
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001789 public void testNormalPkgCannotBypassDnd_creation() {
1790 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1791 test.setBypassDnd(true);
1792
Julia Reynolds1fe10942018-03-28 12:46:51 -04001793 mHelper.createNotificationChannel(PKG, 1000, test, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001794
1795 assertFalse(mHelper.getNotificationChannel(PKG, 1000, "A", false).canBypassDnd());
1796 }
1797
1798 @Test
Julia Reynolds7f6681d2018-05-01 12:28:56 -04001799 public void testAndroidPkgCannotBypassDnd_update() throws Exception {
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001800 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001801 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001802
1803 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1804 update.setBypassDnd(true);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001805 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001806
Julia Reynolds7f6681d2018-05-01 12:28:56 -04001807 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001808 .canBypassDnd());
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001809 }
1810
1811 @Test
Julia Reynolds1fe10942018-03-28 12:46:51 -04001812 public void testDndPkgCanBypassDnd_update() throws Exception {
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001813 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001814 mHelper.createNotificationChannel(PKG, UID, test, true, true);
1815
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001816 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1817 update.setBypassDnd(true);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001818 mHelper.createNotificationChannel(PKG, UID, update, true, true);
1819
1820 assertTrue(mHelper.getNotificationChannel(PKG, UID, "A", false).canBypassDnd());
1821 }
1822
1823 @Test
1824 public void testNormalPkgCannotBypassDnd_update() {
1825 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1826 mHelper.createNotificationChannel(PKG, 1000, test, true, false);
1827 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1828 update.setBypassDnd(true);
1829 mHelper.createNotificationChannel(PKG, 1000, update, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001830 assertFalse(mHelper.getNotificationChannel(PKG, 1000, "A", false).canBypassDnd());
1831 }
Julia Reynoldse273f082018-04-12 13:48:49 -04001832
1833 @Test
1834 public void testGetBlockedAppCount_noApps() {
1835 assertEquals(0, mHelper.getBlockedAppCount(0));
1836 }
1837
1838 @Test
1839 public void testGetBlockedAppCount_noAppsForUserId() {
1840 mHelper.setEnabled(PKG, 100, false);
1841 assertEquals(0, mHelper.getBlockedAppCount(9));
1842 }
1843
1844 @Test
1845 public void testGetBlockedAppCount_appsForUserId() {
1846 mHelper.setEnabled(PKG, 1020, false);
1847 mHelper.setEnabled(PKG, 1030, false);
1848 mHelper.setEnabled(PKG, 1060, false);
1849 mHelper.setEnabled(PKG, 1000, true);
1850 assertEquals(3, mHelper.getBlockedAppCount(0));
1851 }
Chris Wren1031c972014-07-23 13:11:45 +00001852}