blob: 2e49929ec032797274d57cefea25a33e312cca82 [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
2135 public void testIsGroup_appCannotResetBlock() throws Exception {
2136 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002137 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002138 NotificationChannelGroup group2 = group.clone();
2139 group2.setBlocked(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002140 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false);
2141 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002142
2143 NotificationChannelGroup group3 = group.clone();
2144 group3.setBlocked(false);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002145 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
2146 assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002147 }
2148
2149 @Test
2150 public void testGetNotificationChannelGroupWithChannels() throws Exception {
2151 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
2152 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002153 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
2154 mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002155
2156 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
2157 a.setGroup(group.getId());
2158 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
2159 b.setGroup(other.getId());
2160 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2161 c.setGroup(group.getId());
2162 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
2163
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002164 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false);
2165 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false);
2166 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false);
2167 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false);
2168 mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002169
2170 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002171 PKG_N_MR1, UID_N_MR1, group.getId(), true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002172 assertEquals(2, retrieved.getChannels().size());
2173 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2174 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
2175
2176 retrieved = mHelper.getNotificationChannelGroupWithChannels(
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002177 PKG_N_MR1, UID_N_MR1, group.getId(), false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002178 assertEquals(1, retrieved.getChannels().size());
2179 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
2180 }
2181
2182 @Test
2183 public void testAndroidPkgCannotBypassDnd_creation() {
2184 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2185 test.setBypassDnd(true);
2186
2187 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2188
2189 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2190 .canBypassDnd());
2191 }
2192
2193 @Test
2194 public void testDndPkgCanBypassDnd_creation() {
2195 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2196 test.setBypassDnd(true);
2197
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002198 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002199
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002200 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002201 }
2202
2203 @Test
2204 public void testNormalPkgCannotBypassDnd_creation() {
2205 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2206 test.setBypassDnd(true);
2207
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002208 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002209
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002210 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002211 }
2212
2213 @Test
2214 public void testAndroidPkgCannotBypassDnd_update() throws Exception {
2215 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2216 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
2217
2218 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2219 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002220 assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002221
2222 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
2223 .canBypassDnd());
2224 }
2225
2226 @Test
2227 public void testDndPkgCanBypassDnd_update() throws Exception {
2228 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002229 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002230
2231 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2232 update.setBypassDnd(true);
Julia Reynoldsdafd3a42019-05-24 13:33:28 -04002233 assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002234
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002235 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002236 }
2237
2238 @Test
2239 public void testNormalPkgCannotBypassDnd_update() {
2240 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002241 mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002242 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
2243 update.setBypassDnd(true);
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002244 mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false);
2245 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002246 }
2247
2248 @Test
2249 public void testGetBlockedAppCount_noApps() {
2250 assertEquals(0, mHelper.getBlockedAppCount(0));
2251 }
2252
2253 @Test
2254 public void testGetBlockedAppCount_noAppsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002255 mHelper.setEnabled(PKG_N_MR1, 100, false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002256 assertEquals(0, mHelper.getBlockedAppCount(9));
2257 }
2258
2259 @Test
2260 public void testGetBlockedAppCount_appsForUserId() {
Aaron Heuckroth9ae59f82018-07-13 12:23:36 -04002261 mHelper.setEnabled(PKG_N_MR1, 1020, false);
2262 mHelper.setEnabled(PKG_N_MR1, 1030, false);
2263 mHelper.setEnabled(PKG_N_MR1, 1060, false);
2264 mHelper.setEnabled(PKG_N_MR1, 1000, true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002265 assertEquals(3, mHelper.getBlockedAppCount(0));
2266 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002267
2268 @Test
Will Brockman7575e052020-06-16 15:05:12 -04002269 public void testAppBlockedLogging() {
2270 mHelper.setEnabled(PKG_N_MR1, 1020, false);
2271 assertEquals(1, mLogger.getCalls().size());
2272 assertEquals(
2273 NotificationChannelLogger.NotificationChannelEvent.APP_NOTIFICATIONS_BLOCKED,
2274 mLogger.get(0).event);
2275 }
2276 @Test
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002277 public void testXml_statusBarIcons_default() throws Exception {
Julia Reynolds2594b472019-04-03 13:30:16 -04002278 String preQXml = "<ranking version=\"1\">\n"
2279 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
2280 + "<channel id=\"something\" name=\"name\" importance=\"2\" "
2281 + "show_badge=\"true\" />\n"
2282 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
2283 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
2284 + "</package>\n"
2285 + "</ranking>\n";
Mady Mellorc888d512020-04-09 14:48:02 -07002286 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002287 mAppOpsManager, mStatsEventBuilderFactory);
Julia Reynolds2594b472019-04-03 13:30:16 -04002288 loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002289
2290 assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2291 mHelper.shouldHideSilentStatusIcons());
2292 }
2293
2294 @Test
2295 public void testXml_statusBarIcons() throws Exception {
2296 mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
2297
Annie Meng8b646fd2019-02-01 18:46:42 +00002298 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
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);
Annie Meng8b646fd2019-02-01 18:46:42 +00002301 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05002302
2303 assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
2304 mHelper.shouldHideSilentStatusIcons());
2305 }
2306
2307 @Test
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002308 public void testSetNotificationDelegate() {
2309 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2310 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2311 }
2312
2313 @Test
2314 public void testRevokeNotificationDelegate() {
2315 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2316 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2317
2318 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2319 }
2320
2321 @Test
2322 public void testRevokeNotificationDelegate_noDelegateExistsNoCrash() {
2323 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2324
2325 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2326 }
2327
2328 @Test
2329 public void testToggleNotificationDelegate() {
2330 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2331 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2332
2333 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2334
2335 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2336 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2337 }
2338
2339 @Test
2340 public void testToggleNotificationDelegate_noDelegateExistsNoCrash() {
2341 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2342 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2343
2344 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2345 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2346 }
2347
2348 @Test
2349 public void testIsDelegateAllowed_noSource() {
2350 assertFalse(mHelper.isDelegateAllowed("does not exist", -1, "whatever", 0));
2351 }
2352
2353 @Test
2354 public void testIsDelegateAllowed_noDelegate() {
2355 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2356
2357 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "whatever", 0));
2358 }
2359
2360 @Test
2361 public void testIsDelegateAllowed_delegateDisabledByApp() {
2362 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2363 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2364
2365 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2366 }
2367
2368 @Test
2369 public void testIsDelegateAllowed_wrongDelegate() {
2370 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2371 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2372
2373 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "banana", 27));
2374 }
2375
2376 @Test
2377 public void testIsDelegateAllowed_delegateDisabledByUser() {
2378 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2379 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2380
2381 assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2382 }
2383
2384 @Test
2385 public void testIsDelegateAllowed() {
2386 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2387
2388 assertTrue(mHelper.isDelegateAllowed(PKG_O, UID_O, "other", 53));
2389 }
2390
2391 @Test
2392 public void testDelegateXml_noDelegate() throws Exception {
2393 mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
2394
Annie Meng8b646fd2019-02-01 18:46:42 +00002395 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002396 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002397 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002398 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002399
2400 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2401 }
2402
2403 @Test
2404 public void testDelegateXml_delegate() throws Exception {
2405 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2406
Annie Meng8b646fd2019-02-01 18:46:42 +00002407 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002408 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002409 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002410 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002411
2412 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2413 }
2414
2415 @Test
2416 public void testDelegateXml_disabledDelegate() throws Exception {
2417 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2418 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2419
Annie Meng8b646fd2019-02-01 18:46:42 +00002420 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002421 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
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 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2426 }
2427
2428 @Test
2429 public void testDelegateXml_userDisabledDelegate() throws Exception {
2430 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2431 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
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 // appears disabled
2439 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2440
2441 // but was loaded and can be toggled back on
2442 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2443 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2444 }
2445
2446 @Test
2447 public void testDelegateXml_entirelyDisabledDelegate() throws Exception {
2448 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2449 mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
2450 mHelper.revokeNotificationDelegate(PKG_O, UID_O);
2451
Annie Meng8b646fd2019-02-01 18:46:42 +00002452 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002453 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002454 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002455 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002456
2457 // appears disabled
2458 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2459
2460 mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
2461 assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
2462
2463 mHelper.toggleNotificationDelegate(PKG_O, UID_O, true);
2464 assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
2465 }
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002466
2467 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002468 public void testBubblePreference_defaults() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07002469 assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002470
Annie Meng8b646fd2019-02-01 18:46:42 +00002471 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002472 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002473 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002474 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002475
Mady Mellorc888d512020-04-09 14:48:02 -07002476 assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002477 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2478 }
2479
2480 @Test
Mady Mellorc888d512020-04-09 14:48:02 -07002481 public void testBubblePreference_upgradeWithSAWPermission() throws Exception {
2482 when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
2483 anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);
2484
2485 final String xml = "<ranking version=\"1\">\n"
2486 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
2487 + "<channel id=\"someId\" name=\"hi\""
2488 + " importance=\"3\"/>"
2489 + "</package>"
2490 + "</ranking>";
2491 XmlPullParser parser = Xml.newPullParser();
2492 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2493 null);
2494 parser.nextTag();
2495 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2496
2497 assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
2498 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2499 }
2500
2501 @Test
2502 public void testBubblePreference_upgradeWithSAWThenUserOverride() throws Exception {
2503 when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
2504 anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);
2505
2506 final String xml = "<ranking version=\"1\">\n"
2507 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
2508 + "<channel id=\"someId\" name=\"hi\""
2509 + " importance=\"3\"/>"
2510 + "</package>"
2511 + "</ranking>";
2512 XmlPullParser parser = Xml.newPullParser();
2513 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2514 null);
2515 parser.nextTag();
2516 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2517
2518 assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
2519 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2520
2521 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
2522 assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
2523 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
2524 mHelper.getAppLockedFields(PKG_O, UID_O));
2525
2526 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
2527 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002528 mAppOpsManager, mStatsEventBuilderFactory);
Mady Mellorc888d512020-04-09 14:48:02 -07002529 loadStreamXml(baos, false, UserHandle.USER_ALL);
2530
2531 assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
2532 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
2533 mHelper.getAppLockedFields(PKG_O, UID_O));
2534 }
2535
2536 @Test
Mady Mellorbccdf452020-05-27 11:57:12 -07002537 public void testBubblePrefence_noSAWCheckForUnknownUid() throws Exception {
2538 final String xml = "<ranking version=\"1\">\n"
2539 + "<package name=\"" + PKG_O + "\" uid=\"" + UNKNOWN_UID + "\">\n"
2540 + "<channel id=\"someId\" name=\"hi\""
2541 + " importance=\"3\"/>"
2542 + "</package>"
2543 + "</ranking>";
2544 XmlPullParser parser = Xml.newPullParser();
2545 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2546 null);
2547 parser.nextTag();
2548 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2549
2550 assertEquals(DEFAULT_BUBBLE_PREFERENCE, mHelper.getBubblePreference(PKG_O, UID_O));
2551 assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
2552 verify(mAppOpsManager, never()).noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
2553 anyString(), eq(null), anyString());
2554 }
2555
2556 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002557 public void testBubblePreference_xml() throws Exception {
2558 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
2559 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002560 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002561 mHelper.getAppLockedFields(PKG_O, UID_O));
2562
Annie Meng8b646fd2019-02-01 18:46:42 +00002563 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
Mady Mellorc888d512020-04-09 14:48:02 -07002564 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04002565 mAppOpsManager, mStatsEventBuilderFactory);
Annie Meng8b646fd2019-02-01 18:46:42 +00002566 loadStreamXml(baos, false, UserHandle.USER_ALL);
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002567
Mady Mellora92268c2020-03-09 17:25:08 -07002568 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002569 assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
Julia Reynolds33ab8a02018-12-17 16:19:52 -05002570 mHelper.getAppLockedFields(PKG_O, UID_O));
2571 }
Julia Reynolds413ba842019-01-11 10:38:08 -05002572
2573 @Test
2574 public void testLockChannelsForOEM_emptyList() {
2575 mHelper.lockChannelsForOEM(null);
2576 mHelper.lockChannelsForOEM(new String[0]);
2577 // no exception
2578 }
2579
2580 @Test
2581 public void testLockChannelsForOEM_appWide() {
2582 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2583 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2584 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2585 // different uids, same package
2586 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2587 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2588 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2589
2590 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2591
2592 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2593 .isImportanceLockedByOEM());
2594 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2595 .isImportanceLockedByOEM());
2596 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2597 .isImportanceLockedByOEM());
2598 }
2599
2600 @Test
2601 public void testLockChannelsForOEM_onlyGivenPkg() {
2602 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2603 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2604 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2605 mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
2606
2607 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2608
2609 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2610 .isImportanceLockedByOEM());
2611 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
2612 .isImportanceLockedByOEM());
2613 }
2614
2615 @Test
2616 public void testLockChannelsForOEM_channelSpecific() {
2617 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2618 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2619 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2620 // different uids, same package
2621 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2622 mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
2623 mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
2624
2625 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
2626
2627 assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2628 .isImportanceLockedByOEM());
2629 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2630 .isImportanceLockedByOEM());
2631 assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
2632 .isImportanceLockedByOEM());
2633 }
2634
2635 @Test
Julia Reynolds72b28442019-11-12 11:43:39 -05002636 public void testLockChannelsForOEM_channelSpecific_clearData() {
2637 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2638 mHelper.getImportance(PKG_O, UID_O);
2639 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":" + a.getId()});
2640 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2641 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2642 .isImportanceLockedByOEM());
2643
2644 mHelper.clearData(PKG_O, UID_O);
2645
2646 // it's back!
2647 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2648 // and still locked
2649 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2650 .isImportanceLockedByOEM());
2651 }
2652
2653 @Test
Julia Reynolds413ba842019-01-11 10:38:08 -05002654 public void testLockChannelsForOEM_channelDoesNotExistYet_appWide() {
2655 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2656 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2657 mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
2658
2659 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2660
2661 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
2662 .isImportanceLockedByOEM());
2663
2664 mHelper.createNotificationChannel(PKG_O, 3, b, true, false);
2665 assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
2666 .isImportanceLockedByOEM());
2667 }
2668
2669 @Test
2670 public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific() {
2671 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2672 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2673 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2674
2675 mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"});
2676
2677 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2678 .isImportanceLockedByOEM());
2679
2680 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2681 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2682 .isImportanceLockedByOEM());
2683 }
2684
2685 @Test
2686 public void testUpdateNotificationChannel_oemLockedImportance() {
2687 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2688 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2689
2690 mHelper.lockChannelsForOEM(new String[] {PKG_O});
2691
2692 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002693 update.setAllowBubbles(false);
Julia Reynolds413ba842019-01-11 10:38:08 -05002694
2695 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2696
2697 assertEquals(IMPORTANCE_HIGH,
2698 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2699 assertEquals(false,
Mady Mellorc39b4ae2019-01-09 17:11:37 -08002700 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
Julia Reynolds413ba842019-01-11 10:38:08 -05002701
2702 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
2703
2704 assertEquals(IMPORTANCE_HIGH,
2705 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2706 }
Julia Reynolds0c245002019-03-27 16:10:11 -04002707
2708 @Test
2709 public void testUpdateDefaultApps_add_multiUser() {
2710 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2711 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2712 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
2713 // different uids, same package
2714 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2715 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2716 mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
2717
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002718 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2719 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002720 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2721
2722 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2723 .isImportanceLockedByCriticalDeviceFunction());
2724 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2725 .isImportanceLockedByCriticalDeviceFunction());
2726 assertFalse(mHelper.getNotificationChannel(
2727 PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false)
2728 .isImportanceLockedByCriticalDeviceFunction());
2729 }
2730
2731 @Test
2732 public void testUpdateDefaultApps_add_onlyGivenPkg() {
2733 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2734 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2735 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2736 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2737
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002738 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2739 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002740 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2741
Julia Reynolds0c245002019-03-27 16:10:11 -04002742 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2743 .isImportanceLockedByCriticalDeviceFunction());
2744 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2745 .isImportanceLockedByCriticalDeviceFunction());
2746 }
2747
2748 @Test
2749 public void testUpdateDefaultApps_remove() {
2750 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2751 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2752 // different uids, same package
2753 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2754 mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
2755
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002756 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2757 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002758 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2759
2760 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2761 .isImportanceLockedByCriticalDeviceFunction());
2762 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2763 .isImportanceLockedByCriticalDeviceFunction());
2764
2765 ArraySet<String> toRemove = new ArraySet<>();
2766 toRemove.add(PKG_O);
2767 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, null);
2768
2769 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2770 .isImportanceLockedByCriticalDeviceFunction());
2771 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2772 .isImportanceLockedByCriticalDeviceFunction());
2773 }
2774
2775 @Test
2776 public void testUpdateDefaultApps_addAndRemove() {
2777 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2778 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2779 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2780 mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
2781
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002782 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2783 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002784 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2785
2786
2787 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2788 .isImportanceLockedByCriticalDeviceFunction());
2789 assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2790 .isImportanceLockedByCriticalDeviceFunction());
2791
2792 // now the default is PKG_N_MR1
2793 ArraySet<String> toRemove = new ArraySet<>();
2794 toRemove.add(PKG_O);
2795 toAdd = new ArraySet<>();
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002796 toAdd.add(new Pair(PKG_N_MR1, UID_N_MR1));
Julia Reynolds0c245002019-03-27 16:10:11 -04002797 mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd);
2798
2799 assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2800 .isImportanceLockedByCriticalDeviceFunction());
2801 assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
2802 .isImportanceLockedByCriticalDeviceFunction());
2803 }
2804
2805 @Test
2806 public void testUpdateDefaultApps_appDoesNotExist_noCrash() {
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002807 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2808 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002809 ArraySet<String> toRemove = new ArraySet<>();
2810 toRemove.add(PKG_N_MR1);
2811 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd);
2812 }
2813
2814 @Test
2815 public void testUpdateDefaultApps_channelDoesNotExistYet() {
2816 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2817 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
2818 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2819
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 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2823
2824 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
2825 .isImportanceLockedByCriticalDeviceFunction());
2826
2827 mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
2828 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
2829 .isImportanceLockedByCriticalDeviceFunction());
2830 }
2831
2832 @Test
2833 public void testUpdateNotificationChannel_defaultAppLockedImportance() {
2834 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2835 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002836 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2837 toAdd.add(new Pair(PKG_O, UID_O));
Julia Reynolds0c245002019-03-27 16:10:11 -04002838 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2839
2840 NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
2841 update.setAllowBubbles(false);
2842
2843 mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
Julia Reynolds0c245002019-03-27 16:10:11 -04002844 assertEquals(IMPORTANCE_HIGH,
2845 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
2846 assertEquals(false,
2847 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
2848
2849 mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
Julia Reynolds0c245002019-03-27 16:10:11 -04002850 assertEquals(IMPORTANCE_HIGH,
2851 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Beverly47679222019-05-16 15:46:11 -04002852
2853 NotificationChannel updateImportanceLow = new NotificationChannel("a", "a",
2854 IMPORTANCE_LOW);
2855 mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true);
2856 assertEquals(IMPORTANCE_LOW,
2857 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
Julia Reynolds0c245002019-03-27 16:10:11 -04002858 }
Julia Reynoldse7ca31b2019-04-25 15:41:47 -04002859
2860 @Test
2861 public void testDefaultApp_appHasNoSettingsYet() {
2862 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2863 toAdd.add(new Pair(PKG_O, UID_O));
2864 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2865
2866 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
2867 mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
2868
2869 assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
2870 }
2871
2872 @Test
2873 public void testChannelXml_backupDefaultApp() throws Exception {
2874 NotificationChannel channel1 =
2875 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
2876
2877 mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
2878
2879 // clear data
2880 ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
2881 UserHandle.USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
2882 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_O}, new int[]{
2883 UID_O});
2884
2885 ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
2886 toAdd.add(new Pair(PKG_O, UID_O));
2887 mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
2888
2889 XmlPullParser parser = Xml.newPullParser();
2890 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
2891 null);
2892 parser.nextTag();
2893 mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
2894
2895 assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, channel1.getId(), false)
2896 .isImportanceLockedByCriticalDeviceFunction());
2897 }
Mady Mellor9f296142019-05-24 09:42:52 -07002898
2899 @Test
Mady Mellora92268c2020-03-09 17:25:08 -07002900 public void testSetBubblesAllowed_none() {
2901 // Change it to non-default first
2902 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL);
2903 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL);
2904 verify(mHandler, times(1)).requestSort();
2905 reset(mHandler);
2906 // Now test
2907 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
2908 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
2909 verify(mHandler, times(1)).requestSort();
2910 }
2911
2912 @Test
2913 public void testSetBubblesAllowed_all() {
2914 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL);
2915 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL);
2916 verify(mHandler, times(1)).requestSort();
2917 }
2918
2919 @Test
2920 public void testSetBubblesAllowed_selected() {
2921 mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
2922 assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_SELECTED);
Mady Mellor9f296142019-05-24 09:42:52 -07002923 verify(mHandler, times(1)).requestSort();
2924 }
Julia Reynoldsc29370a2019-08-20 16:08:42 -04002925
2926 @Test
2927 public void testTooManyChannels() {
2928 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2929 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2930 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2931 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2932 }
2933 try {
2934 NotificationChannel channel = new NotificationChannel(
2935 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2936 String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
2937 NotificationManager.IMPORTANCE_HIGH);
2938 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2939 fail("Allowed to create too many notification channels");
2940 } catch (IllegalStateException e) {
2941 // great
2942 }
2943 }
2944
2945 @Test
2946 public void testTooManyChannels_xml() throws Exception {
2947 String extraChannel = "EXTRA";
2948 String extraChannel1 = "EXTRA1";
2949
2950 // create first... many... directly so we don't need a big xml blob in this test
2951 for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
2952 NotificationChannel channel = new NotificationChannel(String.valueOf(i),
2953 String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
2954 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
2955 }
2956
2957 final String xml = "<ranking version=\"1\">\n"
2958 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
2959 + "<channel id=\"" + extraChannel + "\" name=\"hi\" importance=\"3\"/>"
2960 + "<channel id=\"" + extraChannel1 + "\" name=\"hi\" importance=\"3\"/>"
2961 + "</package>"
2962 + "</ranking>";
2963 XmlPullParser parser = Xml.newPullParser();
2964 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
2965 null);
2966 parser.nextTag();
2967 mHelper.readXml(parser, false, UserHandle.USER_ALL);
2968
2969 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true));
2970 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true));
2971 }
Julia Reynoldsdb34c1b2019-11-08 10:58:15 -05002972
2973 @Test
2974 public void testRestoreMultiUser() throws Exception {
2975 String pkg = "restore_pkg";
2976 String channelId = "channelId";
2977 int user0Importance = 3;
2978 int user10Importance = 4;
2979 when(mPm.getPackageUidAsUser(eq(pkg), anyInt())).thenReturn(UserHandle.USER_NULL);
2980
2981 // both users have the same package, but different notification settings
2982 final String xmlUser0 = "<ranking version=\"1\">\n"
2983 + "<package name=\"" + pkg + "\" >\n"
2984 + "<channel id=\"" + channelId + "\" name=\"hi\""
2985 + " importance=\"" + user0Importance + "\"/>"
2986 + "</package>"
2987 + "</ranking>";
2988 final String xmlUser10 = "<ranking version=\"1\">\n"
2989 + "<package name=\"" + pkg + "\" >\n"
2990 + "<channel id=\"" + channelId + "\" name=\"hi\""
2991 + " importance=\"" + user10Importance + "\"/>"
2992 + "</package>"
2993 + "</ranking>";
2994
2995 // trigger a restore for both users
2996 XmlPullParser parser = Xml.newPullParser();
2997 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser0.getBytes())),
2998 null);
2999 parser.nextTag();
3000 mHelper.readXml(parser, true, 0);
3001 parser = Xml.newPullParser();
3002 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser10.getBytes())),
3003 null);
3004 parser.nextTag();
3005 mHelper.readXml(parser, true, 10);
3006
3007 // "install" package on both users
3008 String[] pkgList = new String[] {pkg};
3009 int[] uidList0 = new int[] {UserHandle.PER_USER_RANGE};
3010 int[] uidList10 = new int[] {UserHandle.PER_USER_RANGE + 1};
3011 when(mPm.getPackageUidAsUser(pkg, 0)).thenReturn(uidList0[0]);
3012 when(mPm.getPackageUidAsUser(pkg, 10)).thenReturn(uidList10[0]);
3013 ApplicationInfo info = new ApplicationInfo();
3014 info.targetSdkVersion = Build.VERSION_CODES.Q;
3015 when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(info);
3016
3017 mHelper.onPackagesChanged(false, 0, pkgList, uidList0);
3018 mHelper.onPackagesChanged(false, 10, pkgList, uidList10);
3019
3020 assertEquals(user0Importance,
3021 mHelper.getNotificationChannel(pkg, uidList0[0], channelId, false).getImportance());
3022 assertEquals(user10Importance, mHelper.getNotificationChannel(
3023 pkg, uidList10[0], channelId, false).getImportance());
3024 }
Julia Reynolds0f767342019-12-18 09:11:55 -05003025
3026 @Test
3027 public void testGetConversationNotificationChannel() {
3028 String conversationId = "friend";
3029
3030 NotificationChannel parent =
3031 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3032 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3033
3034 NotificationChannel friend = new NotificationChannel(String.format(
3035 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId),
3036 "messages", IMPORTANCE_DEFAULT);
3037 friend.setConversationId(parent.getId(), conversationId);
3038 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3039
Julia Reynolds12ba4cf2020-01-10 16:01:38 -05003040 compareChannelsParentChild(parent, mHelper.getConversationNotificationChannel(
3041 PKG_O, UID_O, parent.getId(), conversationId, false, false), conversationId);
3042 }
3043
3044 @Test
3045 public void testGetNotificationChannel_conversationProvidedByNotCustomizedYet() {
3046 String conversationId = "friend";
3047
3048 NotificationChannel parent =
3049 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3050 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3051
3052 compareChannels(parent, mHelper.getConversationNotificationChannel(
3053 PKG_O, UID_O, parent.getId(), conversationId, true, false));
Julia Reynolds0f767342019-12-18 09:11:55 -05003054 }
3055
3056 @Test
3057 public void testConversationNotificationChannelsRequireParents() {
3058 String parentId = "does not exist";
3059 String conversationId = "friend";
3060
3061 NotificationChannel friend = new NotificationChannel(String.format(
3062 CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId),
3063 "messages", IMPORTANCE_DEFAULT);
3064 friend.setConversationId(parentId, conversationId);
3065
3066 try {
3067 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3068 fail("allowed creation of conversation channel without a parent");
3069 } catch (IllegalArgumentException e) {
3070 // good
3071 }
3072 }
Julia Reynolds7c267522020-01-16 11:26:41 -05003073
3074 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003075 public void testPlaceholderConversationId_shortcutRequired() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07003076 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04003077 mAppOpsManager, mStatsEventBuilderFactory);
Julia Reynolds7c267522020-01-16 11:26:41 -05003078
3079 final String xml = "<ranking version=\"1\">\n"
3080 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3081 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
3082 + "</package>"
3083 + "</ranking>";
3084 XmlPullParser parser = Xml.newPullParser();
3085 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3086 null);
3087 parser.nextTag();
3088 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3089
3090 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3091 }
3092
3093 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003094 public void testNormalConversationId_shortcutRequired() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07003095 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04003096 mAppOpsManager, mStatsEventBuilderFactory);
Julia Reynolds7c267522020-01-16 11:26:41 -05003097
3098 final String xml = "<ranking version=\"1\">\n"
3099 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3100 + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"other\"/>"
3101 + "</package>"
3102 + "</ranking>";
3103 XmlPullParser parser = Xml.newPullParser();
3104 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3105 null);
3106 parser.nextTag();
3107 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3108
3109 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3110 }
3111
3112 @Test
Julia Reynoldse24faa22020-04-02 12:44:47 -04003113 public void testNoConversationId_shortcutRequired() throws Exception {
Mady Mellorc888d512020-04-09 14:48:02 -07003114 mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
Chris Wren1a934a32020-05-19 13:45:46 -04003115 mAppOpsManager, mStatsEventBuilderFactory);
Julia Reynolds7c267522020-01-16 11:26:41 -05003116
3117 final String xml = "<ranking version=\"1\">\n"
3118 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
3119 + "<channel id=\"id\" name=\"hi\" importance=\"3\"/>"
3120 + "</package>"
3121 + "</ranking>";
3122 XmlPullParser parser = Xml.newPullParser();
3123 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
3124 null);
3125 parser.nextTag();
3126 mHelper.readXml(parser, false, UserHandle.USER_ALL);
3127
3128 assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
3129 }
Julia Reynolds882f2062020-02-05 12:11:38 -05003130
3131 @Test
Julia Reynolds02971452020-02-14 16:44:19 -05003132 public void testGetConversations_all() {
3133 String convoId = "convo";
3134 NotificationChannel messages =
3135 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3136 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3137 NotificationChannel calls =
3138 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3139 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3140 NotificationChannel p =
3141 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3142 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3143
3144 NotificationChannel channel =
3145 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3146 channel.setConversationId(messages.getId(), convoId);
3147 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3148
3149 NotificationChannel diffConvo =
3150 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3151 diffConvo.setConversationId(p.getId(), "different convo");
3152 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3153
3154 NotificationChannel channel2 =
3155 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3156 channel2.setConversationId(calls.getId(), convoId);
3157 channel2.setImportantConversation(true);
3158 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3159
3160 List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
3161
3162 assertEquals(3, convos.size());
3163 assertTrue(conversationWrapperContainsChannel(convos, channel));
3164 assertTrue(conversationWrapperContainsChannel(convos, diffConvo));
3165 assertTrue(conversationWrapperContainsChannel(convos, channel2));
3166 }
3167
3168 @Test
Julia Reynoldsb1b9d642020-04-22 16:18:44 -04003169 public void testGetConversations_notDemoted() {
3170 String convoId = "convo";
3171 NotificationChannel messages =
3172 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3173 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3174 NotificationChannel calls =
3175 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3176 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3177 NotificationChannel p =
3178 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3179 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3180
3181 NotificationChannel channel =
3182 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3183 channel.setConversationId(messages.getId(), convoId);
3184 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3185
3186 NotificationChannel diffConvo =
3187 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3188 diffConvo.setConversationId(p.getId(), "different convo");
3189 diffConvo.setDemoted(true);
3190 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3191
3192 NotificationChannel channel2 =
3193 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3194 channel2.setConversationId(calls.getId(), convoId);
3195 channel2.setImportantConversation(true);
3196 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3197
3198 List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
3199
3200 assertEquals(2, convos.size());
3201 assertTrue(conversationWrapperContainsChannel(convos, channel));
3202 assertFalse(conversationWrapperContainsChannel(convos, diffConvo));
3203 assertTrue(conversationWrapperContainsChannel(convos, channel2));
3204 }
3205
3206 @Test
Julia Reynolds02971452020-02-14 16:44:19 -05003207 public void testGetConversations_onlyImportant() {
3208 String convoId = "convo";
3209 NotificationChannel messages =
3210 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3211 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3212 NotificationChannel calls =
3213 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3214 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3215 NotificationChannel p =
3216 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
3217 mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
3218
3219 NotificationChannel channel =
3220 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3221 channel.setConversationId(messages.getId(), convoId);
3222 channel.setImportantConversation(true);
3223 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3224
3225 NotificationChannel diffConvo =
3226 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3227 diffConvo.setConversationId(p.getId(), "different convo");
3228 diffConvo.setImportantConversation(true);
3229 mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
3230
3231 NotificationChannel channel2 =
3232 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3233 channel2.setConversationId(calls.getId(), convoId);
3234 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3235
3236 List<ConversationChannelWrapper> convos = mHelper.getConversations(true);
3237
3238 assertEquals(2, convos.size());
3239 assertTrue(conversationWrapperContainsChannel(convos, channel));
3240 assertTrue(conversationWrapperContainsChannel(convos, diffConvo));
3241 assertFalse(conversationWrapperContainsChannel(convos, channel2));
3242 }
3243
3244 private boolean conversationWrapperContainsChannel(List<ConversationChannelWrapper> list,
3245 NotificationChannel expected) {
3246 for (ConversationChannelWrapper ccw : list) {
3247 if (ccw.getNotificationChannel().equals(expected)) {
3248 return true;
3249 }
3250 }
3251
3252 return false;
3253 }
3254
3255 @Test
Julia Reynolds882f2062020-02-05 12:11:38 -05003256 public void testGetConversations_invalidPkg() {
3257 assertThat(mHelper.getConversations("bad", 1)).isEmpty();
3258 }
3259
3260 @Test
3261 public void testGetConversations_noConversations() {
3262 NotificationChannel channel =
3263 new NotificationChannel("not_convo", "not_convo", IMPORTANCE_DEFAULT);
3264 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3265
3266 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3267 }
3268
3269 @Test
3270 public void testGetConversations_noDisabledGroups() {
3271 NotificationChannelGroup group = new NotificationChannelGroup("a", "a");
3272 group.setBlocked(true);
3273 mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
3274 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3275 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3276
3277 NotificationChannel channel =
3278 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3279 channel.setConversationId("parent", "convo");
3280 channel.setGroup(group.getId());
3281 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3282
3283 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3284 }
3285
3286 @Test
3287 public void testGetConversations_noDeleted() {
3288 NotificationChannel parent = new NotificationChannel("parent", "p", 1);
3289 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3290 NotificationChannel channel =
3291 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
3292 channel.setConversationId("parent", "convo");
3293 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3294 mHelper.deleteNotificationChannel(PKG_O, UID_O, channel.getId());
3295
3296 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3297 }
3298
3299 @Test
Julia Reynolds8582df52020-04-24 18:30:59 -04003300 public void testGetConversations_noDemoted() {
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 channel.setDemoted(true);
3307 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3308
3309 assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
3310 }
3311
3312 @Test
Julia Reynolds882f2062020-02-05 12:11:38 -05003313 public void testGetConversations() {
3314 NotificationChannelGroup group = new NotificationChannelGroup("acct", "account_name");
3315 mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
3316
3317 NotificationChannel messages =
3318 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3319 messages.setGroup(group.getId());
3320 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3321 NotificationChannel calls =
3322 new NotificationChannel("calls", "Calls", IMPORTANCE_HIGH);
3323 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3324
3325 NotificationChannel channel =
3326 new NotificationChannel("A person", "A lovely person", IMPORTANCE_DEFAULT);
3327 channel.setGroup(group.getId());
3328 channel.setConversationId(messages.getId(), channel.getName().toString());
3329 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3330
3331 NotificationChannel channel2 =
3332 new NotificationChannel("B person", "B fabulous person", IMPORTANCE_DEFAULT);
Julia Reynoldsa625b942020-02-15 09:42:23 -05003333 channel2.setConversationId(calls.getId(), channel2.getName().toString());
Julia Reynolds882f2062020-02-05 12:11:38 -05003334 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3335
3336 Map<String, NotificationChannel> expected = new HashMap<>();
3337 expected.put(channel.getId(), channel);
3338 expected.put(channel2.getId(), channel2);
3339
3340 Map<String, CharSequence> expectedGroup = new HashMap<>();
3341 expectedGroup.put(channel.getId(), group.getName());
3342 expectedGroup.put(channel2.getId(), null);
3343
3344 Map<String, CharSequence> expectedParentLabel= new HashMap<>();
3345 expectedParentLabel.put(channel.getId(), messages.getName());
3346 expectedParentLabel.put(channel2.getId(), calls.getName());
3347
3348 ArrayList<ConversationChannelWrapper> convos = mHelper.getConversations(PKG_O, UID_O);
3349 assertThat(convos).hasSize(2);
3350
3351 for (ConversationChannelWrapper convo : convos) {
3352 assertThat(convo.getNotificationChannel())
3353 .isEqualTo(expected.get(convo.getNotificationChannel().getId()));
3354 assertThat(convo.getParentChannelLabel())
3355 .isEqualTo(expectedParentLabel.get(convo.getNotificationChannel().getId()));
3356 assertThat(convo.getGroupLabel())
3357 .isEqualTo(expectedGroup.get(convo.getNotificationChannel().getId()));
3358 }
3359 }
Julia Reynoldsa625b942020-02-15 09:42:23 -05003360
3361 @Test
3362 public void testDeleteConversation() {
3363 String convoId = "convo";
3364 NotificationChannel messages =
3365 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
3366 mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
3367 NotificationChannel calls =
3368 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
3369 mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
3370
3371 NotificationChannel channel =
3372 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
3373 channel.setConversationId(messages.getId(), convoId);
3374 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3375
3376 NotificationChannel noMatch =
3377 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
3378 noMatch.setConversationId(messages.getId(), "different convo");
3379 mHelper.createNotificationChannel(PKG_O, UID_O, noMatch, true, false);
3380
3381 NotificationChannel channel2 =
3382 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
3383 channel2.setConversationId(calls.getId(), convoId);
3384 mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
3385
3386 assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
3387 assertEquals(channel2,
3388 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
3389 assertEquals(2, mHelper.deleteConversation(PKG_O, UID_O, convoId).size());
3390
3391 assertEquals(messages,
3392 mHelper.getNotificationChannel(PKG_O, UID_O, messages.getId(), false));
3393 assertEquals(noMatch,
3394 mHelper.getNotificationChannel(PKG_O, UID_O, noMatch.getId(), false));
3395
3396 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
3397 assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
3398 assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), true));
3399 assertEquals(channel2,
3400 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), true));
Will Brockman23db6d42020-02-28 09:51:12 -05003401
3402 assertEquals(7, mLogger.getCalls().size());
3403 assertEquals(
3404 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
3405 mLogger.get(0).event); // Channel messages
3406 assertEquals(
3407 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
3408 mLogger.get(1).event); // Channel calls
3409 assertEquals(
3410 NotificationChannelLogger.NotificationChannelEvent
3411 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3412 mLogger.get(2).event); // Channel channel - Conversation A person msgs
3413 assertEquals(
3414 NotificationChannelLogger.NotificationChannelEvent
3415 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3416 mLogger.get(3).event); // Channel noMatch - Conversation B person msgs
3417 assertEquals(
3418 NotificationChannelLogger.NotificationChannelEvent
3419 .NOTIFICATION_CHANNEL_CONVERSATION_CREATED,
3420 mLogger.get(4).event); // Channel channel2 - Conversation A person calls
3421 assertEquals(
3422 NotificationChannelLogger.NotificationChannelEvent
3423 .NOTIFICATION_CHANNEL_CONVERSATION_DELETED,
3424 mLogger.get(5).event); // Delete Channel channel - Conversation A person msgs
3425 assertEquals(
3426 NotificationChannelLogger.NotificationChannelEvent
3427 .NOTIFICATION_CHANNEL_CONVERSATION_DELETED,
3428 mLogger.get(6).event); // Delete Channel channel2 - Conversation A person calls
Julia Reynoldsa625b942020-02-15 09:42:23 -05003429 }
Julia Reynoldsa7dac432020-04-23 12:17:31 -04003430
3431 @Test
Julia Reynoldsbc23c7e2020-05-13 18:16:32 -04003432 public void testInvalidMessageSent() {
Julia Reynoldsa7dac432020-04-23 12:17:31 -04003433 // create package preferences
3434 mHelper.canShowBadge(PKG_P, UID_P);
3435
3436 // check default value
Julia Reynoldsbc23c7e2020-05-13 18:16:32 -04003437 assertFalse(mHelper.isInInvalidMsgState(PKG_P, UID_P));
Julia Reynoldsa7dac432020-04-23 12:17:31 -04003438
3439 // change it
Julia Reynoldsbc23c7e2020-05-13 18:16:32 -04003440 mHelper.setInvalidMessageSent(PKG_P, UID_P);
3441 assertTrue(mHelper.isInInvalidMsgState(PKG_P, UID_P));
3442 assertTrue(mHelper.hasSentInvalidMsg(PKG_P, UID_P));
3443 }
3444
3445 @Test
3446 public void testValidMessageSent() {
3447 // create package preferences
3448 mHelper.canShowBadge(PKG_P, UID_P);
3449
3450 // get into the bad state
3451 mHelper.setInvalidMessageSent(PKG_P, UID_P);
3452
3453 // and then fix it
3454 mHelper.setValidMessageSent(PKG_P, UID_P);
3455
3456 assertTrue(mHelper.hasSentValidMsg(PKG_P, UID_P));
3457 assertFalse(mHelper.isInInvalidMsgState(PKG_P, UID_P));
3458 }
3459
3460 @Test
3461 public void testUserDemotedInvalidMsgApp() {
3462 // create package preferences
3463 mHelper.canShowBadge(PKG_P, UID_P);
3464
3465 // demotion means nothing before msg notif sent
3466 mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true);
3467 assertFalse(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
3468
3469 // it's valid when incomplete msgs have been sent
3470 mHelper.setInvalidMessageSent(PKG_P, UID_P);
3471 assertTrue(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
3472
3473 // and is invalid once complete msgs are sent
3474 mHelper.setValidMessageSent(PKG_P, UID_P);
3475 assertFalse(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
Julia Reynoldsa7dac432020-04-23 12:17:31 -04003476 }
Chris Wren1a934a32020-05-19 13:45:46 -04003477
3478 @Test
3479 public void testPullPackageChannelPreferencesStats() {
3480 String channelId = "parent";
3481 String name = "messages";
3482 NotificationChannel fodderA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
3483 mHelper.createNotificationChannel(PKG_O, UID_O, fodderA, true, false);
3484 NotificationChannel channel =
3485 new NotificationChannel(channelId, name, IMPORTANCE_DEFAULT);
3486 mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
3487 NotificationChannel fodderB = new NotificationChannel("b", "b", IMPORTANCE_HIGH);
3488 mHelper.createNotificationChannel(PKG_O, UID_O, fodderB, true, false);
3489
3490 ArrayList<StatsEvent> events = new ArrayList<>();
3491 mHelper.pullPackageChannelPreferencesStats(events);
3492
3493 int found = 0;
3494 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3495 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
3496 && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
3497 ++found;
3498 assertEquals("uid", UID_O, builder.getValue(UID_FIELD_NUMBER));
3499 assertTrue("uid annotation", builder.getBooleanAnnotation(
3500 UID_FIELD_NUMBER, ANNOTATION_ID_IS_UID));
3501 assertEquals("importance", IMPORTANCE_DEFAULT, builder.getValue(
3502 IMPORTANCE_FIELD_NUMBER));
3503 assertEquals("name", name, builder.getValue(CHANNEL_NAME_FIELD_NUMBER));
3504 assertFalse("isconv", builder.getBoolean(IS_CONVERSATION_FIELD_NUMBER));
3505 assertFalse("deleted", builder.getBoolean(IS_DELETED_FIELD_NUMBER));
3506 }
3507 }
3508 }
3509
3510 @Test
3511 public void testPullPackageChannelPreferencesStats_one_to_one() {
3512 NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
3513 mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
3514 NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_LOW);
3515 mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false);
3516 NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
3517 mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false);
3518
3519 List<String> channels = new LinkedList<>(Arrays.asList("a", "b", "c"));
3520
3521 ArrayList<StatsEvent> events = new ArrayList<>();
3522 mHelper.pullPackageChannelPreferencesStats(events);
3523
3524 int found = 0;
3525 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3526 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES) {
3527 Object id = builder.getValue(CHANNEL_ID_FIELD_NUMBER);
3528 assertTrue("missing channel in the output", channels.contains(id));
3529 channels.remove(id);
3530 }
3531 }
3532 assertTrue("unexpected channel in output", channels.isEmpty());
3533 }
3534
3535 @Test
3536 public void testPullPackageChannelPreferencesStats_conversation() {
3537 String conversationId = "friend";
3538
3539 NotificationChannel parent =
3540 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3541 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3542
3543 String channelId = String.format(
3544 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
3545 String name = "conversation";
3546 NotificationChannel friend = new NotificationChannel(channelId,
3547 name, IMPORTANCE_DEFAULT);
3548 friend.setConversationId(parent.getId(), conversationId);
3549 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3550
3551 ArrayList<StatsEvent> events = new ArrayList<>();
3552 mHelper.pullPackageChannelPreferencesStats(events);
3553
3554 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3555 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
3556 && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
3557 assertTrue("isConveration should be true", builder.getBoolean(
3558 IS_CONVERSATION_FIELD_NUMBER));
3559 assertFalse("not demoted", builder.getBoolean(
3560 IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
3561 assertFalse("not important", builder.getBoolean(
3562 IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
3563 }
3564 }
3565 }
3566
3567 @Test
3568 public void testPullPackageChannelPreferencesStats_conversation_demoted() {
3569 NotificationChannel parent =
3570 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3571 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3572 String channelId = String.format(
3573 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
3574 NotificationChannel friend = new NotificationChannel(channelId,
3575 "conversation", IMPORTANCE_DEFAULT);
3576 friend.setConversationId(parent.getId(), "friend");
3577 friend.setDemoted(true);
3578 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3579
3580 ArrayList<StatsEvent> events = new ArrayList<>();
3581 mHelper.pullPackageChannelPreferencesStats(events);
3582
3583 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3584 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
3585 && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
3586 assertTrue("isConveration should be true", builder.getBoolean(
3587 IS_CONVERSATION_FIELD_NUMBER));
3588 assertTrue("is demoted", builder.getBoolean(
3589 IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
3590 assertFalse("not important", builder.getBoolean(
3591 IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
3592 }
3593 }
3594 }
3595
3596 @Test
3597 public void testPullPackageChannelPreferencesStats_conversation_priority() {
3598 NotificationChannel parent =
3599 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
3600 mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
3601 String channelId = String.format(
3602 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
3603 NotificationChannel friend = new NotificationChannel(channelId,
3604 "conversation", IMPORTANCE_DEFAULT);
3605 friend.setConversationId(parent.getId(), "friend");
3606 friend.setImportantConversation(true);
3607 mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
3608
3609 ArrayList<StatsEvent> events = new ArrayList<>();
3610 mHelper.pullPackageChannelPreferencesStats(events);
3611
3612 for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
3613 if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
3614 && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
3615 assertTrue("isConveration should be true", builder.getBoolean(
3616 IS_CONVERSATION_FIELD_NUMBER));
3617 assertFalse("not demoted", builder.getBoolean(
3618 IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
3619 assertTrue("is important", builder.getBoolean(
3620 IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
3621 }
3622 }
3623 }
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04003624}