blob: 80439cf663878c6c790518511acbb30af9847e9c [file] [log] [blame]
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.notification;
17
18import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
19import static android.app.NotificationManager.IMPORTANCE_HIGH;
20import static android.app.NotificationManager.IMPORTANCE_LOW;
21import static android.app.NotificationManager.IMPORTANCE_MAX;
22import static android.app.NotificationManager.IMPORTANCE_NONE;
23import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
24
Julia Reynolds198282a2019-08-20 16:08:42 -040025import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
26
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040027import static junit.framework.Assert.assertNull;
28import static junit.framework.Assert.fail;
29
30import static org.junit.Assert.assertEquals;
31import static org.junit.Assert.assertFalse;
32import static org.junit.Assert.assertNotNull;
33import static org.junit.Assert.assertTrue;
34import static org.mockito.ArgumentMatchers.any;
35import static org.mockito.Matchers.anyInt;
36import static org.mockito.Matchers.anyString;
37import static org.mockito.Matchers.eq;
38import static org.mockito.Mockito.mock;
39import static org.mockito.Mockito.never;
40import static org.mockito.Mockito.reset;
41import static org.mockito.Mockito.times;
42import static org.mockito.Mockito.verify;
43import static org.mockito.Mockito.when;
44
45import android.app.Notification;
46import android.app.NotificationChannel;
47import android.app.NotificationChannelGroup;
48import android.app.NotificationManager;
49import android.content.ContentProvider;
50import android.content.Context;
51import android.content.IContentProvider;
52import android.content.pm.ApplicationInfo;
53import android.content.pm.PackageInfo;
54import android.content.pm.PackageManager;
55import android.content.pm.Signature;
56import android.content.res.Resources;
57import android.graphics.Color;
58import android.media.AudioAttributes;
59import android.net.Uri;
60import android.os.Build;
61import android.os.UserHandle;
62import android.provider.Settings;
Lyn Han4463f842019-07-09 15:27:28 -070063import android.provider.Settings.Global;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040064import android.provider.Settings.Secure;
Lyn Han4463f842019-07-09 15:27:28 -070065
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040066import android.test.suitebuilder.annotation.SmallTest;
67import android.testing.TestableContentResolver;
68import android.util.ArrayMap;
Julia Reynolds0c245002019-03-27 16:10:11 -040069import android.util.ArraySet;
Julia Reynoldse7ca31b2019-04-25 15:41:47 -040070import android.util.Pair;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040071import android.util.Xml;
72
Beverly47679222019-05-16 15:46:11 -040073import androidx.test.InstrumentationRegistry;
74import androidx.test.runner.AndroidJUnit4;
75
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040076import com.android.internal.util.FastXmlSerializer;
77import com.android.server.UiServiceTestCase;
78
79import org.json.JSONArray;
80import org.json.JSONObject;
81import org.junit.Before;
82import org.junit.Test;
83import org.junit.runner.RunWith;
84import org.mockito.Mock;
85import org.mockito.MockitoAnnotations;
86import org.xmlpull.v1.XmlPullParser;
87import org.xmlpull.v1.XmlSerializer;
88
89import java.io.BufferedInputStream;
90import java.io.BufferedOutputStream;
91import java.io.ByteArrayInputStream;
92import java.io.ByteArrayOutputStream;
93import java.util.Arrays;
94import java.util.HashMap;
95import java.util.List;
96import java.util.Map;
97import java.util.Objects;
98import java.util.concurrent.ThreadLocalRandom;
99
100@SmallTest
101@RunWith(AndroidJUnit4.class)
102public class PreferencesHelperTest extends UiServiceTestCase {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400103 private static final int UID_N_MR1 = 0;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400104 private static final UserHandle USER = UserHandle.of(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400105 private static final int UID_O = 1111;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400106 private static final String SYSTEM_PKG = "android";
Beverly0479cde22018-11-09 11:05:34 -0500107 private static final int SYSTEM_UID = 1000;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400108 private static final UserHandle USER2 = UserHandle.of(10);
109 private static final String TEST_CHANNEL_ID = "test_channel_id";
110 private static final String TEST_AUTHORITY = "test";
111 private static final Uri SOUND_URI =
112 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
113 private static final Uri CANONICAL_SOUND_URI =
114 Uri.parse("content://" + TEST_AUTHORITY
115 + "/internal/audio/media/10?title=Test&canonical=1");
116
117 @Mock NotificationUsageStats mUsageStats;
118 @Mock RankingHandler mHandler;
119 @Mock PackageManager mPm;
120 @Mock IContentProvider mTestIContentProvider;
121 @Mock Context mContext;
122 @Mock ZenModeHelper mMockZenModeHelper;
123
124 private NotificationManager.Policy mTestNotificationPolicy;
125
126 private PreferencesHelper mHelper;
127 private AudioAttributes mAudioAttributes;
128
129 @Before
130 public void setUp() throws Exception {
131 MockitoAnnotations.initMocks(this);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400132
133 final ApplicationInfo legacy = new ApplicationInfo();
134 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
135 final ApplicationInfo upgrade = new ApplicationInfo();
136 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400137 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
138 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400139 when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400140 when(mPm.getPackageUidAsUser(eq(PKG_N_MR1), anyInt())).thenReturn(UID_N_MR1);
141 when(mPm.getPackageUidAsUser(eq(PKG_O), anyInt())).thenReturn(UID_O);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400142 when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
143 PackageInfo info = mock(PackageInfo.class);
144 info.signatures = new Signature[] {mock(Signature.class)};
145 when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400146 when(mPm.getPackageInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt()))
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400147 .thenReturn(mock(PackageInfo.class));
148 when(mContext.getResources()).thenReturn(
149 InstrumentationRegistry.getContext().getResources());
150 when(mContext.getContentResolver()).thenReturn(
151 InstrumentationRegistry.getContext().getContentResolver());
152 when(mContext.getPackageManager()).thenReturn(mPm);
153 when(mContext.getApplicationInfo()).thenReturn(legacy);
154 // most tests assume badging is enabled
155 TestableContentResolver contentResolver = getContext().getContentResolver();
156 contentResolver.setFallbackToExisting(false);
157 Secure.putIntForUser(contentResolver,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400158 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID_N_MR1));
Lyn Han4463f842019-07-09 15:27:28 -0700159 Global.putInt(contentResolver, Global.NOTIFICATION_BUBBLES, 1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400160
161 ContentProvider testContentProvider = mock(ContentProvider.class);
162 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
163 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
164
165 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
166 .thenReturn(CANONICAL_SOUND_URI);
167 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
168 .thenReturn(CANONICAL_SOUND_URI);
169 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
170 .thenReturn(SOUND_URI);
171
172 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
173 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
174 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
175 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
176 resetZenModeHelper();
177
178 mAudioAttributes = new AudioAttributes.Builder()
179 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
180 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
181 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
182 .build();
183 }
184
Annie Meng8b646fd2019-02-01 18:46:42 +0000185 private ByteArrayOutputStream writeXmlAndPurge(
186 String pkg, int uid, boolean forBackup, int userId, String... channelIds)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400187 throws Exception {
188 XmlSerializer serializer = new FastXmlSerializer();
189 ByteArrayOutputStream baos = new ByteArrayOutputStream();
190 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
191 serializer.startDocument(null, true);
Annie Meng8b646fd2019-02-01 18:46:42 +0000192 mHelper.writeXml(serializer, forBackup, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400193 serializer.endDocument();
194 serializer.flush();
195 for (String channelId : channelIds) {
196 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
197 }
198 return baos;
199 }
200
Annie Meng8b646fd2019-02-01 18:46:42 +0000201 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore, int userId)
202 throws Exception {
203 loadByteArrayXml(stream.toByteArray(), forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400204 }
205
Annie Meng8b646fd2019-02-01 18:46:42 +0000206 private void loadByteArrayXml(byte[] byteArray, boolean forRestore, int userId)
207 throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400208 XmlPullParser parser = Xml.newPullParser();
209 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
210 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000211 mHelper.readXml(parser, forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400212 }
213
214 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
215 assertEquals(expected.getId(), actual.getId());
216 assertEquals(expected.getName(), actual.getName());
217 assertEquals(expected.getDescription(), actual.getDescription());
218 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
219 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
220 assertEquals(expected.getImportance(), actual.getImportance());
221 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
222 assertEquals(expected.getSound(), actual.getSound());
223 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
224 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
225 assertEquals(expected.getGroup(), actual.getGroup());
226 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
227 assertEquals(expected.getLightColor(), actual.getLightColor());
228 }
229
230 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
231 assertEquals(expected.getId(), actual.getId());
232 assertEquals(expected.getName(), actual.getName());
233 assertEquals(expected.getDescription(), actual.getDescription());
234 assertEquals(expected.isBlocked(), actual.isBlocked());
235 }
236
237 private NotificationChannel getChannel() {
238 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
239 }
240
241 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
242 for (NotificationChannel channel : channels) {
243 if (channel.getId().equals(id)) {
244 return channel;
245 }
246 }
247 return null;
248 }
249
250 private void resetZenModeHelper() {
251 reset(mMockZenModeHelper);
252 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
253 }
254
Annie Meng8b646fd2019-02-01 18:46:42 +0000255 private void setUpPackageWithUid(String packageName, int uid) throws Exception {
256 when(mPm.getApplicationInfoAsUser(eq(packageName), anyInt(), anyInt()))
257 .thenReturn(new ApplicationInfo());
258 when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
259 }
260
261 @Test
262 public void testWriteXml_onlyBackupsTargetUser() throws Exception {
263 // Setup package notifications.
264 String package0 = "test.package.user0";
265 int uid0 = 1001;
266 setUpPackageWithUid(package0, uid0);
267 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400268 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000269
270 String package10 = "test.package.user10";
271 int uid10 = 1001001;
272 setUpPackageWithUid(package10, uid10);
273 NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400274 assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000275
276 ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
277
278 // Reset state.
279 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
280 mHelper.onPackagesChanged(true, 10, new String[] {package10}, new int[] {uid10});
281
282 // Parse backup data.
283 loadStreamXml(baos, true, 0);
284 loadStreamXml(baos, true, 10);
285
286 assertEquals(
287 channel10,
288 mHelper.getNotificationChannel(package10, uid10, channel10.getId(), false));
289 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
290 }
291
292 @Test
293 public void testReadXml_onlyRestoresTargetUser() throws Exception {
294 // Setup package in user 0.
295 String package0 = "test.package.user0";
296 int uid0 = 1001;
297 setUpPackageWithUid(package0, uid0);
298 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400299 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000300
301 ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
302
303 // Reset state.
304 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
305
306 // Restore should convert the uid according to the target user.
307 int expectedUid = 1001001;
308 setUpPackageWithUid(package0, expectedUid);
309 // Parse backup data.
310 loadStreamXml(baos, true, 10);
311
312 assertEquals(
313 channel0,
314 mHelper.getNotificationChannel(package0, expectedUid, channel0.getId(), false));
315 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
316 }
317
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400318 @Test
319 public void testChannelXml() throws Exception {
320 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
321 ncg.setBlocked(true);
322 ncg.setDescription("group desc");
323 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
324 NotificationChannel channel1 =
325 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
326 NotificationChannel channel2 =
327 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
328 channel2.setDescription("descriptions for all");
329 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
330 channel2.enableLights(true);
331 channel2.setBypassDnd(true);
332 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
333 channel2.enableVibration(true);
334 channel2.setGroup(ncg.getId());
335 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
336 channel2.setLightColor(Color.BLUE);
337
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400338 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
339 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400340 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
341 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400342
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400343 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
344 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400345
Annie Meng8b646fd2019-02-01 18:46:42 +0000346 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
347 UserHandle.USER_ALL, channel1.getId(), channel2.getId(),
348 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400349 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
350 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400351
Annie Meng8b646fd2019-02-01 18:46:42 +0000352 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400353
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400354 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
355 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400356 assertEquals(channel1,
357 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400358 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400359 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400360
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400361 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
362 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400363 boolean foundNcg = false;
364 for (NotificationChannelGroup actual : actualGroups) {
365 if (ncg.getId().equals(actual.getId())) {
366 foundNcg = true;
367 compareGroups(ncg, actual);
368 } else if (ncg2.getId().equals(actual.getId())) {
369 compareGroups(ncg2, actual);
370 }
371 }
372 assertTrue(foundNcg);
373
374 boolean foundChannel2Group = false;
375 for (NotificationChannelGroup actual : actualGroups) {
376 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
377 foundChannel2Group = true;
378 break;
379 }
380 }
381 assertTrue(foundChannel2Group);
382 }
383
384 @Test
385 public void testChannelXmlForBackup() throws Exception {
386 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
387 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
388 NotificationChannel channel1 =
389 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
390 NotificationChannel channel2 =
391 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
392 channel2.setDescription("descriptions for all");
393 channel2.setSound(SOUND_URI, mAudioAttributes);
394 channel2.enableLights(true);
395 channel2.setBypassDnd(true);
396 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
397 channel2.enableVibration(false);
398 channel2.setGroup(ncg.getId());
399 channel2.setLightColor(Color.BLUE);
400 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
401 channel3.enableVibration(true);
402
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400403 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
404 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
405 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
406 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
407 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
408 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400409
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400410 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400411
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400412 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400413
Annie Meng8b646fd2019-02-01 18:46:42 +0000414 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
415 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
416 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400417 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1, PKG_O},
418 new int[]{UID_N_MR1, UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400419
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400420 mHelper.setShowBadge(PKG_O, UID_O, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400421
Annie Meng8b646fd2019-02-01 18:46:42 +0000422 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400423
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400424 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O));
425 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400426 assertEquals(channel1,
427 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400428 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400429 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400430 compareChannels(channel3,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400431 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400432
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400433 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
434 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400435 boolean foundNcg = false;
436 for (NotificationChannelGroup actual : actualGroups) {
437 if (ncg.getId().equals(actual.getId())) {
438 foundNcg = true;
439 compareGroups(ncg, actual);
440 } else if (ncg2.getId().equals(actual.getId())) {
441 compareGroups(ncg2, actual);
442 }
443 }
444 assertTrue(foundNcg);
445
446 boolean foundChannel2Group = false;
447 for (NotificationChannelGroup actual : actualGroups) {
448 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
449 foundChannel2Group = true;
450 break;
451 }
452 }
453 assertTrue(foundChannel2Group);
454 }
455
456 @Test
457 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
458 NotificationChannel channel =
459 new NotificationChannel("id", "name", IMPORTANCE_LOW);
460 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400461 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400462
Annie Meng8b646fd2019-02-01 18:46:42 +0000463 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
464 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400465
466 // Testing that in restore we are given the canonical version
Annie Meng8b646fd2019-02-01 18:46:42 +0000467 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400468 verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
469 }
470
471 @Test
472 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
473 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
474 Uri canonicalBasedOnLocal = localUri.buildUpon()
475 .appendQueryParameter("title", "Test")
476 .appendQueryParameter("canonical", "1")
477 .build();
478 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
479 .thenReturn(canonicalBasedOnLocal);
480 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
481 .thenReturn(localUri);
482 when(mTestIContentProvider.uncanonicalize(any(), eq(canonicalBasedOnLocal)))
483 .thenReturn(localUri);
484
485 NotificationChannel channel =
486 new NotificationChannel("id", "name", IMPORTANCE_LOW);
487 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400488 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000489 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
490 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400491
Annie Meng8b646fd2019-02-01 18:46:42 +0000492 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400493
494 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400495 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400496 assertEquals(localUri, actualChannel.getSound());
497 }
498
499 @Test
500 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
501 Thread.sleep(3000);
502 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
503 .thenReturn(null);
504 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
505 .thenReturn(null);
506
507 NotificationChannel channel =
508 new NotificationChannel("id", "name", IMPORTANCE_LOW);
509 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400510 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000511 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
512 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400513
Annie Meng8b646fd2019-02-01 18:46:42 +0000514 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400515
516 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400517 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400518 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
519 }
520
521
522 /**
523 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
524 * handle its restore properly.
525 */
526 @Test
527 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
528 // Not a local uncanonicalized uri, simulating that it fails to exist locally
529 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI))).thenReturn(null);
530 String id = "id";
531 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400532 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400533 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
534 + "sound=\"" + SOUND_URI + "\" "
535 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
536 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
537 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
538 + "</package>\n"
539 + "</ranking>\n";
540
Annie Meng8b646fd2019-02-01 18:46:42 +0000541 loadByteArrayXml(
542 backupWithUncanonicalizedSoundUri.getBytes(), true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400543
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400544 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, id, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400545 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
546 }
547
548 @Test
549 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
550 NotificationChannel channel =
551 new NotificationChannel("id", "name", IMPORTANCE_LOW);
552 channel.setSound(null, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400553 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000554 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
555 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400556
Annie Meng8b646fd2019-02-01 18:46:42 +0000557 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400558
559 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400560 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400561 assertEquals(null, actualChannel.getSound());
562 }
563
564 @Test
565 public void testChannelXml_backup() throws Exception {
566 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
567 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
568 NotificationChannel channel1 =
569 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
570 NotificationChannel channel2 =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400571 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400572 NotificationChannel channel3 =
573 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
574 channel3.setGroup(ncg.getId());
575
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400576 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
577 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
578 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
579 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
580 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400581
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400582 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId());
583 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId());
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400584 assertEquals(channel2,
585 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400586
Annie Meng8b646fd2019-02-01 18:46:42 +0000587 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
588 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
589 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400590 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
591 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400592
593 XmlPullParser parser = Xml.newPullParser();
594 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
595 null);
596 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000597 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400598
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400599 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
600 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
601 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400602 assertEquals(channel2,
603 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400604 }
605
606 @Test
607 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400608 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000609 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400610
Annie Meng8b646fd2019-02-01 18:46:42 +0000611 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400612
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400613 final NotificationChannel updated = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400614 NotificationChannel.DEFAULT_CHANNEL_ID, false);
615 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
616 assertFalse(updated.canBypassDnd());
617 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
618 assertEquals(0, updated.getUserLockedFields());
619 }
620
621 @Test
622 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400623 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
624 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400625 NotificationChannel.DEFAULT_CHANNEL_ID, false);
626 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400627 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400628
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400629 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000630 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400631
Annie Meng8b646fd2019-02-01 18:46:42 +0000632 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400633
634 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400635 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400636 }
637
638 @Test
639 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
640 final String preupgradeXml = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400641 + "<package name=\"" + PKG_N_MR1
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400642 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
643 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400644 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID_N_MR1 + "\" />\n"
645 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" visibility=\""
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400646 + Notification.VISIBILITY_PRIVATE + "\" />\n"
647 + "</ranking>";
648 XmlPullParser parser = Xml.newPullParser();
649 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
650 null);
651 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000652 mHelper.readXml(parser, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400653
654 final NotificationChannel updated1 =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400655 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400656 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
657 assertTrue(updated1.canBypassDnd());
658 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
659 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
660 | NotificationChannel.USER_LOCKED_PRIORITY
661 | NotificationChannel.USER_LOCKED_VISIBILITY,
662 updated1.getUserLockedFields());
663
664 // No Default Channel created for updated packages
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400665 assertEquals(null, mHelper.getNotificationChannel(PKG_O, UID_O,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400666 NotificationChannel.DEFAULT_CHANNEL_ID, false));
667 }
668
669 @Test
670 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
671 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400672 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400673 assertTrue(defaultChannel != null);
Annie Meng8b646fd2019-02-01 18:46:42 +0000674 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
675 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400676 // Load package at higher sdk.
677 final ApplicationInfo upgraded = new ApplicationInfo();
678 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400679 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000680 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400681
682 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400683 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400684 NotificationChannel.DEFAULT_CHANNEL_ID, false));
685 }
686
687 @Test
688 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400689 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400690 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400691 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000692 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400693
694 // Load package at higher sdk.
695 final ApplicationInfo upgraded = new ApplicationInfo();
696 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400697 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000698 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400699
700 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400701 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400702 NotificationChannel.DEFAULT_CHANNEL_ID, false));
703 }
704
705 @Test
706 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400707 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000708 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400709 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400710 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
711
Annie Meng8b646fd2019-02-01 18:46:42 +0000712 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400713
714 // Should still have the newly created channel that wasn't in the xml.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400715 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "bananas", false) != null);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400716 }
717
718 @Test
719 public void testCreateChannel_blocked() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400720 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400721
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400722 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
723 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400724 }
725
726 @Test
727 public void testCreateChannel_badImportance() throws Exception {
728 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400729 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400730 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
731 true, false);
732 fail("Was allowed to create a channel with invalid importance");
733 } catch (IllegalArgumentException e) {
734 // yay
735 }
736 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400737 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400738 new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
739 true, false);
740 fail("Was allowed to create a channel with invalid importance");
741 } catch (IllegalArgumentException e) {
742 // yay
743 }
744 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400745 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400746 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
747 true, false);
748 fail("Was allowed to create a channel with invalid importance");
749 } catch (IllegalArgumentException e) {
750 // yay
751 }
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400752 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
753 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
754 assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
755 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400756 }
757
758
759 @Test
760 public void testUpdate() throws Exception {
761 // no fields locked by user
762 final NotificationChannel channel =
763 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
764 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
765 channel.enableLights(true);
766 channel.setBypassDnd(true);
767 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
768
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400769 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400770
771 // same id, try to update all fields
772 final NotificationChannel channel2 =
773 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
774 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
775 channel2.enableLights(false);
776 channel2.setBypassDnd(false);
777 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
778
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400779 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400780
781 // all fields should be changed
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400782 assertEquals(channel2,
783 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400784
785 verify(mHandler, times(1)).requestSort();
786 }
787
788 @Test
789 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400790 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_UNSPECIFIED);
791 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
792 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400793 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400794 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
795 assertFalse(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400796
797 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400798 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400799
800 defaultChannel.setShowBadge(false);
801 defaultChannel.setImportance(IMPORTANCE_NONE);
802 defaultChannel.setBypassDnd(true);
803 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
804
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400805 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
806 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400807
808 // ensure app level fields are changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400809 assertFalse(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
810 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
811 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1,
812 UID_N_MR1));
813 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1));
814 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400815 }
816
817 @Test
818 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
819 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
820
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400821 mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
822 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
823 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400824 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400825 mHelper.getPackageVisibility(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400826
827 channel.setShowBadge(false);
828 channel.setImportance(IMPORTANCE_NONE);
829 channel.setBypassDnd(true);
830 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
831
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400832 mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400833
834 // ensure app level fields are not changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400835 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
836 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400837 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400838 mHelper.getPackageVisibility(PKG_O, UID_O));
839 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O,
840 UID_O));
841 assertFalse(mHelper.getIsAppImportanceLocked(PKG_O, UID_O));
842 }
843
844 @Test
845 public void testUpdate_preUpgrade_noUpdateAppFieldsWithMultipleChannels() throws Exception {
846 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
847
848 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
849 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
850 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
851 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
852 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
853
854 channel.setShowBadge(false);
855 channel.setImportance(IMPORTANCE_NONE);
856 channel.setBypassDnd(true);
857 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
858
859 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
860
861 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
862 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
863
864 defaultChannel.setShowBadge(false);
865 defaultChannel.setImportance(IMPORTANCE_NONE);
866 defaultChannel.setBypassDnd(true);
867 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
868
869 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
870
871 // ensure app level fields are not changed
872 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
873 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
874 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
875 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
876 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
877 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400878 }
879
880 @Test
881 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400882 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "garbage", false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400883 }
884
885 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400886 public void testCreateChannel_CannotChangeHiddenFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400887 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400888 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400889 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
890 channel.enableLights(true);
891 channel.setBypassDnd(true);
892 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
893 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800894 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400895 int lockMask = 0;
896 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
897 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
898 }
899 channel.lockFields(lockMask);
900
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400901 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400902
903 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400904 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400905
906 assertEquals(channel.getName(), savedChannel.getName());
907 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
908 assertFalse(savedChannel.canBypassDnd());
909 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
910 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800911 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400912
913 verify(mHandler, never()).requestSort();
914 }
915
916 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400917 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400918 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400919 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400920 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
921 channel.enableLights(true);
922 channel.setBypassDnd(true);
923 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
924 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800925 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400926 int lockMask = 0;
927 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
928 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
929 }
930 channel.lockFields(lockMask);
931
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400932 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400933
934 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400935 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400936
937 assertEquals(channel.getName(), savedChannel.getName());
938 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
939 assertFalse(savedChannel.canBypassDnd());
940 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
941 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800942 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400943 }
944
945 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400946 public void testClearLockedFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400947 final NotificationChannel channel = getChannel();
Julia Reynolds5c399c62019-04-08 14:42:53 -0400948 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400949 assertEquals(0, channel.getUserLockedFields());
950
951 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
952 | NotificationChannel.USER_LOCKED_IMPORTANCE);
Julia Reynolds5c399c62019-04-08 14:42:53 -0400953 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400954 assertEquals(0, channel.getUserLockedFields());
955 }
956
957 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400958 public void testLockFields_soundAndVibration() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400959 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400960
961 final NotificationChannel update1 = getChannel();
962 update1.setSound(new Uri.Builder().scheme("test").build(),
963 new AudioAttributes.Builder().build());
964 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400965 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400966 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
967 | NotificationChannel.USER_LOCKED_SOUND,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400968 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400969 .getUserLockedFields());
970
971 NotificationChannel update2 = getChannel();
972 update2.enableVibration(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400973 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400974 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
975 | NotificationChannel.USER_LOCKED_SOUND
976 | NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400977 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400978 .getUserLockedFields());
979 }
980
981 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400982 public void testLockFields_vibrationAndLights() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400983 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400984
985 final NotificationChannel update1 = getChannel();
986 update1.setVibrationPattern(new long[]{7945, 46 ,246});
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400987 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400988 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400989 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400990 .getUserLockedFields());
991
992 final NotificationChannel update2 = getChannel();
993 update2.enableLights(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400994 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400995 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
996 | NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400997 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400998 .getUserLockedFields());
999 }
1000
1001 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001002 public void testLockFields_lightsAndImportance() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001003 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001004
1005 final NotificationChannel update1 = getChannel();
1006 update1.setLightColor(Color.GREEN);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001007 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001008 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001009 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001010 .getUserLockedFields());
1011
1012 final NotificationChannel update2 = getChannel();
1013 update2.setImportance(IMPORTANCE_DEFAULT);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001014 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001015 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
1016 | NotificationChannel.USER_LOCKED_IMPORTANCE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001017 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001018 .getUserLockedFields());
1019 }
1020
1021 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001022 public void testLockFields_visibilityAndDndAndBadge() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001023 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001024 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001025 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001026 .getUserLockedFields());
1027
1028 final NotificationChannel update1 = getChannel();
1029 update1.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001030 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001031 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001032 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001033 .getUserLockedFields());
1034
1035 final NotificationChannel update2 = getChannel();
1036 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001037 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001038 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1039 | NotificationChannel.USER_LOCKED_VISIBILITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001040 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001041 .getUserLockedFields());
1042
1043 final NotificationChannel update3 = getChannel();
1044 update3.setShowBadge(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001045 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001046 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1047 | NotificationChannel.USER_LOCKED_VISIBILITY
1048 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001049 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update3.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001050 .getUserLockedFields());
1051 }
1052
1053 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001054 public void testLockFields_allowBubble() {
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001055 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1056 assertEquals(0,
1057 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
1058 .getUserLockedFields());
1059
1060 final NotificationChannel update = getChannel();
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001061 update.setAllowBubbles(false);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001062 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001063 assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE,
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001064 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false)
1065 .getUserLockedFields());
1066 }
1067
1068 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001069 public void testDeleteNonExistentChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001070 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001071 }
1072
1073 @Test
1074 public void testGetDeletedChannel() throws Exception {
1075 NotificationChannel channel = getChannel();
1076 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1077 channel.enableLights(true);
1078 channel.setBypassDnd(true);
1079 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1080 channel.enableVibration(true);
1081 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1082
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001083 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1084 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001085
1086 // Does not return deleted channel
1087 NotificationChannel response =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001088 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001089 assertNull(response);
1090
1091 // Returns deleted channel
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001092 response = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001093 compareChannels(channel, response);
1094 assertTrue(response.isDeleted());
1095 }
1096
1097 @Test
1098 public void testGetDeletedChannels() throws Exception {
1099 Map<String, NotificationChannel> channelMap = new HashMap<>();
1100 NotificationChannel channel =
1101 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1102 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1103 channel.enableLights(true);
1104 channel.setBypassDnd(true);
1105 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1106 channel.enableVibration(true);
1107 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1108 channelMap.put(channel.getId(), channel);
1109 NotificationChannel channel2 =
1110 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1111 channelMap.put(channel2.getId(), channel2);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001112 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1113 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001114
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001115 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001116
1117 // Returns only non-deleted channels
1118 List<NotificationChannel> channels =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001119 mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001120 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1121 for (NotificationChannel nc : channels) {
1122 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1123 compareChannels(channel2, nc);
1124 }
1125 }
1126
1127 // Returns deleted channels too
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001128 channels = mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001129 assertEquals(3, channels.size()); // Includes default channel
1130 for (NotificationChannel nc : channels) {
1131 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1132 compareChannels(channelMap.get(nc.getId()), nc);
1133 }
1134 }
1135 }
1136
1137 @Test
1138 public void testGetDeletedChannelCount() throws Exception {
1139 NotificationChannel channel =
1140 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1141 NotificationChannel channel2 =
1142 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1143 NotificationChannel channel3 =
1144 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001145 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1146 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1147 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001148
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001149 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1150 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001151
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001152 assertEquals(2, mHelper.getDeletedChannelCount(PKG_N_MR1, UID_N_MR1));
1153 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001154 }
1155
1156 @Test
1157 public void testGetBlockedChannelCount() throws Exception {
1158 NotificationChannel channel =
1159 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1160 NotificationChannel channel2 =
1161 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
1162 NotificationChannel channel3 =
1163 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001164 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1165 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1166 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001167
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001168 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001169
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001170 assertEquals(1, mHelper.getBlockedChannelCount(PKG_N_MR1, UID_N_MR1));
1171 assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001172 }
1173
1174 @Test
Beverly4f7b53d2018-11-20 09:56:31 -05001175 public void testUpdateChannelsBypassingDnd_onUserSwitch_onUserUnlocked() throws Exception {
1176 int user = USER.getIdentifier();
1177 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1178 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1179 NotificationManager.IMPORTANCE_MAX);
1180 channel1.setBypassDnd(true);
1181 channel1.setGroup(ncg.getId());
1182
1183 // channel is associated with a group, then group is deleted
1184 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1185 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1186 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, user, ncg.getId());
1187
1188 mHelper.onUserSwitched(user);
1189 mHelper.onUserUnlocked(user);
1190 }
1191
1192 @Test
Beverly0479cde22018-11-09 11:05:34 -05001193 public void testGetChannelsBypassingDndCount_noChannelsBypassing() throws Exception {
1194 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1195 USER.getIdentifier()).getList().size());
1196 }
1197
1198 @Test
1199 public void testGetChannelsBypassingDnd_noChannelsForUserIdBypassing()
1200 throws Exception {
1201 int user = 9;
1202 NotificationChannel channel = new NotificationChannel("id", "name",
1203 NotificationManager.IMPORTANCE_MAX);
1204 channel.setBypassDnd(true);
1205 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1206
1207 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1208 user).getList().size());
1209 }
1210
1211 @Test
1212 public void testGetChannelsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1213 int user = USER.getIdentifier();
1214 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1215 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1216 NotificationManager.IMPORTANCE_MAX);
1217 channel1.setBypassDnd(true);
1218 channel1.setGroup(ncg.getId());
1219 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1220 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1221
1222 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1223 user).getList().size());
1224
1225 // disable group
1226 ncg.setBlocked(true);
1227 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1228 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1229 user).getList().size());
1230 }
1231
1232 @Test
1233 public void testGetChannelsBypassingDndCount_multipleChannelsBypassing() {
1234 int user = USER.getIdentifier();
1235 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1236 NotificationManager.IMPORTANCE_MAX);
1237 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1238 NotificationManager.IMPORTANCE_MAX);
1239 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1240 NotificationManager.IMPORTANCE_MAX);
1241 channel1.setBypassDnd(true);
1242 channel2.setBypassDnd(true);
1243 channel3.setBypassDnd(true);
1244 // has DND access, so can set bypassDnd attribute
1245 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1246 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1247 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1248 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1249 user).getList().size());
1250
1251 // block notifications from this app
1252 mHelper.setEnabled(PKG_N_MR1, user, false);
1253 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1254 user).getList().size());
1255
1256 // re-enable notifications from this app
1257 mHelper.setEnabled(PKG_N_MR1, user, true);
1258 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1259 user).getList().size());
1260
1261 // setBypassDnd false for some channels
1262 channel1.setBypassDnd(false);
1263 channel2.setBypassDnd(false);
1264 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1265 user).getList().size());
1266
1267 // setBypassDnd false for rest of the channels
1268 channel3.setBypassDnd(false);
1269 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1270 user).getList().size());
1271 }
1272
1273 @Test
1274 public void testGetAppsBypassingDndCount_noAppsBypassing() throws Exception {
1275 assertEquals(0, mHelper.getAppsBypassingDndCount(USER.getIdentifier()));
1276 }
1277
1278 @Test
1279 public void testGetAppsBypassingDndCount_noAppsForUserIdBypassing() throws Exception {
1280 int user = 9;
1281 NotificationChannel channel = new NotificationChannel("id", "name",
1282 NotificationManager.IMPORTANCE_MAX);
1283 channel.setBypassDnd(true);
1284 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1285
1286 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1287 }
1288
1289 @Test
1290 public void testGetAppsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1291 int user = USER.getIdentifier();
1292 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1293 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1294 NotificationManager.IMPORTANCE_MAX);
1295 channel1.setBypassDnd(true);
1296 channel1.setGroup(ncg.getId());
1297 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1298 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1299
1300 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1301
1302 // disable group
1303 ncg.setBlocked(true);
1304 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1305 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1306 }
1307
1308 @Test
1309 public void testGetAppsBypassingDndCount_oneAppBypassing() {
1310 int user = USER.getIdentifier();
1311 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1312 NotificationManager.IMPORTANCE_MAX);
1313 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1314 NotificationManager.IMPORTANCE_MAX);
1315 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1316 NotificationManager.IMPORTANCE_MAX);
1317 channel1.setBypassDnd(true);
1318 channel2.setBypassDnd(true);
1319 channel3.setBypassDnd(true);
1320 // has DND access, so can set bypassDnd attribute
1321 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1322 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1323 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1324 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1325
1326 // block notifications from this app
1327 mHelper.setEnabled(PKG_N_MR1, user, false);
1328 assertEquals(0, mHelper.getAppsBypassingDndCount(user)); // no apps can bypass dnd
1329
1330 // re-enable notifications from this app
1331 mHelper.setEnabled(PKG_N_MR1, user, true);
1332 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1333
1334 // setBypassDnd false for some channels
1335 channel1.setBypassDnd(false);
1336 channel2.setBypassDnd(false);
1337 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1338
1339 // setBypassDnd false for rest of the channels
1340 channel3.setBypassDnd(false);
1341 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1342 }
1343
1344 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001345 public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception {
1346 // create notification channel that can't bypass dnd
1347 // expected result: areChannelsBypassingDnd = false
1348 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1349 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001350 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001351 assertFalse(mHelper.areChannelsBypassingDnd());
1352 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1353 resetZenModeHelper();
1354
1355 // create notification channel that can bypass dnd
1356 // expected result: areChannelsBypassingDnd = true
1357 NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1358 channel2.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001359 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001360 assertTrue(mHelper.areChannelsBypassingDnd());
1361 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1362 resetZenModeHelper();
1363
1364 // delete channels
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001365 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001366 assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
1367 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1368 resetZenModeHelper();
1369
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001370 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001371 assertFalse(mHelper.areChannelsBypassingDnd());
1372 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1373 resetZenModeHelper();
1374 }
1375
1376 @Test
1377 public void testUpdateCanChannelsBypassDnd() throws Exception {
1378 // create notification channel that can't bypass dnd
1379 // expected result: areChannelsBypassingDnd = false
1380 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1381 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001382 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001383 assertFalse(mHelper.areChannelsBypassingDnd());
1384 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1385 resetZenModeHelper();
1386
1387 // update channel so it CAN bypass dnd:
1388 // expected result: areChannelsBypassingDnd = true
1389 channel.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001390 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001391 assertTrue(mHelper.areChannelsBypassingDnd());
1392 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1393 resetZenModeHelper();
1394
1395 // update channel so it can't bypass dnd:
1396 // expected result: areChannelsBypassingDnd = false
1397 channel.setBypassDnd(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001398 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001399 assertFalse(mHelper.areChannelsBypassingDnd());
1400 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1401 resetZenModeHelper();
1402 }
1403
1404 @Test
1405 public void testSetupNewZenModeHelper_canBypass() {
1406 // start notification policy off with mAreChannelsBypassingDnd = true, but
1407 // RankingHelper should change to false
1408 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
1409 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
1410 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
1411 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
1412 assertFalse(mHelper.areChannelsBypassingDnd());
1413 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1414 resetZenModeHelper();
1415 }
1416
1417 @Test
1418 public void testSetupNewZenModeHelper_cannotBypass() {
1419 // start notification policy off with mAreChannelsBypassingDnd = false
1420 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0);
1421 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
1422 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
1423 assertFalse(mHelper.areChannelsBypassingDnd());
1424 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1425 resetZenModeHelper();
1426 }
1427
1428 @Test
1429 public void testCreateDeletedChannel() throws Exception {
1430 long[] vibration = new long[]{100, 67, 145, 156};
1431 NotificationChannel channel =
1432 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1433 channel.setVibrationPattern(vibration);
1434
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001435 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1436 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001437
1438 NotificationChannel newChannel = new NotificationChannel(
1439 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1440 newChannel.setVibrationPattern(new long[]{100});
1441
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001442 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001443
1444 // No long deleted, using old settings
1445 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001446 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001447 }
1448
1449 @Test
1450 public void testOnlyHasDefaultChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001451 assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
1452 assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001453
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001454 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1455 assertFalse(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001456 }
1457
1458 @Test
1459 public void testCreateChannel_defaultChannelId() throws Exception {
1460 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001461 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, new NotificationChannel(
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001462 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
1463 fail("Allowed to create default channel");
1464 } catch (IllegalArgumentException e) {
1465 // pass
1466 }
1467 }
1468
1469 @Test
1470 public void testCreateChannel_alreadyExists() throws Exception {
1471 long[] vibration = new long[]{100, 67, 145, 156};
1472 NotificationChannel channel =
1473 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1474 channel.setVibrationPattern(vibration);
1475
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001476 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001477
1478 NotificationChannel newChannel = new NotificationChannel(
1479 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1480 newChannel.setVibrationPattern(new long[]{100});
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001481 newChannel.setAllowBubbles(!channel.canBubble());
1482 newChannel.setLightColor(Color.BLUE);
1483 newChannel.setSound(Uri.EMPTY, null);
1484 newChannel.setShowBadge(!channel.canShowBadge());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001485
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001486 assertFalse(mHelper.createNotificationChannel(
1487 PKG_N_MR1, UID_N_MR1, newChannel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001488
1489 // Old settings not overridden
1490 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001491 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001492 }
1493
1494 @Test
1495 public void testCreateChannel_noOverrideSound() throws Exception {
1496 Uri sound = new Uri.Builder().scheme("test").build();
1497 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1498 NotificationManager.IMPORTANCE_DEFAULT);
1499 channel.setSound(sound, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001500 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001501 assertEquals(sound, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001502 PKG_N_MR1, UID_N_MR1, channel.getId(), false).getSound());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001503 }
1504
1505 @Test
1506 public void testPermanentlyDeleteChannels() throws Exception {
1507 NotificationChannel channel1 =
1508 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1509 NotificationChannel channel2 =
1510 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1511
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001512 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1513 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001514
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001515 mHelper.permanentlyDeleteNotificationChannels(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001516
1517 // Only default channel remains
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001518 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001519 }
1520
1521 @Test
1522 public void testDeleteGroup() throws Exception {
1523 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1524 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1525 NotificationChannel nonGroupedNonDeletedChannel =
1526 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1527 NotificationChannel groupedButNotDeleted =
1528 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1529 groupedButNotDeleted.setGroup("not");
1530 NotificationChannel groupedAndDeleted =
1531 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1532 groupedAndDeleted.setGroup("totally");
1533
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001534 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
1535 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001536 mHelper.createNotificationChannel(
1537 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001538 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false);
1539 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001540
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001541 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001542
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001543 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001544 assertNotNull(
1545 mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001546
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001547 assertNull(mHelper.getNotificationChannel(
1548 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), false));
1549 compareChannels(groupedAndDeleted, mHelper.getNotificationChannel(
1550 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001551
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001552 compareChannels(groupedButNotDeleted, mHelper.getNotificationChannel(
1553 PKG_N_MR1, UID_N_MR1, groupedButNotDeleted.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001554 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001555 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001556
1557 // notDeleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001558 assertEquals(1, mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001559
1560 verify(mHandler, never()).requestSort();
1561 }
1562
1563 @Test
1564 public void testOnUserRemoved() throws Exception {
1565 int[] user0Uids = {98, 235, 16, 3782};
1566 int[] user1Uids = new int[user0Uids.length];
1567 for (int i = 0; i < user0Uids.length; i++) {
1568 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1569
1570 final ApplicationInfo legacy = new ApplicationInfo();
1571 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001572 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001573
1574 // create records with the default channel for all user 0 and user 1 uids
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001575 mHelper.getImportance(PKG_N_MR1, user0Uids[i]);
1576 mHelper.getImportance(PKG_N_MR1, user1Uids[i]);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001577 }
1578
1579 mHelper.onUserRemoved(1);
1580
1581 // user 0 records remain
1582 for (int i = 0; i < user0Uids.length; i++) {
1583 assertEquals(1,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001584 mHelper.getNotificationChannels(PKG_N_MR1, user0Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001585 }
1586 // user 1 records are gone
1587 for (int i = 0; i < user1Uids.length; i++) {
1588 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001589 mHelper.getNotificationChannels(PKG_N_MR1, user1Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001590 }
1591 }
1592
1593 @Test
1594 public void testOnPackageChanged_packageRemoval() throws Exception {
1595 // Deleted
1596 NotificationChannel channel1 =
1597 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001598 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001599
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001600 assertTrue(mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1},
1601 new int[]{UID_N_MR1}));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001602
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001603 assertEquals(0, mHelper.getNotificationChannels(
1604 PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001605
1606 // Not deleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001607 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001608
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001609 assertFalse(mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM,
1610 new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001611 assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001612 }
1613
1614 @Test
1615 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001616 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001617
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001618 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1619 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001620
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001621 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1622 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001623 }
1624
1625 @Test
1626 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1627 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001628 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001629 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001630 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001631
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001632 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1633 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001634
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001635 assertEquals(0, mHelper.getNotificationChannelGroups(
1636 PKG_N_MR1, UID_N_MR1, true, true, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001637 }
1638
1639 @Test
1640 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1641 // create channel as api 26
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001642 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001643
1644 // install new app version targeting 25
1645 final ApplicationInfo legacy = new ApplicationInfo();
1646 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001647 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001648 mHelper.onPackagesChanged(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001649 false, UserHandle.USER_SYSTEM, new String[]{PKG_O}, new int[]{UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001650
1651 // make sure the default channel was readded
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001652 //assertEquals(2, mHelper.getNotificationChannels(PKG_O, UID_O, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001653 assertNotNull(mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001654 PKG_O, UID_O, NotificationChannel.DEFAULT_CHANNEL_ID, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001655 }
1656
1657 @Test
Julia Reynolds7af51c52019-04-19 11:08:27 -04001658 public void testClearData() {
1659 ArraySet<String> pkg = new ArraySet<>();
1660 pkg.add(PKG_O);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001661 ArraySet<Pair<String, Integer>> pkgPair = new ArraySet<>();
1662 pkgPair.add(new Pair(PKG_O, UID_O));
Julia Reynolds7af51c52019-04-19 11:08:27 -04001663 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
1664 mHelper.createNotificationChannelGroup(
1665 PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
1666 mHelper.lockChannelsForOEM(pkg.toArray(new String[]{}));
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001667 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001668 mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
1669 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
1670 mHelper.setBubblesAllowed(PKG_O, UID_O, false);
1671 mHelper.setShowBadge(PKG_O, UID_O, false);
1672 mHelper.setAppImportanceLocked(PKG_O, UID_O);
1673
1674 mHelper.clearData(PKG_O, UID_O);
1675
1676 assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, UID_O));
1677 assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O));
1678 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
1679 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
1680 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
1681 assertEquals(0, mHelper.getNotificationChannels(PKG_O, UID_O, true).getList().size());
1682 assertEquals(0, mHelper.getNotificationChannelGroups(PKG_O, UID_O).size());
1683
1684 NotificationChannel channel = getChannel();
1685 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
1686
1687 assertTrue(channel.isImportanceLockedByCriticalDeviceFunction());
1688 assertTrue(channel.isImportanceLockedByOEM());
1689 }
1690
1691 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001692 public void testRecordDefaults() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001693 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1694 UID_N_MR1));
1695 assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
1696 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001697 }
1698
1699 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001700 public void testCreateGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001701 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001702 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001703 assertEquals(ncg,
1704 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).iterator().next());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001705 verify(mHandler, never()).requestSort();
1706 }
1707
1708 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001709 public void testCannotCreateChannel_badGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001710 NotificationChannel channel1 =
1711 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1712 channel1.setGroup("garbage");
1713 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001714 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001715 fail("Created a channel with a bad group");
1716 } catch (IllegalArgumentException e) {
1717 }
1718 }
1719
1720 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001721 public void testCannotCreateChannel_goodGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001722 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001723 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001724 NotificationChannel channel1 =
1725 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1726 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001727 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001728
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001729 assertEquals(ncg.getId(), mHelper.getNotificationChannel(
1730 PKG_N_MR1, UID_N_MR1, channel1.getId(), false).getGroup());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001731 }
1732
1733 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001734 public void testGetChannelGroups() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001735 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001736 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001737 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001738 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001739 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001740 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001741
1742 NotificationChannel channel1 =
1743 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1744 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001745 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001746 NotificationChannel channel1a =
1747 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1748 channel1a.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001749 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001750
1751 NotificationChannel channel2 =
1752 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1753 channel2.setGroup(ncg2.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001754 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001755
1756 NotificationChannel channel3 =
1757 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001758 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001759
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001760 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1761 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001762 assertEquals(3, actual.size());
1763 for (NotificationChannelGroup group : actual) {
1764 if (group.getId() == null) {
1765 assertEquals(2, group.getChannels().size()); // misc channel too
1766 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1767 || channel3.getId().equals(group.getChannels().get(1).getId()));
1768 } else if (group.getId().equals(ncg.getId())) {
1769 assertEquals(2, group.getChannels().size());
1770 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1771 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1772 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1773 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1774 } else {
1775 fail("expected channel not found");
1776 }
1777 } else if (group.getId().equals(ncg2.getId())) {
1778 assertEquals(1, group.getChannels().size());
1779 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1780 }
1781 }
1782 }
1783
1784 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001785 public void testGetChannelGroups_noSideEffects() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001786 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001787 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001788
1789 NotificationChannel channel1 =
1790 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1791 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001792 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001793 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001794
1795 channel1.setImportance(IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001796 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001797
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001798 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1799 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001800
1801 assertEquals(2, actual.size());
1802 for (NotificationChannelGroup group : actual) {
1803 if (Objects.equals(group.getId(), ncg.getId())) {
1804 assertEquals(1, group.getChannels().size());
1805 }
1806 }
1807 }
1808
1809 @Test
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001810 public void testGetChannelGroups_includeEmptyGroups() {
1811 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1812 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
1813 NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
1814 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true);
1815
1816 NotificationChannel channel1 =
1817 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1818 channel1.setGroup(ncg.getId());
1819 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1820
1821 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1822 PKG_N_MR1, UID_N_MR1, false, false, true).getList();
1823
1824 assertEquals(2, actual.size());
1825 for (NotificationChannelGroup group : actual) {
1826 if (Objects.equals(group.getId(), ncg.getId())) {
1827 assertEquals(1, group.getChannels().size());
1828 }
1829 if (Objects.equals(group.getId(), ncgEmpty.getId())) {
1830 assertEquals(0, group.getChannels().size());
1831 }
1832 }
1833 }
1834
1835 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001836 public void testCreateChannel_updateName() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001837 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001838 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001839 NotificationChannel actual =
1840 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001841 assertEquals("hello", actual.getName());
1842
1843 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001844 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001845
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001846 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001847 assertEquals("goodbye", actual.getName());
1848 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1849
1850 verify(mHandler, times(1)).requestSort();
1851 }
1852
1853 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001854 public void testCreateChannel_addToGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001855 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001856 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001857 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001858 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001859 NotificationChannel actual =
1860 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001861 assertNull(actual.getGroup());
1862
1863 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1864 nc.setGroup(group.getId());
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001865 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001866
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001867 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001868 assertNotNull(actual.getGroup());
1869 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1870
1871 verify(mHandler, times(1)).requestSort();
1872 }
1873
1874 @Test
1875 public void testDumpChannelsJson() throws Exception {
1876 final ApplicationInfo upgrade = new ApplicationInfo();
1877 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
1878 try {
1879 when(mPm.getApplicationInfoAsUser(
1880 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
1881 } catch (PackageManager.NameNotFoundException e) {
1882 }
1883 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
1884 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
1885 for (int i = 0; i < numPackages; i++) {
1886 String pkgName = "pkg" + i;
1887 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
1888 for (int j = 0; j < numChannels; j++) {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001889 mHelper.createNotificationChannel(pkgName, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001890 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
1891 }
1892 expectedChannels.put(pkgName, numChannels);
1893 }
1894
1895 // delete the first channel of the first package
1896 String pkg = expectedChannels.keyAt(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001897 mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001898 // dump should not include deleted channels
1899 int count = expectedChannels.get(pkg);
1900 expectedChannels.put(pkg, count - 1);
1901
1902 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
1903 assertEquals(numPackages, actual.length());
1904 for (int i = 0; i < numPackages; i++) {
1905 JSONObject object = actual.getJSONObject(i);
1906 assertTrue(expectedChannels.containsKey(object.get("packageName")));
1907 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
1908 object.getInt("channelCount"));
1909 }
1910 }
1911
1912 @Test
1913 public void testBadgingOverrideTrue() throws Exception {
1914 Secure.putIntForUser(getContext().getContentResolver(),
1915 Secure.NOTIFICATION_BADGING, 1,
1916 USER.getIdentifier());
1917 mHelper.updateBadgingEnabled(); // would be called by settings observer
1918 assertTrue(mHelper.badgingEnabled(USER));
1919 }
1920
1921 @Test
1922 public void testBadgingOverrideFalse() throws Exception {
1923 Secure.putIntForUser(getContext().getContentResolver(),
1924 Secure.NOTIFICATION_BADGING, 0,
1925 USER.getIdentifier());
1926 mHelper.updateBadgingEnabled(); // would be called by settings observer
1927 assertFalse(mHelper.badgingEnabled(USER));
1928 }
1929
1930 @Test
1931 public void testBadgingForUserAll() throws Exception {
1932 try {
1933 mHelper.badgingEnabled(UserHandle.ALL);
1934 } catch (Exception e) {
1935 fail("just don't throw");
1936 }
1937 }
1938
1939 @Test
1940 public void testBadgingOverrideUserIsolation() throws Exception {
1941 Secure.putIntForUser(getContext().getContentResolver(),
1942 Secure.NOTIFICATION_BADGING, 0,
1943 USER.getIdentifier());
1944 Secure.putIntForUser(getContext().getContentResolver(),
1945 Secure.NOTIFICATION_BADGING, 1,
1946 USER2.getIdentifier());
1947 mHelper.updateBadgingEnabled(); // would be called by settings observer
1948 assertFalse(mHelper.badgingEnabled(USER));
1949 assertTrue(mHelper.badgingEnabled(USER2));
1950 }
1951
1952 @Test
Julia Reynolds4509ce72019-01-31 13:12:43 -05001953 public void testBubblesOverrideTrue() {
Lyn Han4463f842019-07-09 15:27:28 -07001954 Global.putInt(getContext().getContentResolver(),
1955 Global.NOTIFICATION_BUBBLES, 1);
Julia Reynolds4509ce72019-01-31 13:12:43 -05001956 mHelper.updateBubblesEnabled(); // would be called by settings observer
Lyn Han4463f842019-07-09 15:27:28 -07001957 assertTrue(mHelper.bubblesEnabled());
Julia Reynolds4509ce72019-01-31 13:12:43 -05001958 }
1959
1960 @Test
1961 public void testBubblesOverrideFalse() {
Lyn Han4463f842019-07-09 15:27:28 -07001962 Global.putInt(getContext().getContentResolver(),
1963 Global.NOTIFICATION_BUBBLES, 0);
Julia Reynolds4509ce72019-01-31 13:12:43 -05001964 mHelper.updateBubblesEnabled(); // would be called by settings observer
Lyn Han4463f842019-07-09 15:27:28 -07001965 assertFalse(mHelper.bubblesEnabled());
Julia Reynolds4509ce72019-01-31 13:12:43 -05001966 }
1967
1968 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001969 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
1970 String newLabel = "bananas!";
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001971 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
1972 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001973 NotificationChannel.DEFAULT_CHANNEL_ID, false);
1974 assertFalse(newLabel.equals(defaultChannel.getName()));
1975
1976 Resources res = mock(Resources.class);
1977 when(mContext.getResources()).thenReturn(res);
1978 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
1979 .thenReturn(newLabel);
1980
1981 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
1982
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001983 assertEquals(newLabel, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001984 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
1985 }
1986
1987 @Test
1988 public void testIsGroupBlocked_noGroup() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001989 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, null));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001990
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001991 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, "non existent group"));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001992 }
1993
1994 @Test
1995 public void testIsGroupBlocked_notBlocked() throws Exception {
1996 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001997 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001998
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001999 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002000 }
2001
2002 @Test
2003 public void testIsGroupBlocked_blocked() throws Exception {
2004 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002005 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002006 group.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002007 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002008
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002009 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002010 }
2011
2012 @Test
2013 public void testIsGroup_appCannotResetBlock() throws Exception {
2014 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002015 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002016 NotificationChannelGroup group2 = group.clone();
2017 group2.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002018 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false);
2019 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002020
2021 NotificationChannelGroup group3 = group.clone();
2022 group3.setBlocked(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002023 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
2024 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002025 }
2026
2027 @Test
2028 public void testGetNotificationChannelGroupWithChannels() throws Exception {
2029 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
2030 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002031 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
2032 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002033
2034 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
2035 a.setGroup(group.getId());
2036 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
2037 b.setGroup(other.getId());
2038 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2039 c.setGroup(group.getId());
2040 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
2041
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002042 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false);
2043 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false);
2044 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false);
2045 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false);
2046 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002047
2048 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002049 PKG_N_MR1, UID_N_MR1, group.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002050 assertEquals(2, retrieved.getChannels().size());
2051 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2052 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
2053
2054 retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002055 PKG_N_MR1, UID_N_MR1, group.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002056 assertEquals(1, retrieved.getChannels().size());
2057 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2058 }
2059
2060 @Test
2061 public void testAndroidPkgCannotBypassDnd_creation() {
2062 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2063 test.setBypassDnd(true);
2064
2065 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2066
2067 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2068 .canBypassDnd());
2069 }
2070
2071 @Test
2072 public void testDndPkgCanBypassDnd_creation() {
2073 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2074 test.setBypassDnd(true);
2075
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002076 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002077
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002078 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002079 }
2080
2081 @Test
2082 public void testNormalPkgCannotBypassDnd_creation() {
2083 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2084 test.setBypassDnd(true);
2085
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002086 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002087
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002088 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002089 }
2090
2091 @Test
2092 public void testAndroidPkgCannotBypassDnd_update() throws Exception {
2093 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2094 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2095
2096 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2097 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002098 assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002099
2100 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2101 .canBypassDnd());
2102 }
2103
2104 @Test
2105 public void testDndPkgCanBypassDnd_update() throws Exception {
2106 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002107 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002108
2109 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2110 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002111 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002112
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002113 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002114 }
2115
2116 @Test
2117 public void testNormalPkgCannotBypassDnd_update() {
2118 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002119 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002120 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2121 update.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002122 mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false);
2123 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002124 }
2125
2126 @Test
2127 public void testGetBlockedAppCount_noApps() {
2128 assertEquals(0, mHelper.getBlockedAppCount(0));
2129 }
2130
2131 @Test
2132 public void testGetBlockedAppCount_noAppsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002133 mHelper.setEnabled(PKG_N_MR1, 100, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002134 assertEquals(0, mHelper.getBlockedAppCount(9));
2135 }
2136
2137 @Test
2138 public void testGetBlockedAppCount_appsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002139 mHelper.setEnabled(PKG_N_MR1, 1020, false);
2140 mHelper.setEnabled(PKG_N_MR1, 1030, false);
2141 mHelper.setEnabled(PKG_N_MR1, 1060, false);
2142 mHelper.setEnabled(PKG_N_MR1, 1000, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002143 assertEquals(3, mHelper.getBlockedAppCount(0));
2144 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002145
2146 @Test
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002147 public void testXml_statusBarIcons_default() throws Exception {
Julia Reynolds2594b472019-04-03 13:30:16 -04002148 String preQXml = "<ranking version=\"1\">\n"
2149 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
2150 + "<channel id=\"something\" name=\"name\" importance=\"2\" "
2151 + "show_badge=\"true\" />\n"
2152 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
2153 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
2154 + "</package>\n"
2155 + "</ranking>\n";
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002156 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Julia Reynolds2594b472019-04-03 13:30:16 -04002157 loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002158
2159 assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2160 mHelper.shouldHideSilentStatusIcons());
2161 }
2162
2163 @Test
2164 public void testXml_statusBarIcons() throws Exception {
2165 mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
2166
Annie Meng8b646fd2019-02-01 18:46:42 +00002167 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002168 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002169 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002170
2171 assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2172 mHelper.shouldHideSilentStatusIcons());
2173 }
2174
2175 @Test
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002176 public void testSetNotificationDelegate() {
2177 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2178 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2179 }
2180
2181 @Test
2182 public void testRevokeNotificationDelegate() {
2183 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2184 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2185
2186 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2187 }
2188
2189 @Test
2190 public void testRevokeNotificationDelegate_noDelegateExistsNoCrash() {
2191 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2192
2193 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2194 }
2195
2196 @Test
2197 public void testToggleNotificationDelegate() {
2198 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2199 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2200
2201 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2202
2203 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2204 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2205 }
2206
2207 @Test
2208 public void testToggleNotificationDelegate_noDelegateExistsNoCrash() {
2209 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2210 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2211
2212 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2213 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2214 }
2215
2216 @Test
2217 public void testIsDelegateAllowed_noSource() {
2218 assertFalse(mHelper.isDelegateAllowed("does not exist", -1, "whatever", 0));
2219 }
2220
2221 @Test
2222 public void testIsDelegateAllowed_noDelegate() {
2223 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2224
2225 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "whatever", 0));
2226 }
2227
2228 @Test
2229 public void testIsDelegateAllowed_delegateDisabledByApp() {
2230 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2231 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2232
2233 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2234 }
2235
2236 @Test
2237 public void testIsDelegateAllowed_wrongDelegate() {
2238 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2239 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2240
2241 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "banana", 27));
2242 }
2243
2244 @Test
2245 public void testIsDelegateAllowed_delegateDisabledByUser() {
2246 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2247 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2248
2249 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2250 }
2251
2252 @Test
2253 public void testIsDelegateAllowed() {
2254 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2255
2256 assertTrue(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2257 }
2258
2259 @Test
2260 public void testDelegateXml_noDelegate() throws Exception {
2261 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2262
Annie Meng8b646fd2019-02-01 18:46:42 +00002263 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002264 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002265 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002266
2267 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2268 }
2269
2270 @Test
2271 public void testDelegateXml_delegate() throws Exception {
2272 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2273
Annie Meng8b646fd2019-02-01 18:46:42 +00002274 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002275 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002276 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002277
2278 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2279 }
2280
2281 @Test
2282 public void testDelegateXml_disabledDelegate() throws Exception {
2283 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2284 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2285
Annie Meng8b646fd2019-02-01 18:46:42 +00002286 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002287 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002288 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002289
2290 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2291 }
2292
2293 @Test
2294 public void testDelegateXml_userDisabledDelegate() throws Exception {
2295 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2296 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2297
Annie Meng8b646fd2019-02-01 18:46:42 +00002298 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002299 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002300 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002301
2302 // appears disabled
2303 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2304
2305 // but was loaded and can be toggled back on
2306 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2307 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2308 }
2309
2310 @Test
2311 public void testDelegateXml_entirelyDisabledDelegate() throws Exception {
2312 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2313 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2314 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2315
Annie Meng8b646fd2019-02-01 18:46:42 +00002316 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002317 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002318 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002319
2320 // appears disabled
2321 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2322
2323 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2324 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2325
2326 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2327 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2328 }
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002329
2330 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002331 public void testAllowBubbles_defaults() throws Exception {
Mady Mellor9db685a2019-01-23 13:23:37 -08002332 assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002333
Annie Meng8b646fd2019-02-01 18:46:42 +00002334 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002335 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002336 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002337
Mady Mellor9db685a2019-01-23 13:23:37 -08002338 assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002339 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2340 }
2341
2342 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002343 public void testAllowBubbles_xml() throws Exception {
2344 mHelper.setBubblesAllowed(PKG_O, UID_O, false);
Mady Mellor9db685a2019-01-23 13:23:37 -08002345 assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002346 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002347 mHelper.getAppLockedFields(PKG_O, UID_O));
2348
Annie Meng8b646fd2019-02-01 18:46:42 +00002349 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002350 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002351 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002352
Mady Mellor9db685a2019-01-23 13:23:37 -08002353 assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002354 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002355 mHelper.getAppLockedFields(PKG_O, UID_O));
2356 }
Julia Reynolds413ba842019-01-11 10:38:08 -05002357
2358 @Test
2359 public void testLockChannelsForOEM_emptyList() {
2360 mHelper.lockChannelsForOEM(null);
2361 mHelper.lockChannelsForOEM(new String[0]);
2362 // no exception
2363 }
2364
2365 @Test
2366 public void testLockChannelsForOEM_appWide() {
2367 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2368 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2369 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2370 // different uids, same package
2371 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2372 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2373 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2374
2375 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2376
2377 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2378 .isImportanceLockedByOEM());
2379 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2380 .isImportanceLockedByOEM());
2381 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2382 .isImportanceLockedByOEM());
2383 }
2384
2385 @Test
2386 public void testLockChannelsForOEM_onlyGivenPkg() {
2387 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2388 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2389 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2390 mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
2391
2392 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2393
2394 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2395 .isImportanceLockedByOEM());
2396 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
2397 .isImportanceLockedByOEM());
2398 }
2399
2400 @Test
2401 public void testLockChannelsForOEM_channelSpecific() {
2402 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2403 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2404 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2405 // different uids, same package
2406 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2407 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2408 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2409
2410 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
2411
2412 assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2413 .isImportanceLockedByOEM());
2414 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2415 .isImportanceLockedByOEM());
2416 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2417 .isImportanceLockedByOEM());
2418 }
2419
2420 @Test
2421 public void testLockChannelsForOEM_channelDoesNotExistYet_appWide() {
2422 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2423 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2424 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2425
2426 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2427
2428 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2429 .isImportanceLockedByOEM());
2430
2431 mHelper.createNotificationChannel(PKG_O, 3, b, true, false);
2432 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2433 .isImportanceLockedByOEM());
2434 }
2435
2436 @Test
2437 public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific() {
2438 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2439 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2440 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2441
2442 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"});
2443
2444 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2445 .isImportanceLockedByOEM());
2446
2447 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2448 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2449 .isImportanceLockedByOEM());
2450 }
2451
2452 @Test
2453 public void testUpdateNotificationChannel_oemLockedImportance() {
2454 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2455 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2456
2457 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2458
2459 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002460 update.setAllowBubbles(false);
Julia Reynolds413ba842019-01-11 10:38:08 -05002461
2462 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2463
2464 assertEquals(IMPORTANCE_HIGH,
2465 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2466 assertEquals(false,
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002467 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
Julia Reynolds413ba842019-01-11 10:38:08 -05002468
2469 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2470
2471 assertEquals(IMPORTANCE_HIGH,
2472 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2473 }
Julia Reynolds0c245002019-03-27 16:10:11 -04002474
2475 @Test
2476 public void testUpdateDefaultApps_add_multiUser() {
2477 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2478 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2479 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2480 // different uids, same package
2481 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2482 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2483 mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
2484
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002485 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2486 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002487 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2488
2489 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2490 .isImportanceLockedByCriticalDeviceFunction());
2491 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2492 .isImportanceLockedByCriticalDeviceFunction());
2493 assertFalse(mHelper.getNotificationChannel(
2494 PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false)
2495 .isImportanceLockedByCriticalDeviceFunction());
2496 }
2497
2498 @Test
2499 public void testUpdateDefaultApps_add_onlyGivenPkg() {
2500 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2501 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2502 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2503 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2504
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002505 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2506 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002507 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2508
Julia Reynolds0c245002019-03-27 16:10:11 -04002509 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2510 .isImportanceLockedByCriticalDeviceFunction());
2511 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2512 .isImportanceLockedByCriticalDeviceFunction());
2513 }
2514
2515 @Test
2516 public void testUpdateDefaultApps_remove() {
2517 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2518 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2519 // different uids, same package
2520 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2521 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2522
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002523 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2524 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002525 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2526
2527 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2528 .isImportanceLockedByCriticalDeviceFunction());
2529 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2530 .isImportanceLockedByCriticalDeviceFunction());
2531
2532 ArraySet<String> toRemove = new ArraySet<>();
2533 toRemove.add(PKG_O);
2534 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, null);
2535
2536 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2537 .isImportanceLockedByCriticalDeviceFunction());
2538 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2539 .isImportanceLockedByCriticalDeviceFunction());
2540 }
2541
2542 @Test
2543 public void testUpdateDefaultApps_addAndRemove() {
2544 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2545 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2546 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2547 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2548
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002549 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2550 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002551 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2552
2553
2554 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2555 .isImportanceLockedByCriticalDeviceFunction());
2556 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2557 .isImportanceLockedByCriticalDeviceFunction());
2558
2559 // now the default is PKG_N_MR1
2560 ArraySet<String> toRemove = new ArraySet<>();
2561 toRemove.add(PKG_O);
2562 toAdd = new ArraySet<>();
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002563 toAdd.add(new Pair(PKG_N_MR1, UID_N_MR1));
Julia Reynolds0c245002019-03-27 16:10:11 -04002564 mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd);
2565
2566 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2567 .isImportanceLockedByCriticalDeviceFunction());
2568 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2569 .isImportanceLockedByCriticalDeviceFunction());
2570 }
2571
2572 @Test
2573 public void testUpdateDefaultApps_appDoesNotExist_noCrash() {
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002574 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2575 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002576 ArraySet<String> toRemove = new ArraySet<>();
2577 toRemove.add(PKG_N_MR1);
2578 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd);
2579 }
2580
2581 @Test
2582 public void testUpdateDefaultApps_channelDoesNotExistYet() {
2583 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2584 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2585 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2586
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002587 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2588 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002589 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2590
2591 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2592 .isImportanceLockedByCriticalDeviceFunction());
2593
2594 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2595 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2596 .isImportanceLockedByCriticalDeviceFunction());
2597 }
2598
2599 @Test
2600 public void testUpdateNotificationChannel_defaultAppLockedImportance() {
2601 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2602 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002603 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2604 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002605 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2606
2607 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
2608 update.setAllowBubbles(false);
2609
2610 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
Julia Reynolds0c245002019-03-27 16:10:11 -04002611 assertEquals(IMPORTANCE_HIGH,
2612 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2613 assertEquals(false,
2614 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
2615
2616 mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
Julia Reynolds0c245002019-03-27 16:10:11 -04002617 assertEquals(IMPORTANCE_HIGH,
2618 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Beverly47679222019-05-16 15:46:11 -04002619
2620 NotificationChannel updateImportanceLow = new NotificationChannel("a", "a",
2621 IMPORTANCE_LOW);
2622 mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true);
2623 assertEquals(IMPORTANCE_LOW,
2624 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Julia Reynolds0c245002019-03-27 16:10:11 -04002625 }
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002626
2627 @Test
2628 public void testDefaultApp_appHasNoSettingsYet() {
2629 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2630 toAdd.add(new Pair(PKG_O, UID_O));
2631 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2632
2633 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2634 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2635
2636 assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
2637 }
2638
2639 @Test
2640 public void testChannelXml_backupDefaultApp() throws Exception {
2641 NotificationChannel channel1 =
2642 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
2643
2644 mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
2645
2646 // clear data
2647 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
2648 UserHandle.USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
2649 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_O}, new int[]{
2650 UID_O});
2651
2652 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2653 toAdd.add(new Pair(PKG_O, UID_O));
2654 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2655
2656 XmlPullParser parser = Xml.newPullParser();
2657 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
2658 null);
2659 parser.nextTag();
2660 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
2661
2662 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, channel1.getId(), false)
2663 .isImportanceLockedByCriticalDeviceFunction());
2664 }
Mady Mellor9f296142019-05-24 09:42:52 -07002665
2666 @Test
2667 public void testSetBubblesAllowed_false() {
2668 mHelper.setBubblesAllowed(PKG_O, UID_O, false);
2669 assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
2670 verify(mHandler, times(1)).requestSort();
2671 }
Julia Reynolds198282a2019-08-20 16:08:42 -04002672
2673 @Test
2674 public void testTooManyChannels() {
2675 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2676 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2677 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2678 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2679 }
2680 try {
2681 NotificationChannel channel = new NotificationChannel(
2682 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2683 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2684 NotificationManager.IMPORTANCE_HIGH);
2685 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2686 fail("Allowed to create too many notification channels");
2687 } catch (IllegalStateException e) {
2688 // great
2689 }
2690 }
2691
2692 @Test
2693 public void testTooManyChannels_xml() throws Exception {
2694 String extraChannel = "EXTRA";
2695 String extraChannel1 = "EXTRA1";
2696
2697 // create first... many... directly so we don't need a big xml blob in this test
2698 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2699 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2700 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2701 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2702 }
2703
2704 final String xml = "<ranking version=\"1\">\n"
2705 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
2706 + "<channel id=\"" + extraChannel + "\" name=\"hi\" importance=\"3\"/>"
2707 + "<channel id=\"" + extraChannel1 + "\" name=\"hi\" importance=\"3\"/>"
2708 + "</package>"
2709 + "</ranking>";
2710 XmlPullParser parser = Xml.newPullParser();
2711 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2712 null);
2713 parser.nextTag();
2714 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2715
2716 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true));
2717 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true));
2718 }
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002719}