blob: 8f8b746b59d49d421a5c560825e5565d975d13c9 [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
25import static junit.framework.Assert.assertNull;
26import static junit.framework.Assert.fail;
27
28import static org.junit.Assert.assertEquals;
29import static org.junit.Assert.assertFalse;
30import static org.junit.Assert.assertNotNull;
31import static org.junit.Assert.assertTrue;
32import static org.mockito.ArgumentMatchers.any;
33import static org.mockito.Matchers.anyInt;
34import static org.mockito.Matchers.anyString;
35import static org.mockito.Matchers.eq;
36import static org.mockito.Mockito.mock;
37import static org.mockito.Mockito.never;
38import static org.mockito.Mockito.reset;
39import static org.mockito.Mockito.times;
40import static org.mockito.Mockito.verify;
41import static org.mockito.Mockito.when;
42
43import android.app.Notification;
44import android.app.NotificationChannel;
45import android.app.NotificationChannelGroup;
46import android.app.NotificationManager;
47import android.content.ContentProvider;
48import android.content.Context;
49import android.content.IContentProvider;
50import android.content.pm.ApplicationInfo;
51import android.content.pm.PackageInfo;
52import android.content.pm.PackageManager;
53import android.content.pm.Signature;
54import android.content.res.Resources;
55import android.graphics.Color;
56import android.media.AudioAttributes;
57import android.net.Uri;
58import android.os.Build;
59import android.os.UserHandle;
60import android.provider.Settings;
61import android.provider.Settings.Secure;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040062import android.test.suitebuilder.annotation.SmallTest;
63import android.testing.TestableContentResolver;
64import android.util.ArrayMap;
Julia Reynolds0c245002019-03-27 16:10:11 -040065import android.util.ArraySet;
Julia Reynoldse7ca31b2019-04-25 15:41:47 -040066import android.util.Pair;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040067import android.util.Xml;
68
Beverly47679222019-05-16 15:46:11 -040069import androidx.test.InstrumentationRegistry;
70import androidx.test.runner.AndroidJUnit4;
71
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040072import com.android.internal.util.FastXmlSerializer;
73import com.android.server.UiServiceTestCase;
74
75import org.json.JSONArray;
76import org.json.JSONObject;
77import org.junit.Before;
78import org.junit.Test;
79import org.junit.runner.RunWith;
80import org.mockito.Mock;
81import org.mockito.MockitoAnnotations;
82import org.xmlpull.v1.XmlPullParser;
83import org.xmlpull.v1.XmlSerializer;
84
85import java.io.BufferedInputStream;
86import java.io.BufferedOutputStream;
87import java.io.ByteArrayInputStream;
88import java.io.ByteArrayOutputStream;
89import java.util.Arrays;
90import java.util.HashMap;
91import java.util.List;
92import java.util.Map;
93import java.util.Objects;
94import java.util.concurrent.ThreadLocalRandom;
95
96@SmallTest
97@RunWith(AndroidJUnit4.class)
98public class PreferencesHelperTest extends UiServiceTestCase {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -040099 private static final int UID_N_MR1 = 0;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400100 private static final UserHandle USER = UserHandle.of(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400101 private static final int UID_O = 1111;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400102 private static final String SYSTEM_PKG = "android";
Beverly0479cde22018-11-09 11:05:34 -0500103 private static final int SYSTEM_UID = 1000;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400104 private static final UserHandle USER2 = UserHandle.of(10);
105 private static final String TEST_CHANNEL_ID = "test_channel_id";
106 private static final String TEST_AUTHORITY = "test";
107 private static final Uri SOUND_URI =
108 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
109 private static final Uri CANONICAL_SOUND_URI =
110 Uri.parse("content://" + TEST_AUTHORITY
111 + "/internal/audio/media/10?title=Test&canonical=1");
112
113 @Mock NotificationUsageStats mUsageStats;
114 @Mock RankingHandler mHandler;
115 @Mock PackageManager mPm;
116 @Mock IContentProvider mTestIContentProvider;
117 @Mock Context mContext;
118 @Mock ZenModeHelper mMockZenModeHelper;
119
120 private NotificationManager.Policy mTestNotificationPolicy;
121
122 private PreferencesHelper mHelper;
123 private AudioAttributes mAudioAttributes;
124
125 @Before
126 public void setUp() throws Exception {
127 MockitoAnnotations.initMocks(this);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400128
129 final ApplicationInfo legacy = new ApplicationInfo();
130 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
131 final ApplicationInfo upgrade = new ApplicationInfo();
132 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400133 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
134 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400135 when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400136 when(mPm.getPackageUidAsUser(eq(PKG_N_MR1), anyInt())).thenReturn(UID_N_MR1);
137 when(mPm.getPackageUidAsUser(eq(PKG_O), anyInt())).thenReturn(UID_O);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400138 when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
139 PackageInfo info = mock(PackageInfo.class);
140 info.signatures = new Signature[] {mock(Signature.class)};
141 when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400142 when(mPm.getPackageInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt()))
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400143 .thenReturn(mock(PackageInfo.class));
144 when(mContext.getResources()).thenReturn(
145 InstrumentationRegistry.getContext().getResources());
146 when(mContext.getContentResolver()).thenReturn(
147 InstrumentationRegistry.getContext().getContentResolver());
148 when(mContext.getPackageManager()).thenReturn(mPm);
149 when(mContext.getApplicationInfo()).thenReturn(legacy);
150 // most tests assume badging is enabled
151 TestableContentResolver contentResolver = getContext().getContentResolver();
152 contentResolver.setFallbackToExisting(false);
153 Secure.putIntForUser(contentResolver,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400154 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID_N_MR1));
Julia Reynolds4509ce72019-01-31 13:12:43 -0500155 Secure.putIntForUser(contentResolver,
156 Secure.NOTIFICATION_BUBBLES, 1, UserHandle.getUserId(UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400157
158 ContentProvider testContentProvider = mock(ContentProvider.class);
159 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
160 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
161
162 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
163 .thenReturn(CANONICAL_SOUND_URI);
164 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
165 .thenReturn(CANONICAL_SOUND_URI);
166 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
167 .thenReturn(SOUND_URI);
168
169 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
170 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
171 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
172 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
173 resetZenModeHelper();
174
175 mAudioAttributes = new AudioAttributes.Builder()
176 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
177 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
178 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
179 .build();
180 }
181
Annie Meng8b646fd2019-02-01 18:46:42 +0000182 private ByteArrayOutputStream writeXmlAndPurge(
183 String pkg, int uid, boolean forBackup, int userId, String... channelIds)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400184 throws Exception {
185 XmlSerializer serializer = new FastXmlSerializer();
186 ByteArrayOutputStream baos = new ByteArrayOutputStream();
187 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
188 serializer.startDocument(null, true);
Annie Meng8b646fd2019-02-01 18:46:42 +0000189 mHelper.writeXml(serializer, forBackup, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400190 serializer.endDocument();
191 serializer.flush();
192 for (String channelId : channelIds) {
193 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
194 }
195 return baos;
196 }
197
Annie Meng8b646fd2019-02-01 18:46:42 +0000198 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore, int userId)
199 throws Exception {
200 loadByteArrayXml(stream.toByteArray(), forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400201 }
202
Annie Meng8b646fd2019-02-01 18:46:42 +0000203 private void loadByteArrayXml(byte[] byteArray, boolean forRestore, int userId)
204 throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400205 XmlPullParser parser = Xml.newPullParser();
206 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
207 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000208 mHelper.readXml(parser, forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400209 }
210
211 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
212 assertEquals(expected.getId(), actual.getId());
213 assertEquals(expected.getName(), actual.getName());
214 assertEquals(expected.getDescription(), actual.getDescription());
215 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
216 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
217 assertEquals(expected.getImportance(), actual.getImportance());
218 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
219 assertEquals(expected.getSound(), actual.getSound());
220 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
221 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
222 assertEquals(expected.getGroup(), actual.getGroup());
223 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
224 assertEquals(expected.getLightColor(), actual.getLightColor());
225 }
226
227 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
228 assertEquals(expected.getId(), actual.getId());
229 assertEquals(expected.getName(), actual.getName());
230 assertEquals(expected.getDescription(), actual.getDescription());
231 assertEquals(expected.isBlocked(), actual.isBlocked());
232 }
233
234 private NotificationChannel getChannel() {
235 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
236 }
237
238 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
239 for (NotificationChannel channel : channels) {
240 if (channel.getId().equals(id)) {
241 return channel;
242 }
243 }
244 return null;
245 }
246
247 private void resetZenModeHelper() {
248 reset(mMockZenModeHelper);
249 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
250 }
251
Annie Meng8b646fd2019-02-01 18:46:42 +0000252 private void setUpPackageWithUid(String packageName, int uid) throws Exception {
253 when(mPm.getApplicationInfoAsUser(eq(packageName), anyInt(), anyInt()))
254 .thenReturn(new ApplicationInfo());
255 when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
256 }
257
258 @Test
259 public void testWriteXml_onlyBackupsTargetUser() throws Exception {
260 // Setup package notifications.
261 String package0 = "test.package.user0";
262 int uid0 = 1001;
263 setUpPackageWithUid(package0, uid0);
264 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400265 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000266
267 String package10 = "test.package.user10";
268 int uid10 = 1001001;
269 setUpPackageWithUid(package10, uid10);
270 NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400271 assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000272
273 ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
274
275 // Reset state.
276 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
277 mHelper.onPackagesChanged(true, 10, new String[] {package10}, new int[] {uid10});
278
279 // Parse backup data.
280 loadStreamXml(baos, true, 0);
281 loadStreamXml(baos, true, 10);
282
283 assertEquals(
284 channel10,
285 mHelper.getNotificationChannel(package10, uid10, channel10.getId(), false));
286 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
287 }
288
289 @Test
290 public void testReadXml_onlyRestoresTargetUser() throws Exception {
291 // Setup package in user 0.
292 String package0 = "test.package.user0";
293 int uid0 = 1001;
294 setUpPackageWithUid(package0, uid0);
295 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400296 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000297
298 ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
299
300 // Reset state.
301 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
302
303 // Restore should convert the uid according to the target user.
304 int expectedUid = 1001001;
305 setUpPackageWithUid(package0, expectedUid);
306 // Parse backup data.
307 loadStreamXml(baos, true, 10);
308
309 assertEquals(
310 channel0,
311 mHelper.getNotificationChannel(package0, expectedUid, channel0.getId(), false));
312 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
313 }
314
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400315 @Test
316 public void testChannelXml() throws Exception {
317 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
318 ncg.setBlocked(true);
319 ncg.setDescription("group desc");
320 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
321 NotificationChannel channel1 =
322 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
323 NotificationChannel channel2 =
324 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
325 channel2.setDescription("descriptions for all");
326 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
327 channel2.enableLights(true);
328 channel2.setBypassDnd(true);
329 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
330 channel2.enableVibration(true);
331 channel2.setGroup(ncg.getId());
332 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
333 channel2.setLightColor(Color.BLUE);
334
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400335 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
336 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400337 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
338 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400339
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400340 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
341 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400342
Annie Meng8b646fd2019-02-01 18:46:42 +0000343 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
344 UserHandle.USER_ALL, channel1.getId(), channel2.getId(),
345 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400346 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
347 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400348
Annie Meng8b646fd2019-02-01 18:46:42 +0000349 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400350
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400351 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
352 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400353 assertEquals(channel1,
354 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400355 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400356 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400357
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400358 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
359 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400360 boolean foundNcg = false;
361 for (NotificationChannelGroup actual : actualGroups) {
362 if (ncg.getId().equals(actual.getId())) {
363 foundNcg = true;
364 compareGroups(ncg, actual);
365 } else if (ncg2.getId().equals(actual.getId())) {
366 compareGroups(ncg2, actual);
367 }
368 }
369 assertTrue(foundNcg);
370
371 boolean foundChannel2Group = false;
372 for (NotificationChannelGroup actual : actualGroups) {
373 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
374 foundChannel2Group = true;
375 break;
376 }
377 }
378 assertTrue(foundChannel2Group);
379 }
380
381 @Test
382 public void testChannelXmlForBackup() throws Exception {
383 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
384 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
385 NotificationChannel channel1 =
386 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
387 NotificationChannel channel2 =
388 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
389 channel2.setDescription("descriptions for all");
390 channel2.setSound(SOUND_URI, mAudioAttributes);
391 channel2.enableLights(true);
392 channel2.setBypassDnd(true);
393 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
394 channel2.enableVibration(false);
395 channel2.setGroup(ncg.getId());
396 channel2.setLightColor(Color.BLUE);
397 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
398 channel3.enableVibration(true);
399
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400400 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
401 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
402 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
403 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
404 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
405 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400406
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400407 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400408
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400409 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400410
Annie Meng8b646fd2019-02-01 18:46:42 +0000411 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
412 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
413 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400414 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1, PKG_O},
415 new int[]{UID_N_MR1, UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400416
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400417 mHelper.setShowBadge(PKG_O, UID_O, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400418
Annie Meng8b646fd2019-02-01 18:46:42 +0000419 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400420
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400421 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O));
422 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400423 assertEquals(channel1,
424 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400425 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400426 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400427 compareChannels(channel3,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400428 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400429
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400430 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
431 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400432 boolean foundNcg = false;
433 for (NotificationChannelGroup actual : actualGroups) {
434 if (ncg.getId().equals(actual.getId())) {
435 foundNcg = true;
436 compareGroups(ncg, actual);
437 } else if (ncg2.getId().equals(actual.getId())) {
438 compareGroups(ncg2, actual);
439 }
440 }
441 assertTrue(foundNcg);
442
443 boolean foundChannel2Group = false;
444 for (NotificationChannelGroup actual : actualGroups) {
445 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
446 foundChannel2Group = true;
447 break;
448 }
449 }
450 assertTrue(foundChannel2Group);
451 }
452
453 @Test
454 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
455 NotificationChannel channel =
456 new NotificationChannel("id", "name", IMPORTANCE_LOW);
457 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400458 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400459
Annie Meng8b646fd2019-02-01 18:46:42 +0000460 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
461 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400462
463 // Testing that in restore we are given the canonical version
Annie Meng8b646fd2019-02-01 18:46:42 +0000464 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400465 verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
466 }
467
468 @Test
469 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
470 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
471 Uri canonicalBasedOnLocal = localUri.buildUpon()
472 .appendQueryParameter("title", "Test")
473 .appendQueryParameter("canonical", "1")
474 .build();
475 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
476 .thenReturn(canonicalBasedOnLocal);
477 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
478 .thenReturn(localUri);
479 when(mTestIContentProvider.uncanonicalize(any(), eq(canonicalBasedOnLocal)))
480 .thenReturn(localUri);
481
482 NotificationChannel channel =
483 new NotificationChannel("id", "name", IMPORTANCE_LOW);
484 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400485 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000486 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
487 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400488
Annie Meng8b646fd2019-02-01 18:46:42 +0000489 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400490
491 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400492 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400493 assertEquals(localUri, actualChannel.getSound());
494 }
495
496 @Test
497 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
498 Thread.sleep(3000);
499 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
500 .thenReturn(null);
501 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
502 .thenReturn(null);
503
504 NotificationChannel channel =
505 new NotificationChannel("id", "name", IMPORTANCE_LOW);
506 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400507 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000508 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
509 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400510
Annie Meng8b646fd2019-02-01 18:46:42 +0000511 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400512
513 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400514 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400515 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
516 }
517
518
519 /**
520 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
521 * handle its restore properly.
522 */
523 @Test
524 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
525 // Not a local uncanonicalized uri, simulating that it fails to exist locally
526 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI))).thenReturn(null);
527 String id = "id";
528 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400529 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400530 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
531 + "sound=\"" + SOUND_URI + "\" "
532 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
533 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
534 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
535 + "</package>\n"
536 + "</ranking>\n";
537
Annie Meng8b646fd2019-02-01 18:46:42 +0000538 loadByteArrayXml(
539 backupWithUncanonicalizedSoundUri.getBytes(), true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400540
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400541 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, id, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400542 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
543 }
544
545 @Test
546 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
547 NotificationChannel channel =
548 new NotificationChannel("id", "name", IMPORTANCE_LOW);
549 channel.setSound(null, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400550 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000551 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
552 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400553
Annie Meng8b646fd2019-02-01 18:46:42 +0000554 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400555
556 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400557 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400558 assertEquals(null, actualChannel.getSound());
559 }
560
561 @Test
562 public void testChannelXml_backup() throws Exception {
563 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
564 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
565 NotificationChannel channel1 =
566 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
567 NotificationChannel channel2 =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400568 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400569 NotificationChannel channel3 =
570 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
571 channel3.setGroup(ncg.getId());
572
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400573 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
574 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
575 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
576 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
577 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400578
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400579 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId());
580 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId());
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400581 assertEquals(channel2,
582 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400583
Annie Meng8b646fd2019-02-01 18:46:42 +0000584 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
585 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
586 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400587 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
588 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400589
590 XmlPullParser parser = Xml.newPullParser();
591 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
592 null);
593 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000594 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400595
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400596 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
597 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
598 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400599 assertEquals(channel2,
600 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400601 }
602
603 @Test
604 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400605 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000606 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400607
Annie Meng8b646fd2019-02-01 18:46:42 +0000608 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400609
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400610 final NotificationChannel updated = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400611 NotificationChannel.DEFAULT_CHANNEL_ID, false);
612 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
613 assertFalse(updated.canBypassDnd());
614 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
615 assertEquals(0, updated.getUserLockedFields());
616 }
617
618 @Test
619 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400620 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
621 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400622 NotificationChannel.DEFAULT_CHANNEL_ID, false);
623 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400624 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400625
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400626 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000627 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400628
Annie Meng8b646fd2019-02-01 18:46:42 +0000629 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400630
631 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400632 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400633 }
634
635 @Test
636 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
637 final String preupgradeXml = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400638 + "<package name=\"" + PKG_N_MR1
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400639 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
640 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400641 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID_N_MR1 + "\" />\n"
642 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" visibility=\""
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400643 + Notification.VISIBILITY_PRIVATE + "\" />\n"
644 + "</ranking>";
645 XmlPullParser parser = Xml.newPullParser();
646 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
647 null);
648 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000649 mHelper.readXml(parser, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400650
651 final NotificationChannel updated1 =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400652 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400653 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
654 assertTrue(updated1.canBypassDnd());
655 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
656 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
657 | NotificationChannel.USER_LOCKED_PRIORITY
658 | NotificationChannel.USER_LOCKED_VISIBILITY,
659 updated1.getUserLockedFields());
660
661 // No Default Channel created for updated packages
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400662 assertEquals(null, mHelper.getNotificationChannel(PKG_O, UID_O,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400663 NotificationChannel.DEFAULT_CHANNEL_ID, false));
664 }
665
666 @Test
667 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
668 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400669 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400670 assertTrue(defaultChannel != null);
Annie Meng8b646fd2019-02-01 18:46:42 +0000671 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
672 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400673 // Load package at higher sdk.
674 final ApplicationInfo upgraded = new ApplicationInfo();
675 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400676 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000677 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400678
679 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400680 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400681 NotificationChannel.DEFAULT_CHANNEL_ID, false));
682 }
683
684 @Test
685 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400686 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400687 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400688 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000689 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400690
691 // Load package at higher sdk.
692 final ApplicationInfo upgraded = new ApplicationInfo();
693 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400694 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000695 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400696
697 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400698 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400699 NotificationChannel.DEFAULT_CHANNEL_ID, false));
700 }
701
702 @Test
703 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400704 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000705 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400706 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400707 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
708
Annie Meng8b646fd2019-02-01 18:46:42 +0000709 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400710
711 // Should still have the newly created channel that wasn't in the xml.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400712 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "bananas", false) != null);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400713 }
714
715 @Test
716 public void testCreateChannel_blocked() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400717 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400718
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400719 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
720 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400721 }
722
723 @Test
724 public void testCreateChannel_badImportance() throws Exception {
725 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400726 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400727 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
728 true, false);
729 fail("Was allowed to create a channel with invalid importance");
730 } catch (IllegalArgumentException e) {
731 // yay
732 }
733 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400734 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400735 new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
736 true, false);
737 fail("Was allowed to create a channel with invalid importance");
738 } catch (IllegalArgumentException e) {
739 // yay
740 }
741 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400742 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400743 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
744 true, false);
745 fail("Was allowed to create a channel with invalid importance");
746 } catch (IllegalArgumentException e) {
747 // yay
748 }
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400749 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
750 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
751 assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
752 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400753 }
754
755
756 @Test
757 public void testUpdate() throws Exception {
758 // no fields locked by user
759 final NotificationChannel channel =
760 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
761 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
762 channel.enableLights(true);
763 channel.setBypassDnd(true);
764 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
765
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400766 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400767
768 // same id, try to update all fields
769 final NotificationChannel channel2 =
770 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
771 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
772 channel2.enableLights(false);
773 channel2.setBypassDnd(false);
774 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
775
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400776 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400777
778 // all fields should be changed
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400779 assertEquals(channel2,
780 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400781
782 verify(mHandler, times(1)).requestSort();
783 }
784
785 @Test
786 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400787 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_UNSPECIFIED);
788 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
789 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400790 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400791 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
792 assertFalse(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400793
794 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400795 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400796
797 defaultChannel.setShowBadge(false);
798 defaultChannel.setImportance(IMPORTANCE_NONE);
799 defaultChannel.setBypassDnd(true);
800 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
801
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400802 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
803 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400804
805 // ensure app level fields are changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400806 assertFalse(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
807 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
808 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1,
809 UID_N_MR1));
810 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1));
811 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400812 }
813
814 @Test
815 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
816 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
817
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400818 mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
819 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
820 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400821 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400822 mHelper.getPackageVisibility(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400823
824 channel.setShowBadge(false);
825 channel.setImportance(IMPORTANCE_NONE);
826 channel.setBypassDnd(true);
827 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
828
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400829 mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400830
831 // ensure app level fields are not changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400832 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
833 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400834 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400835 mHelper.getPackageVisibility(PKG_O, UID_O));
836 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O,
837 UID_O));
838 assertFalse(mHelper.getIsAppImportanceLocked(PKG_O, UID_O));
839 }
840
841 @Test
842 public void testUpdate_preUpgrade_noUpdateAppFieldsWithMultipleChannels() throws Exception {
843 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
844
845 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
846 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
847 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
848 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
849 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
850
851 channel.setShowBadge(false);
852 channel.setImportance(IMPORTANCE_NONE);
853 channel.setBypassDnd(true);
854 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
855
856 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
857
858 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
859 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
860
861 defaultChannel.setShowBadge(false);
862 defaultChannel.setImportance(IMPORTANCE_NONE);
863 defaultChannel.setBypassDnd(true);
864 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
865
866 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
867
868 // ensure app level fields are not changed
869 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
870 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
871 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
872 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
873 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
874 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400875 }
876
877 @Test
878 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400879 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "garbage", false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400880 }
881
882 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400883 public void testCreateChannel_CannotChangeHiddenFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400884 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400885 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400886 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
887 channel.enableLights(true);
888 channel.setBypassDnd(true);
889 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
890 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800891 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400892 int lockMask = 0;
893 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
894 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
895 }
896 channel.lockFields(lockMask);
897
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400898 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400899
900 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400901 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400902
903 assertEquals(channel.getName(), savedChannel.getName());
904 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
905 assertFalse(savedChannel.canBypassDnd());
906 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
907 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800908 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400909
910 verify(mHandler, never()).requestSort();
911 }
912
913 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400914 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400915 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400916 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400917 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
918 channel.enableLights(true);
919 channel.setBypassDnd(true);
920 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
921 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800922 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400923 int lockMask = 0;
924 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
925 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
926 }
927 channel.lockFields(lockMask);
928
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400929 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400930
931 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400932 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400933
934 assertEquals(channel.getName(), savedChannel.getName());
935 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
936 assertFalse(savedChannel.canBypassDnd());
937 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
938 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800939 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400940 }
941
942 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400943 public void testClearLockedFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400944 final NotificationChannel channel = getChannel();
Julia Reynolds5c399c62019-04-08 14:42:53 -0400945 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400946 assertEquals(0, channel.getUserLockedFields());
947
948 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
949 | NotificationChannel.USER_LOCKED_IMPORTANCE);
Julia Reynolds5c399c62019-04-08 14:42:53 -0400950 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400951 assertEquals(0, channel.getUserLockedFields());
952 }
953
954 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400955 public void testLockFields_soundAndVibration() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400956 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400957
958 final NotificationChannel update1 = getChannel();
959 update1.setSound(new Uri.Builder().scheme("test").build(),
960 new AudioAttributes.Builder().build());
961 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400962 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400963 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
964 | NotificationChannel.USER_LOCKED_SOUND,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400965 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400966 .getUserLockedFields());
967
968 NotificationChannel update2 = getChannel();
969 update2.enableVibration(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400970 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400971 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
972 | NotificationChannel.USER_LOCKED_SOUND
973 | NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400974 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400975 .getUserLockedFields());
976 }
977
978 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400979 public void testLockFields_vibrationAndLights() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400980 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400981
982 final NotificationChannel update1 = getChannel();
983 update1.setVibrationPattern(new long[]{7945, 46 ,246});
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400984 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400985 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400986 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400987 .getUserLockedFields());
988
989 final NotificationChannel update2 = getChannel();
990 update2.enableLights(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400991 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400992 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
993 | NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400994 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400995 .getUserLockedFields());
996 }
997
998 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400999 public void testLockFields_lightsAndImportance() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001000 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001001
1002 final NotificationChannel update1 = getChannel();
1003 update1.setLightColor(Color.GREEN);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001004 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001005 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001006 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001007 .getUserLockedFields());
1008
1009 final NotificationChannel update2 = getChannel();
1010 update2.setImportance(IMPORTANCE_DEFAULT);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001011 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001012 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
1013 | NotificationChannel.USER_LOCKED_IMPORTANCE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001014 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001015 .getUserLockedFields());
1016 }
1017
1018 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001019 public void testLockFields_visibilityAndDndAndBadge() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001020 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001021 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001022 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001023 .getUserLockedFields());
1024
1025 final NotificationChannel update1 = getChannel();
1026 update1.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001027 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001028 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001029 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001030 .getUserLockedFields());
1031
1032 final NotificationChannel update2 = getChannel();
1033 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001034 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001035 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1036 | NotificationChannel.USER_LOCKED_VISIBILITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001037 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001038 .getUserLockedFields());
1039
1040 final NotificationChannel update3 = getChannel();
1041 update3.setShowBadge(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001042 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001043 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1044 | NotificationChannel.USER_LOCKED_VISIBILITY
1045 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001046 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update3.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001047 .getUserLockedFields());
1048 }
1049
1050 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001051 public void testLockFields_allowBubble() {
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001052 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1053 assertEquals(0,
1054 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
1055 .getUserLockedFields());
1056
1057 final NotificationChannel update = getChannel();
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001058 update.setAllowBubbles(false);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001059 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001060 assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE,
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001061 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false)
1062 .getUserLockedFields());
1063 }
1064
1065 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001066 public void testDeleteNonExistentChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001067 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001068 }
1069
1070 @Test
1071 public void testGetDeletedChannel() throws Exception {
1072 NotificationChannel channel = getChannel();
1073 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1074 channel.enableLights(true);
1075 channel.setBypassDnd(true);
1076 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1077 channel.enableVibration(true);
1078 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1079
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001080 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1081 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001082
1083 // Does not return deleted channel
1084 NotificationChannel response =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001085 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001086 assertNull(response);
1087
1088 // Returns deleted channel
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001089 response = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001090 compareChannels(channel, response);
1091 assertTrue(response.isDeleted());
1092 }
1093
1094 @Test
1095 public void testGetDeletedChannels() throws Exception {
1096 Map<String, NotificationChannel> channelMap = new HashMap<>();
1097 NotificationChannel channel =
1098 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1099 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1100 channel.enableLights(true);
1101 channel.setBypassDnd(true);
1102 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1103 channel.enableVibration(true);
1104 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1105 channelMap.put(channel.getId(), channel);
1106 NotificationChannel channel2 =
1107 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1108 channelMap.put(channel2.getId(), channel2);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001109 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1110 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001111
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001112 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001113
1114 // Returns only non-deleted channels
1115 List<NotificationChannel> channels =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001116 mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001117 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1118 for (NotificationChannel nc : channels) {
1119 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1120 compareChannels(channel2, nc);
1121 }
1122 }
1123
1124 // Returns deleted channels too
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001125 channels = mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001126 assertEquals(3, channels.size()); // Includes default channel
1127 for (NotificationChannel nc : channels) {
1128 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1129 compareChannels(channelMap.get(nc.getId()), nc);
1130 }
1131 }
1132 }
1133
1134 @Test
1135 public void testGetDeletedChannelCount() throws Exception {
1136 NotificationChannel channel =
1137 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1138 NotificationChannel channel2 =
1139 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1140 NotificationChannel channel3 =
1141 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001142 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1143 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1144 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001145
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001146 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1147 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001148
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001149 assertEquals(2, mHelper.getDeletedChannelCount(PKG_N_MR1, UID_N_MR1));
1150 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001151 }
1152
1153 @Test
1154 public void testGetBlockedChannelCount() throws Exception {
1155 NotificationChannel channel =
1156 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1157 NotificationChannel channel2 =
1158 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
1159 NotificationChannel channel3 =
1160 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001161 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1162 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1163 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001164
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001165 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001166
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001167 assertEquals(1, mHelper.getBlockedChannelCount(PKG_N_MR1, UID_N_MR1));
1168 assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001169 }
1170
1171 @Test
Beverly4f7b53d2018-11-20 09:56:31 -05001172 public void testUpdateChannelsBypassingDnd_onUserSwitch_onUserUnlocked() throws Exception {
1173 int user = USER.getIdentifier();
1174 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1175 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1176 NotificationManager.IMPORTANCE_MAX);
1177 channel1.setBypassDnd(true);
1178 channel1.setGroup(ncg.getId());
1179
1180 // channel is associated with a group, then group is deleted
1181 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1182 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1183 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, user, ncg.getId());
1184
1185 mHelper.onUserSwitched(user);
1186 mHelper.onUserUnlocked(user);
1187 }
1188
1189 @Test
Beverly0479cde22018-11-09 11:05:34 -05001190 public void testGetChannelsBypassingDndCount_noChannelsBypassing() throws Exception {
1191 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1192 USER.getIdentifier()).getList().size());
1193 }
1194
1195 @Test
1196 public void testGetChannelsBypassingDnd_noChannelsForUserIdBypassing()
1197 throws Exception {
1198 int user = 9;
1199 NotificationChannel channel = new NotificationChannel("id", "name",
1200 NotificationManager.IMPORTANCE_MAX);
1201 channel.setBypassDnd(true);
1202 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1203
1204 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1205 user).getList().size());
1206 }
1207
1208 @Test
1209 public void testGetChannelsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1210 int user = USER.getIdentifier();
1211 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1212 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1213 NotificationManager.IMPORTANCE_MAX);
1214 channel1.setBypassDnd(true);
1215 channel1.setGroup(ncg.getId());
1216 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1217 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1218
1219 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1220 user).getList().size());
1221
1222 // disable group
1223 ncg.setBlocked(true);
1224 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1225 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1226 user).getList().size());
1227 }
1228
1229 @Test
1230 public void testGetChannelsBypassingDndCount_multipleChannelsBypassing() {
1231 int user = USER.getIdentifier();
1232 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1233 NotificationManager.IMPORTANCE_MAX);
1234 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1235 NotificationManager.IMPORTANCE_MAX);
1236 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1237 NotificationManager.IMPORTANCE_MAX);
1238 channel1.setBypassDnd(true);
1239 channel2.setBypassDnd(true);
1240 channel3.setBypassDnd(true);
1241 // has DND access, so can set bypassDnd attribute
1242 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1243 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1244 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1245 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1246 user).getList().size());
1247
1248 // block notifications from this app
1249 mHelper.setEnabled(PKG_N_MR1, user, false);
1250 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1251 user).getList().size());
1252
1253 // re-enable notifications from this app
1254 mHelper.setEnabled(PKG_N_MR1, user, true);
1255 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1256 user).getList().size());
1257
1258 // setBypassDnd false for some channels
1259 channel1.setBypassDnd(false);
1260 channel2.setBypassDnd(false);
1261 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1262 user).getList().size());
1263
1264 // setBypassDnd false for rest of the channels
1265 channel3.setBypassDnd(false);
1266 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1267 user).getList().size());
1268 }
1269
1270 @Test
1271 public void testGetAppsBypassingDndCount_noAppsBypassing() throws Exception {
1272 assertEquals(0, mHelper.getAppsBypassingDndCount(USER.getIdentifier()));
1273 }
1274
1275 @Test
1276 public void testGetAppsBypassingDndCount_noAppsForUserIdBypassing() throws Exception {
1277 int user = 9;
1278 NotificationChannel channel = new NotificationChannel("id", "name",
1279 NotificationManager.IMPORTANCE_MAX);
1280 channel.setBypassDnd(true);
1281 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1282
1283 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1284 }
1285
1286 @Test
1287 public void testGetAppsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1288 int user = USER.getIdentifier();
1289 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1290 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1291 NotificationManager.IMPORTANCE_MAX);
1292 channel1.setBypassDnd(true);
1293 channel1.setGroup(ncg.getId());
1294 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1295 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1296
1297 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1298
1299 // disable group
1300 ncg.setBlocked(true);
1301 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1302 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1303 }
1304
1305 @Test
1306 public void testGetAppsBypassingDndCount_oneAppBypassing() {
1307 int user = USER.getIdentifier();
1308 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1309 NotificationManager.IMPORTANCE_MAX);
1310 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1311 NotificationManager.IMPORTANCE_MAX);
1312 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1313 NotificationManager.IMPORTANCE_MAX);
1314 channel1.setBypassDnd(true);
1315 channel2.setBypassDnd(true);
1316 channel3.setBypassDnd(true);
1317 // has DND access, so can set bypassDnd attribute
1318 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1319 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1320 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1321 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1322
1323 // block notifications from this app
1324 mHelper.setEnabled(PKG_N_MR1, user, false);
1325 assertEquals(0, mHelper.getAppsBypassingDndCount(user)); // no apps can bypass dnd
1326
1327 // re-enable notifications from this app
1328 mHelper.setEnabled(PKG_N_MR1, user, true);
1329 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1330
1331 // setBypassDnd false for some channels
1332 channel1.setBypassDnd(false);
1333 channel2.setBypassDnd(false);
1334 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1335
1336 // setBypassDnd false for rest of the channels
1337 channel3.setBypassDnd(false);
1338 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1339 }
1340
1341 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001342 public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception {
1343 // create notification channel that can't bypass dnd
1344 // expected result: areChannelsBypassingDnd = false
1345 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1346 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001347 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001348 assertFalse(mHelper.areChannelsBypassingDnd());
1349 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1350 resetZenModeHelper();
1351
1352 // create notification channel that can bypass dnd
1353 // expected result: areChannelsBypassingDnd = true
1354 NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1355 channel2.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001356 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001357 assertTrue(mHelper.areChannelsBypassingDnd());
1358 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1359 resetZenModeHelper();
1360
1361 // delete channels
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001362 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001363 assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
1364 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1365 resetZenModeHelper();
1366
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001367 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001368 assertFalse(mHelper.areChannelsBypassingDnd());
1369 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1370 resetZenModeHelper();
1371 }
1372
1373 @Test
1374 public void testUpdateCanChannelsBypassDnd() throws Exception {
1375 // create notification channel that can't bypass dnd
1376 // expected result: areChannelsBypassingDnd = false
1377 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1378 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001379 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001380 assertFalse(mHelper.areChannelsBypassingDnd());
1381 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1382 resetZenModeHelper();
1383
1384 // update channel so it CAN bypass dnd:
1385 // expected result: areChannelsBypassingDnd = true
1386 channel.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001387 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001388 assertTrue(mHelper.areChannelsBypassingDnd());
1389 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1390 resetZenModeHelper();
1391
1392 // update channel so it can't bypass dnd:
1393 // expected result: areChannelsBypassingDnd = false
1394 channel.setBypassDnd(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001395 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001396 assertFalse(mHelper.areChannelsBypassingDnd());
1397 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1398 resetZenModeHelper();
1399 }
1400
1401 @Test
1402 public void testSetupNewZenModeHelper_canBypass() {
1403 // start notification policy off with mAreChannelsBypassingDnd = true, but
1404 // RankingHelper should change to false
1405 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
1406 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
1407 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
1408 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
1409 assertFalse(mHelper.areChannelsBypassingDnd());
1410 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1411 resetZenModeHelper();
1412 }
1413
1414 @Test
1415 public void testSetupNewZenModeHelper_cannotBypass() {
1416 // start notification policy off with mAreChannelsBypassingDnd = false
1417 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0);
1418 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
1419 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
1420 assertFalse(mHelper.areChannelsBypassingDnd());
1421 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1422 resetZenModeHelper();
1423 }
1424
1425 @Test
1426 public void testCreateDeletedChannel() throws Exception {
1427 long[] vibration = new long[]{100, 67, 145, 156};
1428 NotificationChannel channel =
1429 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1430 channel.setVibrationPattern(vibration);
1431
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001432 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1433 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001434
1435 NotificationChannel newChannel = new NotificationChannel(
1436 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1437 newChannel.setVibrationPattern(new long[]{100});
1438
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001439 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001440
1441 // No long deleted, using old settings
1442 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001443 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001444 }
1445
1446 @Test
1447 public void testOnlyHasDefaultChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001448 assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
1449 assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001450
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001451 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1452 assertFalse(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001453 }
1454
1455 @Test
1456 public void testCreateChannel_defaultChannelId() throws Exception {
1457 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001458 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, new NotificationChannel(
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001459 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
1460 fail("Allowed to create default channel");
1461 } catch (IllegalArgumentException e) {
1462 // pass
1463 }
1464 }
1465
1466 @Test
1467 public void testCreateChannel_alreadyExists() throws Exception {
1468 long[] vibration = new long[]{100, 67, 145, 156};
1469 NotificationChannel channel =
1470 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1471 channel.setVibrationPattern(vibration);
1472
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001473 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001474
1475 NotificationChannel newChannel = new NotificationChannel(
1476 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1477 newChannel.setVibrationPattern(new long[]{100});
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001478 newChannel.setAllowBubbles(!channel.canBubble());
1479 newChannel.setLightColor(Color.BLUE);
1480 newChannel.setSound(Uri.EMPTY, null);
1481 newChannel.setShowBadge(!channel.canShowBadge());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001482
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001483 assertFalse(mHelper.createNotificationChannel(
1484 PKG_N_MR1, UID_N_MR1, newChannel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001485
1486 // Old settings not overridden
1487 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001488 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001489 }
1490
1491 @Test
1492 public void testCreateChannel_noOverrideSound() throws Exception {
1493 Uri sound = new Uri.Builder().scheme("test").build();
1494 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1495 NotificationManager.IMPORTANCE_DEFAULT);
1496 channel.setSound(sound, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001497 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001498 assertEquals(sound, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001499 PKG_N_MR1, UID_N_MR1, channel.getId(), false).getSound());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001500 }
1501
1502 @Test
1503 public void testPermanentlyDeleteChannels() throws Exception {
1504 NotificationChannel channel1 =
1505 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1506 NotificationChannel channel2 =
1507 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1508
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001509 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1510 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001511
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001512 mHelper.permanentlyDeleteNotificationChannels(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001513
1514 // Only default channel remains
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001515 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001516 }
1517
1518 @Test
1519 public void testDeleteGroup() throws Exception {
1520 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1521 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1522 NotificationChannel nonGroupedNonDeletedChannel =
1523 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1524 NotificationChannel groupedButNotDeleted =
1525 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1526 groupedButNotDeleted.setGroup("not");
1527 NotificationChannel groupedAndDeleted =
1528 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1529 groupedAndDeleted.setGroup("totally");
1530
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001531 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
1532 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001533 mHelper.createNotificationChannel(
1534 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001535 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false);
1536 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001537
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001538 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001539
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001540 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001541 assertNotNull(
1542 mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001543
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001544 assertNull(mHelper.getNotificationChannel(
1545 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), false));
1546 compareChannels(groupedAndDeleted, mHelper.getNotificationChannel(
1547 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001548
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001549 compareChannels(groupedButNotDeleted, mHelper.getNotificationChannel(
1550 PKG_N_MR1, UID_N_MR1, groupedButNotDeleted.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001551 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001552 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001553
1554 // notDeleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001555 assertEquals(1, mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001556
1557 verify(mHandler, never()).requestSort();
1558 }
1559
1560 @Test
1561 public void testOnUserRemoved() throws Exception {
1562 int[] user0Uids = {98, 235, 16, 3782};
1563 int[] user1Uids = new int[user0Uids.length];
1564 for (int i = 0; i < user0Uids.length; i++) {
1565 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1566
1567 final ApplicationInfo legacy = new ApplicationInfo();
1568 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001569 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001570
1571 // create records with the default channel for all user 0 and user 1 uids
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001572 mHelper.getImportance(PKG_N_MR1, user0Uids[i]);
1573 mHelper.getImportance(PKG_N_MR1, user1Uids[i]);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001574 }
1575
1576 mHelper.onUserRemoved(1);
1577
1578 // user 0 records remain
1579 for (int i = 0; i < user0Uids.length; i++) {
1580 assertEquals(1,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001581 mHelper.getNotificationChannels(PKG_N_MR1, user0Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001582 }
1583 // user 1 records are gone
1584 for (int i = 0; i < user1Uids.length; i++) {
1585 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001586 mHelper.getNotificationChannels(PKG_N_MR1, user1Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001587 }
1588 }
1589
1590 @Test
1591 public void testOnPackageChanged_packageRemoval() throws Exception {
1592 // Deleted
1593 NotificationChannel channel1 =
1594 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001595 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001596
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001597 assertTrue(mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1},
1598 new int[]{UID_N_MR1}));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001599
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001600 assertEquals(0, mHelper.getNotificationChannels(
1601 PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001602
1603 // Not deleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001604 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001605
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001606 assertFalse(mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM,
1607 new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001608 assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001609 }
1610
1611 @Test
1612 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001613 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001614
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001615 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1616 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001617
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001618 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1619 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001620 }
1621
1622 @Test
1623 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1624 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001625 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001626 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001627 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001628
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001629 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1630 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001631
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001632 assertEquals(0, mHelper.getNotificationChannelGroups(
1633 PKG_N_MR1, UID_N_MR1, true, true, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001634 }
1635
1636 @Test
1637 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1638 // create channel as api 26
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001639 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001640
1641 // install new app version targeting 25
1642 final ApplicationInfo legacy = new ApplicationInfo();
1643 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001644 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001645 mHelper.onPackagesChanged(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001646 false, UserHandle.USER_SYSTEM, new String[]{PKG_O}, new int[]{UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001647
1648 // make sure the default channel was readded
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001649 //assertEquals(2, mHelper.getNotificationChannels(PKG_O, UID_O, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001650 assertNotNull(mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001651 PKG_O, UID_O, NotificationChannel.DEFAULT_CHANNEL_ID, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001652 }
1653
1654 @Test
Julia Reynolds7af51c52019-04-19 11:08:27 -04001655 public void testClearData() {
1656 ArraySet<String> pkg = new ArraySet<>();
1657 pkg.add(PKG_O);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001658 ArraySet<Pair<String, Integer>> pkgPair = new ArraySet<>();
1659 pkgPair.add(new Pair(PKG_O, UID_O));
Julia Reynolds7af51c52019-04-19 11:08:27 -04001660 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
1661 mHelper.createNotificationChannelGroup(
1662 PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
1663 mHelper.lockChannelsForOEM(pkg.toArray(new String[]{}));
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001664 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001665 mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
1666 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
1667 mHelper.setBubblesAllowed(PKG_O, UID_O, false);
1668 mHelper.setShowBadge(PKG_O, UID_O, false);
1669 mHelper.setAppImportanceLocked(PKG_O, UID_O);
1670
1671 mHelper.clearData(PKG_O, UID_O);
1672
1673 assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, UID_O));
1674 assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O));
1675 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
1676 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
1677 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
1678 assertEquals(0, mHelper.getNotificationChannels(PKG_O, UID_O, true).getList().size());
1679 assertEquals(0, mHelper.getNotificationChannelGroups(PKG_O, UID_O).size());
1680
1681 NotificationChannel channel = getChannel();
1682 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
1683
1684 assertTrue(channel.isImportanceLockedByCriticalDeviceFunction());
1685 assertTrue(channel.isImportanceLockedByOEM());
1686 }
1687
1688 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001689 public void testRecordDefaults() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001690 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1691 UID_N_MR1));
1692 assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
1693 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001694 }
1695
1696 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001697 public void testCreateGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001698 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001699 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001700 assertEquals(ncg,
1701 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).iterator().next());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001702 verify(mHandler, never()).requestSort();
1703 }
1704
1705 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001706 public void testCannotCreateChannel_badGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001707 NotificationChannel channel1 =
1708 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1709 channel1.setGroup("garbage");
1710 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001711 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001712 fail("Created a channel with a bad group");
1713 } catch (IllegalArgumentException e) {
1714 }
1715 }
1716
1717 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001718 public void testCannotCreateChannel_goodGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001719 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001720 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001721 NotificationChannel channel1 =
1722 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1723 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001724 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001725
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001726 assertEquals(ncg.getId(), mHelper.getNotificationChannel(
1727 PKG_N_MR1, UID_N_MR1, channel1.getId(), false).getGroup());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001728 }
1729
1730 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001731 public void testGetChannelGroups() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001732 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001733 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001734 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001735 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001736 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001737 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001738
1739 NotificationChannel channel1 =
1740 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1741 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001742 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001743 NotificationChannel channel1a =
1744 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1745 channel1a.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001746 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001747
1748 NotificationChannel channel2 =
1749 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1750 channel2.setGroup(ncg2.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001751 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001752
1753 NotificationChannel channel3 =
1754 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001755 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001756
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001757 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1758 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001759 assertEquals(3, actual.size());
1760 for (NotificationChannelGroup group : actual) {
1761 if (group.getId() == null) {
1762 assertEquals(2, group.getChannels().size()); // misc channel too
1763 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1764 || channel3.getId().equals(group.getChannels().get(1).getId()));
1765 } else if (group.getId().equals(ncg.getId())) {
1766 assertEquals(2, group.getChannels().size());
1767 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1768 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1769 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1770 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1771 } else {
1772 fail("expected channel not found");
1773 }
1774 } else if (group.getId().equals(ncg2.getId())) {
1775 assertEquals(1, group.getChannels().size());
1776 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1777 }
1778 }
1779 }
1780
1781 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001782 public void testGetChannelGroups_noSideEffects() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001783 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001784 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001785
1786 NotificationChannel channel1 =
1787 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1788 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001789 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001790 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001791
1792 channel1.setImportance(IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001793 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001794
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001795 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1796 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001797
1798 assertEquals(2, actual.size());
1799 for (NotificationChannelGroup group : actual) {
1800 if (Objects.equals(group.getId(), ncg.getId())) {
1801 assertEquals(1, group.getChannels().size());
1802 }
1803 }
1804 }
1805
1806 @Test
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001807 public void testGetChannelGroups_includeEmptyGroups() {
1808 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1809 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
1810 NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
1811 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true);
1812
1813 NotificationChannel channel1 =
1814 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1815 channel1.setGroup(ncg.getId());
1816 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1817
1818 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1819 PKG_N_MR1, UID_N_MR1, false, false, true).getList();
1820
1821 assertEquals(2, actual.size());
1822 for (NotificationChannelGroup group : actual) {
1823 if (Objects.equals(group.getId(), ncg.getId())) {
1824 assertEquals(1, group.getChannels().size());
1825 }
1826 if (Objects.equals(group.getId(), ncgEmpty.getId())) {
1827 assertEquals(0, group.getChannels().size());
1828 }
1829 }
1830 }
1831
1832 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001833 public void testCreateChannel_updateName() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001834 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001835 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001836 NotificationChannel actual =
1837 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001838 assertEquals("hello", actual.getName());
1839
1840 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001841 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001842
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001843 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001844 assertEquals("goodbye", actual.getName());
1845 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1846
1847 verify(mHandler, times(1)).requestSort();
1848 }
1849
1850 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001851 public void testCreateChannel_addToGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001852 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001853 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001854 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001855 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001856 NotificationChannel actual =
1857 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001858 assertNull(actual.getGroup());
1859
1860 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1861 nc.setGroup(group.getId());
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001862 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001863
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001864 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001865 assertNotNull(actual.getGroup());
1866 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1867
1868 verify(mHandler, times(1)).requestSort();
1869 }
1870
1871 @Test
1872 public void testDumpChannelsJson() throws Exception {
1873 final ApplicationInfo upgrade = new ApplicationInfo();
1874 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
1875 try {
1876 when(mPm.getApplicationInfoAsUser(
1877 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
1878 } catch (PackageManager.NameNotFoundException e) {
1879 }
1880 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
1881 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
1882 for (int i = 0; i < numPackages; i++) {
1883 String pkgName = "pkg" + i;
1884 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
1885 for (int j = 0; j < numChannels; j++) {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001886 mHelper.createNotificationChannel(pkgName, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001887 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
1888 }
1889 expectedChannels.put(pkgName, numChannels);
1890 }
1891
1892 // delete the first channel of the first package
1893 String pkg = expectedChannels.keyAt(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001894 mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001895 // dump should not include deleted channels
1896 int count = expectedChannels.get(pkg);
1897 expectedChannels.put(pkg, count - 1);
1898
1899 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
1900 assertEquals(numPackages, actual.length());
1901 for (int i = 0; i < numPackages; i++) {
1902 JSONObject object = actual.getJSONObject(i);
1903 assertTrue(expectedChannels.containsKey(object.get("packageName")));
1904 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
1905 object.getInt("channelCount"));
1906 }
1907 }
1908
1909 @Test
1910 public void testBadgingOverrideTrue() throws Exception {
1911 Secure.putIntForUser(getContext().getContentResolver(),
1912 Secure.NOTIFICATION_BADGING, 1,
1913 USER.getIdentifier());
1914 mHelper.updateBadgingEnabled(); // would be called by settings observer
1915 assertTrue(mHelper.badgingEnabled(USER));
1916 }
1917
1918 @Test
1919 public void testBadgingOverrideFalse() throws Exception {
1920 Secure.putIntForUser(getContext().getContentResolver(),
1921 Secure.NOTIFICATION_BADGING, 0,
1922 USER.getIdentifier());
1923 mHelper.updateBadgingEnabled(); // would be called by settings observer
1924 assertFalse(mHelper.badgingEnabled(USER));
1925 }
1926
1927 @Test
1928 public void testBadgingForUserAll() throws Exception {
1929 try {
1930 mHelper.badgingEnabled(UserHandle.ALL);
1931 } catch (Exception e) {
1932 fail("just don't throw");
1933 }
1934 }
1935
1936 @Test
1937 public void testBadgingOverrideUserIsolation() throws Exception {
1938 Secure.putIntForUser(getContext().getContentResolver(),
1939 Secure.NOTIFICATION_BADGING, 0,
1940 USER.getIdentifier());
1941 Secure.putIntForUser(getContext().getContentResolver(),
1942 Secure.NOTIFICATION_BADGING, 1,
1943 USER2.getIdentifier());
1944 mHelper.updateBadgingEnabled(); // would be called by settings observer
1945 assertFalse(mHelper.badgingEnabled(USER));
1946 assertTrue(mHelper.badgingEnabled(USER2));
1947 }
1948
1949 @Test
Julia Reynolds4509ce72019-01-31 13:12:43 -05001950 public void testBubblesOverrideTrue() {
1951 Secure.putIntForUser(getContext().getContentResolver(),
1952 Secure.NOTIFICATION_BUBBLES, 1,
1953 USER.getIdentifier());
1954 mHelper.updateBubblesEnabled(); // would be called by settings observer
1955 assertTrue(mHelper.bubblesEnabled(USER));
1956 }
1957
1958 @Test
1959 public void testBubblesOverrideFalse() {
1960 Secure.putIntForUser(getContext().getContentResolver(),
1961 Secure.NOTIFICATION_BUBBLES, 0,
1962 USER.getIdentifier());
1963 mHelper.updateBubblesEnabled(); // would be called by settings observer
1964 assertFalse(mHelper.bubblesEnabled(USER));
1965 }
1966
1967 @Test
1968 public void testBubblesForUserAll() {
1969 try {
1970 mHelper.bubblesEnabled(UserHandle.ALL);
1971 } catch (Exception e) {
1972 fail("just don't throw");
1973 }
1974 }
1975
1976 @Test
1977 public void testBubblesOverrideUserIsolation() {
1978 Secure.putIntForUser(getContext().getContentResolver(),
1979 Secure.NOTIFICATION_BUBBLES, 0,
1980 USER.getIdentifier());
1981 Secure.putIntForUser(getContext().getContentResolver(),
1982 Secure.NOTIFICATION_BUBBLES, 1,
1983 USER2.getIdentifier());
1984 mHelper.updateBubblesEnabled(); // would be called by settings observer
1985 assertFalse(mHelper.bubblesEnabled(USER));
1986 assertTrue(mHelper.bubblesEnabled(USER2));
1987 }
1988
1989 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001990 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
1991 String newLabel = "bananas!";
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001992 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
1993 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001994 NotificationChannel.DEFAULT_CHANNEL_ID, false);
1995 assertFalse(newLabel.equals(defaultChannel.getName()));
1996
1997 Resources res = mock(Resources.class);
1998 when(mContext.getResources()).thenReturn(res);
1999 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
2000 .thenReturn(newLabel);
2001
2002 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
2003
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002004 assertEquals(newLabel, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002005 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
2006 }
2007
2008 @Test
2009 public void testIsGroupBlocked_noGroup() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002010 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, null));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002011
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002012 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, "non existent group"));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002013 }
2014
2015 @Test
2016 public void testIsGroupBlocked_notBlocked() throws Exception {
2017 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002018 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002019
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002020 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002021 }
2022
2023 @Test
2024 public void testIsGroupBlocked_blocked() throws Exception {
2025 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002026 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002027 group.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002028 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002029
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002030 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002031 }
2032
2033 @Test
2034 public void testIsGroup_appCannotResetBlock() throws Exception {
2035 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002036 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002037 NotificationChannelGroup group2 = group.clone();
2038 group2.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002039 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false);
2040 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002041
2042 NotificationChannelGroup group3 = group.clone();
2043 group3.setBlocked(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002044 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
2045 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002046 }
2047
2048 @Test
2049 public void testGetNotificationChannelGroupWithChannels() throws Exception {
2050 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
2051 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002052 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
2053 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002054
2055 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
2056 a.setGroup(group.getId());
2057 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
2058 b.setGroup(other.getId());
2059 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2060 c.setGroup(group.getId());
2061 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
2062
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002063 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false);
2064 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false);
2065 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false);
2066 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false);
2067 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002068
2069 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002070 PKG_N_MR1, UID_N_MR1, group.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002071 assertEquals(2, retrieved.getChannels().size());
2072 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2073 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
2074
2075 retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002076 PKG_N_MR1, UID_N_MR1, group.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002077 assertEquals(1, retrieved.getChannels().size());
2078 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2079 }
2080
2081 @Test
2082 public void testAndroidPkgCannotBypassDnd_creation() {
2083 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2084 test.setBypassDnd(true);
2085
2086 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2087
2088 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2089 .canBypassDnd());
2090 }
2091
2092 @Test
2093 public void testDndPkgCanBypassDnd_creation() {
2094 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2095 test.setBypassDnd(true);
2096
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002097 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002098
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002099 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002100 }
2101
2102 @Test
2103 public void testNormalPkgCannotBypassDnd_creation() {
2104 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2105 test.setBypassDnd(true);
2106
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002107 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002108
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002109 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002110 }
2111
2112 @Test
2113 public void testAndroidPkgCannotBypassDnd_update() throws Exception {
2114 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2115 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2116
2117 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2118 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002119 assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002120
2121 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2122 .canBypassDnd());
2123 }
2124
2125 @Test
2126 public void testDndPkgCanBypassDnd_update() throws Exception {
2127 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002128 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002129
2130 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2131 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002132 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002133
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002134 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002135 }
2136
2137 @Test
2138 public void testNormalPkgCannotBypassDnd_update() {
2139 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002140 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002141 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2142 update.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002143 mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false);
2144 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002145 }
2146
2147 @Test
2148 public void testGetBlockedAppCount_noApps() {
2149 assertEquals(0, mHelper.getBlockedAppCount(0));
2150 }
2151
2152 @Test
2153 public void testGetBlockedAppCount_noAppsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002154 mHelper.setEnabled(PKG_N_MR1, 100, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002155 assertEquals(0, mHelper.getBlockedAppCount(9));
2156 }
2157
2158 @Test
2159 public void testGetBlockedAppCount_appsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002160 mHelper.setEnabled(PKG_N_MR1, 1020, false);
2161 mHelper.setEnabled(PKG_N_MR1, 1030, false);
2162 mHelper.setEnabled(PKG_N_MR1, 1060, false);
2163 mHelper.setEnabled(PKG_N_MR1, 1000, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002164 assertEquals(3, mHelper.getBlockedAppCount(0));
2165 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002166
2167 @Test
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002168 public void testXml_statusBarIcons_default() throws Exception {
Julia Reynolds2594b472019-04-03 13:30:16 -04002169 String preQXml = "<ranking version=\"1\">\n"
2170 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
2171 + "<channel id=\"something\" name=\"name\" importance=\"2\" "
2172 + "show_badge=\"true\" />\n"
2173 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
2174 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
2175 + "</package>\n"
2176 + "</ranking>\n";
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002177 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Julia Reynolds2594b472019-04-03 13:30:16 -04002178 loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002179
2180 assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2181 mHelper.shouldHideSilentStatusIcons());
2182 }
2183
2184 @Test
2185 public void testXml_statusBarIcons() throws Exception {
2186 mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
2187
Annie Meng8b646fd2019-02-01 18:46:42 +00002188 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002189 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002190 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002191
2192 assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2193 mHelper.shouldHideSilentStatusIcons());
2194 }
2195
2196 @Test
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002197 public void testSetNotificationDelegate() {
2198 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2199 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2200 }
2201
2202 @Test
2203 public void testRevokeNotificationDelegate() {
2204 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2205 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2206
2207 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2208 }
2209
2210 @Test
2211 public void testRevokeNotificationDelegate_noDelegateExistsNoCrash() {
2212 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2213
2214 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2215 }
2216
2217 @Test
2218 public void testToggleNotificationDelegate() {
2219 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2220 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2221
2222 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2223
2224 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2225 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2226 }
2227
2228 @Test
2229 public void testToggleNotificationDelegate_noDelegateExistsNoCrash() {
2230 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2231 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2232
2233 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2234 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2235 }
2236
2237 @Test
2238 public void testIsDelegateAllowed_noSource() {
2239 assertFalse(mHelper.isDelegateAllowed("does not exist", -1, "whatever", 0));
2240 }
2241
2242 @Test
2243 public void testIsDelegateAllowed_noDelegate() {
2244 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2245
2246 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "whatever", 0));
2247 }
2248
2249 @Test
2250 public void testIsDelegateAllowed_delegateDisabledByApp() {
2251 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2252 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2253
2254 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2255 }
2256
2257 @Test
2258 public void testIsDelegateAllowed_wrongDelegate() {
2259 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2260 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2261
2262 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "banana", 27));
2263 }
2264
2265 @Test
2266 public void testIsDelegateAllowed_delegateDisabledByUser() {
2267 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2268 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2269
2270 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2271 }
2272
2273 @Test
2274 public void testIsDelegateAllowed() {
2275 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2276
2277 assertTrue(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2278 }
2279
2280 @Test
2281 public void testDelegateXml_noDelegate() throws Exception {
2282 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2283
Annie Meng8b646fd2019-02-01 18:46:42 +00002284 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002285 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002286 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002287
2288 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2289 }
2290
2291 @Test
2292 public void testDelegateXml_delegate() throws Exception {
2293 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2294
Annie Meng8b646fd2019-02-01 18:46:42 +00002295 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002296 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002297 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002298
2299 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2300 }
2301
2302 @Test
2303 public void testDelegateXml_disabledDelegate() throws Exception {
2304 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2305 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2306
Annie Meng8b646fd2019-02-01 18:46:42 +00002307 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002308 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002309 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002310
2311 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2312 }
2313
2314 @Test
2315 public void testDelegateXml_userDisabledDelegate() throws Exception {
2316 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2317 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2318
Annie Meng8b646fd2019-02-01 18:46:42 +00002319 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002320 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002321 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002322
2323 // appears disabled
2324 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2325
2326 // but was loaded and can be toggled back on
2327 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2328 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2329 }
2330
2331 @Test
2332 public void testDelegateXml_entirelyDisabledDelegate() throws Exception {
2333 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2334 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2335 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2336
Annie Meng8b646fd2019-02-01 18:46:42 +00002337 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002338 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002339 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002340
2341 // appears disabled
2342 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2343
2344 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2345 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2346
2347 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2348 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2349 }
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002350
2351 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002352 public void testAllowBubbles_defaults() throws Exception {
Mady Mellor9db685a2019-01-23 13:23:37 -08002353 assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002354
Annie Meng8b646fd2019-02-01 18:46:42 +00002355 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002356 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002357 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002358
Mady Mellor9db685a2019-01-23 13:23:37 -08002359 assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002360 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2361 }
2362
2363 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002364 public void testAllowBubbles_xml() throws Exception {
2365 mHelper.setBubblesAllowed(PKG_O, UID_O, false);
Mady Mellor9db685a2019-01-23 13:23:37 -08002366 assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002367 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002368 mHelper.getAppLockedFields(PKG_O, UID_O));
2369
Annie Meng8b646fd2019-02-01 18:46:42 +00002370 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002371 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
Annie Meng8b646fd2019-02-01 18:46:42 +00002372 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002373
Mady Mellor9db685a2019-01-23 13:23:37 -08002374 assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002375 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002376 mHelper.getAppLockedFields(PKG_O, UID_O));
2377 }
Julia Reynolds413ba842019-01-11 10:38:08 -05002378
2379 @Test
2380 public void testLockChannelsForOEM_emptyList() {
2381 mHelper.lockChannelsForOEM(null);
2382 mHelper.lockChannelsForOEM(new String[0]);
2383 // no exception
2384 }
2385
2386 @Test
2387 public void testLockChannelsForOEM_appWide() {
2388 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2389 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2390 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2391 // different uids, same package
2392 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2393 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2394 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2395
2396 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2397
2398 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2399 .isImportanceLockedByOEM());
2400 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2401 .isImportanceLockedByOEM());
2402 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2403 .isImportanceLockedByOEM());
2404 }
2405
2406 @Test
2407 public void testLockChannelsForOEM_onlyGivenPkg() {
2408 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2409 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2410 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2411 mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
2412
2413 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2414
2415 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2416 .isImportanceLockedByOEM());
2417 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
2418 .isImportanceLockedByOEM());
2419 }
2420
2421 @Test
2422 public void testLockChannelsForOEM_channelSpecific() {
2423 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2424 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2425 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2426 // different uids, same package
2427 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2428 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2429 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2430
2431 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
2432
2433 assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2434 .isImportanceLockedByOEM());
2435 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2436 .isImportanceLockedByOEM());
2437 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2438 .isImportanceLockedByOEM());
2439 }
2440
2441 @Test
2442 public void testLockChannelsForOEM_channelDoesNotExistYet_appWide() {
2443 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2444 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2445 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2446
2447 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2448
2449 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2450 .isImportanceLockedByOEM());
2451
2452 mHelper.createNotificationChannel(PKG_O, 3, b, true, false);
2453 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2454 .isImportanceLockedByOEM());
2455 }
2456
2457 @Test
2458 public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific() {
2459 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2460 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2461 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2462
2463 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"});
2464
2465 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2466 .isImportanceLockedByOEM());
2467
2468 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2469 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2470 .isImportanceLockedByOEM());
2471 }
2472
2473 @Test
2474 public void testUpdateNotificationChannel_oemLockedImportance() {
2475 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2476 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2477
2478 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2479
2480 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002481 update.setAllowBubbles(false);
Julia Reynolds413ba842019-01-11 10:38:08 -05002482
2483 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2484
2485 assertEquals(IMPORTANCE_HIGH,
2486 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2487 assertEquals(false,
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002488 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
Julia Reynolds413ba842019-01-11 10:38:08 -05002489
2490 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2491
2492 assertEquals(IMPORTANCE_HIGH,
2493 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2494 }
Julia Reynolds0c245002019-03-27 16:10:11 -04002495
2496 @Test
2497 public void testUpdateDefaultApps_add_multiUser() {
2498 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2499 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2500 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2501 // different uids, same package
2502 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2503 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2504 mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
2505
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002506 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2507 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002508 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2509
2510 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2511 .isImportanceLockedByCriticalDeviceFunction());
2512 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2513 .isImportanceLockedByCriticalDeviceFunction());
2514 assertFalse(mHelper.getNotificationChannel(
2515 PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false)
2516 .isImportanceLockedByCriticalDeviceFunction());
2517 }
2518
2519 @Test
2520 public void testUpdateDefaultApps_add_onlyGivenPkg() {
2521 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2522 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2523 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2524 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2525
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002526 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2527 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002528 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2529
Julia Reynolds0c245002019-03-27 16:10:11 -04002530 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2531 .isImportanceLockedByCriticalDeviceFunction());
2532 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2533 .isImportanceLockedByCriticalDeviceFunction());
2534 }
2535
2536 @Test
2537 public void testUpdateDefaultApps_remove() {
2538 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2539 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2540 // different uids, same package
2541 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2542 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2543
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002544 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2545 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002546 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2547
2548 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2549 .isImportanceLockedByCriticalDeviceFunction());
2550 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2551 .isImportanceLockedByCriticalDeviceFunction());
2552
2553 ArraySet<String> toRemove = new ArraySet<>();
2554 toRemove.add(PKG_O);
2555 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, null);
2556
2557 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2558 .isImportanceLockedByCriticalDeviceFunction());
2559 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2560 .isImportanceLockedByCriticalDeviceFunction());
2561 }
2562
2563 @Test
2564 public void testUpdateDefaultApps_addAndRemove() {
2565 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2566 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2567 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2568 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2569
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002570 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2571 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002572 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2573
2574
2575 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2576 .isImportanceLockedByCriticalDeviceFunction());
2577 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2578 .isImportanceLockedByCriticalDeviceFunction());
2579
2580 // now the default is PKG_N_MR1
2581 ArraySet<String> toRemove = new ArraySet<>();
2582 toRemove.add(PKG_O);
2583 toAdd = new ArraySet<>();
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002584 toAdd.add(new Pair(PKG_N_MR1, UID_N_MR1));
Julia Reynolds0c245002019-03-27 16:10:11 -04002585 mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd);
2586
2587 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2588 .isImportanceLockedByCriticalDeviceFunction());
2589 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2590 .isImportanceLockedByCriticalDeviceFunction());
2591 }
2592
2593 @Test
2594 public void testUpdateDefaultApps_appDoesNotExist_noCrash() {
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002595 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2596 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002597 ArraySet<String> toRemove = new ArraySet<>();
2598 toRemove.add(PKG_N_MR1);
2599 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd);
2600 }
2601
2602 @Test
2603 public void testUpdateDefaultApps_channelDoesNotExistYet() {
2604 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2605 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2606 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2607
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002608 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2609 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002610 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2611
2612 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2613 .isImportanceLockedByCriticalDeviceFunction());
2614
2615 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2616 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2617 .isImportanceLockedByCriticalDeviceFunction());
2618 }
2619
2620 @Test
2621 public void testUpdateNotificationChannel_defaultAppLockedImportance() {
2622 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2623 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002624 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2625 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002626 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2627
2628 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
2629 update.setAllowBubbles(false);
2630
2631 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
Julia Reynolds0c245002019-03-27 16:10:11 -04002632 assertEquals(IMPORTANCE_HIGH,
2633 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2634 assertEquals(false,
2635 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
2636
2637 mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
Julia Reynolds0c245002019-03-27 16:10:11 -04002638 assertEquals(IMPORTANCE_HIGH,
2639 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Beverly47679222019-05-16 15:46:11 -04002640
2641 NotificationChannel updateImportanceLow = new NotificationChannel("a", "a",
2642 IMPORTANCE_LOW);
2643 mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true);
2644 assertEquals(IMPORTANCE_LOW,
2645 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Julia Reynolds0c245002019-03-27 16:10:11 -04002646 }
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002647
2648 @Test
2649 public void testDefaultApp_appHasNoSettingsYet() {
2650 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2651 toAdd.add(new Pair(PKG_O, UID_O));
2652 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2653
2654 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2655 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2656
2657 assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
2658 }
2659
2660 @Test
2661 public void testChannelXml_backupDefaultApp() throws Exception {
2662 NotificationChannel channel1 =
2663 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
2664
2665 mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
2666
2667 // clear data
2668 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
2669 UserHandle.USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
2670 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_O}, new int[]{
2671 UID_O});
2672
2673 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2674 toAdd.add(new Pair(PKG_O, UID_O));
2675 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2676
2677 XmlPullParser parser = Xml.newPullParser();
2678 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
2679 null);
2680 parser.nextTag();
2681 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
2682
2683 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, channel1.getId(), false)
2684 .isImportanceLockedByCriticalDeviceFunction());
2685 }
Mady Mellor9f296142019-05-24 09:42:52 -07002686
2687 @Test
2688 public void testSetBubblesAllowed_false() {
2689 mHelper.setBubblesAllowed(PKG_O, UID_O, false);
2690 assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
2691 verify(mHandler, times(1)).requestSort();
2692 }
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002693}