blob: 439f059e97b500825242b626aa15994064c06007 [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
Chris Wren1a934a32020-05-19 13:45:46 -040032import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_IS_UID;
33import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
34import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.CHANNEL_ID_FIELD_NUMBER;
35import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.CHANNEL_NAME_FIELD_NUMBER;
36import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IMPORTANCE_FIELD_NUMBER;
37import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_CONVERSATION_FIELD_NUMBER;
38import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_DELETED_FIELD_NUMBER;
39import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_DEMOTED_CONVERSATION_FIELD_NUMBER;
40import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_IMPORTANT_CONVERSATION_FIELD_NUMBER;
41import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.UID_FIELD_NUMBER;
Mady Mellora92268c2020-03-09 17:25:08 -070042import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE;
Julia Reynoldsc29370a2019-08-20 16:08:42 -040043import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
Mady Mellorbccdf452020-05-27 11:57:12 -070044import static com.android.server.notification.PreferencesHelper.UNKNOWN_UID;
Julia Reynoldsc29370a2019-08-20 16:08:42 -040045
Julia Reynolds882f2062020-02-05 12:11:38 -050046import static com.google.common.truth.Truth.assertThat;
47
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040048import static junit.framework.Assert.assertNull;
49import static junit.framework.Assert.fail;
50
51import static org.junit.Assert.assertEquals;
52import static org.junit.Assert.assertFalse;
53import static org.junit.Assert.assertNotNull;
54import static org.junit.Assert.assertTrue;
55import static org.mockito.ArgumentMatchers.any;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -080056import static org.mockito.ArgumentMatchers.anyInt;
57import static org.mockito.ArgumentMatchers.anyString;
58import static org.mockito.ArgumentMatchers.eq;
59import static org.mockito.Mockito.doReturn;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040060import static org.mockito.Mockito.mock;
61import static org.mockito.Mockito.never;
62import static org.mockito.Mockito.reset;
63import static org.mockito.Mockito.times;
64import static org.mockito.Mockito.verify;
65import static org.mockito.Mockito.when;
66
Mady Mellorc888d512020-04-09 14:48:02 -070067import android.app.AppOpsManager;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040068import android.app.Notification;
69import android.app.NotificationChannel;
70import android.app.NotificationChannelGroup;
71import android.app.NotificationManager;
72import android.content.ContentProvider;
73import android.content.Context;
74import android.content.IContentProvider;
75import android.content.pm.ApplicationInfo;
76import android.content.pm.PackageInfo;
77import android.content.pm.PackageManager;
78import android.content.pm.Signature;
79import android.content.res.Resources;
80import android.graphics.Color;
81import android.media.AudioAttributes;
82import android.net.Uri;
83import android.os.Build;
84import android.os.UserHandle;
85import android.provider.Settings;
Lyn Han4463f842019-07-09 15:27:28 -070086import android.provider.Settings.Global;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040087import android.provider.Settings.Secure;
Julia Reynolds882f2062020-02-05 12:11:38 -050088import android.service.notification.ConversationChannelWrapper;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -080089import android.test.mock.MockIContentProvider;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040090import android.test.suitebuilder.annotation.SmallTest;
91import android.testing.TestableContentResolver;
92import android.util.ArrayMap;
Julia Reynolds0c245002019-03-27 16:10:11 -040093import android.util.ArraySet;
Julia Reynoldse7ca31b2019-04-25 15:41:47 -040094import android.util.Pair;
Chris Wren07cb6a42020-05-14 17:35:30 -040095import android.util.StatsEvent;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -040096import android.util.Xml;
97
Beverly47679222019-05-16 15:46:11 -040098import androidx.test.InstrumentationRegistry;
99import androidx.test.runner.AndroidJUnit4;
100
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400101import com.android.internal.util.FastXmlSerializer;
102import com.android.server.UiServiceTestCase;
103
104import org.json.JSONArray;
105import org.json.JSONObject;
106import org.junit.Before;
107import org.junit.Test;
108import org.junit.runner.RunWith;
109import org.mockito.Mock;
110import org.mockito.MockitoAnnotations;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800111import org.mockito.Spy;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400112import org.xmlpull.v1.XmlPullParser;
113import org.xmlpull.v1.XmlSerializer;
114
115import java.io.BufferedInputStream;
116import java.io.BufferedOutputStream;
117import java.io.ByteArrayInputStream;
118import java.io.ByteArrayOutputStream;
Julia Reynolds882f2062020-02-05 12:11:38 -0500119import java.util.ArrayList;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400120import java.util.Arrays;
121import java.util.HashMap;
Chris Wren1a934a32020-05-19 13:45:46 -0400122import java.util.LinkedList;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400123import java.util.List;
124import java.util.Map;
125import java.util.Objects;
126import java.util.concurrent.ThreadLocalRandom;
127
128@SmallTest
129@RunWith(AndroidJUnit4.class)
130public class PreferencesHelperTest extends UiServiceTestCase {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400131 private static final int UID_N_MR1 = 0;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400132 private static final UserHandle USER = UserHandle.of(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400133 private static final int UID_O = 1111;
Julia Reynolds02971452020-02-14 16:44:19 -0500134 private static final int UID_P = 2222;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400135 private static final String SYSTEM_PKG = "android";
Beverly0479cde22018-11-09 11:05:34 -0500136 private static final int SYSTEM_UID = 1000;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400137 private static final UserHandle USER2 = UserHandle.of(10);
138 private static final String TEST_CHANNEL_ID = "test_channel_id";
139 private static final String TEST_AUTHORITY = "test";
140 private static final Uri SOUND_URI =
141 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
142 private static final Uri CANONICAL_SOUND_URI =
143 Uri.parse("content://" + TEST_AUTHORITY
144 + "/internal/audio/media/10?title=Test&canonical=1");
145
146 @Mock NotificationUsageStats mUsageStats;
147 @Mock RankingHandler mHandler;
148 @Mock PackageManager mPm;
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800149 @Spy IContentProvider mTestIContentProvider = new MockIContentProvider();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400150 @Mock Context mContext;
151 @Mock ZenModeHelper mMockZenModeHelper;
Mady Mellorc888d512020-04-09 14:48:02 -0700152 @Mock AppOpsManager mAppOpsManager;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400153
154 private NotificationManager.Policy mTestNotificationPolicy;
155
156 private PreferencesHelper mHelper;
157 private AudioAttributes mAudioAttributes;
Will Brockman23db6d42020-02-28 09:51:12 -0500158 private NotificationChannelLoggerFake mLogger = new NotificationChannelLoggerFake();
Chris Wren1a934a32020-05-19 13:45:46 -0400159 private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400160
161 @Before
162 public void setUp() throws Exception {
163 MockitoAnnotations.initMocks(this);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400164
165 final ApplicationInfo legacy = new ApplicationInfo();
166 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
167 final ApplicationInfo upgrade = new ApplicationInfo();
168 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400169 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
170 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(upgrade);
Julia Reynolds02971452020-02-14 16:44:19 -0500171 when(mPm.getApplicationInfoAsUser(eq(PKG_P), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400172 when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400173 when(mPm.getPackageUidAsUser(eq(PKG_N_MR1), anyInt())).thenReturn(UID_N_MR1);
174 when(mPm.getPackageUidAsUser(eq(PKG_O), anyInt())).thenReturn(UID_O);
Julia Reynolds02971452020-02-14 16:44:19 -0500175 when(mPm.getPackageUidAsUser(eq(PKG_P), anyInt())).thenReturn(UID_P);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400176 when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
177 PackageInfo info = mock(PackageInfo.class);
178 info.signatures = new Signature[] {mock(Signature.class)};
179 when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400180 when(mPm.getPackageInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt()))
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400181 .thenReturn(mock(PackageInfo.class));
182 when(mContext.getResources()).thenReturn(
183 InstrumentationRegistry.getContext().getResources());
184 when(mContext.getContentResolver()).thenReturn(
185 InstrumentationRegistry.getContext().getContentResolver());
186 when(mContext.getPackageManager()).thenReturn(mPm);
187 when(mContext.getApplicationInfo()).thenReturn(legacy);
188 // most tests assume badging is enabled
189 TestableContentResolver contentResolver = getContext().getContentResolver();
190 contentResolver.setFallbackToExisting(false);
191 Secure.putIntForUser(contentResolver,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400192 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID_N_MR1));
Lyn Han4463f842019-07-09 15:27:28 -0700193 Global.putInt(contentResolver, Global.NOTIFICATION_BUBBLES, 1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400194
195 ContentProvider testContentProvider = mock(ContentProvider.class);
196 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
197 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
198
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800199 doReturn(CANONICAL_SOUND_URI)
200 .when(mTestIContentProvider).canonicalize(any(), any(), eq(SOUND_URI));
201 doReturn(CANONICAL_SOUND_URI)
202 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
203 doReturn(SOUND_URI)
204 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400205
206 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
Julia Reynolds24edc002020-01-29 16:35:32 -0500207 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400208 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Mady Mellorc888d512020-04-09 14:48:02 -0700209 when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(),
210 anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT);
Chris Wren1a934a32020-05-19 13:45:46 -0400211
212 mStatsEventBuilderFactory = new WrappedSysUiStatsEvent.WrappedBuilderFactory();
213
Mady Mellorc888d512020-04-09 14:48:02 -0700214 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -0400215 mAppOpsManager, mStatsEventBuilderFactory);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400216 resetZenModeHelper();
217
218 mAudioAttributes = new AudioAttributes.Builder()
219 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
220 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
221 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
222 .build();
223 }
224
Annie Meng8b646fd2019-02-01 18:46:42 +0000225 private ByteArrayOutputStream writeXmlAndPurge(
226 String pkg, int uid, boolean forBackup, int userId, String... channelIds)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400227 throws Exception {
228 XmlSerializer serializer = new FastXmlSerializer();
229 ByteArrayOutputStream baos = new ByteArrayOutputStream();
230 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
231 serializer.startDocument(null, true);
Annie Meng8b646fd2019-02-01 18:46:42 +0000232 mHelper.writeXml(serializer, forBackup, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400233 serializer.endDocument();
234 serializer.flush();
235 for (String channelId : channelIds) {
236 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
237 }
238 return baos;
239 }
240
Annie Meng8b646fd2019-02-01 18:46:42 +0000241 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore, int userId)
242 throws Exception {
243 loadByteArrayXml(stream.toByteArray(), forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400244 }
245
Annie Meng8b646fd2019-02-01 18:46:42 +0000246 private void loadByteArrayXml(byte[] byteArray, boolean forRestore, int userId)
247 throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400248 XmlPullParser parser = Xml.newPullParser();
249 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
250 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000251 mHelper.readXml(parser, forRestore, userId);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400252 }
253
254 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
255 assertEquals(expected.getId(), actual.getId());
256 assertEquals(expected.getName(), actual.getName());
257 assertEquals(expected.getDescription(), actual.getDescription());
258 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
259 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
260 assertEquals(expected.getImportance(), actual.getImportance());
261 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
262 assertEquals(expected.getSound(), actual.getSound());
263 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
264 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
265 assertEquals(expected.getGroup(), actual.getGroup());
266 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
267 assertEquals(expected.getLightColor(), actual.getLightColor());
Julia Reynolds0f767342019-12-18 09:11:55 -0500268 assertEquals(expected.getParentChannelId(), actual.getParentChannelId());
269 assertEquals(expected.getConversationId(), actual.getConversationId());
Julia Reynoldsdcd70d62020-01-15 10:33:43 -0500270 assertEquals(expected.isDemoted(), actual.isDemoted());
Julia Reynolds0f767342019-12-18 09:11:55 -0500271 }
272
273 private void compareChannelsParentChild(NotificationChannel parent,
274 NotificationChannel actual, String conversationId) {
275 assertEquals(parent.getName(), actual.getName());
276 assertEquals(parent.getDescription(), actual.getDescription());
277 assertEquals(parent.shouldVibrate(), actual.shouldVibrate());
278 assertEquals(parent.shouldShowLights(), actual.shouldShowLights());
279 assertEquals(parent.getImportance(), actual.getImportance());
280 assertEquals(parent.getLockscreenVisibility(), actual.getLockscreenVisibility());
281 assertEquals(parent.getSound(), actual.getSound());
282 assertEquals(parent.canBypassDnd(), actual.canBypassDnd());
283 assertTrue(Arrays.equals(parent.getVibrationPattern(), actual.getVibrationPattern()));
284 assertEquals(parent.getGroup(), actual.getGroup());
285 assertEquals(parent.getAudioAttributes(), actual.getAudioAttributes());
286 assertEquals(parent.getLightColor(), actual.getLightColor());
287 assertEquals(parent.getId(), actual.getParentChannelId());
288 assertEquals(conversationId, actual.getConversationId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400289 }
290
291 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
292 assertEquals(expected.getId(), actual.getId());
293 assertEquals(expected.getName(), actual.getName());
294 assertEquals(expected.getDescription(), actual.getDescription());
295 assertEquals(expected.isBlocked(), actual.isBlocked());
296 }
297
298 private NotificationChannel getChannel() {
299 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
300 }
301
302 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
303 for (NotificationChannel channel : channels) {
304 if (channel.getId().equals(id)) {
305 return channel;
306 }
307 }
308 return null;
309 }
310
311 private void resetZenModeHelper() {
312 reset(mMockZenModeHelper);
313 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
314 }
315
Annie Meng8b646fd2019-02-01 18:46:42 +0000316 private void setUpPackageWithUid(String packageName, int uid) throws Exception {
317 when(mPm.getApplicationInfoAsUser(eq(packageName), anyInt(), anyInt()))
318 .thenReturn(new ApplicationInfo());
319 when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
320 }
321
322 @Test
323 public void testWriteXml_onlyBackupsTargetUser() throws Exception {
324 // Setup package notifications.
325 String package0 = "test.package.user0";
326 int uid0 = 1001;
327 setUpPackageWithUid(package0, uid0);
328 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400329 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000330
331 String package10 = "test.package.user10";
332 int uid10 = 1001001;
333 setUpPackageWithUid(package10, uid10);
334 NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400335 assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000336
337 ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
338
339 // Reset state.
340 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
341 mHelper.onPackagesChanged(true, 10, new String[] {package10}, new int[] {uid10});
342
343 // Parse backup data.
344 loadStreamXml(baos, true, 0);
345 loadStreamXml(baos, true, 10);
346
347 assertEquals(
348 channel10,
349 mHelper.getNotificationChannel(package10, uid10, channel10.getId(), false));
350 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
351 }
352
353 @Test
354 public void testReadXml_onlyRestoresTargetUser() throws Exception {
355 // Setup package in user 0.
356 String package0 = "test.package.user0";
357 int uid0 = 1001;
358 setUpPackageWithUid(package0, uid0);
359 NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400360 assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
Annie Meng8b646fd2019-02-01 18:46:42 +0000361
362 ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
363
364 // Reset state.
365 mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
366
367 // Restore should convert the uid according to the target user.
368 int expectedUid = 1001001;
369 setUpPackageWithUid(package0, expectedUid);
370 // Parse backup data.
371 loadStreamXml(baos, true, 10);
372
373 assertEquals(
374 channel0,
375 mHelper.getNotificationChannel(package0, expectedUid, channel0.getId(), false));
376 assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
377 }
378
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400379 @Test
380 public void testChannelXml() throws Exception {
381 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
382 ncg.setBlocked(true);
383 ncg.setDescription("group desc");
384 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
385 NotificationChannel channel1 =
386 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
387 NotificationChannel channel2 =
388 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
389 channel2.setDescription("descriptions for all");
390 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
391 channel2.enableLights(true);
392 channel2.setBypassDnd(true);
393 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
394 channel2.enableVibration(true);
395 channel2.setGroup(ncg.getId());
396 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
397 channel2.setLightColor(Color.BLUE);
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500398 channel2.setConversationId("id1", "conversation");
Julia Reynoldsdcd70d62020-01-15 10:33:43 -0500399 channel2.setDemoted(true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400400
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400401 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
402 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400403 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
404 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400405
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400406 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
407 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400408
Annie Meng8b646fd2019-02-01 18:46:42 +0000409 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
410 UserHandle.USER_ALL, channel1.getId(), channel2.getId(),
411 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400412 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
413 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400414
Annie Meng8b646fd2019-02-01 18:46:42 +0000415 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400416
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400417 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
418 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400419 assertEquals(channel1,
420 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400421 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400422 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400423
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400424 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
425 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400426 boolean foundNcg = false;
427 for (NotificationChannelGroup actual : actualGroups) {
428 if (ncg.getId().equals(actual.getId())) {
429 foundNcg = true;
430 compareGroups(ncg, actual);
431 } else if (ncg2.getId().equals(actual.getId())) {
432 compareGroups(ncg2, actual);
433 }
434 }
435 assertTrue(foundNcg);
436
437 boolean foundChannel2Group = false;
438 for (NotificationChannelGroup actual : actualGroups) {
439 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
440 foundChannel2Group = true;
441 break;
442 }
443 }
444 assertTrue(foundChannel2Group);
445 }
446
447 @Test
448 public void testChannelXmlForBackup() throws Exception {
449 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
450 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
451 NotificationChannel channel1 =
452 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
453 NotificationChannel channel2 =
454 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
455 channel2.setDescription("descriptions for all");
456 channel2.setSound(SOUND_URI, mAudioAttributes);
457 channel2.enableLights(true);
458 channel2.setBypassDnd(true);
459 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
460 channel2.enableVibration(false);
461 channel2.setGroup(ncg.getId());
462 channel2.setLightColor(Color.BLUE);
463 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
464 channel3.enableVibration(true);
465
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400466 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
467 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
468 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
469 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
470 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
471 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400472
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400473 mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
Julia Reynoldsbc23c7e2020-05-13 18:16:32 -0400474 mHelper.setInvalidMessageSent(PKG_P, UID_P);
475 mHelper.setValidMessageSent(PKG_P, UID_P);
476 mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400477
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400478 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400479
Annie Meng8b646fd2019-02-01 18:46:42 +0000480 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
481 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
482 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400483 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1, PKG_O},
484 new int[]{UID_N_MR1, UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400485
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400486 mHelper.setShowBadge(PKG_O, UID_O, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400487
Annie Meng8b646fd2019-02-01 18:46:42 +0000488 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400489
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400490 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O));
491 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
Julia Reynoldsbc23c7e2020-05-13 18:16:32 -0400492 assertTrue(mHelper.hasSentInvalidMsg(PKG_P, UID_P));
493 assertFalse(mHelper.hasSentInvalidMsg(PKG_N_MR1, UID_N_MR1));
494 assertTrue(mHelper.hasSentValidMsg(PKG_P, UID_P));
495 assertTrue(mHelper.didUserEverDemoteInvalidMsgApp(PKG_P, UID_P));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400496 assertEquals(channel1,
497 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400498 compareChannels(channel2,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400499 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400500 compareChannels(channel3,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400501 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400502
Julia Reynolds13ed28b2018-09-21 15:20:13 -0400503 List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
504 PKG_N_MR1, UID_N_MR1, false, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400505 boolean foundNcg = false;
506 for (NotificationChannelGroup actual : actualGroups) {
507 if (ncg.getId().equals(actual.getId())) {
508 foundNcg = true;
509 compareGroups(ncg, actual);
510 } else if (ncg2.getId().equals(actual.getId())) {
511 compareGroups(ncg2, actual);
512 }
513 }
514 assertTrue(foundNcg);
515
516 boolean foundChannel2Group = false;
517 for (NotificationChannelGroup actual : actualGroups) {
518 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
519 foundChannel2Group = true;
520 break;
521 }
522 }
523 assertTrue(foundChannel2Group);
524 }
525
526 @Test
527 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
528 NotificationChannel channel =
529 new NotificationChannel("id", "name", IMPORTANCE_LOW);
530 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400531 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400532
Annie Meng8b646fd2019-02-01 18:46:42 +0000533 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
534 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400535
536 // Testing that in restore we are given the canonical version
Annie Meng8b646fd2019-02-01 18:46:42 +0000537 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Philip P. Moltmann128b7032019-09-27 08:44:12 -0700538 verify(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400539 }
540
541 @Test
542 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
543 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
544 Uri canonicalBasedOnLocal = localUri.buildUpon()
545 .appendQueryParameter("title", "Test")
546 .appendQueryParameter("canonical", "1")
547 .build();
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800548 doReturn(canonicalBasedOnLocal)
549 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
550 doReturn(localUri)
551 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
552 doReturn(localUri)
553 .when(mTestIContentProvider).uncanonicalize(any(), any(),
554 eq(canonicalBasedOnLocal));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400555
556 NotificationChannel channel =
557 new NotificationChannel("id", "name", IMPORTANCE_LOW);
558 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400559 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000560 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
561 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400562
Annie Meng8b646fd2019-02-01 18:46:42 +0000563 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400564
565 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400566 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400567 assertEquals(localUri, actualChannel.getSound());
568 }
569
570 @Test
571 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
572 Thread.sleep(3000);
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800573 doReturn(null)
574 .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
575 doReturn(null)
576 .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400577
578 NotificationChannel channel =
579 new NotificationChannel("id", "name", IMPORTANCE_LOW);
580 channel.setSound(SOUND_URI, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400581 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000582 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
583 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400584
Annie Meng8b646fd2019-02-01 18:46:42 +0000585 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400586
587 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400588 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400589 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
590 }
591
592
593 /**
594 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
595 * handle its restore properly.
596 */
597 @Test
598 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
599 // Not a local uncanonicalized uri, simulating that it fails to exist locally
Dmitri Plotnikov7a223fb2020-02-14 17:04:13 -0800600 doReturn(null)
601 .when(mTestIContentProvider).canonicalize(any(), any(), eq(SOUND_URI));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400602 String id = "id";
603 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400604 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400605 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
606 + "sound=\"" + SOUND_URI + "\" "
607 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
608 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
609 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
610 + "</package>\n"
611 + "</ranking>\n";
612
Annie Meng8b646fd2019-02-01 18:46:42 +0000613 loadByteArrayXml(
614 backupWithUncanonicalizedSoundUri.getBytes(), true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400615
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400616 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, id, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400617 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
618 }
619
620 @Test
621 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
622 NotificationChannel channel =
623 new NotificationChannel("id", "name", IMPORTANCE_LOW);
624 channel.setSound(null, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400625 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Annie Meng8b646fd2019-02-01 18:46:42 +0000626 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
627 UserHandle.USER_SYSTEM, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400628
Annie Meng8b646fd2019-02-01 18:46:42 +0000629 loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400630
631 NotificationChannel actualChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400632 PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400633 assertEquals(null, actualChannel.getSound());
634 }
635
636 @Test
637 public void testChannelXml_backup() throws Exception {
638 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
639 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
640 NotificationChannel channel1 =
641 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
642 NotificationChannel channel2 =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400643 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400644 NotificationChannel channel3 =
645 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
646 channel3.setGroup(ncg.getId());
647
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400648 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
649 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
650 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
651 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
652 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400653
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400654 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId());
655 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId());
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400656 assertEquals(channel2,
657 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400658
Annie Meng8b646fd2019-02-01 18:46:42 +0000659 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
660 UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
661 NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400662 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
663 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400664
665 XmlPullParser parser = Xml.newPullParser();
666 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
667 null);
668 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000669 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400670
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400671 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
672 assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
673 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400674 assertEquals(channel2,
675 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400676 }
677
678 @Test
679 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400680 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000681 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400682
Annie Meng8b646fd2019-02-01 18:46:42 +0000683 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400684
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400685 final NotificationChannel updated = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400686 NotificationChannel.DEFAULT_CHANNEL_ID, false);
687 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
688 assertFalse(updated.canBypassDnd());
689 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
690 assertEquals(0, updated.getUserLockedFields());
691 }
692
693 @Test
694 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400695 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
696 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400697 NotificationChannel.DEFAULT_CHANNEL_ID, false);
698 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400699 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400700
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400701 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000702 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400703
Annie Meng8b646fd2019-02-01 18:46:42 +0000704 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400705
706 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400707 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400708 }
709
710 @Test
711 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
712 final String preupgradeXml = "<ranking version=\"1\">\n"
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400713 + "<package name=\"" + PKG_N_MR1
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400714 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
715 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400716 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID_N_MR1 + "\" />\n"
717 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" visibility=\""
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400718 + Notification.VISIBILITY_PRIVATE + "\" />\n"
719 + "</ranking>";
720 XmlPullParser parser = Xml.newPullParser();
721 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
722 null);
723 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000724 mHelper.readXml(parser, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400725
726 final NotificationChannel updated1 =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400727 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400728 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
729 assertTrue(updated1.canBypassDnd());
730 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
731 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
732 | NotificationChannel.USER_LOCKED_PRIORITY
733 | NotificationChannel.USER_LOCKED_VISIBILITY,
734 updated1.getUserLockedFields());
735
736 // No Default Channel created for updated packages
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400737 assertEquals(null, mHelper.getNotificationChannel(PKG_O, UID_O,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400738 NotificationChannel.DEFAULT_CHANNEL_ID, false));
739 }
740
741 @Test
742 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
743 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400744 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400745 assertTrue(defaultChannel != null);
Annie Meng8b646fd2019-02-01 18:46:42 +0000746 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
747 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400748 // Load package at higher sdk.
749 final ApplicationInfo upgraded = new ApplicationInfo();
750 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400751 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000752 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400753
754 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400755 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400756 NotificationChannel.DEFAULT_CHANNEL_ID, false));
757 }
758
759 @Test
760 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400761 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400762 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400763 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000764 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400765
766 // Load package at higher sdk.
767 final ApplicationInfo upgraded = new ApplicationInfo();
768 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400769 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
Annie Meng8b646fd2019-02-01 18:46:42 +0000770 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400771
772 // Default Channel should be gone.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400773 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400774 NotificationChannel.DEFAULT_CHANNEL_ID, false));
775 }
776
777 @Test
778 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400779 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
Annie Meng8b646fd2019-02-01 18:46:42 +0000780 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400781 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400782 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
783
Annie Meng8b646fd2019-02-01 18:46:42 +0000784 loadStreamXml(baos, false, UserHandle.USER_ALL);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400785
786 // Should still have the newly created channel that wasn't in the xml.
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400787 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "bananas", false) != null);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400788 }
789
790 @Test
791 public void testCreateChannel_blocked() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400792 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400793
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400794 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
795 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400796 }
797
798 @Test
799 public void testCreateChannel_badImportance() throws Exception {
800 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400801 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400802 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
803 true, false);
804 fail("Was allowed to create a channel with invalid importance");
805 } catch (IllegalArgumentException e) {
806 // yay
807 }
808 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400809 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400810 new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
811 true, false);
812 fail("Was allowed to create a channel with invalid importance");
813 } catch (IllegalArgumentException e) {
814 // yay
815 }
816 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400817 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400818 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
819 true, false);
820 fail("Was allowed to create a channel with invalid importance");
821 } catch (IllegalArgumentException e) {
822 // yay
823 }
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400824 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
825 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
826 assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
827 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400828 }
829
830
831 @Test
832 public void testUpdate() throws Exception {
833 // no fields locked by user
834 final NotificationChannel channel =
835 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
836 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
837 channel.enableLights(true);
838 channel.setBypassDnd(true);
839 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
840
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400841 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400842
843 // same id, try to update all fields
844 final NotificationChannel channel2 =
845 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
846 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
847 channel2.enableLights(false);
848 channel2.setBypassDnd(false);
849 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
850
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400851 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400852
853 // all fields should be changed
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400854 assertEquals(channel2,
855 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400856
857 verify(mHandler, times(1)).requestSort();
858 }
859
860 @Test
861 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400862 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_UNSPECIFIED);
863 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
864 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400865 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400866 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
867 assertFalse(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400868
869 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400870 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400871
872 defaultChannel.setShowBadge(false);
873 defaultChannel.setImportance(IMPORTANCE_NONE);
874 defaultChannel.setBypassDnd(true);
875 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
876
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400877 mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
878 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400879
880 // ensure app level fields are changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400881 assertFalse(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
882 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
883 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1,
884 UID_N_MR1));
885 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1));
886 assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400887 }
888
889 @Test
890 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
891 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
892
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400893 mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
894 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
895 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400896 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400897 mHelper.getPackageVisibility(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400898
899 channel.setShowBadge(false);
900 channel.setImportance(IMPORTANCE_NONE);
901 channel.setBypassDnd(true);
902 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
903
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400904 mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400905
906 // ensure app level fields are not changed
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400907 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
908 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400909 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400910 mHelper.getPackageVisibility(PKG_O, UID_O));
911 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O,
912 UID_O));
913 assertFalse(mHelper.getIsAppImportanceLocked(PKG_O, UID_O));
914 }
915
916 @Test
917 public void testUpdate_preUpgrade_noUpdateAppFieldsWithMultipleChannels() throws Exception {
918 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
919
920 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
921 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
922 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
923 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
924 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
925
926 channel.setShowBadge(false);
927 channel.setImportance(IMPORTANCE_NONE);
928 channel.setBypassDnd(true);
929 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
930
931 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
932
933 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
934 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
935
936 defaultChannel.setShowBadge(false);
937 defaultChannel.setImportance(IMPORTANCE_NONE);
938 defaultChannel.setBypassDnd(true);
939 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
940
941 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
942
943 // ensure app level fields are not changed
944 assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
945 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
946 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
947 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
948 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
949 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400950 }
951
952 @Test
953 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400954 assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "garbage", false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400955 }
956
957 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400958 public void testCreateChannel_CannotChangeHiddenFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400959 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400960 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400961 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
962 channel.enableLights(true);
963 channel.setBypassDnd(true);
964 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
965 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800966 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400967 int lockMask = 0;
968 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
969 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
970 }
971 channel.lockFields(lockMask);
972
Julia Reynoldsdafd3a42019-05-24 13:33:28 -0400973 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400974
975 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -0400976 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400977
978 assertEquals(channel.getName(), savedChannel.getName());
979 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
980 assertFalse(savedChannel.canBypassDnd());
981 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
982 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800983 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400984
985 verify(mHandler, never()).requestSort();
986 }
987
988 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400989 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400990 final NotificationChannel channel =
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -0400991 new NotificationChannel("id2", "name2", IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400992 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
993 channel.enableLights(true);
994 channel.setBypassDnd(true);
995 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
996 channel.setShowBadge(true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -0800997 channel.setAllowBubbles(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400998 int lockMask = 0;
999 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
1000 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
1001 }
1002 channel.lockFields(lockMask);
1003
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001004 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001005
1006 NotificationChannel savedChannel =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001007 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001008
1009 assertEquals(channel.getName(), savedChannel.getName());
1010 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
1011 assertFalse(savedChannel.canBypassDnd());
1012 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
1013 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001014 assertEquals(channel.canBubble(), savedChannel.canBubble());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001015 }
1016
1017 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001018 public void testClearLockedFields() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001019 final NotificationChannel channel = getChannel();
Julia Reynolds5c399c62019-04-08 14:42:53 -04001020 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001021 assertEquals(0, channel.getUserLockedFields());
1022
1023 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
1024 | NotificationChannel.USER_LOCKED_IMPORTANCE);
Julia Reynolds5c399c62019-04-08 14:42:53 -04001025 mHelper.clearLockedFieldsLocked(channel);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001026 assertEquals(0, channel.getUserLockedFields());
1027 }
1028
1029 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001030 public void testLockFields_soundAndVibration() {
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.setSound(new Uri.Builder().scheme("test").build(),
1035 new AudioAttributes.Builder().build());
1036 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001037 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001038 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1039 | NotificationChannel.USER_LOCKED_SOUND,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001040 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001041 .getUserLockedFields());
1042
1043 NotificationChannel update2 = getChannel();
1044 update2.enableVibration(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001045 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001046 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1047 | NotificationChannel.USER_LOCKED_SOUND
1048 | NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001049 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001050 .getUserLockedFields());
1051 }
1052
1053 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001054 public void testLockFields_vibrationAndLights() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001055 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001056
1057 final NotificationChannel update1 = getChannel();
1058 update1.setVibrationPattern(new long[]{7945, 46 ,246});
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001059 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001060 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001061 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001062 .getUserLockedFields());
1063
1064 final NotificationChannel update2 = getChannel();
1065 update2.enableLights(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001066 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001067 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
1068 | NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001069 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001070 .getUserLockedFields());
1071 }
1072
1073 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001074 public void testLockFields_lightsAndImportance() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001075 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001076
1077 final NotificationChannel update1 = getChannel();
1078 update1.setLightColor(Color.GREEN);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001079 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001080 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001081 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001082 .getUserLockedFields());
1083
1084 final NotificationChannel update2 = getChannel();
1085 update2.setImportance(IMPORTANCE_DEFAULT);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001086 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001087 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
1088 | NotificationChannel.USER_LOCKED_IMPORTANCE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001089 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001090 .getUserLockedFields());
1091 }
1092
1093 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001094 public void testLockFields_visibilityAndDndAndBadge() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001095 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001096 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001097 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001098 .getUserLockedFields());
1099
1100 final NotificationChannel update1 = getChannel();
1101 update1.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001102 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001103 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001104 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001105 .getUserLockedFields());
1106
1107 final NotificationChannel update2 = getChannel();
1108 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001109 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001110 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1111 | NotificationChannel.USER_LOCKED_VISIBILITY,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001112 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001113 .getUserLockedFields());
1114
1115 final NotificationChannel update3 = getChannel();
1116 update3.setShowBadge(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001117 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001118 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1119 | NotificationChannel.USER_LOCKED_VISIBILITY
1120 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001121 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update3.getId(), false)
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001122 .getUserLockedFields());
1123 }
1124
1125 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001126 public void testLockFields_allowBubble() {
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001127 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1128 assertEquals(0,
1129 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
1130 .getUserLockedFields());
1131
1132 final NotificationChannel update = getChannel();
Mady Mellora92268c2020-03-09 17:25:08 -07001133 update.setAllowBubbles(true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001134 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001135 assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE,
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001136 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false)
1137 .getUserLockedFields());
1138 }
1139
1140 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001141 public void testDeleteNonExistentChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001142 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001143 }
1144
1145 @Test
Will Brockman23db6d42020-02-28 09:51:12 -05001146 public void testDoubleDeleteChannel() throws Exception {
1147 NotificationChannel channel = getChannel();
1148 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1149 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1150 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1151 assertEquals(2, mLogger.getCalls().size());
1152 assertEquals(
1153 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1154 mLogger.get(0).event);
1155 assertEquals(
1156 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_DELETED,
1157 mLogger.get(1).event);
1158 // No log for the second delete of the same channel.
1159 }
1160
1161 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001162 public void testGetDeletedChannel() throws Exception {
1163 NotificationChannel channel = getChannel();
1164 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1165 channel.enableLights(true);
1166 channel.setBypassDnd(true);
1167 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1168 channel.enableVibration(true);
1169 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1170
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001171 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1172 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001173
1174 // Does not return deleted channel
1175 NotificationChannel response =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001176 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001177 assertNull(response);
1178
1179 // Returns deleted channel
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001180 response = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001181 compareChannels(channel, response);
1182 assertTrue(response.isDeleted());
1183 }
1184
1185 @Test
1186 public void testGetDeletedChannels() throws Exception {
1187 Map<String, NotificationChannel> channelMap = new HashMap<>();
1188 NotificationChannel channel =
1189 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1190 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
1191 channel.enableLights(true);
1192 channel.setBypassDnd(true);
1193 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1194 channel.enableVibration(true);
1195 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
1196 channelMap.put(channel.getId(), channel);
1197 NotificationChannel channel2 =
1198 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1199 channelMap.put(channel2.getId(), channel2);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001200 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1201 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001202
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001203 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001204
1205 // Returns only non-deleted channels
1206 List<NotificationChannel> channels =
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001207 mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001208 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1209 for (NotificationChannel nc : channels) {
1210 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1211 compareChannels(channel2, nc);
1212 }
1213 }
1214
1215 // Returns deleted channels too
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001216 channels = mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001217 assertEquals(3, channels.size()); // Includes default channel
1218 for (NotificationChannel nc : channels) {
1219 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1220 compareChannels(channelMap.get(nc.getId()), nc);
1221 }
1222 }
1223 }
1224
1225 @Test
1226 public void testGetDeletedChannelCount() throws Exception {
1227 NotificationChannel channel =
1228 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1229 NotificationChannel channel2 =
1230 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1231 NotificationChannel channel3 =
1232 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001233 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1234 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1235 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001236
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001237 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
1238 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001239
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001240 assertEquals(2, mHelper.getDeletedChannelCount(PKG_N_MR1, UID_N_MR1));
1241 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001242 }
1243
1244 @Test
1245 public void testGetBlockedChannelCount() throws Exception {
1246 NotificationChannel channel =
1247 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1248 NotificationChannel channel2 =
1249 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
1250 NotificationChannel channel3 =
1251 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001252 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1253 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
1254 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001255
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001256 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001257
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001258 assertEquals(1, mHelper.getBlockedChannelCount(PKG_N_MR1, UID_N_MR1));
1259 assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001260 }
1261
1262 @Test
Beverly4f7b53d2018-11-20 09:56:31 -05001263 public void testUpdateChannelsBypassingDnd_onUserSwitch_onUserUnlocked() throws Exception {
1264 int user = USER.getIdentifier();
1265 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1266 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1267 NotificationManager.IMPORTANCE_MAX);
1268 channel1.setBypassDnd(true);
1269 channel1.setGroup(ncg.getId());
1270
1271 // channel is associated with a group, then group is deleted
1272 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1273 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1274 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, user, ncg.getId());
1275
1276 mHelper.onUserSwitched(user);
1277 mHelper.onUserUnlocked(user);
1278 }
1279
1280 @Test
Beverly0479cde22018-11-09 11:05:34 -05001281 public void testGetChannelsBypassingDndCount_noChannelsBypassing() throws Exception {
1282 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1283 USER.getIdentifier()).getList().size());
1284 }
1285
1286 @Test
1287 public void testGetChannelsBypassingDnd_noChannelsForUserIdBypassing()
1288 throws Exception {
1289 int user = 9;
1290 NotificationChannel channel = new NotificationChannel("id", "name",
1291 NotificationManager.IMPORTANCE_MAX);
1292 channel.setBypassDnd(true);
1293 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1294
1295 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1296 user).getList().size());
1297 }
1298
1299 @Test
1300 public void testGetChannelsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1301 int user = USER.getIdentifier();
1302 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1303 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1304 NotificationManager.IMPORTANCE_MAX);
1305 channel1.setBypassDnd(true);
1306 channel1.setGroup(ncg.getId());
1307 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1308 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1309
1310 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1311 user).getList().size());
1312
1313 // disable group
1314 ncg.setBlocked(true);
1315 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1316 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1317 user).getList().size());
1318 }
1319
1320 @Test
1321 public void testGetChannelsBypassingDndCount_multipleChannelsBypassing() {
1322 int user = USER.getIdentifier();
1323 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1324 NotificationManager.IMPORTANCE_MAX);
1325 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1326 NotificationManager.IMPORTANCE_MAX);
1327 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1328 NotificationManager.IMPORTANCE_MAX);
1329 channel1.setBypassDnd(true);
1330 channel2.setBypassDnd(true);
1331 channel3.setBypassDnd(true);
1332 // has DND access, so can set bypassDnd attribute
1333 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1334 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1335 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1336 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1337 user).getList().size());
1338
1339 // block notifications from this app
1340 mHelper.setEnabled(PKG_N_MR1, user, false);
1341 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1342 user).getList().size());
1343
1344 // re-enable notifications from this app
1345 mHelper.setEnabled(PKG_N_MR1, user, true);
1346 assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1347 user).getList().size());
1348
1349 // setBypassDnd false for some channels
1350 channel1.setBypassDnd(false);
1351 channel2.setBypassDnd(false);
1352 assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1353 user).getList().size());
1354
1355 // setBypassDnd false for rest of the channels
1356 channel3.setBypassDnd(false);
1357 assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
1358 user).getList().size());
1359 }
1360
1361 @Test
1362 public void testGetAppsBypassingDndCount_noAppsBypassing() throws Exception {
1363 assertEquals(0, mHelper.getAppsBypassingDndCount(USER.getIdentifier()));
1364 }
1365
1366 @Test
1367 public void testGetAppsBypassingDndCount_noAppsForUserIdBypassing() throws Exception {
1368 int user = 9;
1369 NotificationChannel channel = new NotificationChannel("id", "name",
1370 NotificationManager.IMPORTANCE_MAX);
1371 channel.setBypassDnd(true);
1372 mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
1373
1374 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1375 }
1376
1377 @Test
1378 public void testGetAppsBypassingDndCount_oneChannelBypassing_groupBlocked() {
1379 int user = USER.getIdentifier();
1380 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1381 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1382 NotificationManager.IMPORTANCE_MAX);
1383 channel1.setBypassDnd(true);
1384 channel1.setGroup(ncg.getId());
1385 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
1386 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1387
1388 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1389
1390 // disable group
1391 ncg.setBlocked(true);
1392 mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
1393 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1394 }
1395
1396 @Test
1397 public void testGetAppsBypassingDndCount_oneAppBypassing() {
1398 int user = USER.getIdentifier();
1399 NotificationChannel channel1 = new NotificationChannel("id1", "name1",
1400 NotificationManager.IMPORTANCE_MAX);
1401 NotificationChannel channel2 = new NotificationChannel("id2", "name2",
1402 NotificationManager.IMPORTANCE_MAX);
1403 NotificationChannel channel3 = new NotificationChannel("id3", "name3",
1404 NotificationManager.IMPORTANCE_MAX);
1405 channel1.setBypassDnd(true);
1406 channel2.setBypassDnd(true);
1407 channel3.setBypassDnd(true);
1408 // has DND access, so can set bypassDnd attribute
1409 mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
1410 mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
1411 mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
1412 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1413
1414 // block notifications from this app
1415 mHelper.setEnabled(PKG_N_MR1, user, false);
1416 assertEquals(0, mHelper.getAppsBypassingDndCount(user)); // no apps can bypass dnd
1417
1418 // re-enable notifications from this app
1419 mHelper.setEnabled(PKG_N_MR1, user, true);
1420 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1421
1422 // setBypassDnd false for some channels
1423 channel1.setBypassDnd(false);
1424 channel2.setBypassDnd(false);
1425 assertEquals(1, mHelper.getAppsBypassingDndCount(user));
1426
1427 // setBypassDnd false for rest of the channels
1428 channel3.setBypassDnd(false);
1429 assertEquals(0, mHelper.getAppsBypassingDndCount(user));
1430 }
1431
1432 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001433 public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception {
1434 // create notification channel that can't bypass dnd
1435 // expected result: areChannelsBypassingDnd = false
1436 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1437 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001438 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001439 assertFalse(mHelper.areChannelsBypassingDnd());
1440 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1441 resetZenModeHelper();
1442
1443 // create notification channel that can bypass dnd
1444 // expected result: areChannelsBypassingDnd = true
1445 NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1446 channel2.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001447 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001448 assertTrue(mHelper.areChannelsBypassingDnd());
1449 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1450 resetZenModeHelper();
1451
1452 // delete channels
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001453 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001454 assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
1455 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1456 resetZenModeHelper();
1457
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001458 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001459 assertFalse(mHelper.areChannelsBypassingDnd());
1460 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1461 resetZenModeHelper();
1462 }
1463
1464 @Test
1465 public void testUpdateCanChannelsBypassDnd() throws Exception {
1466 // create notification channel that can't bypass dnd
1467 // expected result: areChannelsBypassingDnd = false
1468 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
1469 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001470 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001471 assertFalse(mHelper.areChannelsBypassingDnd());
1472 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1473 resetZenModeHelper();
1474
1475 // update channel so it CAN bypass dnd:
1476 // expected result: areChannelsBypassingDnd = true
1477 channel.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001478 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001479 assertTrue(mHelper.areChannelsBypassingDnd());
1480 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1481 resetZenModeHelper();
1482
1483 // update channel so it can't bypass dnd:
1484 // expected result: areChannelsBypassingDnd = false
1485 channel.setBypassDnd(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001486 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001487 assertFalse(mHelper.areChannelsBypassingDnd());
1488 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1489 resetZenModeHelper();
1490 }
1491
1492 @Test
1493 public void testSetupNewZenModeHelper_canBypass() {
1494 // start notification policy off with mAreChannelsBypassingDnd = true, but
1495 // RankingHelper should change to false
1496 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
Julia Reynolds24edc002020-01-29 16:35:32 -05001497 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001498 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Mady Mellorc888d512020-04-09 14:48:02 -07001499 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04001500 mAppOpsManager, mStatsEventBuilderFactory);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001501 assertFalse(mHelper.areChannelsBypassingDnd());
1502 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1503 resetZenModeHelper();
1504 }
1505
1506 @Test
1507 public void testSetupNewZenModeHelper_cannotBypass() {
1508 // start notification policy off with mAreChannelsBypassingDnd = false
Julia Reynolds24edc002020-01-29 16:35:32 -05001509 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001510 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
Mady Mellorc888d512020-04-09 14:48:02 -07001511 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04001512 mAppOpsManager, mStatsEventBuilderFactory);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001513 assertFalse(mHelper.areChannelsBypassingDnd());
1514 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1515 resetZenModeHelper();
1516 }
1517
1518 @Test
1519 public void testCreateDeletedChannel() throws Exception {
1520 long[] vibration = new long[]{100, 67, 145, 156};
1521 NotificationChannel channel =
1522 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1523 channel.setVibrationPattern(vibration);
1524
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001525 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
1526 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001527
1528 NotificationChannel newChannel = new NotificationChannel(
1529 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1530 newChannel.setVibrationPattern(new long[]{100});
1531
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001532 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001533
1534 // No long deleted, using old settings
1535 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001536 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001537 }
1538
1539 @Test
1540 public void testOnlyHasDefaultChannel() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001541 assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
1542 assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001543
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001544 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
1545 assertFalse(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001546 }
1547
1548 @Test
1549 public void testCreateChannel_defaultChannelId() throws Exception {
1550 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001551 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, new NotificationChannel(
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001552 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
1553 fail("Allowed to create default channel");
1554 } catch (IllegalArgumentException e) {
1555 // pass
1556 }
1557 }
1558
1559 @Test
1560 public void testCreateChannel_alreadyExists() throws Exception {
1561 long[] vibration = new long[]{100, 67, 145, 156};
1562 NotificationChannel channel =
1563 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1564 channel.setVibrationPattern(vibration);
1565
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001566 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001567
1568 NotificationChannel newChannel = new NotificationChannel(
1569 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
1570 newChannel.setVibrationPattern(new long[]{100});
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001571 newChannel.setAllowBubbles(!channel.canBubble());
1572 newChannel.setLightColor(Color.BLUE);
1573 newChannel.setSound(Uri.EMPTY, null);
1574 newChannel.setShowBadge(!channel.canShowBadge());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001575
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001576 assertFalse(mHelper.createNotificationChannel(
1577 PKG_N_MR1, UID_N_MR1, newChannel, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001578
1579 // Old settings not overridden
1580 compareChannels(channel,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001581 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel.getId(), false));
Will Brockman23db6d42020-02-28 09:51:12 -05001582
1583 assertEquals(1, mLogger.getCalls().size());
1584 assertEquals(
1585 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1586 mLogger.get(0).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001587 }
1588
1589 @Test
1590 public void testCreateChannel_noOverrideSound() throws Exception {
1591 Uri sound = new Uri.Builder().scheme("test").build();
1592 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1593 NotificationManager.IMPORTANCE_DEFAULT);
1594 channel.setSound(sound, mAudioAttributes);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001595 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001596 assertEquals(sound, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001597 PKG_N_MR1, UID_N_MR1, channel.getId(), false).getSound());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001598 }
1599
1600 @Test
1601 public void testPermanentlyDeleteChannels() throws Exception {
1602 NotificationChannel channel1 =
1603 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1604 NotificationChannel channel2 =
1605 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1606
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001607 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1608 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001609
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001610 mHelper.permanentlyDeleteNotificationChannels(PKG_N_MR1, UID_N_MR1);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001611
1612 // Only default channel remains
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001613 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001614 }
1615
1616 @Test
1617 public void testDeleteGroup() throws Exception {
1618 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1619 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1620 NotificationChannel nonGroupedNonDeletedChannel =
1621 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1622 NotificationChannel groupedButNotDeleted =
1623 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1624 groupedButNotDeleted.setGroup("not");
1625 NotificationChannel groupedAndDeleted =
1626 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1627 groupedAndDeleted.setGroup("totally");
1628
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001629 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
1630 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001631 mHelper.createNotificationChannel(
1632 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001633 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false);
1634 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001635
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001636 mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001637
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001638 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG_N_MR1, UID_N_MR1));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001639 assertNotNull(
1640 mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001641
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001642 assertNull(mHelper.getNotificationChannel(
1643 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), false));
1644 compareChannels(groupedAndDeleted, mHelper.getNotificationChannel(
1645 PKG_N_MR1, UID_N_MR1, groupedAndDeleted.getId(), true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001646
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001647 compareChannels(groupedButNotDeleted, mHelper.getNotificationChannel(
1648 PKG_N_MR1, UID_N_MR1, groupedButNotDeleted.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001649 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001650 PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel.getId(), false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001651
1652 // notDeleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001653 assertEquals(1, mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001654
1655 verify(mHandler, never()).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001656
1657 assertEquals(7, mLogger.getCalls().size());
1658 assertEquals(
1659 NotificationChannelLogger.NotificationChannelEvent
1660 .NOTIFICATION_CHANNEL_GROUP_DELETED,
1661 mLogger.get(5).event); // Next-to-last log is the deletion of the channel group.
1662 assertEquals(
1663 NotificationChannelLogger.NotificationChannelEvent
1664 .NOTIFICATION_CHANNEL_DELETED,
1665 mLogger.get(6).event); // Final log is the deletion of the channel.
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001666 }
1667
1668 @Test
1669 public void testOnUserRemoved() throws Exception {
1670 int[] user0Uids = {98, 235, 16, 3782};
1671 int[] user1Uids = new int[user0Uids.length];
1672 for (int i = 0; i < user0Uids.length; i++) {
1673 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1674
1675 final ApplicationInfo legacy = new ApplicationInfo();
1676 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001677 when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001678
1679 // create records with the default channel for all user 0 and user 1 uids
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001680 mHelper.getImportance(PKG_N_MR1, user0Uids[i]);
1681 mHelper.getImportance(PKG_N_MR1, user1Uids[i]);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001682 }
1683
1684 mHelper.onUserRemoved(1);
1685
1686 // user 0 records remain
1687 for (int i = 0; i < user0Uids.length; i++) {
1688 assertEquals(1,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001689 mHelper.getNotificationChannels(PKG_N_MR1, user0Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001690 }
1691 // user 1 records are gone
1692 for (int i = 0; i < user1Uids.length; i++) {
1693 assertEquals(0,
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001694 mHelper.getNotificationChannels(PKG_N_MR1, user1Uids[i], false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001695 }
1696 }
1697
1698 @Test
1699 public void testOnPackageChanged_packageRemoval() throws Exception {
1700 // Deleted
1701 NotificationChannel channel1 =
1702 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001703 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001704
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001705 assertTrue(mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1},
1706 new int[]{UID_N_MR1}));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001707
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001708 assertEquals(0, mHelper.getNotificationChannels(
1709 PKG_N_MR1, UID_N_MR1, true).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001710
1711 // Not deleted
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001712 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001713
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001714 assertFalse(mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM,
1715 new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001716 assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001717 }
1718
1719 @Test
1720 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001721 mHelper.setImportance(PKG_N_MR1, UID_N_MR1, NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001722
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001723 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1724 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001725
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001726 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1727 UID_N_MR1));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001728 }
1729
1730 @Test
1731 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1732 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001733 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001734 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001735 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001736
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001737 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
1738 UID_N_MR1});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001739
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001740 assertEquals(0, mHelper.getNotificationChannelGroups(
1741 PKG_N_MR1, UID_N_MR1, true, true, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001742 }
1743
1744 @Test
1745 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1746 // create channel as api 26
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001747 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001748
1749 // install new app version targeting 25
1750 final ApplicationInfo legacy = new ApplicationInfo();
1751 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001752 when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(legacy);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001753 mHelper.onPackagesChanged(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001754 false, UserHandle.USER_SYSTEM, new String[]{PKG_O}, new int[]{UID_O});
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001755
1756 // make sure the default channel was readded
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001757 //assertEquals(2, mHelper.getNotificationChannels(PKG_O, UID_O, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001758 assertNotNull(mHelper.getNotificationChannel(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001759 PKG_O, UID_O, NotificationChannel.DEFAULT_CHANNEL_ID, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001760 }
1761
1762 @Test
Julia Reynolds7af51c52019-04-19 11:08:27 -04001763 public void testClearData() {
1764 ArraySet<String> pkg = new ArraySet<>();
1765 pkg.add(PKG_O);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001766 ArraySet<Pair<String, Integer>> pkgPair = new ArraySet<>();
1767 pkgPair.add(new Pair(PKG_O, UID_O));
Julia Reynolds7af51c52019-04-19 11:08:27 -04001768 mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
1769 mHelper.createNotificationChannelGroup(
1770 PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
1771 mHelper.lockChannelsForOEM(pkg.toArray(new String[]{}));
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04001772 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001773 mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
1774 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
Mady Mellora92268c2020-03-09 17:25:08 -07001775 mHelper.setBubblesAllowed(PKG_O, UID_O, DEFAULT_BUBBLE_PREFERENCE);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001776 mHelper.setShowBadge(PKG_O, UID_O, false);
1777 mHelper.setAppImportanceLocked(PKG_O, UID_O);
1778
1779 mHelper.clearData(PKG_O, UID_O);
1780
1781 assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, UID_O));
Mady Mellora92268c2020-03-09 17:25:08 -07001782 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), DEFAULT_BUBBLE_PREFERENCE);
Julia Reynolds7af51c52019-04-19 11:08:27 -04001783 assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
1784 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
1785 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
1786 assertEquals(0, mHelper.getNotificationChannels(PKG_O, UID_O, true).getList().size());
1787 assertEquals(0, mHelper.getNotificationChannelGroups(PKG_O, UID_O).size());
1788
1789 NotificationChannel channel = getChannel();
1790 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
1791
1792 assertTrue(channel.isImportanceLockedByCriticalDeviceFunction());
1793 assertTrue(channel.isImportanceLockedByOEM());
1794 }
1795
1796 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001797 public void testRecordDefaults() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001798 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
1799 UID_N_MR1));
1800 assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
1801 assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001802 }
1803
1804 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001805 public void testCreateGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001806 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001807 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001808 assertEquals(ncg,
1809 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).iterator().next());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001810 verify(mHandler, never()).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001811 assertEquals(1, mLogger.getCalls().size());
1812 assertEquals(
1813 NotificationChannelLogger.NotificationChannelEvent
1814 .NOTIFICATION_CHANNEL_GROUP_CREATED,
1815 mLogger.get(0).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001816 }
1817
1818 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001819 public void testCannotCreateChannel_badGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001820 NotificationChannel channel1 =
1821 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1822 channel1.setGroup("garbage");
1823 try {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001824 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001825 fail("Created a channel with a bad group");
1826 } catch (IllegalArgumentException e) {
1827 }
Will Brockman23db6d42020-02-28 09:51:12 -05001828 assertEquals(0, mLogger.getCalls().size());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001829 }
1830
1831 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001832 public void testCannotCreateChannel_goodGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001833 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001834 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001835 NotificationChannel channel1 =
1836 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1837 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001838 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001839
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001840 assertEquals(ncg.getId(), mHelper.getNotificationChannel(
1841 PKG_N_MR1, UID_N_MR1, channel1.getId(), false).getGroup());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001842 }
1843
1844 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001845 public void testGetChannelGroups() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001846 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001847 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001848 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001849 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001850 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001851 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001852
1853 NotificationChannel channel1 =
1854 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1855 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001856 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001857 NotificationChannel channel1a =
1858 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1859 channel1a.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001860 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001861
1862 NotificationChannel channel2 =
1863 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1864 channel2.setGroup(ncg2.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001865 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001866
1867 NotificationChannel channel3 =
1868 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001869 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001870
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001871 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1872 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001873 assertEquals(3, actual.size());
1874 for (NotificationChannelGroup group : actual) {
1875 if (group.getId() == null) {
1876 assertEquals(2, group.getChannels().size()); // misc channel too
1877 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1878 || channel3.getId().equals(group.getChannels().get(1).getId()));
1879 } else if (group.getId().equals(ncg.getId())) {
1880 assertEquals(2, group.getChannels().size());
1881 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1882 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1883 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1884 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1885 } else {
1886 fail("expected channel not found");
1887 }
1888 } else if (group.getId().equals(ncg2.getId())) {
1889 assertEquals(1, group.getChannels().size());
1890 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1891 }
1892 }
1893 }
1894
1895 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001896 public void testGetChannelGroups_noSideEffects() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001897 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001898 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001899
1900 NotificationChannel channel1 =
1901 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1902 channel1.setGroup(ncg.getId());
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001903 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001904 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001905
1906 channel1.setImportance(IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001907 mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001908
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001909 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1910 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001911
1912 assertEquals(2, actual.size());
1913 for (NotificationChannelGroup group : actual) {
1914 if (Objects.equals(group.getId(), ncg.getId())) {
1915 assertEquals(1, group.getChannels().size());
1916 }
1917 }
1918 }
1919
1920 @Test
Julia Reynolds13ed28b2018-09-21 15:20:13 -04001921 public void testGetChannelGroups_includeEmptyGroups() {
1922 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
1923 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
1924 NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
1925 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true);
1926
1927 NotificationChannel channel1 =
1928 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1929 channel1.setGroup(ncg.getId());
1930 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
1931
1932 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
1933 PKG_N_MR1, UID_N_MR1, false, false, true).getList();
1934
1935 assertEquals(2, actual.size());
1936 for (NotificationChannelGroup group : actual) {
1937 if (Objects.equals(group.getId(), ncg.getId())) {
1938 assertEquals(1, group.getChannels().size());
1939 }
1940 if (Objects.equals(group.getId(), ncgEmpty.getId())) {
1941 assertEquals(0, group.getChannels().size());
1942 }
1943 }
1944 }
1945
1946 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001947 public void testCreateChannel_updateName() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001948 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001949 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001950 NotificationChannel actual =
1951 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001952 assertEquals("hello", actual.getName());
1953
1954 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001955 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001956
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001957 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001958 assertEquals("goodbye", actual.getName());
1959 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1960
1961 verify(mHandler, times(1)).requestSort();
1962 }
1963
1964 @Test
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001965 public void testCreateChannel_addToGroup() {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001966 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001967 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001968 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001969 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Julia Reynoldsb6bd93d2018-10-24 09:22:38 -04001970 NotificationChannel actual =
1971 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001972 assertNull(actual.getGroup());
1973
1974 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1975 nc.setGroup(group.getId());
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04001976 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001977
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04001978 actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001979 assertNotNull(actual.getGroup());
1980 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1981
1982 verify(mHandler, times(1)).requestSort();
Will Brockman23db6d42020-02-28 09:51:12 -05001983 assertEquals(3, mLogger.getCalls().size());
1984 assertEquals(
1985 NotificationChannelLogger.NotificationChannelEvent
1986 .NOTIFICATION_CHANNEL_GROUP_CREATED,
1987 mLogger.get(0).event);
1988 assertEquals(
1989 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
1990 mLogger.get(1).event);
1991 assertEquals(
1992 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED,
1993 mLogger.get(2).event);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001994 }
1995
1996 @Test
1997 public void testDumpChannelsJson() throws Exception {
1998 final ApplicationInfo upgrade = new ApplicationInfo();
1999 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
2000 try {
2001 when(mPm.getApplicationInfoAsUser(
2002 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
2003 } catch (PackageManager.NameNotFoundException e) {
2004 }
2005 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
2006 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
2007 for (int i = 0; i < numPackages; i++) {
2008 String pkgName = "pkg" + i;
2009 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
2010 for (int j = 0; j < numChannels; j++) {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002011 mHelper.createNotificationChannel(pkgName, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002012 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
2013 }
2014 expectedChannels.put(pkgName, numChannels);
2015 }
2016
2017 // delete the first channel of the first package
2018 String pkg = expectedChannels.keyAt(0);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002019 mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002020 // dump should not include deleted channels
2021 int count = expectedChannels.get(pkg);
2022 expectedChannels.put(pkg, count - 1);
2023
2024 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
2025 assertEquals(numPackages, actual.length());
2026 for (int i = 0; i < numPackages; i++) {
2027 JSONObject object = actual.getJSONObject(i);
2028 assertTrue(expectedChannels.containsKey(object.get("packageName")));
2029 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
2030 object.getInt("channelCount"));
2031 }
2032 }
2033
2034 @Test
2035 public void testBadgingOverrideTrue() throws Exception {
2036 Secure.putIntForUser(getContext().getContentResolver(),
2037 Secure.NOTIFICATION_BADGING, 1,
2038 USER.getIdentifier());
2039 mHelper.updateBadgingEnabled(); // would be called by settings observer
2040 assertTrue(mHelper.badgingEnabled(USER));
2041 }
2042
2043 @Test
2044 public void testBadgingOverrideFalse() throws Exception {
2045 Secure.putIntForUser(getContext().getContentResolver(),
2046 Secure.NOTIFICATION_BADGING, 0,
2047 USER.getIdentifier());
2048 mHelper.updateBadgingEnabled(); // would be called by settings observer
2049 assertFalse(mHelper.badgingEnabled(USER));
2050 }
2051
2052 @Test
2053 public void testBadgingForUserAll() throws Exception {
2054 try {
2055 mHelper.badgingEnabled(UserHandle.ALL);
2056 } catch (Exception e) {
2057 fail("just don't throw");
2058 }
2059 }
2060
2061 @Test
2062 public void testBadgingOverrideUserIsolation() throws Exception {
2063 Secure.putIntForUser(getContext().getContentResolver(),
2064 Secure.NOTIFICATION_BADGING, 0,
2065 USER.getIdentifier());
2066 Secure.putIntForUser(getContext().getContentResolver(),
2067 Secure.NOTIFICATION_BADGING, 1,
2068 USER2.getIdentifier());
2069 mHelper.updateBadgingEnabled(); // would be called by settings observer
2070 assertFalse(mHelper.badgingEnabled(USER));
2071 assertTrue(mHelper.badgingEnabled(USER2));
2072 }
2073
2074 @Test
Julia Reynolds4509ce72019-01-31 13:12:43 -05002075 public void testBubblesOverrideTrue() {
Lyn Han4463f842019-07-09 15:27:28 -07002076 Global.putInt(getContext().getContentResolver(),
2077 Global.NOTIFICATION_BUBBLES, 1);
Julia Reynolds4509ce72019-01-31 13:12:43 -05002078 mHelper.updateBubblesEnabled(); // would be called by settings observer
Lyn Han4463f842019-07-09 15:27:28 -07002079 assertTrue(mHelper.bubblesEnabled());
Julia Reynolds4509ce72019-01-31 13:12:43 -05002080 }
2081
2082 @Test
2083 public void testBubblesOverrideFalse() {
Lyn Han4463f842019-07-09 15:27:28 -07002084 Global.putInt(getContext().getContentResolver(),
2085 Global.NOTIFICATION_BUBBLES, 0);
Julia Reynolds4509ce72019-01-31 13:12:43 -05002086 mHelper.updateBubblesEnabled(); // would be called by settings observer
Lyn Han4463f842019-07-09 15:27:28 -07002087 assertFalse(mHelper.bubblesEnabled());
Julia Reynolds4509ce72019-01-31 13:12:43 -05002088 }
2089
2090 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002091 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
2092 String newLabel = "bananas!";
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002093 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
2094 UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002095 NotificationChannel.DEFAULT_CHANNEL_ID, false);
2096 assertFalse(newLabel.equals(defaultChannel.getName()));
2097
2098 Resources res = mock(Resources.class);
2099 when(mContext.getResources()).thenReturn(res);
2100 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
2101 .thenReturn(newLabel);
2102
2103 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
2104
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002105 assertEquals(newLabel, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002106 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
2107 }
2108
2109 @Test
2110 public void testIsGroupBlocked_noGroup() throws Exception {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002111 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, null));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002112
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002113 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, "non existent group"));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002114 }
2115
2116 @Test
2117 public void testIsGroupBlocked_notBlocked() throws Exception {
2118 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002119 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002120
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002121 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002122 }
2123
2124 @Test
2125 public void testIsGroupBlocked_blocked() throws Exception {
2126 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002127 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002128 group.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002129 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002130
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002131 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002132 }
2133
2134 @Test
Julia Reynolds3912e032022-01-12 15:08:29 -05002135 public void testIsGroupBlocked_appCannotCreateAsBlocked() throws Exception {
2136 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
2137 group.setBlocked(true);
2138 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
2139 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
2140
2141 NotificationChannelGroup group3 = group.clone();
2142 group3.setBlocked(false);
2143 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
2144 assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
2145 }
2146
2147 @Test
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002148 public void testIsGroup_appCannotResetBlock() throws Exception {
2149 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002150 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002151 NotificationChannelGroup group2 = group.clone();
2152 group2.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002153 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false);
2154 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002155
2156 NotificationChannelGroup group3 = group.clone();
2157 group3.setBlocked(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002158 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
2159 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002160 }
2161
2162 @Test
2163 public void testGetNotificationChannelGroupWithChannels() throws Exception {
2164 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
2165 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002166 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
2167 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002168
2169 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
2170 a.setGroup(group.getId());
2171 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
2172 b.setGroup(other.getId());
2173 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2174 c.setGroup(group.getId());
2175 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
2176
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002177 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false);
2178 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false);
2179 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false);
2180 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false);
2181 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002182
2183 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002184 PKG_N_MR1, UID_N_MR1, group.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002185 assertEquals(2, retrieved.getChannels().size());
2186 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2187 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
2188
2189 retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002190 PKG_N_MR1, UID_N_MR1, group.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002191 assertEquals(1, retrieved.getChannels().size());
2192 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2193 }
2194
2195 @Test
2196 public void testAndroidPkgCannotBypassDnd_creation() {
2197 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2198 test.setBypassDnd(true);
2199
2200 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2201
2202 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2203 .canBypassDnd());
2204 }
2205
2206 @Test
2207 public void testDndPkgCanBypassDnd_creation() {
2208 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2209 test.setBypassDnd(true);
2210
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002211 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002212
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002213 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002214 }
2215
2216 @Test
2217 public void testNormalPkgCannotBypassDnd_creation() {
2218 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2219 test.setBypassDnd(true);
2220
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002221 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002222
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002223 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002224 }
2225
2226 @Test
2227 public void testAndroidPkgCannotBypassDnd_update() throws Exception {
2228 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2229 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2230
2231 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2232 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002233 assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002234
2235 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2236 .canBypassDnd());
2237 }
2238
2239 @Test
2240 public void testDndPkgCanBypassDnd_update() throws Exception {
2241 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002242 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002243
2244 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2245 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002246 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002247
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002248 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002249 }
2250
2251 @Test
2252 public void testNormalPkgCannotBypassDnd_update() {
2253 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002254 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002255 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2256 update.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002257 mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false);
2258 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002259 }
2260
2261 @Test
2262 public void testGetBlockedAppCount_noApps() {
2263 assertEquals(0, mHelper.getBlockedAppCount(0));
2264 }
2265
2266 @Test
2267 public void testGetBlockedAppCount_noAppsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002268 mHelper.setEnabled(PKG_N_MR1, 100, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002269 assertEquals(0, mHelper.getBlockedAppCount(9));
2270 }
2271
2272 @Test
2273 public void testGetBlockedAppCount_appsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002274 mHelper.setEnabled(PKG_N_MR1, 1020, false);
2275 mHelper.setEnabled(PKG_N_MR1, 1030, false);
2276 mHelper.setEnabled(PKG_N_MR1, 1060, false);
2277 mHelper.setEnabled(PKG_N_MR1, 1000, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002278 assertEquals(3, mHelper.getBlockedAppCount(0));
2279 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002280
2281 @Test
Will Brockman7575e052020-06-16 15:05:12 -04002282 public void testAppBlockedLogging() {
2283 mHelper.setEnabled(PKG_N_MR1, 1020, false);
2284 assertEquals(1, mLogger.getCalls().size());
2285 assertEquals(
2286 NotificationChannelLogger.NotificationChannelEvent.APP_NOTIFICATIONS_BLOCKED,
2287 mLogger.get(0).event);
2288 }
2289 @Test
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002290 public void testXml_statusBarIcons_default() throws Exception {
Julia Reynolds2594b472019-04-03 13:30:16 -04002291 String preQXml = "<ranking version=\"1\">\n"
2292 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
2293 + "<channel id=\"something\" name=\"name\" importance=\"2\" "
2294 + "show_badge=\"true\" />\n"
2295 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
2296 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
2297 + "</package>\n"
2298 + "</ranking>\n";
Mady Mellorc888d512020-04-09 14:48:02 -07002299 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002300 mAppOpsManager, mStatsEventBuilderFactory);
Julia Reynolds2594b472019-04-03 13:30:16 -04002301 loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002302
2303 assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2304 mHelper.shouldHideSilentStatusIcons());
2305 }
2306
2307 @Test
2308 public void testXml_statusBarIcons() throws Exception {
2309 mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
2310
Annie Meng8b646fd2019-02-01 18:46:42 +00002311 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002312 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002313 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002314 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002315
2316 assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2317 mHelper.shouldHideSilentStatusIcons());
2318 }
2319
2320 @Test
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002321 public void testSetNotificationDelegate() {
2322 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2323 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2324 }
2325
2326 @Test
2327 public void testRevokeNotificationDelegate() {
2328 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2329 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2330
2331 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2332 }
2333
2334 @Test
2335 public void testRevokeNotificationDelegate_noDelegateExistsNoCrash() {
2336 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2337
2338 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2339 }
2340
2341 @Test
2342 public void testToggleNotificationDelegate() {
2343 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2344 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2345
2346 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2347
2348 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2349 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2350 }
2351
2352 @Test
2353 public void testToggleNotificationDelegate_noDelegateExistsNoCrash() {
2354 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2355 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2356
2357 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2358 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2359 }
2360
2361 @Test
2362 public void testIsDelegateAllowed_noSource() {
2363 assertFalse(mHelper.isDelegateAllowed("does not exist", -1, "whatever", 0));
2364 }
2365
2366 @Test
2367 public void testIsDelegateAllowed_noDelegate() {
2368 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2369
2370 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "whatever", 0));
2371 }
2372
2373 @Test
2374 public void testIsDelegateAllowed_delegateDisabledByApp() {
2375 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2376 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2377
2378 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2379 }
2380
2381 @Test
2382 public void testIsDelegateAllowed_wrongDelegate() {
2383 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2384 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2385
2386 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "banana", 27));
2387 }
2388
2389 @Test
2390 public void testIsDelegateAllowed_delegateDisabledByUser() {
2391 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2392 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2393
2394 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2395 }
2396
2397 @Test
2398 public void testIsDelegateAllowed() {
2399 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2400
2401 assertTrue(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2402 }
2403
2404 @Test
2405 public void testDelegateXml_noDelegate() throws Exception {
2406 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2407
Annie Meng8b646fd2019-02-01 18:46:42 +00002408 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002409 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002410 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002411 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002412
2413 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2414 }
2415
2416 @Test
2417 public void testDelegateXml_delegate() throws Exception {
2418 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
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,
Chris Wren1a934a32020-05-19 13:45:46 -04002422 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002423 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002424
2425 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2426 }
2427
2428 @Test
2429 public void testDelegateXml_disabledDelegate() throws Exception {
2430 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2431 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2432
Annie Meng8b646fd2019-02-01 18:46:42 +00002433 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002434 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002435 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002436 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002437
2438 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2439 }
2440
2441 @Test
2442 public void testDelegateXml_userDisabledDelegate() throws Exception {
2443 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2444 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2445
Annie Meng8b646fd2019-02-01 18:46:42 +00002446 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002447 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002448 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002449 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002450
2451 // appears disabled
2452 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2453
2454 // but was loaded and can be toggled back on
2455 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2456 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2457 }
2458
2459 @Test
2460 public void testDelegateXml_entirelyDisabledDelegate() throws Exception {
2461 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2462 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2463 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2464
Annie Meng8b646fd2019-02-01 18:46:42 +00002465 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002466 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002467 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002468 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002469
2470 // appears disabled
2471 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2472
2473 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2474 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2475
2476 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2477 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2478 }
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002479
2480 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002481 public void testBubblePreference_defaults() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07002482 assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002483
Annie Meng8b646fd2019-02-01 18:46:42 +00002484 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002485 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002486 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002487 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002488
Mady Mellorc888d512020-04-09 14:48:02 -07002489 assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002490 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2491 }
2492
2493 @Test
Mady Mellorc888d512020-04-09 14:48:02 -07002494 public void testBubblePreference_upgradeWithSAWPermission() throws Exception {
2495 when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
2496 anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);
2497
2498 final String xml = "<ranking version=\"1\">\n"
2499 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
2500 + "<channel id=\"someId\" name=\"hi\""
2501 + " importance=\"3\"/>"
2502 + "</package>"
2503 + "</ranking>";
2504 XmlPullParser parser = Xml.newPullParser();
2505 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2506 null);
2507 parser.nextTag();
2508 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2509
2510 assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
2511 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2512 }
2513
2514 @Test
2515 public void testBubblePreference_upgradeWithSAWThenUserOverride() throws Exception {
2516 when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
2517 anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);
2518
2519 final String xml = "<ranking version=\"1\">\n"
2520 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
2521 + "<channel id=\"someId\" name=\"hi\""
2522 + " importance=\"3\"/>"
2523 + "</package>"
2524 + "</ranking>";
2525 XmlPullParser parser = Xml.newPullParser();
2526 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2527 null);
2528 parser.nextTag();
2529 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2530
2531 assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
2532 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2533
2534 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
2535 assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
2536 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
2537 mHelper.getAppLockedFields(PKG_O, UID_O));
2538
2539 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
2540 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002541 mAppOpsManager, mStatsEventBuilderFactory);
Mady Mellorc888d512020-04-09 14:48:02 -07002542 loadStreamXml(baos, false, UserHandle.USER_ALL);
2543
2544 assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
2545 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
2546 mHelper.getAppLockedFields(PKG_O, UID_O));
2547 }
2548
2549 @Test
Mady Mellorbccdf452020-05-27 11:57:12 -07002550 public void testBubblePrefence_noSAWCheckForUnknownUid() throws Exception {
2551 final String xml = "<ranking version=\"1\">\n"
2552 + "<package name=\"" + PKG_O + "\" uid=\"" + UNKNOWN_UID + "\">\n"
2553 + "<channel id=\"someId\" name=\"hi\""
2554 + " importance=\"3\"/>"
2555 + "</package>"
2556 + "</ranking>";
2557 XmlPullParser parser = Xml.newPullParser();
2558 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2559 null);
2560 parser.nextTag();
2561 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2562
2563 assertEquals(DEFAULT_BUBBLE_PREFERENCE, mHelper.getBubblePreference(PKG_O, UID_O));
2564 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2565 verify(mAppOpsManager, never()).noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
2566 anyString(), eq(null), anyString());
2567 }
2568
2569 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002570 public void testBubblePreference_xml() throws Exception {
2571 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
2572 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002573 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002574 mHelper.getAppLockedFields(PKG_O, UID_O));
2575
Annie Meng8b646fd2019-02-01 18:46:42 +00002576 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002577 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002578 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002579 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002580
Mady Mellora92268c2020-03-09 17:25:08 -07002581 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002582 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002583 mHelper.getAppLockedFields(PKG_O, UID_O));
2584 }
Julia Reynolds413ba842019-01-11 10:38:08 -05002585
2586 @Test
2587 public void testLockChannelsForOEM_emptyList() {
2588 mHelper.lockChannelsForOEM(null);
2589 mHelper.lockChannelsForOEM(new String[0]);
2590 // no exception
2591 }
2592
2593 @Test
2594 public void testLockChannelsForOEM_appWide() {
2595 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2596 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2597 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2598 // different uids, same package
2599 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2600 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2601 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2602
2603 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2604
2605 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2606 .isImportanceLockedByOEM());
2607 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2608 .isImportanceLockedByOEM());
2609 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2610 .isImportanceLockedByOEM());
2611 }
2612
2613 @Test
2614 public void testLockChannelsForOEM_onlyGivenPkg() {
2615 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2616 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2617 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2618 mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
2619
2620 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2621
2622 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2623 .isImportanceLockedByOEM());
2624 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
2625 .isImportanceLockedByOEM());
2626 }
2627
2628 @Test
2629 public void testLockChannelsForOEM_channelSpecific() {
2630 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2631 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2632 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2633 // different uids, same package
2634 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2635 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2636 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2637
2638 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
2639
2640 assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2641 .isImportanceLockedByOEM());
2642 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2643 .isImportanceLockedByOEM());
2644 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2645 .isImportanceLockedByOEM());
2646 }
2647
2648 @Test
Julia Reynolds72b28442019-11-12 11:43:39 -05002649 public void testLockChannelsForOEM_channelSpecific_clearData() {
2650 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2651 mHelper.getImportance(PKG_O, UID_O);
2652 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":" + a.getId()});
2653 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2654 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2655 .isImportanceLockedByOEM());
2656
2657 mHelper.clearData(PKG_O, UID_O);
2658
2659 // it's back!
2660 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2661 // and still locked
2662 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2663 .isImportanceLockedByOEM());
2664 }
2665
2666 @Test
Julia Reynolds413ba842019-01-11 10:38:08 -05002667 public void testLockChannelsForOEM_channelDoesNotExistYet_appWide() {
2668 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2669 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2670 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2671
2672 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2673
2674 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2675 .isImportanceLockedByOEM());
2676
2677 mHelper.createNotificationChannel(PKG_O, 3, b, true, false);
2678 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2679 .isImportanceLockedByOEM());
2680 }
2681
2682 @Test
2683 public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific() {
2684 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2685 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2686 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2687
2688 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"});
2689
2690 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2691 .isImportanceLockedByOEM());
2692
2693 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2694 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2695 .isImportanceLockedByOEM());
2696 }
2697
2698 @Test
2699 public void testUpdateNotificationChannel_oemLockedImportance() {
2700 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2701 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2702
2703 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2704
2705 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002706 update.setAllowBubbles(false);
Julia Reynolds413ba842019-01-11 10:38:08 -05002707
2708 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2709
2710 assertEquals(IMPORTANCE_HIGH,
2711 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2712 assertEquals(false,
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002713 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
Julia Reynolds413ba842019-01-11 10:38:08 -05002714
2715 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2716
2717 assertEquals(IMPORTANCE_HIGH,
2718 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2719 }
Julia Reynolds0c245002019-03-27 16:10:11 -04002720
2721 @Test
2722 public void testUpdateDefaultApps_add_multiUser() {
2723 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2724 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2725 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2726 // different uids, same package
2727 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2728 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2729 mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
2730
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002731 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2732 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002733 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2734
2735 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2736 .isImportanceLockedByCriticalDeviceFunction());
2737 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2738 .isImportanceLockedByCriticalDeviceFunction());
2739 assertFalse(mHelper.getNotificationChannel(
2740 PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false)
2741 .isImportanceLockedByCriticalDeviceFunction());
2742 }
2743
2744 @Test
2745 public void testUpdateDefaultApps_add_onlyGivenPkg() {
2746 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2747 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2748 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2749 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2750
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002751 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2752 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002753 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2754
Julia Reynolds0c245002019-03-27 16:10:11 -04002755 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2756 .isImportanceLockedByCriticalDeviceFunction());
2757 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2758 .isImportanceLockedByCriticalDeviceFunction());
2759 }
2760
2761 @Test
2762 public void testUpdateDefaultApps_remove() {
2763 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2764 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2765 // different uids, same package
2766 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2767 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2768
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002769 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2770 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002771 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2772
2773 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2774 .isImportanceLockedByCriticalDeviceFunction());
2775 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2776 .isImportanceLockedByCriticalDeviceFunction());
2777
2778 ArraySet<String> toRemove = new ArraySet<>();
2779 toRemove.add(PKG_O);
2780 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, null);
2781
2782 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2783 .isImportanceLockedByCriticalDeviceFunction());
2784 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2785 .isImportanceLockedByCriticalDeviceFunction());
2786 }
2787
2788 @Test
2789 public void testUpdateDefaultApps_addAndRemove() {
2790 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2791 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2792 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2793 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2794
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002795 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2796 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002797 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2798
2799
2800 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2801 .isImportanceLockedByCriticalDeviceFunction());
2802 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2803 .isImportanceLockedByCriticalDeviceFunction());
2804
2805 // now the default is PKG_N_MR1
2806 ArraySet<String> toRemove = new ArraySet<>();
2807 toRemove.add(PKG_O);
2808 toAdd = new ArraySet<>();
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002809 toAdd.add(new Pair(PKG_N_MR1, UID_N_MR1));
Julia Reynolds0c245002019-03-27 16:10:11 -04002810 mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd);
2811
2812 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2813 .isImportanceLockedByCriticalDeviceFunction());
2814 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2815 .isImportanceLockedByCriticalDeviceFunction());
2816 }
2817
2818 @Test
2819 public void testUpdateDefaultApps_appDoesNotExist_noCrash() {
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002820 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2821 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002822 ArraySet<String> toRemove = new ArraySet<>();
2823 toRemove.add(PKG_N_MR1);
2824 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd);
2825 }
2826
2827 @Test
2828 public void testUpdateDefaultApps_channelDoesNotExistYet() {
2829 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2830 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2831 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2832
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002833 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2834 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002835 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2836
2837 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2838 .isImportanceLockedByCriticalDeviceFunction());
2839
2840 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2841 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2842 .isImportanceLockedByCriticalDeviceFunction());
2843 }
2844
2845 @Test
2846 public void testUpdateNotificationChannel_defaultAppLockedImportance() {
2847 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2848 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002849 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2850 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002851 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2852
2853 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
2854 update.setAllowBubbles(false);
2855
2856 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
Julia Reynolds0c245002019-03-27 16:10:11 -04002857 assertEquals(IMPORTANCE_HIGH,
2858 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2859 assertEquals(false,
2860 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
2861
2862 mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
Julia Reynolds0c245002019-03-27 16:10:11 -04002863 assertEquals(IMPORTANCE_HIGH,
2864 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Beverly47679222019-05-16 15:46:11 -04002865
2866 NotificationChannel updateImportanceLow = new NotificationChannel("a", "a",
2867 IMPORTANCE_LOW);
2868 mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true);
2869 assertEquals(IMPORTANCE_LOW,
2870 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Julia Reynolds0c245002019-03-27 16:10:11 -04002871 }
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002872
2873 @Test
2874 public void testDefaultApp_appHasNoSettingsYet() {
2875 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2876 toAdd.add(new Pair(PKG_O, UID_O));
2877 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2878
2879 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2880 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2881
2882 assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
2883 }
2884
2885 @Test
2886 public void testChannelXml_backupDefaultApp() throws Exception {
2887 NotificationChannel channel1 =
2888 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
2889
2890 mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
2891
2892 // clear data
2893 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
2894 UserHandle.USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
2895 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_O}, new int[]{
2896 UID_O});
2897
2898 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2899 toAdd.add(new Pair(PKG_O, UID_O));
2900 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2901
2902 XmlPullParser parser = Xml.newPullParser();
2903 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
2904 null);
2905 parser.nextTag();
2906 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
2907
2908 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, channel1.getId(), false)
2909 .isImportanceLockedByCriticalDeviceFunction());
2910 }
Mady Mellor9f296142019-05-24 09:42:52 -07002911
2912 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002913 public void testSetBubblesAllowed_none() {
2914 // Change it to non-default first
2915 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL);
2916 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL);
2917 verify(mHandler, times(1)).requestSort();
2918 reset(mHandler);
2919 // Now test
2920 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
2921 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
2922 verify(mHandler, times(1)).requestSort();
2923 }
2924
2925 @Test
2926 public void testSetBubblesAllowed_all() {
2927 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL);
2928 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL);
2929 verify(mHandler, times(1)).requestSort();
2930 }
2931
2932 @Test
2933 public void testSetBubblesAllowed_selected() {
2934 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
2935 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_SELECTED);
Mady Mellor9f296142019-05-24 09:42:52 -07002936 verify(mHandler, times(1)).requestSort();
2937 }
Julia Reynoldsc29370a2019-08-20 16:08:42 -04002938
2939 @Test
2940 public void testTooManyChannels() {
2941 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2942 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2943 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2944 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2945 }
2946 try {
2947 NotificationChannel channel = new NotificationChannel(
2948 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2949 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2950 NotificationManager.IMPORTANCE_HIGH);
2951 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2952 fail("Allowed to create too many notification channels");
2953 } catch (IllegalStateException e) {
2954 // great
2955 }
2956 }
2957
2958 @Test
2959 public void testTooManyChannels_xml() throws Exception {
2960 String extraChannel = "EXTRA";
2961 String extraChannel1 = "EXTRA1";
2962
2963 // create first... many... directly so we don't need a big xml blob in this test
2964 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2965 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2966 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2967 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2968 }
2969
2970 final String xml = "<ranking version=\"1\">\n"
2971 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
2972 + "<channel id=\"" + extraChannel + "\" name=\"hi\" importance=\"3\"/>"
2973 + "<channel id=\"" + extraChannel1 + "\" name=\"hi\" importance=\"3\"/>"
2974 + "</package>"
2975 + "</ranking>";
2976 XmlPullParser parser = Xml.newPullParser();
2977 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2978 null);
2979 parser.nextTag();
2980 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2981
2982 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true));
2983 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true));
2984 }
Julia Reynoldsdb34c1b2019-11-08 10:58:15 -05002985
2986 @Test
2987 public void testRestoreMultiUser() throws Exception {
2988 String pkg = "restore_pkg";
2989 String channelId = "channelId";
2990 int user0Importance = 3;
2991 int user10Importance = 4;
2992 when(mPm.getPackageUidAsUser(eq(pkg), anyInt())).thenReturn(UserHandle.USER_NULL);
2993
2994 // both users have the same package, but different notification settings
2995 final String xmlUser0 = "<ranking version=\"1\">\n"
2996 + "<package name=\"" + pkg + "\" >\n"
2997 + "<channel id=\"" + channelId + "\" name=\"hi\""
2998 + " importance=\"" + user0Importance + "\"/>"
2999 + "</package>"
3000 + "</ranking>";
3001 final String xmlUser10 = "<ranking version=\"1\">\n"
3002 + "<package name=\"" + pkg + "\" >\n"
3003 + "<channel id=\"" + channelId + "\" name=\"hi\""
3004 + " importance=\"" + user10Importance + "\"/>"
3005 + "</package>"
3006 + "</ranking>";
3007
3008 // trigger a restore for both users
3009 XmlPullParser parser = Xml.newPullParser();
3010 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser0.getBytes())),
3011 null);
3012 parser.nextTag();
3013 mHelper.readXml(parser, true, 0);
3014 parser = Xml.newPullParser();
3015 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser10.getBytes())),
3016 null);
3017 parser.nextTag();
3018 mHelper.readXml(parser, true, 10);
3019
3020 // "install" package on both users
3021 String[] pkgList = new String[] {pkg};
3022 int[] uidList0 = new int[] {UserHandle.PER_USER_RANGE};
3023 int[] uidList10 = new int[] {UserHandle.PER_USER_RANGE + 1};
3024 when(mPm.getPackageUidAsUser(pkg, 0)).thenReturn(uidList0[0]);
3025 when(mPm.getPackageUidAsUser(pkg, 10)).thenReturn(uidList10[0]);
3026 ApplicationInfo info = new ApplicationInfo();
3027 info.targetSdkVersion = Build.VERSION_CODES.Q;
3028 when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(info);
3029
3030 mHelper.onPackagesChanged(false, 0, pkgList, uidList0);
3031 mHelper.onPackagesChanged(false, 10, pkgList, uidList10);
3032
3033 assertEquals(user0Importance,
3034 mHelper.getNotificationChannel(pkg, uidList0[0], channelId, false).getImportance());
3035 assertEquals(user10Importance, mHelper.getNotificationChannel(
3036 pkg, uidList10[0], channelId, false).getImportance());
3037 }
Julia Reynolds0f767342019-12-18 09:11:55 -05003038
3039 @Test
3040 public void testGetConversationNotificationChannel() {
3041 String conversationId = "friend";
3042
3043 NotificationChannel parent =
3044 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3045 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3046
3047 NotificationChannel friend = new NotificationChannel(String.format(
3048 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId),
3049 "messages", IMPORTANCE_DEFAULT);
3050 friend.setConversationId(parent.getId(), conversationId);
3051 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3052
Julia Reynolds12ba4cf2020-01-10 16:01:38 -05003053 compareChannelsParentChild(parent, mHelper.getConversationNotificationChannel(
3054 PKG_O, UID_O, parent.getId(), conversationId, false, false), conversationId);
3055 }
3056
3057 @Test
3058 public void testGetNotificationChannel_conversationProvidedByNotCustomizedYet() {
3059 String conversationId = "friend";
3060
3061 NotificationChannel parent =
3062 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3063 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3064
3065 compareChannels(parent, mHelper.getConversationNotificationChannel(
3066 PKG_O, UID_O, parent.getId(), conversationId, true, false));
Julia Reynolds0f767342019-12-18 09:11:55 -05003067 }
3068
3069 @Test
3070 public void testConversationNotificationChannelsRequireParents() {
3071 String parentId = "does not exist";
3072 String conversationId = "friend";
3073
3074 NotificationChannel friend = new NotificationChannel(String.format(
3075 CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId),
3076 "messages", IMPORTANCE_DEFAULT);
3077 friend.setConversationId(parentId, conversationId);
3078
3079 try {
3080 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3081 fail("allowed creation of conversation channel without a parent");
3082 } catch (IllegalArgumentException e) {
3083 // good
3084 }
3085 }
Julia Reynolds7c267522020-01-16 11:26:41 -05003086
3087 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003088 public void testPlaceholderConversationId_shortcutRequired() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07003089 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04003090 mAppOpsManager, mStatsEventBuilderFactory);
Julia Reynolds7c267522020-01-16 11:26:41 -05003091
3092 final String xml = "<ranking version=\"1\">\n"
3093 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3094 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
3095 + "</package>"
3096 + "</ranking>";
3097 XmlPullParser parser = Xml.newPullParser();
3098 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3099 null);
3100 parser.nextTag();
3101 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3102
3103 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3104 }
3105
3106 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003107 public void testNormalConversationId_shortcutRequired() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07003108 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04003109 mAppOpsManager, mStatsEventBuilderFactory);
Julia Reynolds7c267522020-01-16 11:26:41 -05003110
3111 final String xml = "<ranking version=\"1\">\n"
3112 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3113 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"other\"/>"
3114 + "</package>"
3115 + "</ranking>";
3116 XmlPullParser parser = Xml.newPullParser();
3117 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3118 null);
3119 parser.nextTag();
3120 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3121
3122 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3123 }
3124
3125 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003126 public void testNoConversationId_shortcutRequired() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07003127 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04003128 mAppOpsManager, mStatsEventBuilderFactory);
Julia Reynolds7c267522020-01-16 11:26:41 -05003129
3130 final String xml = "<ranking version=\"1\">\n"
3131 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3132 + "<channel id=\"id\" name=\"hi\" importance=\"3\"/>"
3133 + "</package>"
3134 + "</ranking>";
3135 XmlPullParser parser = Xml.newPullParser();
3136 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3137 null);
3138 parser.nextTag();
3139 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3140
3141 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3142 }
Julia Reynolds882f2062020-02-05 12:11:38 -05003143
3144 @Test
Julia Reynolds02971452020-02-14 16:44:19 -05003145 public void testGetConversations_all() {
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 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3161
3162 NotificationChannel diffConvo =
3163 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3164 diffConvo.setConversationId(p.getId(), "different convo");
3165 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3166
3167 NotificationChannel channel2 =
3168 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3169 channel2.setConversationId(calls.getId(), convoId);
3170 channel2.setImportantConversation(true);
3171 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3172
3173 List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
3174
3175 assertEquals(3, convos.size());
3176 assertTrue(conversationWrapperContainsChannel(convos, channel));
3177 assertTrue(conversationWrapperContainsChannel(convos, diffConvo));
3178 assertTrue(conversationWrapperContainsChannel(convos, channel2));
3179 }
3180
3181 @Test
Julia Reynoldsb1b9d642020-04-22 16:18:44 -04003182 public void testGetConversations_notDemoted() {
3183 String convoId = "convo";
3184 NotificationChannel messages =
3185 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3186 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3187 NotificationChannel calls =
3188 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3189 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3190 NotificationChannel p =
3191 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3192 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3193
3194 NotificationChannel channel =
3195 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3196 channel.setConversationId(messages.getId(), convoId);
3197 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3198
3199 NotificationChannel diffConvo =
3200 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3201 diffConvo.setConversationId(p.getId(), "different convo");
3202 diffConvo.setDemoted(true);
3203 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3204
3205 NotificationChannel channel2 =
3206 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3207 channel2.setConversationId(calls.getId(), convoId);
3208 channel2.setImportantConversation(true);
3209 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3210
3211 List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
3212
3213 assertEquals(2, convos.size());
3214 assertTrue(conversationWrapperContainsChannel(convos, channel));
3215 assertFalse(conversationWrapperContainsChannel(convos, diffConvo));
3216 assertTrue(conversationWrapperContainsChannel(convos, channel2));
3217 }
3218
3219 @Test
Julia Reynolds02971452020-02-14 16:44:19 -05003220 public void testGetConversations_onlyImportant() {
3221 String convoId = "convo";
3222 NotificationChannel messages =
3223 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3224 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3225 NotificationChannel calls =
3226 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3227 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3228 NotificationChannel p =
3229 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3230 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3231
3232 NotificationChannel channel =
3233 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3234 channel.setConversationId(messages.getId(), convoId);
3235 channel.setImportantConversation(true);
3236 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3237
3238 NotificationChannel diffConvo =
3239 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3240 diffConvo.setConversationId(p.getId(), "different convo");
3241 diffConvo.setImportantConversation(true);
3242 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3243
3244 NotificationChannel channel2 =
3245 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3246 channel2.setConversationId(calls.getId(), convoId);
3247 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3248
3249 List<ConversationChannelWrapper> convos = mHelper.getConversations(true);
3250
3251 assertEquals(2, convos.size());
3252 assertTrue(conversationWrapperContainsChannel(convos, channel));
3253 assertTrue(conversationWrapperContainsChannel(convos, diffConvo));
3254 assertFalse(conversationWrapperContainsChannel(convos, channel2));
3255 }
3256
3257 private boolean conversationWrapperContainsChannel(List<ConversationChannelWrapper> list,
3258 NotificationChannel expected) {
3259 for (ConversationChannelWrapper ccw : list) {
3260 if (ccw.getNotificationChannel().equals(expected)) {
3261 return true;
3262 }
3263 }
3264
3265 return false;
3266 }
3267
3268 @Test
Julia Reynolds882f2062020-02-05 12:11:38 -05003269 public void testGetConversations_invalidPkg() {
3270 assertThat(mHelper.getConversations("bad", 1)).isEmpty();
3271 }
3272
3273 @Test
3274 public void testGetConversations_noConversations() {
3275 NotificationChannel channel =
3276 new NotificationChannel("not_convo", "not_convo", IMPORTANCE_DEFAULT);
3277 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3278
3279 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3280 }
3281
3282 @Test
3283 public void testGetConversations_noDisabledGroups() {
3284 NotificationChannelGroup group = new NotificationChannelGroup("a", "a");
3285 group.setBlocked(true);
Julia Reynolds3912e032022-01-12 15:08:29 -05003286 mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, false);
Julia Reynolds882f2062020-02-05 12:11:38 -05003287 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3288 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3289
3290 NotificationChannel channel =
3291 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3292 channel.setConversationId("parent", "convo");
3293 channel.setGroup(group.getId());
3294 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3295
3296 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3297 }
3298
3299 @Test
3300 public void testGetConversations_noDeleted() {
3301 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3302 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3303 NotificationChannel channel =
3304 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3305 channel.setConversationId("parent", "convo");
3306 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3307 mHelper.deleteNotificationChannel(PKG_O, UID_O, channel.getId());
3308
3309 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3310 }
3311
3312 @Test
Julia Reynolds8582df52020-04-24 18:30:59 -04003313 public void testGetConversations_noDemoted() {
3314 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3315 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3316 NotificationChannel channel =
3317 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3318 channel.setConversationId("parent", "convo");
3319 channel.setDemoted(true);
3320 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3321
3322 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3323 }
3324
3325 @Test
Julia Reynolds882f2062020-02-05 12:11:38 -05003326 public void testGetConversations() {
3327 NotificationChannelGroup group = new NotificationChannelGroup("acct", "account_name");
3328 mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
3329
3330 NotificationChannel messages =
3331 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3332 messages.setGroup(group.getId());
3333 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3334 NotificationChannel calls =
3335 new NotificationChannel("calls", "Calls", IMPORTANCE_HIGH);
3336 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3337
3338 NotificationChannel channel =
3339 new NotificationChannel("A person", "A lovely person", IMPORTANCE_DEFAULT);
3340 channel.setGroup(group.getId());
3341 channel.setConversationId(messages.getId(), channel.getName().toString());
3342 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3343
3344 NotificationChannel channel2 =
3345 new NotificationChannel("B person", "B fabulous person", IMPORTANCE_DEFAULT);
Julia Reynoldsa625b942020-02-15 09:42:23 -05003346 channel2.setConversationId(calls.getId(), channel2.getName().toString());
Julia Reynolds882f2062020-02-05 12:11:38 -05003347 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3348
3349 Map<String, NotificationChannel> expected = new HashMap<>();
3350 expected.put(channel.getId(), channel);
3351 expected.put(channel2.getId(), channel2);
3352
3353 Map<String, CharSequence> expectedGroup = new HashMap<>();
3354 expectedGroup.put(channel.getId(), group.getName());
3355 expectedGroup.put(channel2.getId(), null);
3356
3357 Map<String, CharSequence> expectedParentLabel= new HashMap<>();
3358 expectedParentLabel.put(channel.getId(), messages.getName());
3359 expectedParentLabel.put(channel2.getId(), calls.getName());
3360
3361 ArrayList<ConversationChannelWrapper> convos = mHelper.getConversations(PKG_O, UID_O);
3362 assertThat(convos).hasSize(2);
3363
3364 for (ConversationChannelWrapper convo : convos) {
3365 assertThat(convo.getNotificationChannel())
3366 .isEqualTo(expected.get(convo.getNotificationChannel().getId()));
3367 assertThat(convo.getParentChannelLabel())
3368 .isEqualTo(expectedParentLabel.get(convo.getNotificationChannel().getId()));
3369 assertThat(convo.getGroupLabel())
3370 .isEqualTo(expectedGroup.get(convo.getNotificationChannel().getId()));
3371 }
3372 }
Julia Reynoldsa625b942020-02-15 09:42:23 -05003373
3374 @Test
3375 public void testDeleteConversation() {
3376 String convoId = "convo";
3377 NotificationChannel messages =
3378 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3379 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3380 NotificationChannel calls =
3381 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3382 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3383
3384 NotificationChannel channel =
3385 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3386 channel.setConversationId(messages.getId(), convoId);
3387 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3388
3389 NotificationChannel noMatch =
3390 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3391 noMatch.setConversationId(messages.getId(), "different convo");
3392 mHelper.createNotificationChannel(PKG_O, UID_O, noMatch, true, false);
3393
3394 NotificationChannel channel2 =
3395 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3396 channel2.setConversationId(calls.getId(), convoId);
3397 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3398
3399 assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
3400 assertEquals(channel2,
3401 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
3402 assertEquals(2, mHelper.deleteConversation(PKG_O, UID_O, convoId).size());
3403
3404 assertEquals(messages,
3405 mHelper.getNotificationChannel(PKG_O, UID_O, messages.getId(), false));
3406 assertEquals(noMatch,
3407 mHelper.getNotificationChannel(PKG_O, UID_O, noMatch.getId(), false));
3408
3409 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
3410 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
3411 assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), true));
3412 assertEquals(channel2,
3413 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), true));
Will Brockman23db6d42020-02-28 09:51:12 -05003414
3415 assertEquals(7, mLogger.getCalls().size());
3416 assertEquals(
3417 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
3418 mLogger.get(0).event); // Channel messages
3419 assertEquals(
3420 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
3421 mLogger.get(1).event); // Channel calls
3422 assertEquals(
3423 NotificationChannelLogger.NotificationChannelEvent
3424 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3425 mLogger.get(2).event); // Channel channel - Conversation A person msgs
3426 assertEquals(
3427 NotificationChannelLogger.NotificationChannelEvent
3428 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3429 mLogger.get(3).event); // Channel noMatch - Conversation B person msgs
3430 assertEquals(
3431 NotificationChannelLogger.NotificationChannelEvent
3432 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3433 mLogger.get(4).event); // Channel channel2 - Conversation A person calls
3434 assertEquals(
3435 NotificationChannelLogger.NotificationChannelEvent
3436 .NOTIFICATION_CHANNEL_CONVERSATION_DELETED,
3437 mLogger.get(5).event); // Delete Channel channel - Conversation A person msgs
3438 assertEquals(
3439 NotificationChannelLogger.NotificationChannelEvent
3440 .NOTIFICATION_CHANNEL_CONVERSATION_DELETED,
3441 mLogger.get(6).event); // Delete Channel channel2 - Conversation A person calls
Julia Reynoldsa625b942020-02-15 09:42:23 -05003442 }
Julia Reynoldsa7dac432020-04-23 12:17:31 -04003443
3444 @Test
Julia Reynoldsbc23c7e2020-05-13 18:16:32 -04003445 public void testInvalidMessageSent() {
Julia Reynoldsa7dac432020-04-23 12:17:31 -04003446 // create package preferences
3447 mHelper.canShowBadge(PKG_P, UID_P);
3448
3449 // check default value
Julia Reynoldsbc23c7e2020-05-13 18:16:32 -04003450 assertFalse(mHelper.isInInvalidMsgState(PKG_P, UID_P));
Julia Reynoldsa7dac432020-04-23 12:17:31 -04003451
3452 // change it
Julia Reynoldsbc23c7e2020-05-13 18:16:32 -04003453 mHelper.setInvalidMessageSent(PKG_P, UID_P);
3454 assertTrue(mHelper.isInInvalidMsgState(PKG_P, UID_P));
3455 assertTrue(mHelper.hasSentInvalidMsg(PKG_P, UID_P));
3456 }
3457
3458 @Test
3459 public void testValidMessageSent() {
3460 // create package preferences
3461 mHelper.canShowBadge(PKG_P, UID_P);
3462
3463 // get into the bad state
3464 mHelper.setInvalidMessageSent(PKG_P, UID_P);
3465
3466 // and then fix it
3467 mHelper.setValidMessageSent(PKG_P, UID_P);
3468
3469 assertTrue(mHelper.hasSentValidMsg(PKG_P, UID_P));
3470 assertFalse(mHelper.isInInvalidMsgState(PKG_P, UID_P));
3471 }
3472
3473 @Test
3474 public void testUserDemotedInvalidMsgApp() {
3475 // create package preferences
3476 mHelper.canShowBadge(PKG_P, UID_P);
3477
3478 // demotion means nothing before msg notif sent
3479 mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true);
3480 assertFalse(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
3481
3482 // it's valid when incomplete msgs have been sent
3483 mHelper.setInvalidMessageSent(PKG_P, UID_P);
3484 assertTrue(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
3485
3486 // and is invalid once complete msgs are sent
3487 mHelper.setValidMessageSent(PKG_P, UID_P);
3488 assertFalse(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
Julia Reynoldsa7dac432020-04-23 12:17:31 -04003489 }
Chris Wren1a934a32020-05-19 13:45:46 -04003490
3491 @Test
3492 public void testPullPackageChannelPreferencesStats() {
3493 String channelId = "parent";
3494 String name = "messages";
3495 NotificationChannel fodderA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
3496 mHelper.createNotificationChannel(PKG_O, UID_O, fodderA, true, false);
3497 NotificationChannel channel =
3498 new NotificationChannel(channelId, name, IMPORTANCE_DEFAULT);
3499 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3500 NotificationChannel fodderB = new NotificationChannel("b", "b", IMPORTANCE_HIGH);
3501 mHelper.createNotificationChannel(PKG_O, UID_O, fodderB, true, false);
3502
3503 ArrayList<StatsEvent> events = new ArrayList<>();
3504 mHelper.pullPackageChannelPreferencesStats(events);
3505
3506 int found = 0;
3507 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3508 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
3509 && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
3510 ++found;
3511 assertEquals("uid", UID_O, builder.getValue(UID_FIELD_NUMBER));
3512 assertTrue("uid annotation", builder.getBooleanAnnotation(
3513 UID_FIELD_NUMBER, ANNOTATION_ID_IS_UID));
3514 assertEquals("importance", IMPORTANCE_DEFAULT, builder.getValue(
3515 IMPORTANCE_FIELD_NUMBER));
3516 assertEquals("name", name, builder.getValue(CHANNEL_NAME_FIELD_NUMBER));
3517 assertFalse("isconv", builder.getBoolean(IS_CONVERSATION_FIELD_NUMBER));
3518 assertFalse("deleted", builder.getBoolean(IS_DELETED_FIELD_NUMBER));
3519 }
3520 }
3521 }
3522
3523 @Test
3524 public void testPullPackageChannelPreferencesStats_one_to_one() {
3525 NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
3526 mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
3527 NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_LOW);
3528 mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false);
3529 NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
3530 mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false);
3531
3532 List<String> channels = new LinkedList<>(Arrays.asList("a", "b", "c"));
3533
3534 ArrayList<StatsEvent> events = new ArrayList<>();
3535 mHelper.pullPackageChannelPreferencesStats(events);
3536
3537 int found = 0;
3538 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3539 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES) {
3540 Object id = builder.getValue(CHANNEL_ID_FIELD_NUMBER);
3541 assertTrue("missing channel in the output", channels.contains(id));
3542 channels.remove(id);
3543 }
3544 }
3545 assertTrue("unexpected channel in output", channels.isEmpty());
3546 }
3547
3548 @Test
3549 public void testPullPackageChannelPreferencesStats_conversation() {
3550 String conversationId = "friend";
3551
3552 NotificationChannel parent =
3553 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3554 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3555
3556 String channelId = String.format(
3557 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
3558 String name = "conversation";
3559 NotificationChannel friend = new NotificationChannel(channelId,
3560 name, IMPORTANCE_DEFAULT);
3561 friend.setConversationId(parent.getId(), conversationId);
3562 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3563
3564 ArrayList<StatsEvent> events = new ArrayList<>();
3565 mHelper.pullPackageChannelPreferencesStats(events);
3566
3567 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3568 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
3569 && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
3570 assertTrue("isConveration should be true", builder.getBoolean(
3571 IS_CONVERSATION_FIELD_NUMBER));
3572 assertFalse("not demoted", builder.getBoolean(
3573 IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
3574 assertFalse("not important", builder.getBoolean(
3575 IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
3576 }
3577 }
3578 }
3579
3580 @Test
3581 public void testPullPackageChannelPreferencesStats_conversation_demoted() {
3582 NotificationChannel parent =
3583 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3584 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3585 String channelId = String.format(
3586 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
3587 NotificationChannel friend = new NotificationChannel(channelId,
3588 "conversation", IMPORTANCE_DEFAULT);
3589 friend.setConversationId(parent.getId(), "friend");
3590 friend.setDemoted(true);
3591 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3592
3593 ArrayList<StatsEvent> events = new ArrayList<>();
3594 mHelper.pullPackageChannelPreferencesStats(events);
3595
3596 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3597 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
3598 && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
3599 assertTrue("isConveration should be true", builder.getBoolean(
3600 IS_CONVERSATION_FIELD_NUMBER));
3601 assertTrue("is demoted", builder.getBoolean(
3602 IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
3603 assertFalse("not important", builder.getBoolean(
3604 IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
3605 }
3606 }
3607 }
3608
3609 @Test
3610 public void testPullPackageChannelPreferencesStats_conversation_priority() {
3611 NotificationChannel parent =
3612 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3613 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3614 String channelId = String.format(
3615 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
3616 NotificationChannel friend = new NotificationChannel(channelId,
3617 "conversation", IMPORTANCE_DEFAULT);
3618 friend.setConversationId(parent.getId(), "friend");
3619 friend.setImportantConversation(true);
3620 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3621
3622 ArrayList<StatsEvent> events = new ArrayList<>();
3623 mHelper.pullPackageChannelPreferencesStats(events);
3624
3625 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3626 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
3627 && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
3628 assertTrue("isConveration should be true", builder.getBoolean(
3629 IS_CONVERSATION_FIELD_NUMBER));
3630 assertFalse("not demoted", builder.getBoolean(
3631 IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
3632 assertTrue("is important", builder.getBoolean(
3633 IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
3634 }
3635 }
3636 }
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04003637}