blob: 427237c4be0fd275a9dd703090ebe65ca593db3e [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
Julia Reynolds0f767342019-12-18 09:11:55 -050018import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
Mady Mellora92268c2020-03-09 17:25:08 -070019import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
20import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
21import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040022import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
23import static android.app.NotificationManager.IMPORTANCE_HIGH;
24import static android.app.NotificationManager.IMPORTANCE_LOW;
25import static android.app.NotificationManager.IMPORTANCE_MAX;
26import static android.app.NotificationManager.IMPORTANCE_NONE;
27import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
28
Mady Mellora92268c2020-03-09 17:25:08 -070029import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE;
Julia Reynoldsc29370a2019-08-20 16:08:42 -040030import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
31
Julia Reynolds882f2062020-02-05 12:11:38 -050032import static com.google.common.truth.Truth.assertThat;
33
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040034import static junit.framework.Assert.assertNull;
35import static junit.framework.Assert.fail;
36
37import static org.junit.Assert.assertEquals;
38import static org.junit.Assert.assertFalse;
39import static org.junit.Assert.assertNotNull;
40import static org.junit.Assert.assertTrue;
41import static org.mockito.ArgumentMatchers.any;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -080042import static org.mockito.ArgumentMatchers.anyInt;
43import static org.mockito.ArgumentMatchers.anyString;
44import static org.mockito.ArgumentMatchers.eq;
45import static org.mockito.Mockito.doReturn;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040046import static org.mockito.Mockito.mock;
47import static org.mockito.Mockito.never;
48import static org.mockito.Mockito.reset;
49import static org.mockito.Mockito.times;
50import static org.mockito.Mockito.verify;
51import static org.mockito.Mockito.when;
52
53import android.app.Notification;
54import android.app.NotificationChannel;
55import android.app.NotificationChannelGroup;
56import android.app.NotificationManager;
57import android.content.ContentProvider;
58import android.content.Context;
59import android.content.IContentProvider;
60import android.content.pm.ApplicationInfo;
61import android.content.pm.PackageInfo;
62import android.content.pm.PackageManager;
63import android.content.pm.Signature;
64import android.content.res.Resources;
65import android.graphics.Color;
66import android.media.AudioAttributes;
67import android.net.Uri;
68import android.os.Build;
69import android.os.UserHandle;
70import android.provider.Settings;
Lyn Han4463f842019-07-09 15:27:28 -070071import android.provider.Settings.Global;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040072import android.provider.Settings.Secure;
Julia Reynolds882f2062020-02-05 12:11:38 -050073import android.service.notification.ConversationChannelWrapper;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -080074import android.test.mock.MockIContentProvider;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040075import android.test.suitebuilder.annotation.SmallTest;
76import android.testing.TestableContentResolver;
77import android.util.ArrayMap;
Julia Reynolds0c245002019-03-27 16:10:11 -040078import android.util.ArraySet;
Julia Reynoldse7ca31b2019-04-25 15:41:47 -040079import android.util.Pair;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040080import android.util.Xml;
81
Beverly47679222019-05-16 15:46:11 -040082import androidx.test.InstrumentationRegistry;
83import androidx.test.runner.AndroidJUnit4;
84
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040085import com.android.internal.util.FastXmlSerializer;
86import com.android.server.UiServiceTestCase;
87
88import org.json.JSONArray;
89import org.json.JSONObject;
90import org.junit.Before;
91import org.junit.Test;
92import org.junit.runner.RunWith;
93import org.mockito.Mock;
94import org.mockito.MockitoAnnotations;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -080095import org.mockito.Spy;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040096import org.xmlpull.v1.XmlPullParser;
97import org.xmlpull.v1.XmlSerializer;
98
99import java.io.BufferedInputStream;
100import java.io.BufferedOutputStream;
101import java.io.ByteArrayInputStream;
102import java.io.ByteArrayOutputStream;
Julia Reynolds882f2062020-02-05 12:11:38 -0500103import java.util.ArrayList;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400104import java.util.Arrays;
105import java.util.HashMap;
106import java.util.List;
107import java.util.Map;
108import java.util.Objects;
109import java.util.concurrent.ThreadLocalRandom;
110
111@SmallTest
112@RunWith(AndroidJUnit4.class)
113public class PreferencesHelperTest extends UiServiceTestCase {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400114 private static final int UID_N_MR1 = 0;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400115 private static final UserHandle USER = UserHandle.of(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400116 private static final int UID_O = 1111;
Julia Reynolds02971452020-02-14 16:44:19 -0500117 private static final int UID_P = 2222;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400118 private static final String SYSTEM_PKG = "android";
Beverly0479cde22018-11-09 11:05:34 -0500119 private static final int SYSTEM_UID = 1000;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400120 private static final UserHandle USER2 = UserHandle.of(10);
121 private static final String TEST_CHANNEL_ID = "test_channel_id";
122 private static final String TEST_AUTHORITY = "test";
123 private static final Uri SOUND_URI =
124 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
125 private static final Uri CANONICAL_SOUND_URI =
126 Uri.parse("content://" + TEST_AUTHORITY
127 + "/internal/audio/media/10?title=Test&canonical=1");
128
129 @Mock NotificationUsageStats mUsageStats;
130 @Mock RankingHandler mHandler;
131 @Mock PackageManager mPm;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800132 @Spy IContentProvider mTestIContentProvider = new MockIContentProvider();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400133 @Mock Context mContext;
134 @Mock ZenModeHelper mMockZenModeHelper;
135
136 private NotificationManager.Policy mTestNotificationPolicy;
137
138 private PreferencesHelper mHelper;
139 private AudioAttributes mAudioAttributes;
Will Brockman23db6d42020-02-28 09:51:12 -0500140 private NotificationChannelLoggerFake mLogger = new NotificationChannelLoggerFake();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400141
142 @Before
143 public void setUp() throws Exception {
144 MockitoAnnotations.initMocks(this);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400145
146 final ApplicationInfo legacy = new ApplicationInfo();
147 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
148 final ApplicationInfo upgrade = new ApplicationInfo();
149 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400150 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
151 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(upgrade);
Julia Reynolds02971452020-02-14 16:44:19 -0500152 when(mPm.getApplicationInfoAsUser(eq(PKG_P), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400153 when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400154 when(mPm.getPackageUidAsUser(eq(PKG_N_MR1), anyInt())).thenReturn(UID_N_MR1);
155 when(mPm.getPackageUidAsUser(eq(PKG_O), anyInt())).thenReturn(UID_O);
Julia Reynolds02971452020-02-14 16:44:19 -0500156 when(mPm.getPackageUidAsUser(eq(PKG_P), anyInt())).thenReturn(UID_P);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400157 when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
158 PackageInfo info = mock(PackageInfo.class);
159 info.signatures = new Signature[] {mock(Signature.class)};
160 when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400161 when(mPm.getPackageInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt()))
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400162 .thenReturn(mock(PackageInfo.class));
163 when(mContext.getResources()).thenReturn(
164 InstrumentationRegistry.getContext().getResources());
165 when(mContext.getContentResolver()).thenReturn(
166 InstrumentationRegistry.getContext().getContentResolver());
167 when(mContext.getPackageManager()).thenReturn(mPm);
168 when(mContext.getApplicationInfo()).thenReturn(legacy);
169 // most tests assume badging is enabled
170 TestableContentResolver contentResolver = getContext().getContentResolver();
171 contentResolver.setFallbackToExisting(false);
172 Secure.putIntForUser(contentResolver,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400173 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID_N_MR1));
Lyn Han4463f842019-07-09 15:27:28 -0700174 Global.putInt(contentResolver, Global.NOTIFICATION_BUBBLES, 1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400175
176 ContentProvider testContentProvider = mock(ContentProvider.class);
177 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
178 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
179
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800180 doReturn(CANONICAL_SOUND_URI)
181 .when(mTestIContentProvider).canonicalize(any(), any(), eq(SOUND_URI));
182 doReturn(CANONICAL_SOUND_URI)
183 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
184 doReturn(SOUND_URI)
185 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400186
187 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
Julia Reynolds24edc002020-01-29 16:35:32 -0500188 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400189 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Will Brockman23db6d42020-02-28 09:51:12 -0500190 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400191 resetZenModeHelper();
192
193 mAudioAttributes = new AudioAttributes.Builder()
194 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
195 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
196 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
197 .build();
198 }
199
Annie Meng8b646fd2019-02-01 18:46:42 +0000200 private ByteArrayOutputStream writeXmlAndPurge(
201 String pkg, int uid, boolean forBackup, int userId, String... channelIds)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400202 throws Exception {
203 XmlSerializer serializer = new FastXmlSerializer();
204 ByteArrayOutputStream baos = new ByteArrayOutputStream();
205 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
206 serializer.startDocument(null, true);
Annie Meng8b646fd2019-02-01 18:46:42 +0000207 mHelper.writeXml(serializer, forBackup, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400208 serializer.endDocument();
209 serializer.flush();
210 for (String channelId : channelIds) {
211 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
212 }
213 return baos;
214 }
215
Annie Meng8b646fd2019-02-01 18:46:42 +0000216 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore, int userId)
217 throws Exception {
218 loadByteArrayXml(stream.toByteArray(), forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400219 }
220
Annie Meng8b646fd2019-02-01 18:46:42 +0000221 private void loadByteArrayXml(byte[] byteArray, boolean forRestore, int userId)
222 throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400223 XmlPullParser parser = Xml.newPullParser();
224 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
225 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000226 mHelper.readXml(parser, forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400227 }
228
229 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
230 assertEquals(expected.getId(), actual.getId());
231 assertEquals(expected.getName(), actual.getName());
232 assertEquals(expected.getDescription(), actual.getDescription());
233 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
234 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
235 assertEquals(expected.getImportance(), actual.getImportance());
236 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
237 assertEquals(expected.getSound(), actual.getSound());
238 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
239 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
240 assertEquals(expected.getGroup(), actual.getGroup());
241 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
242 assertEquals(expected.getLightColor(), actual.getLightColor());
Julia Reynolds0f767342019-12-18 09:11:55 -0500243 assertEquals(expected.getParentChannelId(), actual.getParentChannelId());
244 assertEquals(expected.getConversationId(), actual.getConversationId());
Julia Reynoldsdcd70d62020-01-15 10:33:43 -0500245 assertEquals(expected.isDemoted(), actual.isDemoted());
Julia Reynolds0f767342019-12-18 09:11:55 -0500246 }
247
248 private void compareChannelsParentChild(NotificationChannel parent,
249 NotificationChannel actual, String conversationId) {
250 assertEquals(parent.getName(), actual.getName());
251 assertEquals(parent.getDescription(), actual.getDescription());
252 assertEquals(parent.shouldVibrate(), actual.shouldVibrate());
253 assertEquals(parent.shouldShowLights(), actual.shouldShowLights());
254 assertEquals(parent.getImportance(), actual.getImportance());
255 assertEquals(parent.getLockscreenVisibility(), actual.getLockscreenVisibility());
256 assertEquals(parent.getSound(), actual.getSound());
257 assertEquals(parent.canBypassDnd(), actual.canBypassDnd());
258 assertTrue(Arrays.equals(parent.getVibrationPattern(), actual.getVibrationPattern()));
259 assertEquals(parent.getGroup(), actual.getGroup());
260 assertEquals(parent.getAudioAttributes(), actual.getAudioAttributes());
261 assertEquals(parent.getLightColor(), actual.getLightColor());
262 assertEquals(parent.getId(), actual.getParentChannelId());
263 assertEquals(conversationId, actual.getConversationId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400264 }
265
266 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
267 assertEquals(expected.getId(), actual.getId());
268 assertEquals(expected.getName(), actual.getName());
269 assertEquals(expected.getDescription(), actual.getDescription());
270 assertEquals(expected.isBlocked(), actual.isBlocked());
271 }
272
273 private NotificationChannel getChannel() {
274 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
275 }
276
277 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
278 for (NotificationChannel channel : channels) {
279 if (channel.getId().equals(id)) {
280 return channel;
281 }
282 }
283 return null;
284 }
285
286 private void resetZenModeHelper() {
287 reset(mMockZenModeHelper);
288 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
289 }
290
Annie Meng8b646fd2019-02-01 18:46:42 +0000291 private void setUpPackageWithUid(String packageName, int uid) throws Exception {
292 when(mPm.getApplicationInfoAsUser(eq(packageName), anyInt(), anyInt()))
293 .thenReturn(new ApplicationInfo());
294 when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
295 }
296
297 @Test
298 public void testWriteXml_onlyBackupsTargetUser() throws Exception {
299 // Setup package notifications.
300 String package0 = "test.package.user0";
301 int uid0 = 1001;
302 setUpPackageWithUid(package0, uid0);
303 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400304 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000305
306 String package10 = "test.package.user10";
307 int uid10 = 1001001;
308 setUpPackageWithUid(package10, uid10);
309 NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400310 assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000311
312 ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
313
314 // Reset state.
315 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
316 mHelper.onPackagesChanged(true, 10, new String[] {package10}, new int[] {uid10});
317
318 // Parse backup data.
319 loadStreamXml(baos, true, 0);
320 loadStreamXml(baos, true, 10);
321
322 assertEquals(
323 channel10,
324 mHelper.getNotificationChannel(package10, uid10, channel10.getId(), false));
325 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
326 }
327
328 @Test
329 public void testReadXml_onlyRestoresTargetUser() throws Exception {
330 // Setup package in user 0.
331 String package0 = "test.package.user0";
332 int uid0 = 1001;
333 setUpPackageWithUid(package0, uid0);
334 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400335 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000336
337 ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
338
339 // Reset state.
340 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
341
342 // Restore should convert the uid according to the target user.
343 int expectedUid = 1001001;
344 setUpPackageWithUid(package0, expectedUid);
345 // Parse backup data.
346 loadStreamXml(baos, true, 10);
347
348 assertEquals(
349 channel0,
350 mHelper.getNotificationChannel(package0, expectedUid, channel0.getId(), false));
351 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
352 }
353
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400354 @Test
355 public void testChannelXml() throws Exception {
356 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
357 ncg.setBlocked(true);
358 ncg.setDescription("group desc");
359 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
360 NotificationChannel channel1 =
361 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
362 NotificationChannel channel2 =
363 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
364 channel2.setDescription("descriptions for all");
365 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
366 channel2.enableLights(true);
367 channel2.setBypassDnd(true);
368 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
369 channel2.enableVibration(true);
370 channel2.setGroup(ncg.getId());
371 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
372 channel2.setLightColor(Color.BLUE);
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500373 channel2.setConversationId("id1", "conversation");
Julia Reynoldsdcd70d62020-01-15 10:33:43 -0500374 channel2.setDemoted(true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400375
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400376 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
377 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400378 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
379 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400380
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400381 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
382 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400383
Annie Meng8b646fd2019-02-01 18:46:42 +0000384 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
385 UserHandle.USER_ALL, channel1.getId(), channel2.getId(),
386 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400387 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
388 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400389
Annie Meng8b646fd2019-02-01 18:46:42 +0000390 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400391
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400392 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
393 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400394 assertEquals(channel1,
395 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400396 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400397 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400398
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400399 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
400 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400401 boolean foundNcg = false;
402 for (NotificationChannelGroup actual : actualGroups) {
403 if (ncg.getId().equals(actual.getId())) {
404 foundNcg = true;
405 compareGroups(ncg, actual);
406 } else if (ncg2.getId().equals(actual.getId())) {
407 compareGroups(ncg2, actual);
408 }
409 }
410 assertTrue(foundNcg);
411
412 boolean foundChannel2Group = false;
413 for (NotificationChannelGroup actual : actualGroups) {
414 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
415 foundChannel2Group = true;
416 break;
417 }
418 }
419 assertTrue(foundChannel2Group);
420 }
421
422 @Test
423 public void testChannelXmlForBackup() throws Exception {
424 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
425 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
426 NotificationChannel channel1 =
427 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
428 NotificationChannel channel2 =
429 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
430 channel2.setDescription("descriptions for all");
431 channel2.setSound(SOUND_URI, mAudioAttributes);
432 channel2.enableLights(true);
433 channel2.setBypassDnd(true);
434 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
435 channel2.enableVibration(false);
436 channel2.setGroup(ncg.getId());
437 channel2.setLightColor(Color.BLUE);
438 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
439 channel3.enableVibration(true);
440
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400441 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
442 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
443 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
444 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
445 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
446 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400447
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400448 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400449
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400450 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400451
Annie Meng8b646fd2019-02-01 18:46:42 +0000452 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
453 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
454 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400455 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1, PKG_O},
456 new int[]{UID_N_MR1, UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400457
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400458 mHelper.setShowBadge(PKG_O, UID_O, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400459
Annie Meng8b646fd2019-02-01 18:46:42 +0000460 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400461
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400462 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O));
463 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400464 assertEquals(channel1,
465 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400466 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400467 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400468 compareChannels(channel3,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400469 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400470
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400471 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
472 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400473 boolean foundNcg = false;
474 for (NotificationChannelGroup actual : actualGroups) {
475 if (ncg.getId().equals(actual.getId())) {
476 foundNcg = true;
477 compareGroups(ncg, actual);
478 } else if (ncg2.getId().equals(actual.getId())) {
479 compareGroups(ncg2, actual);
480 }
481 }
482 assertTrue(foundNcg);
483
484 boolean foundChannel2Group = false;
485 for (NotificationChannelGroup actual : actualGroups) {
486 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
487 foundChannel2Group = true;
488 break;
489 }
490 }
491 assertTrue(foundChannel2Group);
492 }
493
494 @Test
495 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
496 NotificationChannel channel =
497 new NotificationChannel("id", "name", IMPORTANCE_LOW);
498 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400499 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400500
Annie Meng8b646fd2019-02-01 18:46:42 +0000501 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
502 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400503
504 // Testing that in restore we are given the canonical version
Annie Meng8b646fd2019-02-01 18:46:42 +0000505 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Philip P. Moltmann128b7032019-09-27 08:44:12 -0700506 verify(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400507 }
508
509 @Test
510 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
511 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
512 Uri canonicalBasedOnLocal = localUri.buildUpon()
513 .appendQueryParameter("title", "Test")
514 .appendQueryParameter("canonical", "1")
515 .build();
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800516 doReturn(canonicalBasedOnLocal)
517 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
518 doReturn(localUri)
519 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
520 doReturn(localUri)
521 .when(mTestIContentProvider).uncanonicalize(any(), any(),
522 eq(canonicalBasedOnLocal));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400523
524 NotificationChannel channel =
525 new NotificationChannel("id", "name", IMPORTANCE_LOW);
526 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400527 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000528 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
529 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400530
Annie Meng8b646fd2019-02-01 18:46:42 +0000531 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400532
533 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400534 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400535 assertEquals(localUri, actualChannel.getSound());
536 }
537
538 @Test
539 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
540 Thread.sleep(3000);
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800541 doReturn(null)
542 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
543 doReturn(null)
544 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400545
546 NotificationChannel channel =
547 new NotificationChannel("id", "name", IMPORTANCE_LOW);
548 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400549 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000550 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
551 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400552
Annie Meng8b646fd2019-02-01 18:46:42 +0000553 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400554
555 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400556 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400557 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
558 }
559
560
561 /**
562 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
563 * handle its restore properly.
564 */
565 @Test
566 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
567 // Not a local uncanonicalized uri, simulating that it fails to exist locally
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800568 doReturn(null)
569 .when(mTestIContentProvider).canonicalize(any(), any(), eq(SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400570 String id = "id";
571 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400572 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400573 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
574 + "sound=\"" + SOUND_URI + "\" "
575 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
576 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
577 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
578 + "</package>\n"
579 + "</ranking>\n";
580
Annie Meng8b646fd2019-02-01 18:46:42 +0000581 loadByteArrayXml(
582 backupWithUncanonicalizedSoundUri.getBytes(), true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400583
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400584 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, id, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400585 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
586 }
587
588 @Test
589 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
590 NotificationChannel channel =
591 new NotificationChannel("id", "name", IMPORTANCE_LOW);
592 channel.setSound(null, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400593 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000594 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
595 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400596
Annie Meng8b646fd2019-02-01 18:46:42 +0000597 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400598
599 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400600 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400601 assertEquals(null, actualChannel.getSound());
602 }
603
604 @Test
605 public void testChannelXml_backup() throws Exception {
606 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
607 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
608 NotificationChannel channel1 =
609 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
610 NotificationChannel channel2 =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400611 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400612 NotificationChannel channel3 =
613 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
614 channel3.setGroup(ncg.getId());
615
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400616 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
617 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
618 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
619 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
620 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400621
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400622 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId());
623 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId());
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400624 assertEquals(channel2,
625 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400626
Annie Meng8b646fd2019-02-01 18:46:42 +0000627 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
628 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
629 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400630 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
631 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400632
633 XmlPullParser parser = Xml.newPullParser();
634 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
635 null);
636 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000637 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400638
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400639 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
640 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
641 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400642 assertEquals(channel2,
643 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400644 }
645
646 @Test
647 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400648 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000649 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400650
Annie Meng8b646fd2019-02-01 18:46:42 +0000651 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400652
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400653 final NotificationChannel updated = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400654 NotificationChannel.DEFAULT_CHANNEL_ID, false);
655 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
656 assertFalse(updated.canBypassDnd());
657 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
658 assertEquals(0, updated.getUserLockedFields());
659 }
660
661 @Test
662 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400663 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
664 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400665 NotificationChannel.DEFAULT_CHANNEL_ID, false);
666 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400667 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400668
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400669 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000670 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400671
Annie Meng8b646fd2019-02-01 18:46:42 +0000672 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400673
674 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400675 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400676 }
677
678 @Test
679 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
680 final String preupgradeXml = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400681 + "<package name=\"" + PKG_N_MR1
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400682 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
683 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400684 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID_N_MR1 + "\" />\n"
685 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" visibility=\""
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400686 + Notification.VISIBILITY_PRIVATE + "\" />\n"
687 + "</ranking>";
688 XmlPullParser parser = Xml.newPullParser();
689 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
690 null);
691 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000692 mHelper.readXml(parser, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400693
694 final NotificationChannel updated1 =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400695 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400696 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
697 assertTrue(updated1.canBypassDnd());
698 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
699 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
700 | NotificationChannel.USER_LOCKED_PRIORITY
701 | NotificationChannel.USER_LOCKED_VISIBILITY,
702 updated1.getUserLockedFields());
703
704 // No Default Channel created for updated packages
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400705 assertEquals(null, mHelper.getNotificationChannel(PKG_O, UID_O,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400706 NotificationChannel.DEFAULT_CHANNEL_ID, false));
707 }
708
709 @Test
710 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
711 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400712 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400713 assertTrue(defaultChannel != null);
Annie Meng8b646fd2019-02-01 18:46:42 +0000714 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
715 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400716 // Load package at higher sdk.
717 final ApplicationInfo upgraded = new ApplicationInfo();
718 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400719 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000720 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400721
722 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400723 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400724 NotificationChannel.DEFAULT_CHANNEL_ID, false));
725 }
726
727 @Test
728 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400729 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400730 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400731 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000732 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400733
734 // Load package at higher sdk.
735 final ApplicationInfo upgraded = new ApplicationInfo();
736 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400737 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000738 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400739
740 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400741 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400742 NotificationChannel.DEFAULT_CHANNEL_ID, false));
743 }
744
745 @Test
746 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400747 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000748 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400749 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400750 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
751
Annie Meng8b646fd2019-02-01 18:46:42 +0000752 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400753
754 // Should still have the newly created channel that wasn't in the xml.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400755 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "bananas", false) != null);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400756 }
757
758 @Test
759 public void testCreateChannel_blocked() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400760 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400761
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400762 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
763 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400764 }
765
766 @Test
767 public void testCreateChannel_badImportance() throws Exception {
768 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400769 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400770 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
771 true, false);
772 fail("Was allowed to create a channel with invalid importance");
773 } catch (IllegalArgumentException e) {
774 // yay
775 }
776 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400777 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400778 new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
779 true, false);
780 fail("Was allowed to create a channel with invalid importance");
781 } catch (IllegalArgumentException e) {
782 // yay
783 }
784 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400785 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400786 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
787 true, false);
788 fail("Was allowed to create a channel with invalid importance");
789 } catch (IllegalArgumentException e) {
790 // yay
791 }
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400792 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
793 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
794 assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
795 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400796 }
797
798
799 @Test
800 public void testUpdate() throws Exception {
801 // no fields locked by user
802 final NotificationChannel channel =
803 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
804 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
805 channel.enableLights(true);
806 channel.setBypassDnd(true);
807 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
808
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400809 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400810
811 // same id, try to update all fields
812 final NotificationChannel channel2 =
813 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
814 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
815 channel2.enableLights(false);
816 channel2.setBypassDnd(false);
817 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
818
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400819 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400820
821 // all fields should be changed
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400822 assertEquals(channel2,
823 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400824
825 verify(mHandler, times(1)).requestSort();
826 }
827
828 @Test
829 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400830 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_UNSPECIFIED);
831 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
832 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400833 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400834 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
835 assertFalse(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400836
837 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400838 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400839
840 defaultChannel.setShowBadge(false);
841 defaultChannel.setImportance(IMPORTANCE_NONE);
842 defaultChannel.setBypassDnd(true);
843 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
844
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400845 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
846 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400847
848 // ensure app level fields are changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400849 assertFalse(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
850 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
851 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1,
852 UID_N_MR1));
853 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1));
854 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400855 }
856
857 @Test
858 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
859 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
860
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400861 mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
862 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
863 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400864 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400865 mHelper.getPackageVisibility(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400866
867 channel.setShowBadge(false);
868 channel.setImportance(IMPORTANCE_NONE);
869 channel.setBypassDnd(true);
870 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
871
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400872 mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400873
874 // ensure app level fields are not changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400875 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
876 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400877 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400878 mHelper.getPackageVisibility(PKG_O, UID_O));
879 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O,
880 UID_O));
881 assertFalse(mHelper.getIsAppImportanceLocked(PKG_O, UID_O));
882 }
883
884 @Test
885 public void testUpdate_preUpgrade_noUpdateAppFieldsWithMultipleChannels() throws Exception {
886 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
887
888 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
889 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
890 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
891 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
892 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
893
894 channel.setShowBadge(false);
895 channel.setImportance(IMPORTANCE_NONE);
896 channel.setBypassDnd(true);
897 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
898
899 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
900
901 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
902 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
903
904 defaultChannel.setShowBadge(false);
905 defaultChannel.setImportance(IMPORTANCE_NONE);
906 defaultChannel.setBypassDnd(true);
907 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
908
909 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
910
911 // ensure app level fields are not changed
912 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
913 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
914 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
915 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
916 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
917 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400918 }
919
920 @Test
921 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400922 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "garbage", false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400923 }
924
925 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400926 public void testCreateChannel_CannotChangeHiddenFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400927 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400928 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400929 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
930 channel.enableLights(true);
931 channel.setBypassDnd(true);
932 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
933 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800934 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400935 int lockMask = 0;
936 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
937 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
938 }
939 channel.lockFields(lockMask);
940
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400941 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400942
943 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400944 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400945
946 assertEquals(channel.getName(), savedChannel.getName());
947 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
948 assertFalse(savedChannel.canBypassDnd());
949 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
950 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800951 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400952
953 verify(mHandler, never()).requestSort();
954 }
955
956 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400957 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400958 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400959 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400960 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
961 channel.enableLights(true);
962 channel.setBypassDnd(true);
963 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
964 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800965 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400966 int lockMask = 0;
967 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
968 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
969 }
970 channel.lockFields(lockMask);
971
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400972 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400973
974 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400975 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400976
977 assertEquals(channel.getName(), savedChannel.getName());
978 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
979 assertFalse(savedChannel.canBypassDnd());
980 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
981 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800982 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400983 }
984
985 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400986 public void testClearLockedFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400987 final NotificationChannel channel = getChannel();
Julia Reynolds5c399c62019-04-08 14:42:53 -0400988 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400989 assertEquals(0, channel.getUserLockedFields());
990
991 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
992 | NotificationChannel.USER_LOCKED_IMPORTANCE);
Julia Reynolds5c399c62019-04-08 14:42:53 -0400993 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400994 assertEquals(0, channel.getUserLockedFields());
995 }
996
997 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400998 public void testLockFields_soundAndVibration() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400999 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001000
1001 final NotificationChannel update1 = getChannel();
1002 update1.setSound(new Uri.Builder().scheme("test").build(),
1003 new AudioAttributes.Builder().build());
1004 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001005 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001006 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1007 | NotificationChannel.USER_LOCKED_SOUND,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001008 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001009 .getUserLockedFields());
1010
1011 NotificationChannel update2 = getChannel();
1012 update2.enableVibration(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001013 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001014 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1015 | NotificationChannel.USER_LOCKED_SOUND
1016 | NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001017 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001018 .getUserLockedFields());
1019 }
1020
1021 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001022 public void testLockFields_vibrationAndLights() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001023 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001024
1025 final NotificationChannel update1 = getChannel();
1026 update1.setVibrationPattern(new long[]{7945, 46 ,246});
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_VIBRATION,
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.enableLights(true);
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_VIBRATION
1036 | NotificationChannel.USER_LOCKED_LIGHTS,
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
1041 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001042 public void testLockFields_lightsAndImportance() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001043 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001044
1045 final NotificationChannel update1 = getChannel();
1046 update1.setLightColor(Color.GREEN);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001047 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001048 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001049 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001050 .getUserLockedFields());
1051
1052 final NotificationChannel update2 = getChannel();
1053 update2.setImportance(IMPORTANCE_DEFAULT);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001054 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001055 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
1056 | NotificationChannel.USER_LOCKED_IMPORTANCE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001057 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001058 .getUserLockedFields());
1059 }
1060
1061 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001062 public void testLockFields_visibilityAndDndAndBadge() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001063 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001064 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001065 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001066 .getUserLockedFields());
1067
1068 final NotificationChannel update1 = getChannel();
1069 update1.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001070 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001071 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001072 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001073 .getUserLockedFields());
1074
1075 final NotificationChannel update2 = getChannel();
1076 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001077 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001078 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1079 | NotificationChannel.USER_LOCKED_VISIBILITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001080 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001081 .getUserLockedFields());
1082
1083 final NotificationChannel update3 = getChannel();
1084 update3.setShowBadge(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001085 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001086 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1087 | NotificationChannel.USER_LOCKED_VISIBILITY
1088 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001089 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update3.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001090 .getUserLockedFields());
1091 }
1092
1093 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001094 public void testLockFields_allowBubble() {
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001095 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1096 assertEquals(0,
1097 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
1098 .getUserLockedFields());
1099
1100 final NotificationChannel update = getChannel();
Mady Mellora92268c2020-03-09 17:25:08 -07001101 update.setAllowBubbles(true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001102 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001103 assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE,
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001104 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false)
1105 .getUserLockedFields());
1106 }
1107
1108 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001109 public void testDeleteNonExistentChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001110 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001111 }
1112
1113 @Test
Will Brockman23db6d42020-02-28 09:51:12 -05001114 public void testDoubleDeleteChannel() throws Exception {
1115 NotificationChannel channel = getChannel();
1116 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1117 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1118 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1119 assertEquals(2, mLogger.getCalls().size());
1120 assertEquals(
1121 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1122 mLogger.get(0).event);
1123 assertEquals(
1124 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_DELETED,
1125 mLogger.get(1).event);
1126 // No log for the second delete of the same channel.
1127 }
1128
1129 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001130 public void testGetDeletedChannel() throws Exception {
1131 NotificationChannel channel = getChannel();
1132 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1133 channel.enableLights(true);
1134 channel.setBypassDnd(true);
1135 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1136 channel.enableVibration(true);
1137 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1138
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001139 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1140 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001141
1142 // Does not return deleted channel
1143 NotificationChannel response =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001144 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001145 assertNull(response);
1146
1147 // Returns deleted channel
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001148 response = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001149 compareChannels(channel, response);
1150 assertTrue(response.isDeleted());
1151 }
1152
1153 @Test
1154 public void testGetDeletedChannels() throws Exception {
1155 Map<String, NotificationChannel> channelMap = new HashMap<>();
1156 NotificationChannel channel =
1157 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1158 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1159 channel.enableLights(true);
1160 channel.setBypassDnd(true);
1161 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1162 channel.enableVibration(true);
1163 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1164 channelMap.put(channel.getId(), channel);
1165 NotificationChannel channel2 =
1166 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1167 channelMap.put(channel2.getId(), channel2);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001168 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1169 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001170
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001171 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001172
1173 // Returns only non-deleted channels
1174 List<NotificationChannel> channels =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001175 mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001176 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1177 for (NotificationChannel nc : channels) {
1178 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1179 compareChannels(channel2, nc);
1180 }
1181 }
1182
1183 // Returns deleted channels too
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001184 channels = mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001185 assertEquals(3, channels.size()); // Includes default channel
1186 for (NotificationChannel nc : channels) {
1187 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1188 compareChannels(channelMap.get(nc.getId()), nc);
1189 }
1190 }
1191 }
1192
1193 @Test
1194 public void testGetDeletedChannelCount() throws Exception {
1195 NotificationChannel channel =
1196 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1197 NotificationChannel channel2 =
1198 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1199 NotificationChannel channel3 =
1200 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001201 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1202 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1203 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001204
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001205 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1206 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001207
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001208 assertEquals(2, mHelper.getDeletedChannelCount(PKG_N_MR1, UID_N_MR1));
1209 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001210 }
1211
1212 @Test
1213 public void testGetBlockedChannelCount() throws Exception {
1214 NotificationChannel channel =
1215 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1216 NotificationChannel channel2 =
1217 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
1218 NotificationChannel channel3 =
1219 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001220 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1221 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1222 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001223
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001224 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001225
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001226 assertEquals(1, mHelper.getBlockedChannelCount(PKG_N_MR1, UID_N_MR1));
1227 assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001228 }
1229
1230 @Test
Beverly4f7b53d2018-11-20 09:56:31 -05001231 public void testUpdateChannelsBypassingDnd_onUserSwitch_onUserUnlocked() throws Exception {
1232 int user = USER.getIdentifier();
1233 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1234 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1235 NotificationManager.IMPORTANCE_MAX);
1236 channel1.setBypassDnd(true);
1237 channel1.setGroup(ncg.getId());
1238
1239 // channel is associated with a group, then group is deleted
1240 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1241 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1242 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, user, ncg.getId());
1243
1244 mHelper.onUserSwitched(user);
1245 mHelper.onUserUnlocked(user);
1246 }
1247
1248 @Test
Beverly0479cde22018-11-09 11:05:34 -05001249 public void testGetChannelsBypassingDndCount_noChannelsBypassing() throws Exception {
1250 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1251 USER.getIdentifier()).getList().size());
1252 }
1253
1254 @Test
1255 public void testGetChannelsBypassingDnd_noChannelsForUserIdBypassing()
1256 throws Exception {
1257 int user = 9;
1258 NotificationChannel channel = new NotificationChannel("id", "name",
1259 NotificationManager.IMPORTANCE_MAX);
1260 channel.setBypassDnd(true);
1261 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1262
1263 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1264 user).getList().size());
1265 }
1266
1267 @Test
1268 public void testGetChannelsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1269 int user = USER.getIdentifier();
1270 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1271 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1272 NotificationManager.IMPORTANCE_MAX);
1273 channel1.setBypassDnd(true);
1274 channel1.setGroup(ncg.getId());
1275 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1276 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1277
1278 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1279 user).getList().size());
1280
1281 // disable group
1282 ncg.setBlocked(true);
1283 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1284 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1285 user).getList().size());
1286 }
1287
1288 @Test
1289 public void testGetChannelsBypassingDndCount_multipleChannelsBypassing() {
1290 int user = USER.getIdentifier();
1291 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1292 NotificationManager.IMPORTANCE_MAX);
1293 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1294 NotificationManager.IMPORTANCE_MAX);
1295 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1296 NotificationManager.IMPORTANCE_MAX);
1297 channel1.setBypassDnd(true);
1298 channel2.setBypassDnd(true);
1299 channel3.setBypassDnd(true);
1300 // has DND access, so can set bypassDnd attribute
1301 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1302 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1303 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1304 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1305 user).getList().size());
1306
1307 // block notifications from this app
1308 mHelper.setEnabled(PKG_N_MR1, user, false);
1309 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1310 user).getList().size());
1311
1312 // re-enable notifications from this app
1313 mHelper.setEnabled(PKG_N_MR1, user, true);
1314 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1315 user).getList().size());
1316
1317 // setBypassDnd false for some channels
1318 channel1.setBypassDnd(false);
1319 channel2.setBypassDnd(false);
1320 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1321 user).getList().size());
1322
1323 // setBypassDnd false for rest of the channels
1324 channel3.setBypassDnd(false);
1325 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1326 user).getList().size());
1327 }
1328
1329 @Test
1330 public void testGetAppsBypassingDndCount_noAppsBypassing() throws Exception {
1331 assertEquals(0, mHelper.getAppsBypassingDndCount(USER.getIdentifier()));
1332 }
1333
1334 @Test
1335 public void testGetAppsBypassingDndCount_noAppsForUserIdBypassing() throws Exception {
1336 int user = 9;
1337 NotificationChannel channel = new NotificationChannel("id", "name",
1338 NotificationManager.IMPORTANCE_MAX);
1339 channel.setBypassDnd(true);
1340 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1341
1342 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1343 }
1344
1345 @Test
1346 public void testGetAppsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1347 int user = USER.getIdentifier();
1348 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1349 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1350 NotificationManager.IMPORTANCE_MAX);
1351 channel1.setBypassDnd(true);
1352 channel1.setGroup(ncg.getId());
1353 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1354 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1355
1356 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1357
1358 // disable group
1359 ncg.setBlocked(true);
1360 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1361 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1362 }
1363
1364 @Test
1365 public void testGetAppsBypassingDndCount_oneAppBypassing() {
1366 int user = USER.getIdentifier();
1367 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1368 NotificationManager.IMPORTANCE_MAX);
1369 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1370 NotificationManager.IMPORTANCE_MAX);
1371 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1372 NotificationManager.IMPORTANCE_MAX);
1373 channel1.setBypassDnd(true);
1374 channel2.setBypassDnd(true);
1375 channel3.setBypassDnd(true);
1376 // has DND access, so can set bypassDnd attribute
1377 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1378 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1379 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1380 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1381
1382 // block notifications from this app
1383 mHelper.setEnabled(PKG_N_MR1, user, false);
1384 assertEquals(0, mHelper.getAppsBypassingDndCount(user)); // no apps can bypass dnd
1385
1386 // re-enable notifications from this app
1387 mHelper.setEnabled(PKG_N_MR1, user, true);
1388 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1389
1390 // setBypassDnd false for some channels
1391 channel1.setBypassDnd(false);
1392 channel2.setBypassDnd(false);
1393 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1394
1395 // setBypassDnd false for rest of the channels
1396 channel3.setBypassDnd(false);
1397 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1398 }
1399
1400 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001401 public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception {
1402 // create notification channel that can't bypass dnd
1403 // expected result: areChannelsBypassingDnd = false
1404 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1405 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001406 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001407 assertFalse(mHelper.areChannelsBypassingDnd());
1408 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1409 resetZenModeHelper();
1410
1411 // create notification channel that can bypass dnd
1412 // expected result: areChannelsBypassingDnd = true
1413 NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1414 channel2.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001415 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001416 assertTrue(mHelper.areChannelsBypassingDnd());
1417 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1418 resetZenModeHelper();
1419
1420 // delete channels
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001421 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001422 assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
1423 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1424 resetZenModeHelper();
1425
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001426 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001427 assertFalse(mHelper.areChannelsBypassingDnd());
1428 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1429 resetZenModeHelper();
1430 }
1431
1432 @Test
1433 public void testUpdateCanChannelsBypassDnd() throws Exception {
1434 // create notification channel that can't bypass dnd
1435 // expected result: areChannelsBypassingDnd = false
1436 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1437 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001438 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001439 assertFalse(mHelper.areChannelsBypassingDnd());
1440 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1441 resetZenModeHelper();
1442
1443 // update channel so it CAN bypass dnd:
1444 // expected result: areChannelsBypassingDnd = true
1445 channel.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001446 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001447 assertTrue(mHelper.areChannelsBypassingDnd());
1448 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1449 resetZenModeHelper();
1450
1451 // update channel so it can't bypass dnd:
1452 // expected result: areChannelsBypassingDnd = false
1453 channel.setBypassDnd(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001454 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001455 assertFalse(mHelper.areChannelsBypassingDnd());
1456 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1457 resetZenModeHelper();
1458 }
1459
1460 @Test
1461 public void testSetupNewZenModeHelper_canBypass() {
1462 // start notification policy off with mAreChannelsBypassingDnd = true, but
1463 // RankingHelper should change to false
1464 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
Julia Reynolds24edc002020-01-29 16:35:32 -05001465 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001466 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Will Brockman23db6d42020-02-28 09:51:12 -05001467 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001468 assertFalse(mHelper.areChannelsBypassingDnd());
1469 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1470 resetZenModeHelper();
1471 }
1472
1473 @Test
1474 public void testSetupNewZenModeHelper_cannotBypass() {
1475 // start notification policy off with mAreChannelsBypassingDnd = false
Julia Reynolds24edc002020-01-29 16:35:32 -05001476 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001477 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Will Brockman23db6d42020-02-28 09:51:12 -05001478 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001479 assertFalse(mHelper.areChannelsBypassingDnd());
1480 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1481 resetZenModeHelper();
1482 }
1483
1484 @Test
1485 public void testCreateDeletedChannel() throws Exception {
1486 long[] vibration = new long[]{100, 67, 145, 156};
1487 NotificationChannel channel =
1488 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1489 channel.setVibrationPattern(vibration);
1490
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001491 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1492 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001493
1494 NotificationChannel newChannel = new NotificationChannel(
1495 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1496 newChannel.setVibrationPattern(new long[]{100});
1497
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001498 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001499
1500 // No long deleted, using old settings
1501 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001502 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001503 }
1504
1505 @Test
1506 public void testOnlyHasDefaultChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001507 assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
1508 assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001509
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001510 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1511 assertFalse(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001512 }
1513
1514 @Test
1515 public void testCreateChannel_defaultChannelId() throws Exception {
1516 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001517 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, new NotificationChannel(
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001518 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
1519 fail("Allowed to create default channel");
1520 } catch (IllegalArgumentException e) {
1521 // pass
1522 }
1523 }
1524
1525 @Test
1526 public void testCreateChannel_alreadyExists() throws Exception {
1527 long[] vibration = new long[]{100, 67, 145, 156};
1528 NotificationChannel channel =
1529 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1530 channel.setVibrationPattern(vibration);
1531
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001532 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001533
1534 NotificationChannel newChannel = new NotificationChannel(
1535 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1536 newChannel.setVibrationPattern(new long[]{100});
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001537 newChannel.setAllowBubbles(!channel.canBubble());
1538 newChannel.setLightColor(Color.BLUE);
1539 newChannel.setSound(Uri.EMPTY, null);
1540 newChannel.setShowBadge(!channel.canShowBadge());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001541
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001542 assertFalse(mHelper.createNotificationChannel(
1543 PKG_N_MR1, UID_N_MR1, newChannel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001544
1545 // Old settings not overridden
1546 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001547 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Will Brockman23db6d42020-02-28 09:51:12 -05001548
1549 assertEquals(1, mLogger.getCalls().size());
1550 assertEquals(
1551 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1552 mLogger.get(0).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001553 }
1554
1555 @Test
1556 public void testCreateChannel_noOverrideSound() throws Exception {
1557 Uri sound = new Uri.Builder().scheme("test").build();
1558 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1559 NotificationManager.IMPORTANCE_DEFAULT);
1560 channel.setSound(sound, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001561 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001562 assertEquals(sound, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001563 PKG_N_MR1, UID_N_MR1, channel.getId(), false).getSound());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001564 }
1565
1566 @Test
1567 public void testPermanentlyDeleteChannels() throws Exception {
1568 NotificationChannel channel1 =
1569 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1570 NotificationChannel channel2 =
1571 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1572
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001573 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1574 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001575
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001576 mHelper.permanentlyDeleteNotificationChannels(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001577
1578 // Only default channel remains
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001579 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001580 }
1581
1582 @Test
1583 public void testDeleteGroup() throws Exception {
1584 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1585 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1586 NotificationChannel nonGroupedNonDeletedChannel =
1587 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1588 NotificationChannel groupedButNotDeleted =
1589 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1590 groupedButNotDeleted.setGroup("not");
1591 NotificationChannel groupedAndDeleted =
1592 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1593 groupedAndDeleted.setGroup("totally");
1594
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001595 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
1596 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001597 mHelper.createNotificationChannel(
1598 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001599 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false);
1600 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001601
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001602 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001603
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001604 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001605 assertNotNull(
1606 mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001607
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001608 assertNull(mHelper.getNotificationChannel(
1609 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), false));
1610 compareChannels(groupedAndDeleted, mHelper.getNotificationChannel(
1611 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001612
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001613 compareChannels(groupedButNotDeleted, mHelper.getNotificationChannel(
1614 PKG_N_MR1, UID_N_MR1, groupedButNotDeleted.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001615 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001616 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001617
1618 // notDeleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001619 assertEquals(1, mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001620
1621 verify(mHandler, never()).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001622
1623 assertEquals(7, mLogger.getCalls().size());
1624 assertEquals(
1625 NotificationChannelLogger.NotificationChannelEvent
1626 .NOTIFICATION_CHANNEL_GROUP_DELETED,
1627 mLogger.get(5).event); // Next-to-last log is the deletion of the channel group.
1628 assertEquals(
1629 NotificationChannelLogger.NotificationChannelEvent
1630 .NOTIFICATION_CHANNEL_DELETED,
1631 mLogger.get(6).event); // Final log is the deletion of the channel.
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001632 }
1633
1634 @Test
1635 public void testOnUserRemoved() throws Exception {
1636 int[] user0Uids = {98, 235, 16, 3782};
1637 int[] user1Uids = new int[user0Uids.length];
1638 for (int i = 0; i < user0Uids.length; i++) {
1639 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1640
1641 final ApplicationInfo legacy = new ApplicationInfo();
1642 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001643 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001644
1645 // create records with the default channel for all user 0 and user 1 uids
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001646 mHelper.getImportance(PKG_N_MR1, user0Uids[i]);
1647 mHelper.getImportance(PKG_N_MR1, user1Uids[i]);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001648 }
1649
1650 mHelper.onUserRemoved(1);
1651
1652 // user 0 records remain
1653 for (int i = 0; i < user0Uids.length; i++) {
1654 assertEquals(1,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001655 mHelper.getNotificationChannels(PKG_N_MR1, user0Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001656 }
1657 // user 1 records are gone
1658 for (int i = 0; i < user1Uids.length; i++) {
1659 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001660 mHelper.getNotificationChannels(PKG_N_MR1, user1Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001661 }
1662 }
1663
1664 @Test
1665 public void testOnPackageChanged_packageRemoval() throws Exception {
1666 // Deleted
1667 NotificationChannel channel1 =
1668 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001669 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001670
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001671 assertTrue(mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1},
1672 new int[]{UID_N_MR1}));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001673
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001674 assertEquals(0, mHelper.getNotificationChannels(
1675 PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001676
1677 // Not deleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001678 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001679
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001680 assertFalse(mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM,
1681 new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001682 assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001683 }
1684
1685 @Test
1686 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001687 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001688
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001689 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1690 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001691
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001692 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1693 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001694 }
1695
1696 @Test
1697 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1698 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001699 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001700 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001701 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001702
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001703 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1704 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001705
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001706 assertEquals(0, mHelper.getNotificationChannelGroups(
1707 PKG_N_MR1, UID_N_MR1, true, true, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001708 }
1709
1710 @Test
1711 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1712 // create channel as api 26
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001713 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001714
1715 // install new app version targeting 25
1716 final ApplicationInfo legacy = new ApplicationInfo();
1717 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001718 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001719 mHelper.onPackagesChanged(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001720 false, UserHandle.USER_SYSTEM, new String[]{PKG_O}, new int[]{UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001721
1722 // make sure the default channel was readded
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001723 //assertEquals(2, mHelper.getNotificationChannels(PKG_O, UID_O, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001724 assertNotNull(mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001725 PKG_O, UID_O, NotificationChannel.DEFAULT_CHANNEL_ID, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001726 }
1727
1728 @Test
Julia Reynolds7af51c52019-04-19 11:08:27 -04001729 public void testClearData() {
1730 ArraySet<String> pkg = new ArraySet<>();
1731 pkg.add(PKG_O);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001732 ArraySet<Pair<String, Integer>> pkgPair = new ArraySet<>();
1733 pkgPair.add(new Pair(PKG_O, UID_O));
Julia Reynolds7af51c52019-04-19 11:08:27 -04001734 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
1735 mHelper.createNotificationChannelGroup(
1736 PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
1737 mHelper.lockChannelsForOEM(pkg.toArray(new String[]{}));
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001738 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001739 mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
1740 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
Mady Mellora92268c2020-03-09 17:25:08 -07001741 mHelper.setBubblesAllowed(PKG_O, UID_O, DEFAULT_BUBBLE_PREFERENCE);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001742 mHelper.setShowBadge(PKG_O, UID_O, false);
1743 mHelper.setAppImportanceLocked(PKG_O, UID_O);
1744
1745 mHelper.clearData(PKG_O, UID_O);
1746
1747 assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, UID_O));
Mady Mellora92268c2020-03-09 17:25:08 -07001748 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), DEFAULT_BUBBLE_PREFERENCE);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001749 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
1750 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
1751 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
1752 assertEquals(0, mHelper.getNotificationChannels(PKG_O, UID_O, true).getList().size());
1753 assertEquals(0, mHelper.getNotificationChannelGroups(PKG_O, UID_O).size());
1754
1755 NotificationChannel channel = getChannel();
1756 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
1757
1758 assertTrue(channel.isImportanceLockedByCriticalDeviceFunction());
1759 assertTrue(channel.isImportanceLockedByOEM());
1760 }
1761
1762 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001763 public void testRecordDefaults() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001764 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1765 UID_N_MR1));
1766 assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
1767 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001768 }
1769
1770 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001771 public void testCreateGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001772 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001773 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001774 assertEquals(ncg,
1775 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).iterator().next());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001776 verify(mHandler, never()).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001777 assertEquals(1, mLogger.getCalls().size());
1778 assertEquals(
1779 NotificationChannelLogger.NotificationChannelEvent
1780 .NOTIFICATION_CHANNEL_GROUP_CREATED,
1781 mLogger.get(0).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001782 }
1783
1784 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001785 public void testCannotCreateChannel_badGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001786 NotificationChannel channel1 =
1787 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1788 channel1.setGroup("garbage");
1789 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001790 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001791 fail("Created a channel with a bad group");
1792 } catch (IllegalArgumentException e) {
1793 }
Will Brockman23db6d42020-02-28 09:51:12 -05001794 assertEquals(0, mLogger.getCalls().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001795 }
1796
1797 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001798 public void testCannotCreateChannel_goodGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001799 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001800 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001801 NotificationChannel channel1 =
1802 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1803 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001804 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001805
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001806 assertEquals(ncg.getId(), mHelper.getNotificationChannel(
1807 PKG_N_MR1, UID_N_MR1, channel1.getId(), false).getGroup());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001808 }
1809
1810 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001811 public void testGetChannelGroups() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001812 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001813 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001814 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001815 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001816 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001817 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001818
1819 NotificationChannel channel1 =
1820 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1821 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001822 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001823 NotificationChannel channel1a =
1824 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1825 channel1a.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001826 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001827
1828 NotificationChannel channel2 =
1829 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1830 channel2.setGroup(ncg2.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001831 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001832
1833 NotificationChannel channel3 =
1834 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001835 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001836
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001837 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1838 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001839 assertEquals(3, actual.size());
1840 for (NotificationChannelGroup group : actual) {
1841 if (group.getId() == null) {
1842 assertEquals(2, group.getChannels().size()); // misc channel too
1843 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1844 || channel3.getId().equals(group.getChannels().get(1).getId()));
1845 } else if (group.getId().equals(ncg.getId())) {
1846 assertEquals(2, group.getChannels().size());
1847 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1848 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1849 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1850 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1851 } else {
1852 fail("expected channel not found");
1853 }
1854 } else if (group.getId().equals(ncg2.getId())) {
1855 assertEquals(1, group.getChannels().size());
1856 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1857 }
1858 }
1859 }
1860
1861 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001862 public void testGetChannelGroups_noSideEffects() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001863 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001864 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001865
1866 NotificationChannel channel1 =
1867 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1868 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001869 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001870 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001871
1872 channel1.setImportance(IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001873 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001874
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001875 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1876 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001877
1878 assertEquals(2, actual.size());
1879 for (NotificationChannelGroup group : actual) {
1880 if (Objects.equals(group.getId(), ncg.getId())) {
1881 assertEquals(1, group.getChannels().size());
1882 }
1883 }
1884 }
1885
1886 @Test
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001887 public void testGetChannelGroups_includeEmptyGroups() {
1888 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1889 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
1890 NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
1891 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true);
1892
1893 NotificationChannel channel1 =
1894 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1895 channel1.setGroup(ncg.getId());
1896 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1897
1898 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1899 PKG_N_MR1, UID_N_MR1, false, false, true).getList();
1900
1901 assertEquals(2, actual.size());
1902 for (NotificationChannelGroup group : actual) {
1903 if (Objects.equals(group.getId(), ncg.getId())) {
1904 assertEquals(1, group.getChannels().size());
1905 }
1906 if (Objects.equals(group.getId(), ncgEmpty.getId())) {
1907 assertEquals(0, group.getChannels().size());
1908 }
1909 }
1910 }
1911
1912 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001913 public void testCreateChannel_updateName() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001914 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001915 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001916 NotificationChannel actual =
1917 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001918 assertEquals("hello", actual.getName());
1919
1920 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001921 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001922
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001923 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001924 assertEquals("goodbye", actual.getName());
1925 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1926
1927 verify(mHandler, times(1)).requestSort();
1928 }
1929
1930 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001931 public void testCreateChannel_addToGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001932 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001933 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001934 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001935 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001936 NotificationChannel actual =
1937 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001938 assertNull(actual.getGroup());
1939
1940 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1941 nc.setGroup(group.getId());
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001942 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001943
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001944 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001945 assertNotNull(actual.getGroup());
1946 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1947
1948 verify(mHandler, times(1)).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001949 assertEquals(3, mLogger.getCalls().size());
1950 assertEquals(
1951 NotificationChannelLogger.NotificationChannelEvent
1952 .NOTIFICATION_CHANNEL_GROUP_CREATED,
1953 mLogger.get(0).event);
1954 assertEquals(
1955 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1956 mLogger.get(1).event);
1957 assertEquals(
1958 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED,
1959 mLogger.get(2).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001960 }
1961
1962 @Test
1963 public void testDumpChannelsJson() throws Exception {
1964 final ApplicationInfo upgrade = new ApplicationInfo();
1965 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
1966 try {
1967 when(mPm.getApplicationInfoAsUser(
1968 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
1969 } catch (PackageManager.NameNotFoundException e) {
1970 }
1971 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
1972 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
1973 for (int i = 0; i < numPackages; i++) {
1974 String pkgName = "pkg" + i;
1975 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
1976 for (int j = 0; j < numChannels; j++) {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001977 mHelper.createNotificationChannel(pkgName, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001978 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
1979 }
1980 expectedChannels.put(pkgName, numChannels);
1981 }
1982
1983 // delete the first channel of the first package
1984 String pkg = expectedChannels.keyAt(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001985 mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001986 // dump should not include deleted channels
1987 int count = expectedChannels.get(pkg);
1988 expectedChannels.put(pkg, count - 1);
1989
1990 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
1991 assertEquals(numPackages, actual.length());
1992 for (int i = 0; i < numPackages; i++) {
1993 JSONObject object = actual.getJSONObject(i);
1994 assertTrue(expectedChannels.containsKey(object.get("packageName")));
1995 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
1996 object.getInt("channelCount"));
1997 }
1998 }
1999
2000 @Test
2001 public void testBadgingOverrideTrue() throws Exception {
2002 Secure.putIntForUser(getContext().getContentResolver(),
2003 Secure.NOTIFICATION_BADGING, 1,
2004 USER.getIdentifier());
2005 mHelper.updateBadgingEnabled(); // would be called by settings observer
2006 assertTrue(mHelper.badgingEnabled(USER));
2007 }
2008
2009 @Test
2010 public void testBadgingOverrideFalse() throws Exception {
2011 Secure.putIntForUser(getContext().getContentResolver(),
2012 Secure.NOTIFICATION_BADGING, 0,
2013 USER.getIdentifier());
2014 mHelper.updateBadgingEnabled(); // would be called by settings observer
2015 assertFalse(mHelper.badgingEnabled(USER));
2016 }
2017
2018 @Test
2019 public void testBadgingForUserAll() throws Exception {
2020 try {
2021 mHelper.badgingEnabled(UserHandle.ALL);
2022 } catch (Exception e) {
2023 fail("just don't throw");
2024 }
2025 }
2026
2027 @Test
2028 public void testBadgingOverrideUserIsolation() throws Exception {
2029 Secure.putIntForUser(getContext().getContentResolver(),
2030 Secure.NOTIFICATION_BADGING, 0,
2031 USER.getIdentifier());
2032 Secure.putIntForUser(getContext().getContentResolver(),
2033 Secure.NOTIFICATION_BADGING, 1,
2034 USER2.getIdentifier());
2035 mHelper.updateBadgingEnabled(); // would be called by settings observer
2036 assertFalse(mHelper.badgingEnabled(USER));
2037 assertTrue(mHelper.badgingEnabled(USER2));
2038 }
2039
2040 @Test
Julia Reynolds4509ce72019-01-31 13:12:43 -05002041 public void testBubblesOverrideTrue() {
Lyn Han4463f842019-07-09 15:27:28 -07002042 Global.putInt(getContext().getContentResolver(),
2043 Global.NOTIFICATION_BUBBLES, 1);
Julia Reynolds4509ce72019-01-31 13:12:43 -05002044 mHelper.updateBubblesEnabled(); // would be called by settings observer
Lyn Han4463f842019-07-09 15:27:28 -07002045 assertTrue(mHelper.bubblesEnabled());
Julia Reynolds4509ce72019-01-31 13:12:43 -05002046 }
2047
2048 @Test
2049 public void testBubblesOverrideFalse() {
Lyn Han4463f842019-07-09 15:27:28 -07002050 Global.putInt(getContext().getContentResolver(),
2051 Global.NOTIFICATION_BUBBLES, 0);
Julia Reynolds4509ce72019-01-31 13:12:43 -05002052 mHelper.updateBubblesEnabled(); // would be called by settings observer
Lyn Han4463f842019-07-09 15:27:28 -07002053 assertFalse(mHelper.bubblesEnabled());
Julia Reynolds4509ce72019-01-31 13:12:43 -05002054 }
2055
2056 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002057 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
2058 String newLabel = "bananas!";
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002059 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
2060 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002061 NotificationChannel.DEFAULT_CHANNEL_ID, false);
2062 assertFalse(newLabel.equals(defaultChannel.getName()));
2063
2064 Resources res = mock(Resources.class);
2065 when(mContext.getResources()).thenReturn(res);
2066 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
2067 .thenReturn(newLabel);
2068
2069 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
2070
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002071 assertEquals(newLabel, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002072 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
2073 }
2074
2075 @Test
2076 public void testIsGroupBlocked_noGroup() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002077 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, null));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002078
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002079 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, "non existent group"));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002080 }
2081
2082 @Test
2083 public void testIsGroupBlocked_notBlocked() throws Exception {
2084 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002085 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002086
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002087 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002088 }
2089
2090 @Test
2091 public void testIsGroupBlocked_blocked() throws Exception {
2092 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002093 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002094 group.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002095 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002096
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002097 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002098 }
2099
2100 @Test
2101 public void testIsGroup_appCannotResetBlock() throws Exception {
2102 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002103 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002104 NotificationChannelGroup group2 = group.clone();
2105 group2.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002106 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false);
2107 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002108
2109 NotificationChannelGroup group3 = group.clone();
2110 group3.setBlocked(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002111 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
2112 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002113 }
2114
2115 @Test
2116 public void testGetNotificationChannelGroupWithChannels() throws Exception {
2117 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
2118 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002119 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
2120 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002121
2122 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
2123 a.setGroup(group.getId());
2124 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
2125 b.setGroup(other.getId());
2126 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2127 c.setGroup(group.getId());
2128 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
2129
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002130 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false);
2131 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false);
2132 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false);
2133 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false);
2134 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002135
2136 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002137 PKG_N_MR1, UID_N_MR1, group.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002138 assertEquals(2, retrieved.getChannels().size());
2139 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2140 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
2141
2142 retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002143 PKG_N_MR1, UID_N_MR1, group.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002144 assertEquals(1, retrieved.getChannels().size());
2145 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2146 }
2147
2148 @Test
2149 public void testAndroidPkgCannotBypassDnd_creation() {
2150 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2151 test.setBypassDnd(true);
2152
2153 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2154
2155 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2156 .canBypassDnd());
2157 }
2158
2159 @Test
2160 public void testDndPkgCanBypassDnd_creation() {
2161 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2162 test.setBypassDnd(true);
2163
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002164 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002165
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002166 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002167 }
2168
2169 @Test
2170 public void testNormalPkgCannotBypassDnd_creation() {
2171 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2172 test.setBypassDnd(true);
2173
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002174 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002175
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002176 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002177 }
2178
2179 @Test
2180 public void testAndroidPkgCannotBypassDnd_update() throws Exception {
2181 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2182 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2183
2184 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2185 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002186 assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002187
2188 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2189 .canBypassDnd());
2190 }
2191
2192 @Test
2193 public void testDndPkgCanBypassDnd_update() throws Exception {
2194 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002195 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002196
2197 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2198 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002199 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002200
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002201 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002202 }
2203
2204 @Test
2205 public void testNormalPkgCannotBypassDnd_update() {
2206 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002207 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002208 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2209 update.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002210 mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false);
2211 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002212 }
2213
2214 @Test
2215 public void testGetBlockedAppCount_noApps() {
2216 assertEquals(0, mHelper.getBlockedAppCount(0));
2217 }
2218
2219 @Test
2220 public void testGetBlockedAppCount_noAppsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002221 mHelper.setEnabled(PKG_N_MR1, 100, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002222 assertEquals(0, mHelper.getBlockedAppCount(9));
2223 }
2224
2225 @Test
2226 public void testGetBlockedAppCount_appsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002227 mHelper.setEnabled(PKG_N_MR1, 1020, false);
2228 mHelper.setEnabled(PKG_N_MR1, 1030, false);
2229 mHelper.setEnabled(PKG_N_MR1, 1060, false);
2230 mHelper.setEnabled(PKG_N_MR1, 1000, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002231 assertEquals(3, mHelper.getBlockedAppCount(0));
2232 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002233
2234 @Test
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002235 public void testXml_statusBarIcons_default() throws Exception {
Julia Reynolds2594b472019-04-03 13:30:16 -04002236 String preQXml = "<ranking version=\"1\">\n"
2237 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
2238 + "<channel id=\"something\" name=\"name\" importance=\"2\" "
2239 + "show_badge=\"true\" />\n"
2240 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
2241 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
2242 + "</package>\n"
2243 + "</ranking>\n";
Will Brockman23db6d42020-02-28 09:51:12 -05002244 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Julia Reynolds2594b472019-04-03 13:30:16 -04002245 loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002246
2247 assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2248 mHelper.shouldHideSilentStatusIcons());
2249 }
2250
2251 @Test
2252 public void testXml_statusBarIcons() throws Exception {
2253 mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
2254
Annie Meng8b646fd2019-02-01 18:46:42 +00002255 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Will Brockman23db6d42020-02-28 09:51:12 -05002256 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Annie Meng8b646fd2019-02-01 18:46:42 +00002257 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002258
2259 assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2260 mHelper.shouldHideSilentStatusIcons());
2261 }
2262
2263 @Test
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002264 public void testSetNotificationDelegate() {
2265 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2266 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2267 }
2268
2269 @Test
2270 public void testRevokeNotificationDelegate() {
2271 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2272 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2273
2274 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2275 }
2276
2277 @Test
2278 public void testRevokeNotificationDelegate_noDelegateExistsNoCrash() {
2279 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2280
2281 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2282 }
2283
2284 @Test
2285 public void testToggleNotificationDelegate() {
2286 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2287 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2288
2289 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2290
2291 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2292 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2293 }
2294
2295 @Test
2296 public void testToggleNotificationDelegate_noDelegateExistsNoCrash() {
2297 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2298 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2299
2300 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2301 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2302 }
2303
2304 @Test
2305 public void testIsDelegateAllowed_noSource() {
2306 assertFalse(mHelper.isDelegateAllowed("does not exist", -1, "whatever", 0));
2307 }
2308
2309 @Test
2310 public void testIsDelegateAllowed_noDelegate() {
2311 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2312
2313 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "whatever", 0));
2314 }
2315
2316 @Test
2317 public void testIsDelegateAllowed_delegateDisabledByApp() {
2318 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2319 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2320
2321 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2322 }
2323
2324 @Test
2325 public void testIsDelegateAllowed_wrongDelegate() {
2326 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2327 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2328
2329 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "banana", 27));
2330 }
2331
2332 @Test
2333 public void testIsDelegateAllowed_delegateDisabledByUser() {
2334 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2335 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2336
2337 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2338 }
2339
2340 @Test
2341 public void testIsDelegateAllowed() {
2342 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2343
2344 assertTrue(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2345 }
2346
2347 @Test
2348 public void testDelegateXml_noDelegate() throws Exception {
2349 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2350
Annie Meng8b646fd2019-02-01 18:46:42 +00002351 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Will Brockman23db6d42020-02-28 09:51:12 -05002352 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Annie Meng8b646fd2019-02-01 18:46:42 +00002353 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002354
2355 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2356 }
2357
2358 @Test
2359 public void testDelegateXml_delegate() throws Exception {
2360 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2361
Annie Meng8b646fd2019-02-01 18:46:42 +00002362 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Will Brockman23db6d42020-02-28 09:51:12 -05002363 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Annie Meng8b646fd2019-02-01 18:46:42 +00002364 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002365
2366 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2367 }
2368
2369 @Test
2370 public void testDelegateXml_disabledDelegate() throws Exception {
2371 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2372 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2373
Annie Meng8b646fd2019-02-01 18:46:42 +00002374 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Will Brockman23db6d42020-02-28 09:51:12 -05002375 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Annie Meng8b646fd2019-02-01 18:46:42 +00002376 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002377
2378 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2379 }
2380
2381 @Test
2382 public void testDelegateXml_userDisabledDelegate() throws Exception {
2383 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2384 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2385
Annie Meng8b646fd2019-02-01 18:46:42 +00002386 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Will Brockman23db6d42020-02-28 09:51:12 -05002387 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Annie Meng8b646fd2019-02-01 18:46:42 +00002388 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002389
2390 // appears disabled
2391 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2392
2393 // but was loaded and can be toggled back on
2394 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2395 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2396 }
2397
2398 @Test
2399 public void testDelegateXml_entirelyDisabledDelegate() throws Exception {
2400 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2401 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2402 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2403
Annie Meng8b646fd2019-02-01 18:46:42 +00002404 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Will Brockman23db6d42020-02-28 09:51:12 -05002405 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Annie Meng8b646fd2019-02-01 18:46:42 +00002406 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002407
2408 // appears disabled
2409 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2410
2411 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2412 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2413
2414 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2415 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2416 }
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002417
2418 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002419 public void testBubblePreference_defaults() throws Exception {
2420 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002421
Annie Meng8b646fd2019-02-01 18:46:42 +00002422 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Will Brockman23db6d42020-02-28 09:51:12 -05002423 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Annie Meng8b646fd2019-02-01 18:46:42 +00002424 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002425
Mady Mellora92268c2020-03-09 17:25:08 -07002426 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002427 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2428 }
2429
2430 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002431 public void testBubblePreference_xml() throws Exception {
2432 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
2433 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002434 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002435 mHelper.getAppLockedFields(PKG_O, UID_O));
2436
Annie Meng8b646fd2019-02-01 18:46:42 +00002437 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Will Brockman23db6d42020-02-28 09:51:12 -05002438 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Annie Meng8b646fd2019-02-01 18:46:42 +00002439 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002440
Mady Mellora92268c2020-03-09 17:25:08 -07002441 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002442 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002443 mHelper.getAppLockedFields(PKG_O, UID_O));
2444 }
Julia Reynolds413ba842019-01-11 10:38:08 -05002445
2446 @Test
2447 public void testLockChannelsForOEM_emptyList() {
2448 mHelper.lockChannelsForOEM(null);
2449 mHelper.lockChannelsForOEM(new String[0]);
2450 // no exception
2451 }
2452
2453 @Test
2454 public void testLockChannelsForOEM_appWide() {
2455 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2456 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2457 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2458 // different uids, same package
2459 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2460 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2461 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2462
2463 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2464
2465 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2466 .isImportanceLockedByOEM());
2467 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2468 .isImportanceLockedByOEM());
2469 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2470 .isImportanceLockedByOEM());
2471 }
2472
2473 @Test
2474 public void testLockChannelsForOEM_onlyGivenPkg() {
2475 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2476 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2477 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2478 mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
2479
2480 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2481
2482 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2483 .isImportanceLockedByOEM());
2484 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
2485 .isImportanceLockedByOEM());
2486 }
2487
2488 @Test
2489 public void testLockChannelsForOEM_channelSpecific() {
2490 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2491 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2492 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2493 // different uids, same package
2494 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2495 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2496 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2497
2498 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
2499
2500 assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2501 .isImportanceLockedByOEM());
2502 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2503 .isImportanceLockedByOEM());
2504 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2505 .isImportanceLockedByOEM());
2506 }
2507
2508 @Test
Julia Reynolds72b28442019-11-12 11:43:39 -05002509 public void testLockChannelsForOEM_channelSpecific_clearData() {
2510 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2511 mHelper.getImportance(PKG_O, UID_O);
2512 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":" + a.getId()});
2513 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2514 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2515 .isImportanceLockedByOEM());
2516
2517 mHelper.clearData(PKG_O, UID_O);
2518
2519 // it's back!
2520 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2521 // and still locked
2522 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2523 .isImportanceLockedByOEM());
2524 }
2525
2526 @Test
Julia Reynolds413ba842019-01-11 10:38:08 -05002527 public void testLockChannelsForOEM_channelDoesNotExistYet_appWide() {
2528 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2529 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2530 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2531
2532 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2533
2534 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2535 .isImportanceLockedByOEM());
2536
2537 mHelper.createNotificationChannel(PKG_O, 3, b, true, false);
2538 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2539 .isImportanceLockedByOEM());
2540 }
2541
2542 @Test
2543 public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific() {
2544 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2545 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2546 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2547
2548 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"});
2549
2550 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2551 .isImportanceLockedByOEM());
2552
2553 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2554 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2555 .isImportanceLockedByOEM());
2556 }
2557
2558 @Test
2559 public void testUpdateNotificationChannel_oemLockedImportance() {
2560 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2561 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2562
2563 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2564
2565 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002566 update.setAllowBubbles(false);
Julia Reynolds413ba842019-01-11 10:38:08 -05002567
2568 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2569
2570 assertEquals(IMPORTANCE_HIGH,
2571 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2572 assertEquals(false,
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002573 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
Julia Reynolds413ba842019-01-11 10:38:08 -05002574
2575 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2576
2577 assertEquals(IMPORTANCE_HIGH,
2578 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2579 }
Julia Reynolds0c245002019-03-27 16:10:11 -04002580
2581 @Test
2582 public void testUpdateDefaultApps_add_multiUser() {
2583 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2584 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2585 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2586 // different uids, same package
2587 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2588 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2589 mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
2590
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002591 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2592 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002593 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2594
2595 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2596 .isImportanceLockedByCriticalDeviceFunction());
2597 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2598 .isImportanceLockedByCriticalDeviceFunction());
2599 assertFalse(mHelper.getNotificationChannel(
2600 PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false)
2601 .isImportanceLockedByCriticalDeviceFunction());
2602 }
2603
2604 @Test
2605 public void testUpdateDefaultApps_add_onlyGivenPkg() {
2606 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2607 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2608 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2609 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2610
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002611 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2612 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002613 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2614
Julia Reynolds0c245002019-03-27 16:10:11 -04002615 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2616 .isImportanceLockedByCriticalDeviceFunction());
2617 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2618 .isImportanceLockedByCriticalDeviceFunction());
2619 }
2620
2621 @Test
2622 public void testUpdateDefaultApps_remove() {
2623 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2624 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2625 // different uids, same package
2626 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2627 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2628
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002629 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2630 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002631 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2632
2633 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2634 .isImportanceLockedByCriticalDeviceFunction());
2635 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2636 .isImportanceLockedByCriticalDeviceFunction());
2637
2638 ArraySet<String> toRemove = new ArraySet<>();
2639 toRemove.add(PKG_O);
2640 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, null);
2641
2642 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2643 .isImportanceLockedByCriticalDeviceFunction());
2644 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2645 .isImportanceLockedByCriticalDeviceFunction());
2646 }
2647
2648 @Test
2649 public void testUpdateDefaultApps_addAndRemove() {
2650 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2651 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2652 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2653 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2654
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002655 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2656 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002657 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2658
2659
2660 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2661 .isImportanceLockedByCriticalDeviceFunction());
2662 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2663 .isImportanceLockedByCriticalDeviceFunction());
2664
2665 // now the default is PKG_N_MR1
2666 ArraySet<String> toRemove = new ArraySet<>();
2667 toRemove.add(PKG_O);
2668 toAdd = new ArraySet<>();
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002669 toAdd.add(new Pair(PKG_N_MR1, UID_N_MR1));
Julia Reynolds0c245002019-03-27 16:10:11 -04002670 mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd);
2671
2672 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2673 .isImportanceLockedByCriticalDeviceFunction());
2674 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2675 .isImportanceLockedByCriticalDeviceFunction());
2676 }
2677
2678 @Test
2679 public void testUpdateDefaultApps_appDoesNotExist_noCrash() {
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002680 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2681 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002682 ArraySet<String> toRemove = new ArraySet<>();
2683 toRemove.add(PKG_N_MR1);
2684 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd);
2685 }
2686
2687 @Test
2688 public void testUpdateDefaultApps_channelDoesNotExistYet() {
2689 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2690 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2691 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2692
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002693 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2694 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002695 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2696
2697 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2698 .isImportanceLockedByCriticalDeviceFunction());
2699
2700 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2701 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2702 .isImportanceLockedByCriticalDeviceFunction());
2703 }
2704
2705 @Test
2706 public void testUpdateNotificationChannel_defaultAppLockedImportance() {
2707 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2708 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002709 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2710 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002711 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2712
2713 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
2714 update.setAllowBubbles(false);
2715
2716 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
Julia Reynolds0c245002019-03-27 16:10:11 -04002717 assertEquals(IMPORTANCE_HIGH,
2718 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2719 assertEquals(false,
2720 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
2721
2722 mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
Julia Reynolds0c245002019-03-27 16:10:11 -04002723 assertEquals(IMPORTANCE_HIGH,
2724 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Beverly47679222019-05-16 15:46:11 -04002725
2726 NotificationChannel updateImportanceLow = new NotificationChannel("a", "a",
2727 IMPORTANCE_LOW);
2728 mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true);
2729 assertEquals(IMPORTANCE_LOW,
2730 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Julia Reynolds0c245002019-03-27 16:10:11 -04002731 }
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002732
2733 @Test
2734 public void testDefaultApp_appHasNoSettingsYet() {
2735 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2736 toAdd.add(new Pair(PKG_O, UID_O));
2737 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2738
2739 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2740 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2741
2742 assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
2743 }
2744
2745 @Test
2746 public void testChannelXml_backupDefaultApp() throws Exception {
2747 NotificationChannel channel1 =
2748 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
2749
2750 mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
2751
2752 // clear data
2753 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
2754 UserHandle.USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
2755 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_O}, new int[]{
2756 UID_O});
2757
2758 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2759 toAdd.add(new Pair(PKG_O, UID_O));
2760 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2761
2762 XmlPullParser parser = Xml.newPullParser();
2763 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
2764 null);
2765 parser.nextTag();
2766 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
2767
2768 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, channel1.getId(), false)
2769 .isImportanceLockedByCriticalDeviceFunction());
2770 }
Mady Mellor9f296142019-05-24 09:42:52 -07002771
2772 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002773 public void testSetBubblesAllowed_none() {
2774 // Change it to non-default first
2775 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL);
2776 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL);
2777 verify(mHandler, times(1)).requestSort();
2778 reset(mHandler);
2779 // Now test
2780 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
2781 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
2782 verify(mHandler, times(1)).requestSort();
2783 }
2784
2785 @Test
2786 public void testSetBubblesAllowed_all() {
2787 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL);
2788 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL);
2789 verify(mHandler, times(1)).requestSort();
2790 }
2791
2792 @Test
2793 public void testSetBubblesAllowed_selected() {
2794 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
2795 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_SELECTED);
Mady Mellor9f296142019-05-24 09:42:52 -07002796 verify(mHandler, times(1)).requestSort();
2797 }
Julia Reynoldsc29370a2019-08-20 16:08:42 -04002798
2799 @Test
2800 public void testTooManyChannels() {
2801 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2802 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2803 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2804 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2805 }
2806 try {
2807 NotificationChannel channel = new NotificationChannel(
2808 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2809 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2810 NotificationManager.IMPORTANCE_HIGH);
2811 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2812 fail("Allowed to create too many notification channels");
2813 } catch (IllegalStateException e) {
2814 // great
2815 }
2816 }
2817
2818 @Test
2819 public void testTooManyChannels_xml() throws Exception {
2820 String extraChannel = "EXTRA";
2821 String extraChannel1 = "EXTRA1";
2822
2823 // create first... many... directly so we don't need a big xml blob in this test
2824 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2825 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2826 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2827 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2828 }
2829
2830 final String xml = "<ranking version=\"1\">\n"
2831 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
2832 + "<channel id=\"" + extraChannel + "\" name=\"hi\" importance=\"3\"/>"
2833 + "<channel id=\"" + extraChannel1 + "\" name=\"hi\" importance=\"3\"/>"
2834 + "</package>"
2835 + "</ranking>";
2836 XmlPullParser parser = Xml.newPullParser();
2837 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2838 null);
2839 parser.nextTag();
2840 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2841
2842 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true));
2843 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true));
2844 }
Julia Reynoldsdb34c1b2019-11-08 10:58:15 -05002845
2846 @Test
2847 public void testRestoreMultiUser() throws Exception {
2848 String pkg = "restore_pkg";
2849 String channelId = "channelId";
2850 int user0Importance = 3;
2851 int user10Importance = 4;
2852 when(mPm.getPackageUidAsUser(eq(pkg), anyInt())).thenReturn(UserHandle.USER_NULL);
2853
2854 // both users have the same package, but different notification settings
2855 final String xmlUser0 = "<ranking version=\"1\">\n"
2856 + "<package name=\"" + pkg + "\" >\n"
2857 + "<channel id=\"" + channelId + "\" name=\"hi\""
2858 + " importance=\"" + user0Importance + "\"/>"
2859 + "</package>"
2860 + "</ranking>";
2861 final String xmlUser10 = "<ranking version=\"1\">\n"
2862 + "<package name=\"" + pkg + "\" >\n"
2863 + "<channel id=\"" + channelId + "\" name=\"hi\""
2864 + " importance=\"" + user10Importance + "\"/>"
2865 + "</package>"
2866 + "</ranking>";
2867
2868 // trigger a restore for both users
2869 XmlPullParser parser = Xml.newPullParser();
2870 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser0.getBytes())),
2871 null);
2872 parser.nextTag();
2873 mHelper.readXml(parser, true, 0);
2874 parser = Xml.newPullParser();
2875 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser10.getBytes())),
2876 null);
2877 parser.nextTag();
2878 mHelper.readXml(parser, true, 10);
2879
2880 // "install" package on both users
2881 String[] pkgList = new String[] {pkg};
2882 int[] uidList0 = new int[] {UserHandle.PER_USER_RANGE};
2883 int[] uidList10 = new int[] {UserHandle.PER_USER_RANGE + 1};
2884 when(mPm.getPackageUidAsUser(pkg, 0)).thenReturn(uidList0[0]);
2885 when(mPm.getPackageUidAsUser(pkg, 10)).thenReturn(uidList10[0]);
2886 ApplicationInfo info = new ApplicationInfo();
2887 info.targetSdkVersion = Build.VERSION_CODES.Q;
2888 when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(info);
2889
2890 mHelper.onPackagesChanged(false, 0, pkgList, uidList0);
2891 mHelper.onPackagesChanged(false, 10, pkgList, uidList10);
2892
2893 assertEquals(user0Importance,
2894 mHelper.getNotificationChannel(pkg, uidList0[0], channelId, false).getImportance());
2895 assertEquals(user10Importance, mHelper.getNotificationChannel(
2896 pkg, uidList10[0], channelId, false).getImportance());
2897 }
Julia Reynolds0f767342019-12-18 09:11:55 -05002898
2899 @Test
2900 public void testGetConversationNotificationChannel() {
2901 String conversationId = "friend";
2902
2903 NotificationChannel parent =
2904 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
2905 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
2906
2907 NotificationChannel friend = new NotificationChannel(String.format(
2908 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId),
2909 "messages", IMPORTANCE_DEFAULT);
2910 friend.setConversationId(parent.getId(), conversationId);
2911 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
2912
Julia Reynolds12ba4cf2020-01-10 16:01:38 -05002913 compareChannelsParentChild(parent, mHelper.getConversationNotificationChannel(
2914 PKG_O, UID_O, parent.getId(), conversationId, false, false), conversationId);
2915 }
2916
2917 @Test
2918 public void testGetNotificationChannel_conversationProvidedByNotCustomizedYet() {
2919 String conversationId = "friend";
2920
2921 NotificationChannel parent =
2922 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
2923 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
2924
2925 compareChannels(parent, mHelper.getConversationNotificationChannel(
2926 PKG_O, UID_O, parent.getId(), conversationId, true, false));
Julia Reynolds0f767342019-12-18 09:11:55 -05002927 }
2928
2929 @Test
2930 public void testConversationNotificationChannelsRequireParents() {
2931 String parentId = "does not exist";
2932 String conversationId = "friend";
2933
2934 NotificationChannel friend = new NotificationChannel(String.format(
2935 CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId),
2936 "messages", IMPORTANCE_DEFAULT);
2937 friend.setConversationId(parentId, conversationId);
2938
2939 try {
2940 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
2941 fail("allowed creation of conversation channel without a parent");
2942 } catch (IllegalArgumentException e) {
2943 // good
2944 }
2945 }
Julia Reynolds7c267522020-01-16 11:26:41 -05002946
2947 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04002948 public void testPlaceholderConversationId_shortcutNotRequired() throws Exception {
2949 Settings.Global.putInt(mContext.getContentResolver(),
2950 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0);
2951
Will Brockman23db6d42020-02-28 09:51:12 -05002952 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Julia Reynolds7c267522020-01-16 11:26:41 -05002953
2954 final String xml = "<ranking version=\"1\">\n"
2955 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
2956 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
2957 + "</package>"
2958 + "</ranking>";
2959 XmlPullParser parser = Xml.newPullParser();
2960 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2961 null);
2962 parser.nextTag();
2963 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2964
2965 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
2966 }
2967
2968 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04002969 public void testPlaceholderConversationId_shortcutRequired() throws Exception {
2970 Settings.Global.putInt(mContext.getContentResolver(),
2971 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
Will Brockman23db6d42020-02-28 09:51:12 -05002972 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Julia Reynolds7c267522020-01-16 11:26:41 -05002973
2974 final String xml = "<ranking version=\"1\">\n"
2975 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
2976 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
2977 + "</package>"
2978 + "</ranking>";
2979 XmlPullParser parser = Xml.newPullParser();
2980 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2981 null);
2982 parser.nextTag();
2983 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2984
2985 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
2986 }
2987
2988 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04002989 public void testNormalConversationId_shortcutRequired() throws Exception {
2990 Settings.Global.putInt(mContext.getContentResolver(),
2991 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
Will Brockman23db6d42020-02-28 09:51:12 -05002992 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Julia Reynolds7c267522020-01-16 11:26:41 -05002993
2994 final String xml = "<ranking version=\"1\">\n"
2995 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
2996 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"other\"/>"
2997 + "</package>"
2998 + "</ranking>";
2999 XmlPullParser parser = Xml.newPullParser();
3000 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3001 null);
3002 parser.nextTag();
3003 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3004
3005 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3006 }
3007
3008 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003009 public void testNoConversationId_shortcutRequired() throws Exception {
3010 Settings.Global.putInt(mContext.getContentResolver(),
3011 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
Will Brockman23db6d42020-02-28 09:51:12 -05003012 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
Julia Reynolds7c267522020-01-16 11:26:41 -05003013
3014 final String xml = "<ranking version=\"1\">\n"
3015 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3016 + "<channel id=\"id\" name=\"hi\" importance=\"3\"/>"
3017 + "</package>"
3018 + "</ranking>";
3019 XmlPullParser parser = Xml.newPullParser();
3020 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3021 null);
3022 parser.nextTag();
3023 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3024
3025 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3026 }
Julia Reynolds882f2062020-02-05 12:11:38 -05003027
3028 @Test
Julia Reynolds02971452020-02-14 16:44:19 -05003029 public void testGetConversations_all() {
3030 String convoId = "convo";
3031 NotificationChannel messages =
3032 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3033 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3034 NotificationChannel calls =
3035 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3036 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3037 NotificationChannel p =
3038 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3039 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3040
3041 NotificationChannel channel =
3042 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3043 channel.setConversationId(messages.getId(), convoId);
3044 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3045
3046 NotificationChannel diffConvo =
3047 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3048 diffConvo.setConversationId(p.getId(), "different convo");
3049 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3050
3051 NotificationChannel channel2 =
3052 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3053 channel2.setConversationId(calls.getId(), convoId);
3054 channel2.setImportantConversation(true);
3055 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3056
3057 List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
3058
3059 assertEquals(3, convos.size());
3060 assertTrue(conversationWrapperContainsChannel(convos, channel));
3061 assertTrue(conversationWrapperContainsChannel(convos, diffConvo));
3062 assertTrue(conversationWrapperContainsChannel(convos, channel2));
3063 }
3064
3065 @Test
3066 public void testGetConversations_onlyImportant() {
3067 String convoId = "convo";
3068 NotificationChannel messages =
3069 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3070 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3071 NotificationChannel calls =
3072 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3073 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3074 NotificationChannel p =
3075 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3076 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3077
3078 NotificationChannel channel =
3079 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3080 channel.setConversationId(messages.getId(), convoId);
3081 channel.setImportantConversation(true);
3082 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3083
3084 NotificationChannel diffConvo =
3085 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3086 diffConvo.setConversationId(p.getId(), "different convo");
3087 diffConvo.setImportantConversation(true);
3088 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3089
3090 NotificationChannel channel2 =
3091 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3092 channel2.setConversationId(calls.getId(), convoId);
3093 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3094
3095 List<ConversationChannelWrapper> convos = mHelper.getConversations(true);
3096
3097 assertEquals(2, convos.size());
3098 assertTrue(conversationWrapperContainsChannel(convos, channel));
3099 assertTrue(conversationWrapperContainsChannel(convos, diffConvo));
3100 assertFalse(conversationWrapperContainsChannel(convos, channel2));
3101 }
3102
3103 private boolean conversationWrapperContainsChannel(List<ConversationChannelWrapper> list,
3104 NotificationChannel expected) {
3105 for (ConversationChannelWrapper ccw : list) {
3106 if (ccw.getNotificationChannel().equals(expected)) {
3107 return true;
3108 }
3109 }
3110
3111 return false;
3112 }
3113
3114 @Test
Julia Reynolds882f2062020-02-05 12:11:38 -05003115 public void testGetConversations_invalidPkg() {
3116 assertThat(mHelper.getConversations("bad", 1)).isEmpty();
3117 }
3118
3119 @Test
3120 public void testGetConversations_noConversations() {
3121 NotificationChannel channel =
3122 new NotificationChannel("not_convo", "not_convo", IMPORTANCE_DEFAULT);
3123 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3124
3125 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3126 }
3127
3128 @Test
3129 public void testGetConversations_noDisabledGroups() {
3130 NotificationChannelGroup group = new NotificationChannelGroup("a", "a");
3131 group.setBlocked(true);
3132 mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
3133 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3134 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3135
3136 NotificationChannel channel =
3137 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3138 channel.setConversationId("parent", "convo");
3139 channel.setGroup(group.getId());
3140 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3141
3142 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3143 }
3144
3145 @Test
3146 public void testGetConversations_noDeleted() {
3147 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3148 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3149 NotificationChannel channel =
3150 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3151 channel.setConversationId("parent", "convo");
3152 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3153 mHelper.deleteNotificationChannel(PKG_O, UID_O, channel.getId());
3154
3155 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3156 }
3157
3158 @Test
3159 public void testGetConversations() {
3160 NotificationChannelGroup group = new NotificationChannelGroup("acct", "account_name");
3161 mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
3162
3163 NotificationChannel messages =
3164 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3165 messages.setGroup(group.getId());
3166 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3167 NotificationChannel calls =
3168 new NotificationChannel("calls", "Calls", IMPORTANCE_HIGH);
3169 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3170
3171 NotificationChannel channel =
3172 new NotificationChannel("A person", "A lovely person", IMPORTANCE_DEFAULT);
3173 channel.setGroup(group.getId());
3174 channel.setConversationId(messages.getId(), channel.getName().toString());
3175 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3176
3177 NotificationChannel channel2 =
3178 new NotificationChannel("B person", "B fabulous person", IMPORTANCE_DEFAULT);
Julia Reynoldsa625b942020-02-15 09:42:23 -05003179 channel2.setConversationId(calls.getId(), channel2.getName().toString());
Julia Reynolds882f2062020-02-05 12:11:38 -05003180 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3181
3182 Map<String, NotificationChannel> expected = new HashMap<>();
3183 expected.put(channel.getId(), channel);
3184 expected.put(channel2.getId(), channel2);
3185
3186 Map<String, CharSequence> expectedGroup = new HashMap<>();
3187 expectedGroup.put(channel.getId(), group.getName());
3188 expectedGroup.put(channel2.getId(), null);
3189
3190 Map<String, CharSequence> expectedParentLabel= new HashMap<>();
3191 expectedParentLabel.put(channel.getId(), messages.getName());
3192 expectedParentLabel.put(channel2.getId(), calls.getName());
3193
3194 ArrayList<ConversationChannelWrapper> convos = mHelper.getConversations(PKG_O, UID_O);
3195 assertThat(convos).hasSize(2);
3196
3197 for (ConversationChannelWrapper convo : convos) {
3198 assertThat(convo.getNotificationChannel())
3199 .isEqualTo(expected.get(convo.getNotificationChannel().getId()));
3200 assertThat(convo.getParentChannelLabel())
3201 .isEqualTo(expectedParentLabel.get(convo.getNotificationChannel().getId()));
3202 assertThat(convo.getGroupLabel())
3203 .isEqualTo(expectedGroup.get(convo.getNotificationChannel().getId()));
3204 }
3205 }
Julia Reynoldsa625b942020-02-15 09:42:23 -05003206
3207 @Test
3208 public void testDeleteConversation() {
3209 String convoId = "convo";
3210 NotificationChannel messages =
3211 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3212 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3213 NotificationChannel calls =
3214 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3215 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3216
3217 NotificationChannel channel =
3218 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3219 channel.setConversationId(messages.getId(), convoId);
3220 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3221
3222 NotificationChannel noMatch =
3223 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3224 noMatch.setConversationId(messages.getId(), "different convo");
3225 mHelper.createNotificationChannel(PKG_O, UID_O, noMatch, true, false);
3226
3227 NotificationChannel channel2 =
3228 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3229 channel2.setConversationId(calls.getId(), convoId);
3230 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3231
3232 assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
3233 assertEquals(channel2,
3234 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
3235 assertEquals(2, mHelper.deleteConversation(PKG_O, UID_O, convoId).size());
3236
3237 assertEquals(messages,
3238 mHelper.getNotificationChannel(PKG_O, UID_O, messages.getId(), false));
3239 assertEquals(noMatch,
3240 mHelper.getNotificationChannel(PKG_O, UID_O, noMatch.getId(), false));
3241
3242 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
3243 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
3244 assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), true));
3245 assertEquals(channel2,
3246 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), true));
Will Brockman23db6d42020-02-28 09:51:12 -05003247
3248 assertEquals(7, mLogger.getCalls().size());
3249 assertEquals(
3250 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
3251 mLogger.get(0).event); // Channel messages
3252 assertEquals(
3253 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
3254 mLogger.get(1).event); // Channel calls
3255 assertEquals(
3256 NotificationChannelLogger.NotificationChannelEvent
3257 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3258 mLogger.get(2).event); // Channel channel - Conversation A person msgs
3259 assertEquals(
3260 NotificationChannelLogger.NotificationChannelEvent
3261 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3262 mLogger.get(3).event); // Channel noMatch - Conversation B person msgs
3263 assertEquals(
3264 NotificationChannelLogger.NotificationChannelEvent
3265 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3266 mLogger.get(4).event); // Channel channel2 - Conversation A person calls
3267 assertEquals(
3268 NotificationChannelLogger.NotificationChannelEvent
3269 .NOTIFICATION_CHANNEL_CONVERSATION_DELETED,
3270 mLogger.get(5).event); // Delete Channel channel - Conversation A person msgs
3271 assertEquals(
3272 NotificationChannelLogger.NotificationChannelEvent
3273 .NOTIFICATION_CHANNEL_CONVERSATION_DELETED,
3274 mLogger.get(6).event); // Delete Channel channel2 - Conversation A person calls
Julia Reynoldsa625b942020-02-15 09:42:23 -05003275 }
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04003276}