blob: ac51750f23f820e4cd7d1e351bb2f7b1fb96d301 [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
Mady Mellorc888d512020-04-09 14:48:02 -070018import static android.app.AppOpsManager.MODE_ALLOWED;
19import static android.app.AppOpsManager.MODE_DEFAULT;
20import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
Julia Reynolds0f767342019-12-18 09:11:55 -050021import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
Mady Mellora92268c2020-03-09 17:25:08 -070022import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
23import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
24import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040025import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
26import static android.app.NotificationManager.IMPORTANCE_HIGH;
27import static android.app.NotificationManager.IMPORTANCE_LOW;
28import static android.app.NotificationManager.IMPORTANCE_MAX;
29import static android.app.NotificationManager.IMPORTANCE_NONE;
30import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
31
Mady Mellora92268c2020-03-09 17:25:08 -070032import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE;
Julia Reynoldsc29370a2019-08-20 16:08:42 -040033import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
34
Julia Reynolds882f2062020-02-05 12:11:38 -050035import static com.google.common.truth.Truth.assertThat;
36
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040037import static junit.framework.Assert.assertNull;
38import static junit.framework.Assert.fail;
39
40import static org.junit.Assert.assertEquals;
41import static org.junit.Assert.assertFalse;
42import static org.junit.Assert.assertNotNull;
43import static org.junit.Assert.assertTrue;
44import static org.mockito.ArgumentMatchers.any;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -080045import static org.mockito.ArgumentMatchers.anyInt;
46import static org.mockito.ArgumentMatchers.anyString;
47import static org.mockito.ArgumentMatchers.eq;
48import static org.mockito.Mockito.doReturn;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040049import static org.mockito.Mockito.mock;
50import static org.mockito.Mockito.never;
51import static org.mockito.Mockito.reset;
52import static org.mockito.Mockito.times;
53import static org.mockito.Mockito.verify;
54import static org.mockito.Mockito.when;
55
Mady Mellorc888d512020-04-09 14:48:02 -070056import android.app.AppOpsManager;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040057import android.app.Notification;
58import android.app.NotificationChannel;
59import android.app.NotificationChannelGroup;
60import android.app.NotificationManager;
61import android.content.ContentProvider;
62import android.content.Context;
63import android.content.IContentProvider;
64import android.content.pm.ApplicationInfo;
65import android.content.pm.PackageInfo;
66import android.content.pm.PackageManager;
67import android.content.pm.Signature;
68import android.content.res.Resources;
69import android.graphics.Color;
70import android.media.AudioAttributes;
71import android.net.Uri;
72import android.os.Build;
73import android.os.UserHandle;
74import android.provider.Settings;
Lyn Han4463f842019-07-09 15:27:28 -070075import android.provider.Settings.Global;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040076import android.provider.Settings.Secure;
Julia Reynolds882f2062020-02-05 12:11:38 -050077import android.service.notification.ConversationChannelWrapper;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -080078import android.test.mock.MockIContentProvider;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040079import android.test.suitebuilder.annotation.SmallTest;
80import android.testing.TestableContentResolver;
81import android.util.ArrayMap;
Julia Reynolds0c245002019-03-27 16:10:11 -040082import android.util.ArraySet;
Julia Reynoldse7ca31b2019-04-25 15:41:47 -040083import android.util.Pair;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040084import android.util.Xml;
85
Beverly47679222019-05-16 15:46:11 -040086import androidx.test.InstrumentationRegistry;
87import androidx.test.runner.AndroidJUnit4;
88
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040089import com.android.internal.util.FastXmlSerializer;
90import com.android.server.UiServiceTestCase;
91
92import org.json.JSONArray;
93import org.json.JSONObject;
94import org.junit.Before;
95import org.junit.Test;
96import org.junit.runner.RunWith;
97import org.mockito.Mock;
98import org.mockito.MockitoAnnotations;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -080099import org.mockito.Spy;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400100import org.xmlpull.v1.XmlPullParser;
101import org.xmlpull.v1.XmlSerializer;
102
103import java.io.BufferedInputStream;
104import java.io.BufferedOutputStream;
105import java.io.ByteArrayInputStream;
106import java.io.ByteArrayOutputStream;
Julia Reynolds882f2062020-02-05 12:11:38 -0500107import java.util.ArrayList;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400108import java.util.Arrays;
109import java.util.HashMap;
110import java.util.List;
111import java.util.Map;
112import java.util.Objects;
113import java.util.concurrent.ThreadLocalRandom;
114
115@SmallTest
116@RunWith(AndroidJUnit4.class)
117public class PreferencesHelperTest extends UiServiceTestCase {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400118 private static final int UID_N_MR1 = 0;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400119 private static final UserHandle USER = UserHandle.of(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400120 private static final int UID_O = 1111;
Julia Reynolds02971452020-02-14 16:44:19 -0500121 private static final int UID_P = 2222;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400122 private static final String SYSTEM_PKG = "android";
Beverly0479cde22018-11-09 11:05:34 -0500123 private static final int SYSTEM_UID = 1000;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400124 private static final UserHandle USER2 = UserHandle.of(10);
125 private static final String TEST_CHANNEL_ID = "test_channel_id";
126 private static final String TEST_AUTHORITY = "test";
127 private static final Uri SOUND_URI =
128 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
129 private static final Uri CANONICAL_SOUND_URI =
130 Uri.parse("content://" + TEST_AUTHORITY
131 + "/internal/audio/media/10?title=Test&canonical=1");
132
133 @Mock NotificationUsageStats mUsageStats;
134 @Mock RankingHandler mHandler;
135 @Mock PackageManager mPm;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800136 @Spy IContentProvider mTestIContentProvider = new MockIContentProvider();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400137 @Mock Context mContext;
138 @Mock ZenModeHelper mMockZenModeHelper;
Mady Mellorc888d512020-04-09 14:48:02 -0700139 @Mock AppOpsManager mAppOpsManager;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400140
141 private NotificationManager.Policy mTestNotificationPolicy;
142
143 private PreferencesHelper mHelper;
144 private AudioAttributes mAudioAttributes;
Will Brockman23db6d42020-02-28 09:51:12 -0500145 private NotificationChannelLoggerFake mLogger = new NotificationChannelLoggerFake();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400146
147 @Before
148 public void setUp() throws Exception {
149 MockitoAnnotations.initMocks(this);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400150
151 final ApplicationInfo legacy = new ApplicationInfo();
152 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
153 final ApplicationInfo upgrade = new ApplicationInfo();
154 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400155 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
156 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(upgrade);
Julia Reynolds02971452020-02-14 16:44:19 -0500157 when(mPm.getApplicationInfoAsUser(eq(PKG_P), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400158 when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400159 when(mPm.getPackageUidAsUser(eq(PKG_N_MR1), anyInt())).thenReturn(UID_N_MR1);
160 when(mPm.getPackageUidAsUser(eq(PKG_O), anyInt())).thenReturn(UID_O);
Julia Reynolds02971452020-02-14 16:44:19 -0500161 when(mPm.getPackageUidAsUser(eq(PKG_P), anyInt())).thenReturn(UID_P);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400162 when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
163 PackageInfo info = mock(PackageInfo.class);
164 info.signatures = new Signature[] {mock(Signature.class)};
165 when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400166 when(mPm.getPackageInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt()))
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400167 .thenReturn(mock(PackageInfo.class));
168 when(mContext.getResources()).thenReturn(
169 InstrumentationRegistry.getContext().getResources());
170 when(mContext.getContentResolver()).thenReturn(
171 InstrumentationRegistry.getContext().getContentResolver());
172 when(mContext.getPackageManager()).thenReturn(mPm);
173 when(mContext.getApplicationInfo()).thenReturn(legacy);
174 // most tests assume badging is enabled
175 TestableContentResolver contentResolver = getContext().getContentResolver();
176 contentResolver.setFallbackToExisting(false);
177 Secure.putIntForUser(contentResolver,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400178 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID_N_MR1));
Lyn Han4463f842019-07-09 15:27:28 -0700179 Global.putInt(contentResolver, Global.NOTIFICATION_BUBBLES, 1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400180
181 ContentProvider testContentProvider = mock(ContentProvider.class);
182 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
183 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
184
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800185 doReturn(CANONICAL_SOUND_URI)
186 .when(mTestIContentProvider).canonicalize(any(), any(), eq(SOUND_URI));
187 doReturn(CANONICAL_SOUND_URI)
188 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
189 doReturn(SOUND_URI)
190 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400191
192 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
Julia Reynolds24edc002020-01-29 16:35:32 -0500193 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400194 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Mady Mellorc888d512020-04-09 14:48:02 -0700195 when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(),
196 anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT);
197 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
198 mAppOpsManager);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400199 resetZenModeHelper();
200
201 mAudioAttributes = new AudioAttributes.Builder()
202 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
203 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
204 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
205 .build();
206 }
207
Annie Meng8b646fd2019-02-01 18:46:42 +0000208 private ByteArrayOutputStream writeXmlAndPurge(
209 String pkg, int uid, boolean forBackup, int userId, String... channelIds)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400210 throws Exception {
211 XmlSerializer serializer = new FastXmlSerializer();
212 ByteArrayOutputStream baos = new ByteArrayOutputStream();
213 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
214 serializer.startDocument(null, true);
Annie Meng8b646fd2019-02-01 18:46:42 +0000215 mHelper.writeXml(serializer, forBackup, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400216 serializer.endDocument();
217 serializer.flush();
218 for (String channelId : channelIds) {
219 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
220 }
221 return baos;
222 }
223
Annie Meng8b646fd2019-02-01 18:46:42 +0000224 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore, int userId)
225 throws Exception {
226 loadByteArrayXml(stream.toByteArray(), forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400227 }
228
Annie Meng8b646fd2019-02-01 18:46:42 +0000229 private void loadByteArrayXml(byte[] byteArray, boolean forRestore, int userId)
230 throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400231 XmlPullParser parser = Xml.newPullParser();
232 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
233 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000234 mHelper.readXml(parser, forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400235 }
236
237 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
238 assertEquals(expected.getId(), actual.getId());
239 assertEquals(expected.getName(), actual.getName());
240 assertEquals(expected.getDescription(), actual.getDescription());
241 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
242 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
243 assertEquals(expected.getImportance(), actual.getImportance());
244 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
245 assertEquals(expected.getSound(), actual.getSound());
246 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
247 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
248 assertEquals(expected.getGroup(), actual.getGroup());
249 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
250 assertEquals(expected.getLightColor(), actual.getLightColor());
Julia Reynolds0f767342019-12-18 09:11:55 -0500251 assertEquals(expected.getParentChannelId(), actual.getParentChannelId());
252 assertEquals(expected.getConversationId(), actual.getConversationId());
Julia Reynoldsdcd70d62020-01-15 10:33:43 -0500253 assertEquals(expected.isDemoted(), actual.isDemoted());
Julia Reynolds0f767342019-12-18 09:11:55 -0500254 }
255
256 private void compareChannelsParentChild(NotificationChannel parent,
257 NotificationChannel actual, String conversationId) {
258 assertEquals(parent.getName(), actual.getName());
259 assertEquals(parent.getDescription(), actual.getDescription());
260 assertEquals(parent.shouldVibrate(), actual.shouldVibrate());
261 assertEquals(parent.shouldShowLights(), actual.shouldShowLights());
262 assertEquals(parent.getImportance(), actual.getImportance());
263 assertEquals(parent.getLockscreenVisibility(), actual.getLockscreenVisibility());
264 assertEquals(parent.getSound(), actual.getSound());
265 assertEquals(parent.canBypassDnd(), actual.canBypassDnd());
266 assertTrue(Arrays.equals(parent.getVibrationPattern(), actual.getVibrationPattern()));
267 assertEquals(parent.getGroup(), actual.getGroup());
268 assertEquals(parent.getAudioAttributes(), actual.getAudioAttributes());
269 assertEquals(parent.getLightColor(), actual.getLightColor());
270 assertEquals(parent.getId(), actual.getParentChannelId());
271 assertEquals(conversationId, actual.getConversationId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400272 }
273
274 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
275 assertEquals(expected.getId(), actual.getId());
276 assertEquals(expected.getName(), actual.getName());
277 assertEquals(expected.getDescription(), actual.getDescription());
278 assertEquals(expected.isBlocked(), actual.isBlocked());
279 }
280
281 private NotificationChannel getChannel() {
282 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
283 }
284
285 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
286 for (NotificationChannel channel : channels) {
287 if (channel.getId().equals(id)) {
288 return channel;
289 }
290 }
291 return null;
292 }
293
294 private void resetZenModeHelper() {
295 reset(mMockZenModeHelper);
296 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
297 }
298
Annie Meng8b646fd2019-02-01 18:46:42 +0000299 private void setUpPackageWithUid(String packageName, int uid) throws Exception {
300 when(mPm.getApplicationInfoAsUser(eq(packageName), anyInt(), anyInt()))
301 .thenReturn(new ApplicationInfo());
302 when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
303 }
304
305 @Test
306 public void testWriteXml_onlyBackupsTargetUser() throws Exception {
307 // Setup package notifications.
308 String package0 = "test.package.user0";
309 int uid0 = 1001;
310 setUpPackageWithUid(package0, uid0);
311 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400312 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000313
314 String package10 = "test.package.user10";
315 int uid10 = 1001001;
316 setUpPackageWithUid(package10, uid10);
317 NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400318 assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000319
320 ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
321
322 // Reset state.
323 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
324 mHelper.onPackagesChanged(true, 10, new String[] {package10}, new int[] {uid10});
325
326 // Parse backup data.
327 loadStreamXml(baos, true, 0);
328 loadStreamXml(baos, true, 10);
329
330 assertEquals(
331 channel10,
332 mHelper.getNotificationChannel(package10, uid10, channel10.getId(), false));
333 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
334 }
335
336 @Test
337 public void testReadXml_onlyRestoresTargetUser() throws Exception {
338 // Setup package in user 0.
339 String package0 = "test.package.user0";
340 int uid0 = 1001;
341 setUpPackageWithUid(package0, uid0);
342 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400343 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000344
345 ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
346
347 // Reset state.
348 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
349
350 // Restore should convert the uid according to the target user.
351 int expectedUid = 1001001;
352 setUpPackageWithUid(package0, expectedUid);
353 // Parse backup data.
354 loadStreamXml(baos, true, 10);
355
356 assertEquals(
357 channel0,
358 mHelper.getNotificationChannel(package0, expectedUid, channel0.getId(), false));
359 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
360 }
361
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400362 @Test
363 public void testChannelXml() throws Exception {
364 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
365 ncg.setBlocked(true);
366 ncg.setDescription("group desc");
367 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
368 NotificationChannel channel1 =
369 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
370 NotificationChannel channel2 =
371 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
372 channel2.setDescription("descriptions for all");
373 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
374 channel2.enableLights(true);
375 channel2.setBypassDnd(true);
376 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
377 channel2.enableVibration(true);
378 channel2.setGroup(ncg.getId());
379 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
380 channel2.setLightColor(Color.BLUE);
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500381 channel2.setConversationId("id1", "conversation");
Julia Reynoldsdcd70d62020-01-15 10:33:43 -0500382 channel2.setDemoted(true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400383
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400384 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
385 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400386 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
387 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400388
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400389 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
390 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400391
Annie Meng8b646fd2019-02-01 18:46:42 +0000392 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
393 UserHandle.USER_ALL, channel1.getId(), channel2.getId(),
394 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400395 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
396 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400397
Annie Meng8b646fd2019-02-01 18:46:42 +0000398 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400399
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400400 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
401 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400402 assertEquals(channel1,
403 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400404 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400405 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400406
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400407 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
408 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400409 boolean foundNcg = false;
410 for (NotificationChannelGroup actual : actualGroups) {
411 if (ncg.getId().equals(actual.getId())) {
412 foundNcg = true;
413 compareGroups(ncg, actual);
414 } else if (ncg2.getId().equals(actual.getId())) {
415 compareGroups(ncg2, actual);
416 }
417 }
418 assertTrue(foundNcg);
419
420 boolean foundChannel2Group = false;
421 for (NotificationChannelGroup actual : actualGroups) {
422 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
423 foundChannel2Group = true;
424 break;
425 }
426 }
427 assertTrue(foundChannel2Group);
428 }
429
430 @Test
431 public void testChannelXmlForBackup() throws Exception {
432 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
433 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
434 NotificationChannel channel1 =
435 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
436 NotificationChannel channel2 =
437 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
438 channel2.setDescription("descriptions for all");
439 channel2.setSound(SOUND_URI, mAudioAttributes);
440 channel2.enableLights(true);
441 channel2.setBypassDnd(true);
442 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
443 channel2.enableVibration(false);
444 channel2.setGroup(ncg.getId());
445 channel2.setLightColor(Color.BLUE);
446 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
447 channel3.enableVibration(true);
448
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400449 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
450 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
451 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
452 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
453 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
454 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400455
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400456 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400457
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400458 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400459
Annie Meng8b646fd2019-02-01 18:46:42 +0000460 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
461 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
462 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400463 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1, PKG_O},
464 new int[]{UID_N_MR1, UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400465
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400466 mHelper.setShowBadge(PKG_O, UID_O, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400467
Annie Meng8b646fd2019-02-01 18:46:42 +0000468 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400469
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400470 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O));
471 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400472 assertEquals(channel1,
473 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400474 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400475 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400476 compareChannels(channel3,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400477 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400478
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400479 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
480 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400481 boolean foundNcg = false;
482 for (NotificationChannelGroup actual : actualGroups) {
483 if (ncg.getId().equals(actual.getId())) {
484 foundNcg = true;
485 compareGroups(ncg, actual);
486 } else if (ncg2.getId().equals(actual.getId())) {
487 compareGroups(ncg2, actual);
488 }
489 }
490 assertTrue(foundNcg);
491
492 boolean foundChannel2Group = false;
493 for (NotificationChannelGroup actual : actualGroups) {
494 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
495 foundChannel2Group = true;
496 break;
497 }
498 }
499 assertTrue(foundChannel2Group);
500 }
501
502 @Test
503 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
504 NotificationChannel channel =
505 new NotificationChannel("id", "name", IMPORTANCE_LOW);
506 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400507 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400508
Annie Meng8b646fd2019-02-01 18:46:42 +0000509 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
510 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400511
512 // Testing that in restore we are given the canonical version
Annie Meng8b646fd2019-02-01 18:46:42 +0000513 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Philip P. Moltmann128b7032019-09-27 08:44:12 -0700514 verify(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400515 }
516
517 @Test
518 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
519 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
520 Uri canonicalBasedOnLocal = localUri.buildUpon()
521 .appendQueryParameter("title", "Test")
522 .appendQueryParameter("canonical", "1")
523 .build();
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800524 doReturn(canonicalBasedOnLocal)
525 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
526 doReturn(localUri)
527 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
528 doReturn(localUri)
529 .when(mTestIContentProvider).uncanonicalize(any(), any(),
530 eq(canonicalBasedOnLocal));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400531
532 NotificationChannel channel =
533 new NotificationChannel("id", "name", IMPORTANCE_LOW);
534 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400535 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000536 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
537 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400538
Annie Meng8b646fd2019-02-01 18:46:42 +0000539 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400540
541 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400542 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400543 assertEquals(localUri, actualChannel.getSound());
544 }
545
546 @Test
547 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
548 Thread.sleep(3000);
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800549 doReturn(null)
550 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
551 doReturn(null)
552 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400553
554 NotificationChannel channel =
555 new NotificationChannel("id", "name", IMPORTANCE_LOW);
556 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400557 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000558 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
559 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400560
Annie Meng8b646fd2019-02-01 18:46:42 +0000561 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400562
563 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400564 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400565 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
566 }
567
568
569 /**
570 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
571 * handle its restore properly.
572 */
573 @Test
574 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
575 // Not a local uncanonicalized uri, simulating that it fails to exist locally
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800576 doReturn(null)
577 .when(mTestIContentProvider).canonicalize(any(), any(), eq(SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400578 String id = "id";
579 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400580 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400581 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
582 + "sound=\"" + SOUND_URI + "\" "
583 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
584 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
585 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
586 + "</package>\n"
587 + "</ranking>\n";
588
Annie Meng8b646fd2019-02-01 18:46:42 +0000589 loadByteArrayXml(
590 backupWithUncanonicalizedSoundUri.getBytes(), true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400591
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400592 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, id, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400593 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
594 }
595
596 @Test
597 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
598 NotificationChannel channel =
599 new NotificationChannel("id", "name", IMPORTANCE_LOW);
600 channel.setSound(null, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400601 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000602 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
603 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400604
Annie Meng8b646fd2019-02-01 18:46:42 +0000605 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400606
607 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400608 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400609 assertEquals(null, actualChannel.getSound());
610 }
611
612 @Test
613 public void testChannelXml_backup() throws Exception {
614 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
615 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
616 NotificationChannel channel1 =
617 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
618 NotificationChannel channel2 =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400619 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400620 NotificationChannel channel3 =
621 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
622 channel3.setGroup(ncg.getId());
623
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400624 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
625 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
626 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
627 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
628 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400629
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400630 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId());
631 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId());
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400632 assertEquals(channel2,
633 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400634
Annie Meng8b646fd2019-02-01 18:46:42 +0000635 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
636 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
637 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400638 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
639 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400640
641 XmlPullParser parser = Xml.newPullParser();
642 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
643 null);
644 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000645 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400646
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400647 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
648 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
649 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400650 assertEquals(channel2,
651 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400652 }
653
654 @Test
655 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400656 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000657 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400658
Annie Meng8b646fd2019-02-01 18:46:42 +0000659 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400660
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400661 final NotificationChannel updated = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400662 NotificationChannel.DEFAULT_CHANNEL_ID, false);
663 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
664 assertFalse(updated.canBypassDnd());
665 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
666 assertEquals(0, updated.getUserLockedFields());
667 }
668
669 @Test
670 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400671 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
672 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400673 NotificationChannel.DEFAULT_CHANNEL_ID, false);
674 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400675 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400676
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400677 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000678 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400679
Annie Meng8b646fd2019-02-01 18:46:42 +0000680 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400681
682 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400683 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400684 }
685
686 @Test
687 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
688 final String preupgradeXml = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400689 + "<package name=\"" + PKG_N_MR1
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400690 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
691 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400692 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID_N_MR1 + "\" />\n"
693 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" visibility=\""
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400694 + Notification.VISIBILITY_PRIVATE + "\" />\n"
695 + "</ranking>";
696 XmlPullParser parser = Xml.newPullParser();
697 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
698 null);
699 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000700 mHelper.readXml(parser, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400701
702 final NotificationChannel updated1 =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400703 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400704 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
705 assertTrue(updated1.canBypassDnd());
706 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
707 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
708 | NotificationChannel.USER_LOCKED_PRIORITY
709 | NotificationChannel.USER_LOCKED_VISIBILITY,
710 updated1.getUserLockedFields());
711
712 // No Default Channel created for updated packages
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400713 assertEquals(null, mHelper.getNotificationChannel(PKG_O, UID_O,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400714 NotificationChannel.DEFAULT_CHANNEL_ID, false));
715 }
716
717 @Test
718 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
719 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400720 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400721 assertTrue(defaultChannel != null);
Annie Meng8b646fd2019-02-01 18:46:42 +0000722 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
723 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400724 // Load package at higher sdk.
725 final ApplicationInfo upgraded = new ApplicationInfo();
726 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400727 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000728 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400729
730 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400731 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400732 NotificationChannel.DEFAULT_CHANNEL_ID, false));
733 }
734
735 @Test
736 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400737 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400738 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400739 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000740 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400741
742 // Load package at higher sdk.
743 final ApplicationInfo upgraded = new ApplicationInfo();
744 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400745 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000746 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400747
748 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400749 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400750 NotificationChannel.DEFAULT_CHANNEL_ID, false));
751 }
752
753 @Test
754 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400755 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000756 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400757 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400758 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
759
Annie Meng8b646fd2019-02-01 18:46:42 +0000760 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400761
762 // Should still have the newly created channel that wasn't in the xml.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400763 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "bananas", false) != null);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400764 }
765
766 @Test
767 public void testCreateChannel_blocked() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400768 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400769
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400770 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
771 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400772 }
773
774 @Test
775 public void testCreateChannel_badImportance() throws Exception {
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_NONE - 1),
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_UNSPECIFIED),
787 true, false);
788 fail("Was allowed to create a channel with invalid importance");
789 } catch (IllegalArgumentException e) {
790 // yay
791 }
792 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400793 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400794 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
795 true, false);
796 fail("Was allowed to create a channel with invalid importance");
797 } catch (IllegalArgumentException e) {
798 // yay
799 }
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400800 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
801 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
802 assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
803 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400804 }
805
806
807 @Test
808 public void testUpdate() throws Exception {
809 // no fields locked by user
810 final NotificationChannel channel =
811 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
812 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
813 channel.enableLights(true);
814 channel.setBypassDnd(true);
815 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
816
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400817 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400818
819 // same id, try to update all fields
820 final NotificationChannel channel2 =
821 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
822 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
823 channel2.enableLights(false);
824 channel2.setBypassDnd(false);
825 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
826
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400827 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400828
829 // all fields should be changed
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400830 assertEquals(channel2,
831 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400832
833 verify(mHandler, times(1)).requestSort();
834 }
835
836 @Test
837 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400838 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_UNSPECIFIED);
839 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
840 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400841 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400842 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
843 assertFalse(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400844
845 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400846 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400847
848 defaultChannel.setShowBadge(false);
849 defaultChannel.setImportance(IMPORTANCE_NONE);
850 defaultChannel.setBypassDnd(true);
851 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
852
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400853 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
854 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400855
856 // ensure app level fields are changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400857 assertFalse(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
858 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
859 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1,
860 UID_N_MR1));
861 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1));
862 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400863 }
864
865 @Test
866 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
867 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
868
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400869 mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
870 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
871 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400872 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400873 mHelper.getPackageVisibility(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400874
875 channel.setShowBadge(false);
876 channel.setImportance(IMPORTANCE_NONE);
877 channel.setBypassDnd(true);
878 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
879
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400880 mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400881
882 // ensure app level fields are not changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400883 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
884 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400885 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400886 mHelper.getPackageVisibility(PKG_O, UID_O));
887 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O,
888 UID_O));
889 assertFalse(mHelper.getIsAppImportanceLocked(PKG_O, UID_O));
890 }
891
892 @Test
893 public void testUpdate_preUpgrade_noUpdateAppFieldsWithMultipleChannels() throws Exception {
894 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
895
896 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
897 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
898 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
899 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
900 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
901
902 channel.setShowBadge(false);
903 channel.setImportance(IMPORTANCE_NONE);
904 channel.setBypassDnd(true);
905 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
906
907 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
908
909 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
910 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
911
912 defaultChannel.setShowBadge(false);
913 defaultChannel.setImportance(IMPORTANCE_NONE);
914 defaultChannel.setBypassDnd(true);
915 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
916
917 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
918
919 // ensure app level fields are not changed
920 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
921 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
922 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
923 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
924 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
925 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400926 }
927
928 @Test
929 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400930 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "garbage", false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400931 }
932
933 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400934 public void testCreateChannel_CannotChangeHiddenFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400935 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400936 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400937 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
938 channel.enableLights(true);
939 channel.setBypassDnd(true);
940 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
941 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800942 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400943 int lockMask = 0;
944 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
945 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
946 }
947 channel.lockFields(lockMask);
948
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400949 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400950
951 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400952 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400953
954 assertEquals(channel.getName(), savedChannel.getName());
955 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
956 assertFalse(savedChannel.canBypassDnd());
957 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
958 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800959 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400960
961 verify(mHandler, never()).requestSort();
962 }
963
964 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400965 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400966 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400967 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400968 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
969 channel.enableLights(true);
970 channel.setBypassDnd(true);
971 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
972 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800973 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400974 int lockMask = 0;
975 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
976 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
977 }
978 channel.lockFields(lockMask);
979
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400980 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400981
982 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400983 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400984
985 assertEquals(channel.getName(), savedChannel.getName());
986 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
987 assertFalse(savedChannel.canBypassDnd());
988 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
989 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800990 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400991 }
992
993 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400994 public void testClearLockedFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400995 final NotificationChannel channel = getChannel();
Julia Reynolds5c399c62019-04-08 14:42:53 -0400996 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400997 assertEquals(0, channel.getUserLockedFields());
998
999 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
1000 | NotificationChannel.USER_LOCKED_IMPORTANCE);
Julia Reynolds5c399c62019-04-08 14:42:53 -04001001 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001002 assertEquals(0, channel.getUserLockedFields());
1003 }
1004
1005 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001006 public void testLockFields_soundAndVibration() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001007 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001008
1009 final NotificationChannel update1 = getChannel();
1010 update1.setSound(new Uri.Builder().scheme("test").build(),
1011 new AudioAttributes.Builder().build());
1012 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001013 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001014 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1015 | NotificationChannel.USER_LOCKED_SOUND,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001016 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001017 .getUserLockedFields());
1018
1019 NotificationChannel update2 = getChannel();
1020 update2.enableVibration(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001021 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001022 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1023 | NotificationChannel.USER_LOCKED_SOUND
1024 | NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001025 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001026 .getUserLockedFields());
1027 }
1028
1029 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001030 public void testLockFields_vibrationAndLights() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001031 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001032
1033 final NotificationChannel update1 = getChannel();
1034 update1.setVibrationPattern(new long[]{7945, 46 ,246});
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001035 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001036 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001037 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001038 .getUserLockedFields());
1039
1040 final NotificationChannel update2 = getChannel();
1041 update2.enableLights(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001042 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001043 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
1044 | NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001045 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001046 .getUserLockedFields());
1047 }
1048
1049 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001050 public void testLockFields_lightsAndImportance() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001051 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001052
1053 final NotificationChannel update1 = getChannel();
1054 update1.setLightColor(Color.GREEN);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001055 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001056 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001057 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001058 .getUserLockedFields());
1059
1060 final NotificationChannel update2 = getChannel();
1061 update2.setImportance(IMPORTANCE_DEFAULT);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001062 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001063 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
1064 | NotificationChannel.USER_LOCKED_IMPORTANCE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001065 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001066 .getUserLockedFields());
1067 }
1068
1069 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001070 public void testLockFields_visibilityAndDndAndBadge() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001071 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001072 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001073 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001074 .getUserLockedFields());
1075
1076 final NotificationChannel update1 = getChannel();
1077 update1.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001078 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001079 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001080 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001081 .getUserLockedFields());
1082
1083 final NotificationChannel update2 = getChannel();
1084 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001085 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001086 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1087 | NotificationChannel.USER_LOCKED_VISIBILITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001088 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001089 .getUserLockedFields());
1090
1091 final NotificationChannel update3 = getChannel();
1092 update3.setShowBadge(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001093 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001094 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1095 | NotificationChannel.USER_LOCKED_VISIBILITY
1096 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001097 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update3.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001098 .getUserLockedFields());
1099 }
1100
1101 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001102 public void testLockFields_allowBubble() {
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001103 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1104 assertEquals(0,
1105 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
1106 .getUserLockedFields());
1107
1108 final NotificationChannel update = getChannel();
Mady Mellora92268c2020-03-09 17:25:08 -07001109 update.setAllowBubbles(true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001110 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001111 assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE,
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001112 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false)
1113 .getUserLockedFields());
1114 }
1115
1116 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001117 public void testDeleteNonExistentChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001118 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001119 }
1120
1121 @Test
Will Brockman23db6d42020-02-28 09:51:12 -05001122 public void testDoubleDeleteChannel() throws Exception {
1123 NotificationChannel channel = getChannel();
1124 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1125 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1126 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1127 assertEquals(2, mLogger.getCalls().size());
1128 assertEquals(
1129 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1130 mLogger.get(0).event);
1131 assertEquals(
1132 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_DELETED,
1133 mLogger.get(1).event);
1134 // No log for the second delete of the same channel.
1135 }
1136
1137 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001138 public void testGetDeletedChannel() throws Exception {
1139 NotificationChannel channel = getChannel();
1140 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1141 channel.enableLights(true);
1142 channel.setBypassDnd(true);
1143 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1144 channel.enableVibration(true);
1145 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1146
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001147 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1148 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001149
1150 // Does not return deleted channel
1151 NotificationChannel response =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001152 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001153 assertNull(response);
1154
1155 // Returns deleted channel
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001156 response = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001157 compareChannels(channel, response);
1158 assertTrue(response.isDeleted());
1159 }
1160
1161 @Test
1162 public void testGetDeletedChannels() throws Exception {
1163 Map<String, NotificationChannel> channelMap = new HashMap<>();
1164 NotificationChannel channel =
1165 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1166 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1167 channel.enableLights(true);
1168 channel.setBypassDnd(true);
1169 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1170 channel.enableVibration(true);
1171 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1172 channelMap.put(channel.getId(), channel);
1173 NotificationChannel channel2 =
1174 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1175 channelMap.put(channel2.getId(), channel2);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001176 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1177 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001178
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001179 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001180
1181 // Returns only non-deleted channels
1182 List<NotificationChannel> channels =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001183 mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001184 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1185 for (NotificationChannel nc : channels) {
1186 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1187 compareChannels(channel2, nc);
1188 }
1189 }
1190
1191 // Returns deleted channels too
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001192 channels = mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001193 assertEquals(3, channels.size()); // Includes default channel
1194 for (NotificationChannel nc : channels) {
1195 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1196 compareChannels(channelMap.get(nc.getId()), nc);
1197 }
1198 }
1199 }
1200
1201 @Test
1202 public void testGetDeletedChannelCount() throws Exception {
1203 NotificationChannel channel =
1204 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1205 NotificationChannel channel2 =
1206 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1207 NotificationChannel channel3 =
1208 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001209 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1210 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1211 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001212
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001213 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1214 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001215
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001216 assertEquals(2, mHelper.getDeletedChannelCount(PKG_N_MR1, UID_N_MR1));
1217 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001218 }
1219
1220 @Test
1221 public void testGetBlockedChannelCount() throws Exception {
1222 NotificationChannel channel =
1223 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1224 NotificationChannel channel2 =
1225 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
1226 NotificationChannel channel3 =
1227 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001228 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1229 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1230 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001231
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001232 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001233
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001234 assertEquals(1, mHelper.getBlockedChannelCount(PKG_N_MR1, UID_N_MR1));
1235 assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001236 }
1237
1238 @Test
Beverly4f7b53d2018-11-20 09:56:31 -05001239 public void testUpdateChannelsBypassingDnd_onUserSwitch_onUserUnlocked() throws Exception {
1240 int user = USER.getIdentifier();
1241 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1242 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1243 NotificationManager.IMPORTANCE_MAX);
1244 channel1.setBypassDnd(true);
1245 channel1.setGroup(ncg.getId());
1246
1247 // channel is associated with a group, then group is deleted
1248 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1249 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1250 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, user, ncg.getId());
1251
1252 mHelper.onUserSwitched(user);
1253 mHelper.onUserUnlocked(user);
1254 }
1255
1256 @Test
Beverly0479cde22018-11-09 11:05:34 -05001257 public void testGetChannelsBypassingDndCount_noChannelsBypassing() throws Exception {
1258 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1259 USER.getIdentifier()).getList().size());
1260 }
1261
1262 @Test
1263 public void testGetChannelsBypassingDnd_noChannelsForUserIdBypassing()
1264 throws Exception {
1265 int user = 9;
1266 NotificationChannel channel = new NotificationChannel("id", "name",
1267 NotificationManager.IMPORTANCE_MAX);
1268 channel.setBypassDnd(true);
1269 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1270
1271 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1272 user).getList().size());
1273 }
1274
1275 @Test
1276 public void testGetChannelsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1277 int user = USER.getIdentifier();
1278 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1279 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1280 NotificationManager.IMPORTANCE_MAX);
1281 channel1.setBypassDnd(true);
1282 channel1.setGroup(ncg.getId());
1283 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1284 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1285
1286 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1287 user).getList().size());
1288
1289 // disable group
1290 ncg.setBlocked(true);
1291 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1292 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1293 user).getList().size());
1294 }
1295
1296 @Test
1297 public void testGetChannelsBypassingDndCount_multipleChannelsBypassing() {
1298 int user = USER.getIdentifier();
1299 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1300 NotificationManager.IMPORTANCE_MAX);
1301 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1302 NotificationManager.IMPORTANCE_MAX);
1303 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1304 NotificationManager.IMPORTANCE_MAX);
1305 channel1.setBypassDnd(true);
1306 channel2.setBypassDnd(true);
1307 channel3.setBypassDnd(true);
1308 // has DND access, so can set bypassDnd attribute
1309 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1310 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1311 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1312 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1313 user).getList().size());
1314
1315 // block notifications from this app
1316 mHelper.setEnabled(PKG_N_MR1, user, false);
1317 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1318 user).getList().size());
1319
1320 // re-enable notifications from this app
1321 mHelper.setEnabled(PKG_N_MR1, user, true);
1322 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1323 user).getList().size());
1324
1325 // setBypassDnd false for some channels
1326 channel1.setBypassDnd(false);
1327 channel2.setBypassDnd(false);
1328 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1329 user).getList().size());
1330
1331 // setBypassDnd false for rest of the channels
1332 channel3.setBypassDnd(false);
1333 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1334 user).getList().size());
1335 }
1336
1337 @Test
1338 public void testGetAppsBypassingDndCount_noAppsBypassing() throws Exception {
1339 assertEquals(0, mHelper.getAppsBypassingDndCount(USER.getIdentifier()));
1340 }
1341
1342 @Test
1343 public void testGetAppsBypassingDndCount_noAppsForUserIdBypassing() throws Exception {
1344 int user = 9;
1345 NotificationChannel channel = new NotificationChannel("id", "name",
1346 NotificationManager.IMPORTANCE_MAX);
1347 channel.setBypassDnd(true);
1348 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1349
1350 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1351 }
1352
1353 @Test
1354 public void testGetAppsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1355 int user = USER.getIdentifier();
1356 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1357 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1358 NotificationManager.IMPORTANCE_MAX);
1359 channel1.setBypassDnd(true);
1360 channel1.setGroup(ncg.getId());
1361 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1362 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1363
1364 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1365
1366 // disable group
1367 ncg.setBlocked(true);
1368 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1369 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1370 }
1371
1372 @Test
1373 public void testGetAppsBypassingDndCount_oneAppBypassing() {
1374 int user = USER.getIdentifier();
1375 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1376 NotificationManager.IMPORTANCE_MAX);
1377 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1378 NotificationManager.IMPORTANCE_MAX);
1379 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1380 NotificationManager.IMPORTANCE_MAX);
1381 channel1.setBypassDnd(true);
1382 channel2.setBypassDnd(true);
1383 channel3.setBypassDnd(true);
1384 // has DND access, so can set bypassDnd attribute
1385 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1386 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1387 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1388 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1389
1390 // block notifications from this app
1391 mHelper.setEnabled(PKG_N_MR1, user, false);
1392 assertEquals(0, mHelper.getAppsBypassingDndCount(user)); // no apps can bypass dnd
1393
1394 // re-enable notifications from this app
1395 mHelper.setEnabled(PKG_N_MR1, user, true);
1396 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1397
1398 // setBypassDnd false for some channels
1399 channel1.setBypassDnd(false);
1400 channel2.setBypassDnd(false);
1401 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1402
1403 // setBypassDnd false for rest of the channels
1404 channel3.setBypassDnd(false);
1405 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1406 }
1407
1408 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001409 public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception {
1410 // create notification channel that can't bypass dnd
1411 // expected result: areChannelsBypassingDnd = false
1412 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1413 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001414 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001415 assertFalse(mHelper.areChannelsBypassingDnd());
1416 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1417 resetZenModeHelper();
1418
1419 // create notification channel that can bypass dnd
1420 // expected result: areChannelsBypassingDnd = true
1421 NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1422 channel2.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001423 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001424 assertTrue(mHelper.areChannelsBypassingDnd());
1425 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1426 resetZenModeHelper();
1427
1428 // delete channels
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001429 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001430 assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
1431 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1432 resetZenModeHelper();
1433
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001434 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001435 assertFalse(mHelper.areChannelsBypassingDnd());
1436 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1437 resetZenModeHelper();
1438 }
1439
1440 @Test
1441 public void testUpdateCanChannelsBypassDnd() throws Exception {
1442 // create notification channel that can't bypass dnd
1443 // expected result: areChannelsBypassingDnd = false
1444 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1445 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001446 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001447 assertFalse(mHelper.areChannelsBypassingDnd());
1448 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1449 resetZenModeHelper();
1450
1451 // update channel so it CAN bypass dnd:
1452 // expected result: areChannelsBypassingDnd = true
1453 channel.setBypassDnd(true);
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 assertTrue(mHelper.areChannelsBypassingDnd());
1456 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1457 resetZenModeHelper();
1458
1459 // update channel so it can't bypass dnd:
1460 // expected result: areChannelsBypassingDnd = false
1461 channel.setBypassDnd(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001462 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001463 assertFalse(mHelper.areChannelsBypassingDnd());
1464 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1465 resetZenModeHelper();
1466 }
1467
1468 @Test
1469 public void testSetupNewZenModeHelper_canBypass() {
1470 // start notification policy off with mAreChannelsBypassingDnd = true, but
1471 // RankingHelper should change to false
1472 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
Julia Reynolds24edc002020-01-29 16:35:32 -05001473 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001474 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Mady Mellorc888d512020-04-09 14:48:02 -07001475 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
1476 mAppOpsManager);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001477 assertFalse(mHelper.areChannelsBypassingDnd());
1478 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1479 resetZenModeHelper();
1480 }
1481
1482 @Test
1483 public void testSetupNewZenModeHelper_cannotBypass() {
1484 // start notification policy off with mAreChannelsBypassingDnd = false
Julia Reynolds24edc002020-01-29 16:35:32 -05001485 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001486 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Mady Mellorc888d512020-04-09 14:48:02 -07001487 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
1488 mAppOpsManager);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001489 assertFalse(mHelper.areChannelsBypassingDnd());
1490 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1491 resetZenModeHelper();
1492 }
1493
1494 @Test
1495 public void testCreateDeletedChannel() throws Exception {
1496 long[] vibration = new long[]{100, 67, 145, 156};
1497 NotificationChannel channel =
1498 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1499 channel.setVibrationPattern(vibration);
1500
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001501 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1502 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001503
1504 NotificationChannel newChannel = new NotificationChannel(
1505 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1506 newChannel.setVibrationPattern(new long[]{100});
1507
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001508 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001509
1510 // No long deleted, using old settings
1511 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001512 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001513 }
1514
1515 @Test
1516 public void testOnlyHasDefaultChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001517 assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
1518 assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001519
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001520 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1521 assertFalse(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001522 }
1523
1524 @Test
1525 public void testCreateChannel_defaultChannelId() throws Exception {
1526 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001527 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, new NotificationChannel(
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001528 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
1529 fail("Allowed to create default channel");
1530 } catch (IllegalArgumentException e) {
1531 // pass
1532 }
1533 }
1534
1535 @Test
1536 public void testCreateChannel_alreadyExists() throws Exception {
1537 long[] vibration = new long[]{100, 67, 145, 156};
1538 NotificationChannel channel =
1539 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1540 channel.setVibrationPattern(vibration);
1541
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001542 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001543
1544 NotificationChannel newChannel = new NotificationChannel(
1545 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1546 newChannel.setVibrationPattern(new long[]{100});
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001547 newChannel.setAllowBubbles(!channel.canBubble());
1548 newChannel.setLightColor(Color.BLUE);
1549 newChannel.setSound(Uri.EMPTY, null);
1550 newChannel.setShowBadge(!channel.canShowBadge());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001551
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001552 assertFalse(mHelper.createNotificationChannel(
1553 PKG_N_MR1, UID_N_MR1, newChannel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001554
1555 // Old settings not overridden
1556 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001557 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Will Brockman23db6d42020-02-28 09:51:12 -05001558
1559 assertEquals(1, mLogger.getCalls().size());
1560 assertEquals(
1561 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1562 mLogger.get(0).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001563 }
1564
1565 @Test
1566 public void testCreateChannel_noOverrideSound() throws Exception {
1567 Uri sound = new Uri.Builder().scheme("test").build();
1568 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1569 NotificationManager.IMPORTANCE_DEFAULT);
1570 channel.setSound(sound, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001571 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001572 assertEquals(sound, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001573 PKG_N_MR1, UID_N_MR1, channel.getId(), false).getSound());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001574 }
1575
1576 @Test
1577 public void testPermanentlyDeleteChannels() throws Exception {
1578 NotificationChannel channel1 =
1579 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1580 NotificationChannel channel2 =
1581 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1582
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001583 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1584 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001585
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001586 mHelper.permanentlyDeleteNotificationChannels(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001587
1588 // Only default channel remains
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001589 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001590 }
1591
1592 @Test
1593 public void testDeleteGroup() throws Exception {
1594 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1595 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1596 NotificationChannel nonGroupedNonDeletedChannel =
1597 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1598 NotificationChannel groupedButNotDeleted =
1599 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1600 groupedButNotDeleted.setGroup("not");
1601 NotificationChannel groupedAndDeleted =
1602 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1603 groupedAndDeleted.setGroup("totally");
1604
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001605 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
1606 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001607 mHelper.createNotificationChannel(
1608 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001609 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false);
1610 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001611
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001612 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001613
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001614 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001615 assertNotNull(
1616 mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001617
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001618 assertNull(mHelper.getNotificationChannel(
1619 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), false));
1620 compareChannels(groupedAndDeleted, mHelper.getNotificationChannel(
1621 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001622
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001623 compareChannels(groupedButNotDeleted, mHelper.getNotificationChannel(
1624 PKG_N_MR1, UID_N_MR1, groupedButNotDeleted.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001625 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001626 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001627
1628 // notDeleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001629 assertEquals(1, mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001630
1631 verify(mHandler, never()).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001632
1633 assertEquals(7, mLogger.getCalls().size());
1634 assertEquals(
1635 NotificationChannelLogger.NotificationChannelEvent
1636 .NOTIFICATION_CHANNEL_GROUP_DELETED,
1637 mLogger.get(5).event); // Next-to-last log is the deletion of the channel group.
1638 assertEquals(
1639 NotificationChannelLogger.NotificationChannelEvent
1640 .NOTIFICATION_CHANNEL_DELETED,
1641 mLogger.get(6).event); // Final log is the deletion of the channel.
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001642 }
1643
1644 @Test
1645 public void testOnUserRemoved() throws Exception {
1646 int[] user0Uids = {98, 235, 16, 3782};
1647 int[] user1Uids = new int[user0Uids.length];
1648 for (int i = 0; i < user0Uids.length; i++) {
1649 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1650
1651 final ApplicationInfo legacy = new ApplicationInfo();
1652 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001653 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001654
1655 // create records with the default channel for all user 0 and user 1 uids
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001656 mHelper.getImportance(PKG_N_MR1, user0Uids[i]);
1657 mHelper.getImportance(PKG_N_MR1, user1Uids[i]);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001658 }
1659
1660 mHelper.onUserRemoved(1);
1661
1662 // user 0 records remain
1663 for (int i = 0; i < user0Uids.length; i++) {
1664 assertEquals(1,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001665 mHelper.getNotificationChannels(PKG_N_MR1, user0Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001666 }
1667 // user 1 records are gone
1668 for (int i = 0; i < user1Uids.length; i++) {
1669 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001670 mHelper.getNotificationChannels(PKG_N_MR1, user1Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001671 }
1672 }
1673
1674 @Test
1675 public void testOnPackageChanged_packageRemoval() throws Exception {
1676 // Deleted
1677 NotificationChannel channel1 =
1678 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001679 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001680
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001681 assertTrue(mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1},
1682 new int[]{UID_N_MR1}));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001683
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001684 assertEquals(0, mHelper.getNotificationChannels(
1685 PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001686
1687 // Not deleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001688 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001689
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001690 assertFalse(mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM,
1691 new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001692 assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001693 }
1694
1695 @Test
1696 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001697 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001698
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001699 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1700 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001701
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001702 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1703 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001704 }
1705
1706 @Test
1707 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1708 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001709 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001710 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001711 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001712
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001713 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1714 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001715
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001716 assertEquals(0, mHelper.getNotificationChannelGroups(
1717 PKG_N_MR1, UID_N_MR1, true, true, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001718 }
1719
1720 @Test
1721 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1722 // create channel as api 26
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001723 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001724
1725 // install new app version targeting 25
1726 final ApplicationInfo legacy = new ApplicationInfo();
1727 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001728 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001729 mHelper.onPackagesChanged(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001730 false, UserHandle.USER_SYSTEM, new String[]{PKG_O}, new int[]{UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001731
1732 // make sure the default channel was readded
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001733 //assertEquals(2, mHelper.getNotificationChannels(PKG_O, UID_O, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001734 assertNotNull(mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001735 PKG_O, UID_O, NotificationChannel.DEFAULT_CHANNEL_ID, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001736 }
1737
1738 @Test
Julia Reynolds7af51c52019-04-19 11:08:27 -04001739 public void testClearData() {
1740 ArraySet<String> pkg = new ArraySet<>();
1741 pkg.add(PKG_O);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001742 ArraySet<Pair<String, Integer>> pkgPair = new ArraySet<>();
1743 pkgPair.add(new Pair(PKG_O, UID_O));
Julia Reynolds7af51c52019-04-19 11:08:27 -04001744 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
1745 mHelper.createNotificationChannelGroup(
1746 PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
1747 mHelper.lockChannelsForOEM(pkg.toArray(new String[]{}));
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001748 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001749 mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
1750 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
Mady Mellora92268c2020-03-09 17:25:08 -07001751 mHelper.setBubblesAllowed(PKG_O, UID_O, DEFAULT_BUBBLE_PREFERENCE);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001752 mHelper.setShowBadge(PKG_O, UID_O, false);
1753 mHelper.setAppImportanceLocked(PKG_O, UID_O);
1754
1755 mHelper.clearData(PKG_O, UID_O);
1756
1757 assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, UID_O));
Mady Mellora92268c2020-03-09 17:25:08 -07001758 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), DEFAULT_BUBBLE_PREFERENCE);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001759 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
1760 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
1761 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
1762 assertEquals(0, mHelper.getNotificationChannels(PKG_O, UID_O, true).getList().size());
1763 assertEquals(0, mHelper.getNotificationChannelGroups(PKG_O, UID_O).size());
1764
1765 NotificationChannel channel = getChannel();
1766 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
1767
1768 assertTrue(channel.isImportanceLockedByCriticalDeviceFunction());
1769 assertTrue(channel.isImportanceLockedByOEM());
1770 }
1771
1772 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001773 public void testRecordDefaults() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001774 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1775 UID_N_MR1));
1776 assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
1777 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001778 }
1779
1780 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001781 public void testCreateGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001782 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001783 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001784 assertEquals(ncg,
1785 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).iterator().next());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001786 verify(mHandler, never()).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001787 assertEquals(1, mLogger.getCalls().size());
1788 assertEquals(
1789 NotificationChannelLogger.NotificationChannelEvent
1790 .NOTIFICATION_CHANNEL_GROUP_CREATED,
1791 mLogger.get(0).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001792 }
1793
1794 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001795 public void testCannotCreateChannel_badGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001796 NotificationChannel channel1 =
1797 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1798 channel1.setGroup("garbage");
1799 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001800 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001801 fail("Created a channel with a bad group");
1802 } catch (IllegalArgumentException e) {
1803 }
Will Brockman23db6d42020-02-28 09:51:12 -05001804 assertEquals(0, mLogger.getCalls().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001805 }
1806
1807 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001808 public void testCannotCreateChannel_goodGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001809 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001810 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001811 NotificationChannel channel1 =
1812 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1813 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001814 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001815
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001816 assertEquals(ncg.getId(), mHelper.getNotificationChannel(
1817 PKG_N_MR1, UID_N_MR1, channel1.getId(), false).getGroup());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001818 }
1819
1820 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001821 public void testGetChannelGroups() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001822 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001823 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001824 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001825 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001826 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001827 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001828
1829 NotificationChannel channel1 =
1830 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1831 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001832 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001833 NotificationChannel channel1a =
1834 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1835 channel1a.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001836 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001837
1838 NotificationChannel channel2 =
1839 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1840 channel2.setGroup(ncg2.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001841 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001842
1843 NotificationChannel channel3 =
1844 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001845 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001846
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001847 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1848 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001849 assertEquals(3, actual.size());
1850 for (NotificationChannelGroup group : actual) {
1851 if (group.getId() == null) {
1852 assertEquals(2, group.getChannels().size()); // misc channel too
1853 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1854 || channel3.getId().equals(group.getChannels().get(1).getId()));
1855 } else if (group.getId().equals(ncg.getId())) {
1856 assertEquals(2, group.getChannels().size());
1857 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1858 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1859 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1860 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1861 } else {
1862 fail("expected channel not found");
1863 }
1864 } else if (group.getId().equals(ncg2.getId())) {
1865 assertEquals(1, group.getChannels().size());
1866 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1867 }
1868 }
1869 }
1870
1871 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001872 public void testGetChannelGroups_noSideEffects() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001873 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001874 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001875
1876 NotificationChannel channel1 =
1877 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1878 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001879 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001880 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001881
1882 channel1.setImportance(IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001883 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001884
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001885 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1886 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001887
1888 assertEquals(2, actual.size());
1889 for (NotificationChannelGroup group : actual) {
1890 if (Objects.equals(group.getId(), ncg.getId())) {
1891 assertEquals(1, group.getChannels().size());
1892 }
1893 }
1894 }
1895
1896 @Test
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001897 public void testGetChannelGroups_includeEmptyGroups() {
1898 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1899 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
1900 NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
1901 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true);
1902
1903 NotificationChannel channel1 =
1904 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1905 channel1.setGroup(ncg.getId());
1906 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1907
1908 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1909 PKG_N_MR1, UID_N_MR1, false, false, true).getList();
1910
1911 assertEquals(2, actual.size());
1912 for (NotificationChannelGroup group : actual) {
1913 if (Objects.equals(group.getId(), ncg.getId())) {
1914 assertEquals(1, group.getChannels().size());
1915 }
1916 if (Objects.equals(group.getId(), ncgEmpty.getId())) {
1917 assertEquals(0, group.getChannels().size());
1918 }
1919 }
1920 }
1921
1922 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001923 public void testCreateChannel_updateName() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001924 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001925 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001926 NotificationChannel actual =
1927 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001928 assertEquals("hello", actual.getName());
1929
1930 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001931 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001932
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001933 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001934 assertEquals("goodbye", actual.getName());
1935 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1936
1937 verify(mHandler, times(1)).requestSort();
1938 }
1939
1940 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001941 public void testCreateChannel_addToGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001942 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001943 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001944 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001945 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001946 NotificationChannel actual =
1947 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001948 assertNull(actual.getGroup());
1949
1950 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1951 nc.setGroup(group.getId());
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001952 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001953
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001954 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001955 assertNotNull(actual.getGroup());
1956 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1957
1958 verify(mHandler, times(1)).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001959 assertEquals(3, mLogger.getCalls().size());
1960 assertEquals(
1961 NotificationChannelLogger.NotificationChannelEvent
1962 .NOTIFICATION_CHANNEL_GROUP_CREATED,
1963 mLogger.get(0).event);
1964 assertEquals(
1965 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1966 mLogger.get(1).event);
1967 assertEquals(
1968 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED,
1969 mLogger.get(2).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001970 }
1971
1972 @Test
1973 public void testDumpChannelsJson() throws Exception {
1974 final ApplicationInfo upgrade = new ApplicationInfo();
1975 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
1976 try {
1977 when(mPm.getApplicationInfoAsUser(
1978 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
1979 } catch (PackageManager.NameNotFoundException e) {
1980 }
1981 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
1982 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
1983 for (int i = 0; i < numPackages; i++) {
1984 String pkgName = "pkg" + i;
1985 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
1986 for (int j = 0; j < numChannels; j++) {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001987 mHelper.createNotificationChannel(pkgName, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001988 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
1989 }
1990 expectedChannels.put(pkgName, numChannels);
1991 }
1992
1993 // delete the first channel of the first package
1994 String pkg = expectedChannels.keyAt(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001995 mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001996 // dump should not include deleted channels
1997 int count = expectedChannels.get(pkg);
1998 expectedChannels.put(pkg, count - 1);
1999
2000 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
2001 assertEquals(numPackages, actual.length());
2002 for (int i = 0; i < numPackages; i++) {
2003 JSONObject object = actual.getJSONObject(i);
2004 assertTrue(expectedChannels.containsKey(object.get("packageName")));
2005 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
2006 object.getInt("channelCount"));
2007 }
2008 }
2009
2010 @Test
2011 public void testBadgingOverrideTrue() throws Exception {
2012 Secure.putIntForUser(getContext().getContentResolver(),
2013 Secure.NOTIFICATION_BADGING, 1,
2014 USER.getIdentifier());
2015 mHelper.updateBadgingEnabled(); // would be called by settings observer
2016 assertTrue(mHelper.badgingEnabled(USER));
2017 }
2018
2019 @Test
2020 public void testBadgingOverrideFalse() throws Exception {
2021 Secure.putIntForUser(getContext().getContentResolver(),
2022 Secure.NOTIFICATION_BADGING, 0,
2023 USER.getIdentifier());
2024 mHelper.updateBadgingEnabled(); // would be called by settings observer
2025 assertFalse(mHelper.badgingEnabled(USER));
2026 }
2027
2028 @Test
2029 public void testBadgingForUserAll() throws Exception {
2030 try {
2031 mHelper.badgingEnabled(UserHandle.ALL);
2032 } catch (Exception e) {
2033 fail("just don't throw");
2034 }
2035 }
2036
2037 @Test
2038 public void testBadgingOverrideUserIsolation() throws Exception {
2039 Secure.putIntForUser(getContext().getContentResolver(),
2040 Secure.NOTIFICATION_BADGING, 0,
2041 USER.getIdentifier());
2042 Secure.putIntForUser(getContext().getContentResolver(),
2043 Secure.NOTIFICATION_BADGING, 1,
2044 USER2.getIdentifier());
2045 mHelper.updateBadgingEnabled(); // would be called by settings observer
2046 assertFalse(mHelper.badgingEnabled(USER));
2047 assertTrue(mHelper.badgingEnabled(USER2));
2048 }
2049
2050 @Test
Julia Reynolds4509ce72019-01-31 13:12:43 -05002051 public void testBubblesOverrideTrue() {
Lyn Han4463f842019-07-09 15:27:28 -07002052 Global.putInt(getContext().getContentResolver(),
2053 Global.NOTIFICATION_BUBBLES, 1);
Julia Reynolds4509ce72019-01-31 13:12:43 -05002054 mHelper.updateBubblesEnabled(); // would be called by settings observer
Lyn Han4463f842019-07-09 15:27:28 -07002055 assertTrue(mHelper.bubblesEnabled());
Julia Reynolds4509ce72019-01-31 13:12:43 -05002056 }
2057
2058 @Test
2059 public void testBubblesOverrideFalse() {
Lyn Han4463f842019-07-09 15:27:28 -07002060 Global.putInt(getContext().getContentResolver(),
2061 Global.NOTIFICATION_BUBBLES, 0);
Julia Reynolds4509ce72019-01-31 13:12:43 -05002062 mHelper.updateBubblesEnabled(); // would be called by settings observer
Lyn Han4463f842019-07-09 15:27:28 -07002063 assertFalse(mHelper.bubblesEnabled());
Julia Reynolds4509ce72019-01-31 13:12:43 -05002064 }
2065
2066 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002067 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
2068 String newLabel = "bananas!";
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002069 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
2070 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002071 NotificationChannel.DEFAULT_CHANNEL_ID, false);
2072 assertFalse(newLabel.equals(defaultChannel.getName()));
2073
2074 Resources res = mock(Resources.class);
2075 when(mContext.getResources()).thenReturn(res);
2076 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
2077 .thenReturn(newLabel);
2078
2079 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
2080
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002081 assertEquals(newLabel, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002082 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
2083 }
2084
2085 @Test
2086 public void testIsGroupBlocked_noGroup() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002087 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, null));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002088
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002089 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, "non existent group"));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002090 }
2091
2092 @Test
2093 public void testIsGroupBlocked_notBlocked() throws Exception {
2094 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002095 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002096
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002097 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002098 }
2099
2100 @Test
2101 public void testIsGroupBlocked_blocked() 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 group.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002105 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002106
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002107 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002108 }
2109
2110 @Test
2111 public void testIsGroup_appCannotResetBlock() throws Exception {
2112 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002113 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002114 NotificationChannelGroup group2 = group.clone();
2115 group2.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002116 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false);
2117 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002118
2119 NotificationChannelGroup group3 = group.clone();
2120 group3.setBlocked(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002121 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
2122 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002123 }
2124
2125 @Test
2126 public void testGetNotificationChannelGroupWithChannels() throws Exception {
2127 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
2128 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002129 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
2130 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002131
2132 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
2133 a.setGroup(group.getId());
2134 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
2135 b.setGroup(other.getId());
2136 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2137 c.setGroup(group.getId());
2138 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
2139
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002140 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false);
2141 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false);
2142 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false);
2143 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false);
2144 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002145
2146 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002147 PKG_N_MR1, UID_N_MR1, group.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002148 assertEquals(2, retrieved.getChannels().size());
2149 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2150 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
2151
2152 retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002153 PKG_N_MR1, UID_N_MR1, group.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002154 assertEquals(1, retrieved.getChannels().size());
2155 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2156 }
2157
2158 @Test
2159 public void testAndroidPkgCannotBypassDnd_creation() {
2160 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2161 test.setBypassDnd(true);
2162
2163 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2164
2165 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2166 .canBypassDnd());
2167 }
2168
2169 @Test
2170 public void testDndPkgCanBypassDnd_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, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002175
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002176 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002177 }
2178
2179 @Test
2180 public void testNormalPkgCannotBypassDnd_creation() {
2181 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2182 test.setBypassDnd(true);
2183
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002184 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002185
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002186 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002187 }
2188
2189 @Test
2190 public void testAndroidPkgCannotBypassDnd_update() throws Exception {
2191 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2192 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2193
2194 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2195 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002196 assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002197
2198 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2199 .canBypassDnd());
2200 }
2201
2202 @Test
2203 public void testDndPkgCanBypassDnd_update() throws Exception {
2204 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002205 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002206
2207 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2208 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002209 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002210
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002211 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002212 }
2213
2214 @Test
2215 public void testNormalPkgCannotBypassDnd_update() {
2216 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002217 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002218 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2219 update.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002220 mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false);
2221 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002222 }
2223
2224 @Test
2225 public void testGetBlockedAppCount_noApps() {
2226 assertEquals(0, mHelper.getBlockedAppCount(0));
2227 }
2228
2229 @Test
2230 public void testGetBlockedAppCount_noAppsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002231 mHelper.setEnabled(PKG_N_MR1, 100, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002232 assertEquals(0, mHelper.getBlockedAppCount(9));
2233 }
2234
2235 @Test
2236 public void testGetBlockedAppCount_appsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002237 mHelper.setEnabled(PKG_N_MR1, 1020, false);
2238 mHelper.setEnabled(PKG_N_MR1, 1030, false);
2239 mHelper.setEnabled(PKG_N_MR1, 1060, false);
2240 mHelper.setEnabled(PKG_N_MR1, 1000, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002241 assertEquals(3, mHelper.getBlockedAppCount(0));
2242 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002243
2244 @Test
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002245 public void testXml_statusBarIcons_default() throws Exception {
Julia Reynolds2594b472019-04-03 13:30:16 -04002246 String preQXml = "<ranking version=\"1\">\n"
2247 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
2248 + "<channel id=\"something\" name=\"name\" importance=\"2\" "
2249 + "show_badge=\"true\" />\n"
2250 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
2251 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
2252 + "</package>\n"
2253 + "</ranking>\n";
Mady Mellorc888d512020-04-09 14:48:02 -07002254 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2255 mAppOpsManager);
Julia Reynolds2594b472019-04-03 13:30:16 -04002256 loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002257
2258 assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2259 mHelper.shouldHideSilentStatusIcons());
2260 }
2261
2262 @Test
2263 public void testXml_statusBarIcons() throws Exception {
2264 mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
2265
Annie Meng8b646fd2019-02-01 18:46:42 +00002266 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002267 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2268 mAppOpsManager);
Annie Meng8b646fd2019-02-01 18:46:42 +00002269 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002270
2271 assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2272 mHelper.shouldHideSilentStatusIcons());
2273 }
2274
2275 @Test
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002276 public void testSetNotificationDelegate() {
2277 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2278 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2279 }
2280
2281 @Test
2282 public void testRevokeNotificationDelegate() {
2283 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2284 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2285
2286 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2287 }
2288
2289 @Test
2290 public void testRevokeNotificationDelegate_noDelegateExistsNoCrash() {
2291 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2292
2293 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2294 }
2295
2296 @Test
2297 public void testToggleNotificationDelegate() {
2298 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2299 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2300
2301 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2302
2303 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2304 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2305 }
2306
2307 @Test
2308 public void testToggleNotificationDelegate_noDelegateExistsNoCrash() {
2309 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2310 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2311
2312 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2313 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2314 }
2315
2316 @Test
2317 public void testIsDelegateAllowed_noSource() {
2318 assertFalse(mHelper.isDelegateAllowed("does not exist", -1, "whatever", 0));
2319 }
2320
2321 @Test
2322 public void testIsDelegateAllowed_noDelegate() {
2323 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2324
2325 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "whatever", 0));
2326 }
2327
2328 @Test
2329 public void testIsDelegateAllowed_delegateDisabledByApp() {
2330 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2331 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2332
2333 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2334 }
2335
2336 @Test
2337 public void testIsDelegateAllowed_wrongDelegate() {
2338 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2339 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2340
2341 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "banana", 27));
2342 }
2343
2344 @Test
2345 public void testIsDelegateAllowed_delegateDisabledByUser() {
2346 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2347 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2348
2349 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2350 }
2351
2352 @Test
2353 public void testIsDelegateAllowed() {
2354 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2355
2356 assertTrue(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2357 }
2358
2359 @Test
2360 public void testDelegateXml_noDelegate() throws Exception {
2361 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2362
Annie Meng8b646fd2019-02-01 18:46:42 +00002363 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002364 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2365 mAppOpsManager);
Annie Meng8b646fd2019-02-01 18:46:42 +00002366 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002367
2368 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2369 }
2370
2371 @Test
2372 public void testDelegateXml_delegate() throws Exception {
2373 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2374
Annie Meng8b646fd2019-02-01 18:46:42 +00002375 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002376 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2377 mAppOpsManager);
Annie Meng8b646fd2019-02-01 18:46:42 +00002378 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002379
2380 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2381 }
2382
2383 @Test
2384 public void testDelegateXml_disabledDelegate() throws Exception {
2385 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2386 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2387
Annie Meng8b646fd2019-02-01 18:46:42 +00002388 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002389 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2390 mAppOpsManager);
Annie Meng8b646fd2019-02-01 18:46:42 +00002391 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002392
2393 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2394 }
2395
2396 @Test
2397 public void testDelegateXml_userDisabledDelegate() throws Exception {
2398 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2399 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2400
Annie Meng8b646fd2019-02-01 18:46:42 +00002401 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002402 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2403 mAppOpsManager);
Annie Meng8b646fd2019-02-01 18:46:42 +00002404 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002405
2406 // appears disabled
2407 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2408
2409 // but was loaded and can be toggled back on
2410 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2411 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2412 }
2413
2414 @Test
2415 public void testDelegateXml_entirelyDisabledDelegate() throws Exception {
2416 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2417 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2418 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2419
Annie Meng8b646fd2019-02-01 18:46:42 +00002420 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002421 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2422 mAppOpsManager);
Annie Meng8b646fd2019-02-01 18:46:42 +00002423 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002424
2425 // appears disabled
2426 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2427
2428 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2429 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2430
2431 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2432 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2433 }
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002434
2435 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002436 public void testBubblePreference_defaults() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07002437 assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002438
Annie Meng8b646fd2019-02-01 18:46:42 +00002439 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002440 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2441 mAppOpsManager);
Annie Meng8b646fd2019-02-01 18:46:42 +00002442 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002443
Mady Mellorc888d512020-04-09 14:48:02 -07002444 assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002445 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2446 }
2447
2448 @Test
Mady Mellorc888d512020-04-09 14:48:02 -07002449 public void testBubblePreference_upgradeWithSAWPermission() throws Exception {
2450 when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
2451 anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);
2452
2453 final String xml = "<ranking version=\"1\">\n"
2454 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
2455 + "<channel id=\"someId\" name=\"hi\""
2456 + " importance=\"3\"/>"
2457 + "</package>"
2458 + "</ranking>";
2459 XmlPullParser parser = Xml.newPullParser();
2460 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2461 null);
2462 parser.nextTag();
2463 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2464
2465 assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
2466 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2467 }
2468
2469 @Test
2470 public void testBubblePreference_upgradeWithSAWThenUserOverride() throws Exception {
2471 when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
2472 anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);
2473
2474 final String xml = "<ranking version=\"1\">\n"
2475 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
2476 + "<channel id=\"someId\" name=\"hi\""
2477 + " importance=\"3\"/>"
2478 + "</package>"
2479 + "</ranking>";
2480 XmlPullParser parser = Xml.newPullParser();
2481 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2482 null);
2483 parser.nextTag();
2484 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2485
2486 assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
2487 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2488
2489 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
2490 assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
2491 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
2492 mHelper.getAppLockedFields(PKG_O, UID_O));
2493
2494 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
2495 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2496 mAppOpsManager);
2497 loadStreamXml(baos, false, UserHandle.USER_ALL);
2498
2499 assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
2500 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
2501 mHelper.getAppLockedFields(PKG_O, UID_O));
2502 }
2503
2504 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002505 public void testBubblePreference_xml() throws Exception {
2506 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
2507 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002508 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002509 mHelper.getAppLockedFields(PKG_O, UID_O));
2510
Annie Meng8b646fd2019-02-01 18:46:42 +00002511 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002512 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
2513 mAppOpsManager);
Annie Meng8b646fd2019-02-01 18:46:42 +00002514 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002515
Mady Mellora92268c2020-03-09 17:25:08 -07002516 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002517 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002518 mHelper.getAppLockedFields(PKG_O, UID_O));
2519 }
Julia Reynolds413ba842019-01-11 10:38:08 -05002520
2521 @Test
2522 public void testLockChannelsForOEM_emptyList() {
2523 mHelper.lockChannelsForOEM(null);
2524 mHelper.lockChannelsForOEM(new String[0]);
2525 // no exception
2526 }
2527
2528 @Test
2529 public void testLockChannelsForOEM_appWide() {
2530 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2531 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2532 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2533 // different uids, same package
2534 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2535 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2536 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2537
2538 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2539
2540 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2541 .isImportanceLockedByOEM());
2542 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2543 .isImportanceLockedByOEM());
2544 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2545 .isImportanceLockedByOEM());
2546 }
2547
2548 @Test
2549 public void testLockChannelsForOEM_onlyGivenPkg() {
2550 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2551 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2552 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2553 mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
2554
2555 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2556
2557 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2558 .isImportanceLockedByOEM());
2559 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
2560 .isImportanceLockedByOEM());
2561 }
2562
2563 @Test
2564 public void testLockChannelsForOEM_channelSpecific() {
2565 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2566 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2567 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2568 // different uids, same package
2569 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2570 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2571 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2572
2573 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
2574
2575 assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2576 .isImportanceLockedByOEM());
2577 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2578 .isImportanceLockedByOEM());
2579 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2580 .isImportanceLockedByOEM());
2581 }
2582
2583 @Test
Julia Reynolds72b28442019-11-12 11:43:39 -05002584 public void testLockChannelsForOEM_channelSpecific_clearData() {
2585 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2586 mHelper.getImportance(PKG_O, UID_O);
2587 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":" + a.getId()});
2588 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2589 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2590 .isImportanceLockedByOEM());
2591
2592 mHelper.clearData(PKG_O, UID_O);
2593
2594 // it's back!
2595 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2596 // and still locked
2597 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2598 .isImportanceLockedByOEM());
2599 }
2600
2601 @Test
Julia Reynolds413ba842019-01-11 10:38:08 -05002602 public void testLockChannelsForOEM_channelDoesNotExistYet_appWide() {
2603 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2604 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2605 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2606
2607 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2608
2609 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2610 .isImportanceLockedByOEM());
2611
2612 mHelper.createNotificationChannel(PKG_O, 3, b, true, false);
2613 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2614 .isImportanceLockedByOEM());
2615 }
2616
2617 @Test
2618 public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific() {
2619 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2620 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2621 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2622
2623 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"});
2624
2625 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2626 .isImportanceLockedByOEM());
2627
2628 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2629 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2630 .isImportanceLockedByOEM());
2631 }
2632
2633 @Test
2634 public void testUpdateNotificationChannel_oemLockedImportance() {
2635 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2636 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2637
2638 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2639
2640 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002641 update.setAllowBubbles(false);
Julia Reynolds413ba842019-01-11 10:38:08 -05002642
2643 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2644
2645 assertEquals(IMPORTANCE_HIGH,
2646 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2647 assertEquals(false,
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002648 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
Julia Reynolds413ba842019-01-11 10:38:08 -05002649
2650 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2651
2652 assertEquals(IMPORTANCE_HIGH,
2653 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2654 }
Julia Reynolds0c245002019-03-27 16:10:11 -04002655
2656 @Test
2657 public void testUpdateDefaultApps_add_multiUser() {
2658 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2659 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2660 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2661 // different uids, same package
2662 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2663 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2664 mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
2665
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002666 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2667 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002668 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2669
2670 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2671 .isImportanceLockedByCriticalDeviceFunction());
2672 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2673 .isImportanceLockedByCriticalDeviceFunction());
2674 assertFalse(mHelper.getNotificationChannel(
2675 PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false)
2676 .isImportanceLockedByCriticalDeviceFunction());
2677 }
2678
2679 @Test
2680 public void testUpdateDefaultApps_add_onlyGivenPkg() {
2681 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2682 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2683 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2684 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2685
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002686 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2687 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002688 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2689
Julia Reynolds0c245002019-03-27 16:10:11 -04002690 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2691 .isImportanceLockedByCriticalDeviceFunction());
2692 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2693 .isImportanceLockedByCriticalDeviceFunction());
2694 }
2695
2696 @Test
2697 public void testUpdateDefaultApps_remove() {
2698 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2699 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2700 // different uids, same package
2701 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2702 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2703
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002704 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2705 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002706 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2707
2708 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2709 .isImportanceLockedByCriticalDeviceFunction());
2710 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2711 .isImportanceLockedByCriticalDeviceFunction());
2712
2713 ArraySet<String> toRemove = new ArraySet<>();
2714 toRemove.add(PKG_O);
2715 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, null);
2716
2717 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2718 .isImportanceLockedByCriticalDeviceFunction());
2719 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2720 .isImportanceLockedByCriticalDeviceFunction());
2721 }
2722
2723 @Test
2724 public void testUpdateDefaultApps_addAndRemove() {
2725 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2726 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2727 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2728 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2729
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002730 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2731 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002732 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2733
2734
2735 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2736 .isImportanceLockedByCriticalDeviceFunction());
2737 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2738 .isImportanceLockedByCriticalDeviceFunction());
2739
2740 // now the default is PKG_N_MR1
2741 ArraySet<String> toRemove = new ArraySet<>();
2742 toRemove.add(PKG_O);
2743 toAdd = new ArraySet<>();
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002744 toAdd.add(new Pair(PKG_N_MR1, UID_N_MR1));
Julia Reynolds0c245002019-03-27 16:10:11 -04002745 mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd);
2746
2747 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2748 .isImportanceLockedByCriticalDeviceFunction());
2749 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2750 .isImportanceLockedByCriticalDeviceFunction());
2751 }
2752
2753 @Test
2754 public void testUpdateDefaultApps_appDoesNotExist_noCrash() {
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002755 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2756 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002757 ArraySet<String> toRemove = new ArraySet<>();
2758 toRemove.add(PKG_N_MR1);
2759 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd);
2760 }
2761
2762 @Test
2763 public void testUpdateDefaultApps_channelDoesNotExistYet() {
2764 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2765 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2766 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2767
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002768 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2769 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002770 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2771
2772 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2773 .isImportanceLockedByCriticalDeviceFunction());
2774
2775 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2776 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2777 .isImportanceLockedByCriticalDeviceFunction());
2778 }
2779
2780 @Test
2781 public void testUpdateNotificationChannel_defaultAppLockedImportance() {
2782 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2783 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002784 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2785 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002786 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2787
2788 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
2789 update.setAllowBubbles(false);
2790
2791 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
Julia Reynolds0c245002019-03-27 16:10:11 -04002792 assertEquals(IMPORTANCE_HIGH,
2793 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2794 assertEquals(false,
2795 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
2796
2797 mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
Julia Reynolds0c245002019-03-27 16:10:11 -04002798 assertEquals(IMPORTANCE_HIGH,
2799 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Beverly47679222019-05-16 15:46:11 -04002800
2801 NotificationChannel updateImportanceLow = new NotificationChannel("a", "a",
2802 IMPORTANCE_LOW);
2803 mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true);
2804 assertEquals(IMPORTANCE_LOW,
2805 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Julia Reynolds0c245002019-03-27 16:10:11 -04002806 }
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002807
2808 @Test
2809 public void testDefaultApp_appHasNoSettingsYet() {
2810 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2811 toAdd.add(new Pair(PKG_O, UID_O));
2812 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2813
2814 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2815 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2816
2817 assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
2818 }
2819
2820 @Test
2821 public void testChannelXml_backupDefaultApp() throws Exception {
2822 NotificationChannel channel1 =
2823 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
2824
2825 mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
2826
2827 // clear data
2828 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
2829 UserHandle.USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
2830 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_O}, new int[]{
2831 UID_O});
2832
2833 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2834 toAdd.add(new Pair(PKG_O, UID_O));
2835 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2836
2837 XmlPullParser parser = Xml.newPullParser();
2838 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
2839 null);
2840 parser.nextTag();
2841 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
2842
2843 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, channel1.getId(), false)
2844 .isImportanceLockedByCriticalDeviceFunction());
2845 }
Mady Mellor9f296142019-05-24 09:42:52 -07002846
2847 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002848 public void testSetBubblesAllowed_none() {
2849 // Change it to non-default first
2850 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL);
2851 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL);
2852 verify(mHandler, times(1)).requestSort();
2853 reset(mHandler);
2854 // Now test
2855 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
2856 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
2857 verify(mHandler, times(1)).requestSort();
2858 }
2859
2860 @Test
2861 public void testSetBubblesAllowed_all() {
2862 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL);
2863 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL);
2864 verify(mHandler, times(1)).requestSort();
2865 }
2866
2867 @Test
2868 public void testSetBubblesAllowed_selected() {
2869 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
2870 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_SELECTED);
Mady Mellor9f296142019-05-24 09:42:52 -07002871 verify(mHandler, times(1)).requestSort();
2872 }
Julia Reynoldsc29370a2019-08-20 16:08:42 -04002873
2874 @Test
2875 public void testTooManyChannels() {
2876 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2877 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2878 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2879 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2880 }
2881 try {
2882 NotificationChannel channel = new NotificationChannel(
2883 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2884 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2885 NotificationManager.IMPORTANCE_HIGH);
2886 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2887 fail("Allowed to create too many notification channels");
2888 } catch (IllegalStateException e) {
2889 // great
2890 }
2891 }
2892
2893 @Test
2894 public void testTooManyChannels_xml() throws Exception {
2895 String extraChannel = "EXTRA";
2896 String extraChannel1 = "EXTRA1";
2897
2898 // create first... many... directly so we don't need a big xml blob in this test
2899 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2900 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2901 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2902 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2903 }
2904
2905 final String xml = "<ranking version=\"1\">\n"
2906 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
2907 + "<channel id=\"" + extraChannel + "\" name=\"hi\" importance=\"3\"/>"
2908 + "<channel id=\"" + extraChannel1 + "\" name=\"hi\" importance=\"3\"/>"
2909 + "</package>"
2910 + "</ranking>";
2911 XmlPullParser parser = Xml.newPullParser();
2912 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2913 null);
2914 parser.nextTag();
2915 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2916
2917 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true));
2918 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true));
2919 }
Julia Reynoldsdb34c1b2019-11-08 10:58:15 -05002920
2921 @Test
2922 public void testRestoreMultiUser() throws Exception {
2923 String pkg = "restore_pkg";
2924 String channelId = "channelId";
2925 int user0Importance = 3;
2926 int user10Importance = 4;
2927 when(mPm.getPackageUidAsUser(eq(pkg), anyInt())).thenReturn(UserHandle.USER_NULL);
2928
2929 // both users have the same package, but different notification settings
2930 final String xmlUser0 = "<ranking version=\"1\">\n"
2931 + "<package name=\"" + pkg + "\" >\n"
2932 + "<channel id=\"" + channelId + "\" name=\"hi\""
2933 + " importance=\"" + user0Importance + "\"/>"
2934 + "</package>"
2935 + "</ranking>";
2936 final String xmlUser10 = "<ranking version=\"1\">\n"
2937 + "<package name=\"" + pkg + "\" >\n"
2938 + "<channel id=\"" + channelId + "\" name=\"hi\""
2939 + " importance=\"" + user10Importance + "\"/>"
2940 + "</package>"
2941 + "</ranking>";
2942
2943 // trigger a restore for both users
2944 XmlPullParser parser = Xml.newPullParser();
2945 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser0.getBytes())),
2946 null);
2947 parser.nextTag();
2948 mHelper.readXml(parser, true, 0);
2949 parser = Xml.newPullParser();
2950 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser10.getBytes())),
2951 null);
2952 parser.nextTag();
2953 mHelper.readXml(parser, true, 10);
2954
2955 // "install" package on both users
2956 String[] pkgList = new String[] {pkg};
2957 int[] uidList0 = new int[] {UserHandle.PER_USER_RANGE};
2958 int[] uidList10 = new int[] {UserHandle.PER_USER_RANGE + 1};
2959 when(mPm.getPackageUidAsUser(pkg, 0)).thenReturn(uidList0[0]);
2960 when(mPm.getPackageUidAsUser(pkg, 10)).thenReturn(uidList10[0]);
2961 ApplicationInfo info = new ApplicationInfo();
2962 info.targetSdkVersion = Build.VERSION_CODES.Q;
2963 when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(info);
2964
2965 mHelper.onPackagesChanged(false, 0, pkgList, uidList0);
2966 mHelper.onPackagesChanged(false, 10, pkgList, uidList10);
2967
2968 assertEquals(user0Importance,
2969 mHelper.getNotificationChannel(pkg, uidList0[0], channelId, false).getImportance());
2970 assertEquals(user10Importance, mHelper.getNotificationChannel(
2971 pkg, uidList10[0], channelId, false).getImportance());
2972 }
Julia Reynolds0f767342019-12-18 09:11:55 -05002973
2974 @Test
2975 public void testGetConversationNotificationChannel() {
2976 String conversationId = "friend";
2977
2978 NotificationChannel parent =
2979 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
2980 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
2981
2982 NotificationChannel friend = new NotificationChannel(String.format(
2983 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId),
2984 "messages", IMPORTANCE_DEFAULT);
2985 friend.setConversationId(parent.getId(), conversationId);
2986 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
2987
Julia Reynolds12ba4cf2020-01-10 16:01:38 -05002988 compareChannelsParentChild(parent, mHelper.getConversationNotificationChannel(
2989 PKG_O, UID_O, parent.getId(), conversationId, false, false), conversationId);
2990 }
2991
2992 @Test
2993 public void testGetNotificationChannel_conversationProvidedByNotCustomizedYet() {
2994 String conversationId = "friend";
2995
2996 NotificationChannel parent =
2997 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
2998 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
2999
3000 compareChannels(parent, mHelper.getConversationNotificationChannel(
3001 PKG_O, UID_O, parent.getId(), conversationId, true, false));
Julia Reynolds0f767342019-12-18 09:11:55 -05003002 }
3003
3004 @Test
3005 public void testConversationNotificationChannelsRequireParents() {
3006 String parentId = "does not exist";
3007 String conversationId = "friend";
3008
3009 NotificationChannel friend = new NotificationChannel(String.format(
3010 CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId),
3011 "messages", IMPORTANCE_DEFAULT);
3012 friend.setConversationId(parentId, conversationId);
3013
3014 try {
3015 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3016 fail("allowed creation of conversation channel without a parent");
3017 } catch (IllegalArgumentException e) {
3018 // good
3019 }
3020 }
Julia Reynolds7c267522020-01-16 11:26:41 -05003021
3022 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003023 public void testPlaceholderConversationId_shortcutNotRequired() throws Exception {
3024 Settings.Global.putInt(mContext.getContentResolver(),
3025 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0);
3026
Mady Mellorc888d512020-04-09 14:48:02 -07003027 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
3028 mAppOpsManager);
Julia Reynolds7c267522020-01-16 11:26:41 -05003029
3030 final String xml = "<ranking version=\"1\">\n"
3031 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3032 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
3033 + "</package>"
3034 + "</ranking>";
3035 XmlPullParser parser = Xml.newPullParser();
3036 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3037 null);
3038 parser.nextTag();
3039 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3040
3041 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3042 }
3043
3044 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003045 public void testPlaceholderConversationId_shortcutRequired() throws Exception {
3046 Settings.Global.putInt(mContext.getContentResolver(),
3047 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
Mady Mellorc888d512020-04-09 14:48:02 -07003048 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
3049 mAppOpsManager);
Julia Reynolds7c267522020-01-16 11:26:41 -05003050
3051 final String xml = "<ranking version=\"1\">\n"
3052 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3053 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
3054 + "</package>"
3055 + "</ranking>";
3056 XmlPullParser parser = Xml.newPullParser();
3057 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3058 null);
3059 parser.nextTag();
3060 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3061
3062 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3063 }
3064
3065 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003066 public void testNormalConversationId_shortcutRequired() throws Exception {
3067 Settings.Global.putInt(mContext.getContentResolver(),
3068 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
Mady Mellorc888d512020-04-09 14:48:02 -07003069 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
3070 mAppOpsManager);
Julia Reynolds7c267522020-01-16 11:26:41 -05003071
3072 final String xml = "<ranking version=\"1\">\n"
3073 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3074 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"other\"/>"
3075 + "</package>"
3076 + "</ranking>";
3077 XmlPullParser parser = Xml.newPullParser();
3078 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3079 null);
3080 parser.nextTag();
3081 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3082
3083 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3084 }
3085
3086 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003087 public void testNoConversationId_shortcutRequired() throws Exception {
3088 Settings.Global.putInt(mContext.getContentResolver(),
3089 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
Mady Mellorc888d512020-04-09 14:48:02 -07003090 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
3091 mAppOpsManager);
Julia Reynolds7c267522020-01-16 11:26:41 -05003092
3093 final String xml = "<ranking version=\"1\">\n"
3094 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3095 + "<channel id=\"id\" name=\"hi\" importance=\"3\"/>"
3096 + "</package>"
3097 + "</ranking>";
3098 XmlPullParser parser = Xml.newPullParser();
3099 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3100 null);
3101 parser.nextTag();
3102 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3103
3104 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3105 }
Julia Reynolds882f2062020-02-05 12:11:38 -05003106
3107 @Test
Julia Reynolds02971452020-02-14 16:44:19 -05003108 public void testGetConversations_all() {
3109 String convoId = "convo";
3110 NotificationChannel messages =
3111 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3112 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3113 NotificationChannel calls =
3114 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3115 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3116 NotificationChannel p =
3117 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3118 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3119
3120 NotificationChannel channel =
3121 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3122 channel.setConversationId(messages.getId(), convoId);
3123 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3124
3125 NotificationChannel diffConvo =
3126 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3127 diffConvo.setConversationId(p.getId(), "different convo");
3128 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3129
3130 NotificationChannel channel2 =
3131 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3132 channel2.setConversationId(calls.getId(), convoId);
3133 channel2.setImportantConversation(true);
3134 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3135
3136 List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
3137
3138 assertEquals(3, convos.size());
3139 assertTrue(conversationWrapperContainsChannel(convos, channel));
3140 assertTrue(conversationWrapperContainsChannel(convos, diffConvo));
3141 assertTrue(conversationWrapperContainsChannel(convos, channel2));
3142 }
3143
3144 @Test
3145 public void testGetConversations_onlyImportant() {
3146 String convoId = "convo";
3147 NotificationChannel messages =
3148 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3149 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3150 NotificationChannel calls =
3151 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3152 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3153 NotificationChannel p =
3154 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3155 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3156
3157 NotificationChannel channel =
3158 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3159 channel.setConversationId(messages.getId(), convoId);
3160 channel.setImportantConversation(true);
3161 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3162
3163 NotificationChannel diffConvo =
3164 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3165 diffConvo.setConversationId(p.getId(), "different convo");
3166 diffConvo.setImportantConversation(true);
3167 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3168
3169 NotificationChannel channel2 =
3170 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3171 channel2.setConversationId(calls.getId(), convoId);
3172 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3173
3174 List<ConversationChannelWrapper> convos = mHelper.getConversations(true);
3175
3176 assertEquals(2, convos.size());
3177 assertTrue(conversationWrapperContainsChannel(convos, channel));
3178 assertTrue(conversationWrapperContainsChannel(convos, diffConvo));
3179 assertFalse(conversationWrapperContainsChannel(convos, channel2));
3180 }
3181
3182 private boolean conversationWrapperContainsChannel(List<ConversationChannelWrapper> list,
3183 NotificationChannel expected) {
3184 for (ConversationChannelWrapper ccw : list) {
3185 if (ccw.getNotificationChannel().equals(expected)) {
3186 return true;
3187 }
3188 }
3189
3190 return false;
3191 }
3192
3193 @Test
Julia Reynolds882f2062020-02-05 12:11:38 -05003194 public void testGetConversations_invalidPkg() {
3195 assertThat(mHelper.getConversations("bad", 1)).isEmpty();
3196 }
3197
3198 @Test
3199 public void testGetConversations_noConversations() {
3200 NotificationChannel channel =
3201 new NotificationChannel("not_convo", "not_convo", IMPORTANCE_DEFAULT);
3202 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3203
3204 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3205 }
3206
3207 @Test
3208 public void testGetConversations_noDisabledGroups() {
3209 NotificationChannelGroup group = new NotificationChannelGroup("a", "a");
3210 group.setBlocked(true);
3211 mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
3212 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3213 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3214
3215 NotificationChannel channel =
3216 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3217 channel.setConversationId("parent", "convo");
3218 channel.setGroup(group.getId());
3219 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3220
3221 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3222 }
3223
3224 @Test
3225 public void testGetConversations_noDeleted() {
3226 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3227 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3228 NotificationChannel channel =
3229 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3230 channel.setConversationId("parent", "convo");
3231 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3232 mHelper.deleteNotificationChannel(PKG_O, UID_O, channel.getId());
3233
3234 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3235 }
3236
3237 @Test
3238 public void testGetConversations() {
3239 NotificationChannelGroup group = new NotificationChannelGroup("acct", "account_name");
3240 mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
3241
3242 NotificationChannel messages =
3243 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3244 messages.setGroup(group.getId());
3245 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3246 NotificationChannel calls =
3247 new NotificationChannel("calls", "Calls", IMPORTANCE_HIGH);
3248 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3249
3250 NotificationChannel channel =
3251 new NotificationChannel("A person", "A lovely person", IMPORTANCE_DEFAULT);
3252 channel.setGroup(group.getId());
3253 channel.setConversationId(messages.getId(), channel.getName().toString());
3254 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3255
3256 NotificationChannel channel2 =
3257 new NotificationChannel("B person", "B fabulous person", IMPORTANCE_DEFAULT);
Julia Reynoldsa625b942020-02-15 09:42:23 -05003258 channel2.setConversationId(calls.getId(), channel2.getName().toString());
Julia Reynolds882f2062020-02-05 12:11:38 -05003259 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3260
3261 Map<String, NotificationChannel> expected = new HashMap<>();
3262 expected.put(channel.getId(), channel);
3263 expected.put(channel2.getId(), channel2);
3264
3265 Map<String, CharSequence> expectedGroup = new HashMap<>();
3266 expectedGroup.put(channel.getId(), group.getName());
3267 expectedGroup.put(channel2.getId(), null);
3268
3269 Map<String, CharSequence> expectedParentLabel= new HashMap<>();
3270 expectedParentLabel.put(channel.getId(), messages.getName());
3271 expectedParentLabel.put(channel2.getId(), calls.getName());
3272
3273 ArrayList<ConversationChannelWrapper> convos = mHelper.getConversations(PKG_O, UID_O);
3274 assertThat(convos).hasSize(2);
3275
3276 for (ConversationChannelWrapper convo : convos) {
3277 assertThat(convo.getNotificationChannel())
3278 .isEqualTo(expected.get(convo.getNotificationChannel().getId()));
3279 assertThat(convo.getParentChannelLabel())
3280 .isEqualTo(expectedParentLabel.get(convo.getNotificationChannel().getId()));
3281 assertThat(convo.getGroupLabel())
3282 .isEqualTo(expectedGroup.get(convo.getNotificationChannel().getId()));
3283 }
3284 }
Julia Reynoldsa625b942020-02-15 09:42:23 -05003285
3286 @Test
3287 public void testDeleteConversation() {
3288 String convoId = "convo";
3289 NotificationChannel messages =
3290 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3291 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3292 NotificationChannel calls =
3293 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3294 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3295
3296 NotificationChannel channel =
3297 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3298 channel.setConversationId(messages.getId(), convoId);
3299 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3300
3301 NotificationChannel noMatch =
3302 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3303 noMatch.setConversationId(messages.getId(), "different convo");
3304 mHelper.createNotificationChannel(PKG_O, UID_O, noMatch, true, false);
3305
3306 NotificationChannel channel2 =
3307 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3308 channel2.setConversationId(calls.getId(), convoId);
3309 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3310
3311 assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
3312 assertEquals(channel2,
3313 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
3314 assertEquals(2, mHelper.deleteConversation(PKG_O, UID_O, convoId).size());
3315
3316 assertEquals(messages,
3317 mHelper.getNotificationChannel(PKG_O, UID_O, messages.getId(), false));
3318 assertEquals(noMatch,
3319 mHelper.getNotificationChannel(PKG_O, UID_O, noMatch.getId(), false));
3320
3321 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
3322 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
3323 assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), true));
3324 assertEquals(channel2,
3325 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), true));
Will Brockman23db6d42020-02-28 09:51:12 -05003326
3327 assertEquals(7, mLogger.getCalls().size());
3328 assertEquals(
3329 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
3330 mLogger.get(0).event); // Channel messages
3331 assertEquals(
3332 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
3333 mLogger.get(1).event); // Channel calls
3334 assertEquals(
3335 NotificationChannelLogger.NotificationChannelEvent
3336 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3337 mLogger.get(2).event); // Channel channel - Conversation A person msgs
3338 assertEquals(
3339 NotificationChannelLogger.NotificationChannelEvent
3340 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3341 mLogger.get(3).event); // Channel noMatch - Conversation B person msgs
3342 assertEquals(
3343 NotificationChannelLogger.NotificationChannelEvent
3344 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3345 mLogger.get(4).event); // Channel channel2 - Conversation A person calls
3346 assertEquals(
3347 NotificationChannelLogger.NotificationChannelEvent
3348 .NOTIFICATION_CHANNEL_CONVERSATION_DELETED,
3349 mLogger.get(5).event); // Delete Channel channel - Conversation A person msgs
3350 assertEquals(
3351 NotificationChannelLogger.NotificationChannelEvent
3352 .NOTIFICATION_CHANNEL_CONVERSATION_DELETED,
3353 mLogger.get(6).event); // Delete Channel channel2 - Conversation A person calls
Julia Reynoldsa625b942020-02-15 09:42:23 -05003354 }
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04003355}