blob: a9e713e5778b848fa823e29470e71e6f3088aeef [file] [log] [blame]
Chris Wren1031c972014-07-23 13:11:45 +00001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.notification;
17
Julia Reynoldsd373d782017-03-03 13:32:57 -050018import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
Julia Reynolds03fa85d2017-03-06 15:14:50 -050019import static android.app.NotificationManager.IMPORTANCE_HIGH;
Julia Reynolds74856c42017-02-08 14:47:23 -050020import static android.app.NotificationManager.IMPORTANCE_LOW;
Julia Reynolds3e50bf62017-05-24 16:33:32 -040021import static android.app.NotificationManager.IMPORTANCE_MAX;
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -040022import static android.app.NotificationManager.IMPORTANCE_NONE;
Julia Reynoldsfa04e142017-04-23 13:32:01 -040023import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
Julia Reynolds74856c42017-02-08 14:47:23 -050024
Julia Reynolds4036e8d2017-01-13 09:50:05 -050025import static junit.framework.Assert.assertNull;
Julia Reynolds32c97ef2016-11-28 10:47:18 -050026import static junit.framework.Assert.fail;
27
Julia Reynolds3d5b3c72017-11-07 09:04:58 -050028import static org.junit.Assert.assertEquals;
29import static org.junit.Assert.assertFalse;
30import static org.junit.Assert.assertNotNull;
31import static org.junit.Assert.assertTrue;
32import static org.mockito.ArgumentMatchers.any;
33import static org.mockito.Matchers.anyInt;
34import static org.mockito.Matchers.anyString;
35import static org.mockito.Matchers.eq;
Beverlyc36640f2018-05-21 16:14:15 -040036import static org.mockito.Mockito.atLeast;
Julia Reynolds3d5b3c72017-11-07 09:04:58 -050037import static org.mockito.Mockito.mock;
38import static org.mockito.Mockito.never;
Beverlyc36640f2018-05-21 16:14:15 -040039import static org.mockito.Mockito.reset;
Julia Reynolds3d5b3c72017-11-07 09:04:58 -050040import static org.mockito.Mockito.times;
41import static org.mockito.Mockito.verify;
42import static org.mockito.Mockito.when;
43
Chris Wren1031c972014-07-23 13:11:45 +000044import android.app.Notification;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040045import android.app.NotificationChannel;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010046import android.app.NotificationChannelGroup;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040047import android.app.NotificationManager;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010048import android.content.ContentProvider;
49import android.content.Context;
50import android.content.IContentProvider;
Julia Reynolds85769912016-10-25 09:08:57 -040051import android.content.pm.ApplicationInfo;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -040052import android.content.pm.PackageInfo;
Julia Reynolds85769912016-10-25 09:08:57 -040053import android.content.pm.PackageManager;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -040054import android.content.pm.Signature;
Julia Reynolds816797a2017-08-11 15:47:09 -040055import android.content.res.Resources;
Julia Reynolds529e3322017-02-06 08:33:01 -050056import android.graphics.Color;
Julia Reynolds619a69f2017-01-27 15:11:38 -050057import android.media.AudioAttributes;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040058import android.net.Uri;
Julia Reynolds85769912016-10-25 09:08:57 -040059import android.os.Build;
Chris Wren1031c972014-07-23 13:11:45 +000060import android.os.UserHandle;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010061import android.provider.Settings;
Chris Wren89aa2262017-05-05 18:05:56 -040062import android.provider.Settings.Secure;
Chris Wren1031c972014-07-23 13:11:45 +000063import android.service.notification.StatusBarNotification;
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040064import android.support.test.InstrumentationRegistry;
65import android.support.test.runner.AndroidJUnit4;
Chris Wren1031c972014-07-23 13:11:45 +000066import android.test.suitebuilder.annotation.SmallTest;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010067import android.testing.TestableContentResolver;
Julia Reynoldsd373d782017-03-03 13:32:57 -050068import android.util.ArrayMap;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040069import android.util.Xml;
Chris Wren1031c972014-07-23 13:11:45 +000070
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010071import com.android.internal.util.FastXmlSerializer;
Jason Monk74f5e362017-12-06 08:56:33 -050072import com.android.server.UiServiceTestCase;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010073
74import org.json.JSONArray;
75import org.json.JSONObject;
76import org.junit.Before;
77import org.junit.Test;
78import org.junit.runner.RunWith;
79import org.mockito.Mock;
80import org.mockito.MockitoAnnotations;
81import org.xmlpull.v1.XmlPullParser;
82import org.xmlpull.v1.XmlSerializer;
83
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040084import java.io.BufferedInputStream;
85import java.io.BufferedOutputStream;
86import java.io.ByteArrayInputStream;
87import java.io.ByteArrayOutputStream;
Chris Wren1031c972014-07-23 13:11:45 +000088import java.util.ArrayList;
Julia Reynoldsf57de462016-11-23 11:31:46 -050089import java.util.Arrays;
Julia Reynolds4036e8d2017-01-13 09:50:05 -050090import java.util.HashMap;
91import java.util.List;
92import java.util.Map;
Julia Reynolds74856c42017-02-08 14:47:23 -050093import java.util.Objects;
Julia Reynoldsd373d782017-03-03 13:32:57 -050094import java.util.concurrent.ThreadLocalRandom;
Chris Wren1031c972014-07-23 13:11:45 +000095
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040096@SmallTest
97@RunWith(AndroidJUnit4.class)
Jason Monk74f5e362017-12-06 08:56:33 -050098public class RankingHelperTest extends UiServiceTestCase {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -050099 private static final String PKG = "com.android.server.notification";
100 private static final int UID = 0;
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400101 private static final UserHandle USER = UserHandle.of(0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500102 private static final String UPDATED_PKG = "updatedPkg";
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400103 private static final int UID2 = 1111;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400104 private static final String SYSTEM_PKG = "android";
105 private static final int SYSTEM_UID= 1000;
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400106 private static final UserHandle USER2 = UserHandle.of(10);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500107 private static final String TEST_CHANNEL_ID = "test_channel_id";
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100108 private static final String TEST_AUTHORITY = "test";
109 private static final Uri SOUND_URI =
110 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
111 private static final Uri CANONICAL_SOUND_URI =
112 Uri.parse("content://" + TEST_AUTHORITY
113 + "/internal/audio/media/10?title=Test&canonical=1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500114
115 @Mock NotificationUsageStats mUsageStats;
116 @Mock RankingHandler mHandler;
117 @Mock PackageManager mPm;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100118 @Mock IContentProvider mTestIContentProvider;
Julia Reynoldse0b25742017-05-08 12:55:24 -0400119 @Mock Context mContext;
Beverlyc36640f2018-05-21 16:14:15 -0400120 @Mock ZenModeHelper mMockZenModeHelper;
Chris Wren1031c972014-07-23 13:11:45 +0000121
Beverlyc36640f2018-05-21 16:14:15 -0400122 private NotificationManager.Policy mTestNotificationPolicy;
Chris Wren1031c972014-07-23 13:11:45 +0000123 private Notification mNotiGroupGSortA;
124 private Notification mNotiGroupGSortB;
125 private Notification mNotiNoGroup;
126 private Notification mNotiNoGroup2;
127 private Notification mNotiNoGroupSortA;
128 private NotificationRecord mRecordGroupGSortA;
129 private NotificationRecord mRecordGroupGSortB;
130 private NotificationRecord mRecordNoGroup;
131 private NotificationRecord mRecordNoGroup2;
132 private NotificationRecord mRecordNoGroupSortA;
133 private RankingHelper mHelper;
Julia Reynolds619a69f2017-01-27 15:11:38 -0500134 private AudioAttributes mAudioAttributes;
Chris Wren1031c972014-07-23 13:11:45 +0000135
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400136 @Before
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500137 public void setUp() throws Exception {
Chris Wren5eab2b72015-06-16 13:56:22 -0400138 MockitoAnnotations.initMocks(this);
Chris Wren1031c972014-07-23 13:11:45 +0000139 UserHandle user = UserHandle.ALL;
140
Julia Reynolds85769912016-10-25 09:08:57 -0400141 final ApplicationInfo legacy = new ApplicationInfo();
142 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Julia Reynolds1864ff52016-11-02 09:54:47 -0400143 final ApplicationInfo upgrade = new ApplicationInfo();
Dan Sandlere103b782017-05-17 16:07:56 -0700144 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500145 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
146 when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400147 when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500148 when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
Julia Reynoldsf26eb912017-05-22 15:47:06 -0400149 when(mPm.getPackageUidAsUser(eq(UPDATED_PKG), anyInt())).thenReturn(UID2);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400150 when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
151 PackageInfo info = mock(PackageInfo.class);
152 info.signatures = new Signature[] {mock(Signature.class)};
153 when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
154 when(mPm.getPackageInfoAsUser(eq(PKG), anyInt(), anyInt()))
155 .thenReturn(mock(PackageInfo.class));
Julia Reynoldse0b25742017-05-08 12:55:24 -0400156 when(mContext.getResources()).thenReturn(
157 InstrumentationRegistry.getContext().getResources());
Julia Reynolds816797a2017-08-11 15:47:09 -0400158 when(mContext.getContentResolver()).thenReturn(
159 InstrumentationRegistry.getContext().getContentResolver());
Julia Reynoldse0b25742017-05-08 12:55:24 -0400160 when(mContext.getPackageManager()).thenReturn(mPm);
161 when(mContext.getApplicationInfo()).thenReturn(legacy);
Chris Wren89aa2262017-05-05 18:05:56 -0400162 // most tests assume badging is enabled
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100163 TestableContentResolver contentResolver = getContext().getContentResolver();
164 contentResolver.setFallbackToExisting(false);
165 Secure.putIntForUser(contentResolver,
Chris Wren89aa2262017-05-05 18:05:56 -0400166 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID));
Julia Reynoldse0b25742017-05-08 12:55:24 -0400167
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100168 ContentProvider testContentProvider = mock(ContentProvider.class);
169 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
170 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
171
172 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
173 .thenReturn(CANONICAL_SOUND_URI);
174 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
175 .thenReturn(CANONICAL_SOUND_URI);
176 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
177 .thenReturn(SOUND_URI);
178
Beverlyc36640f2018-05-21 16:14:15 -0400179 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
180 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
181 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
182 mHelper = new RankingHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
Julia Reynoldsc861a3d2018-02-15 10:34:49 -0500183 mUsageStats, new String[] {ImportanceExtractor.class.getName()});
Beverlyc36640f2018-05-21 16:14:15 -0400184 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -0400185
Julia Reynoldse0b25742017-05-08 12:55:24 -0400186 mNotiGroupGSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
187 .setContentTitle("A")
188 .setGroup("G")
189 .setSortKey("A")
190 .setWhen(1205)
191 .build();
192 mRecordGroupGSortA = new NotificationRecord(mContext, new StatusBarNotification(
193 PKG, PKG, 1, null, 0, 0, mNotiGroupGSortA, user,
194 null, System.currentTimeMillis()), getDefaultChannel());
195
196 mNotiGroupGSortB = new Notification.Builder(mContext, TEST_CHANNEL_ID)
197 .setContentTitle("B")
198 .setGroup("G")
199 .setSortKey("B")
200 .setWhen(1200)
201 .build();
202 mRecordGroupGSortB = new NotificationRecord(mContext, new StatusBarNotification(
203 PKG, PKG, 1, null, 0, 0, mNotiGroupGSortB, user,
204 null, System.currentTimeMillis()), getDefaultChannel());
205
206 mNotiNoGroup = new Notification.Builder(mContext, TEST_CHANNEL_ID)
207 .setContentTitle("C")
208 .setWhen(1201)
209 .build();
210 mRecordNoGroup = new NotificationRecord(mContext, new StatusBarNotification(
211 PKG, PKG, 1, null, 0, 0, mNotiNoGroup, user,
212 null, System.currentTimeMillis()), getDefaultChannel());
213
214 mNotiNoGroup2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
215 .setContentTitle("D")
216 .setWhen(1202)
217 .build();
218 mRecordNoGroup2 = new NotificationRecord(mContext, new StatusBarNotification(
219 PKG, PKG, 1, null, 0, 0, mNotiNoGroup2, user,
220 null, System.currentTimeMillis()), getDefaultChannel());
221
222 mNotiNoGroupSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
223 .setContentTitle("E")
224 .setWhen(1201)
225 .setSortKey("A")
226 .build();
227 mRecordNoGroupSortA = new NotificationRecord(mContext, new StatusBarNotification(
228 PKG, PKG, 1, null, 0, 0, mNotiNoGroupSortA, user,
229 null, System.currentTimeMillis()), getDefaultChannel());
230
231 mAudioAttributes = new AudioAttributes.Builder()
232 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
233 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
234 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
235 .build();
Chris Wren1031c972014-07-23 13:11:45 +0000236 }
237
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400238 private NotificationChannel getDefaultChannel() {
Julia Reynolds85769912016-10-25 09:08:57 -0400239 return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
Julia Reynolds74856c42017-02-08 14:47:23 -0500240 IMPORTANCE_LOW);
Julia Reynolds85769912016-10-25 09:08:57 -0400241 }
242
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400243 private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, boolean forBackup,
244 String... channelIds)
Julia Reynolds85769912016-10-25 09:08:57 -0400245 throws Exception {
246 XmlSerializer serializer = new FastXmlSerializer();
247 ByteArrayOutputStream baos = new ByteArrayOutputStream();
248 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
249 serializer.startDocument(null, true);
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400250 mHelper.writeXml(serializer, forBackup);
Julia Reynolds85769912016-10-25 09:08:57 -0400251 serializer.endDocument();
252 serializer.flush();
Julia Reynolds85769912016-10-25 09:08:57 -0400253 for (String channelId : channelIds) {
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500254 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
Julia Reynolds85769912016-10-25 09:08:57 -0400255 }
256 return baos;
257 }
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400258
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400259 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore) throws Exception {
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100260 loadByteArrayXml(stream.toByteArray(), forRestore);
261 }
262
263 private void loadByteArrayXml(byte[] byteArray, boolean forRestore) throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500264 XmlPullParser parser = Xml.newPullParser();
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100265 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500266 parser.nextTag();
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400267 mHelper.readXml(parser, forRestore);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500268 }
269
Julia Reynoldsf57de462016-11-23 11:31:46 -0500270 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
271 assertEquals(expected.getId(), actual.getId());
272 assertEquals(expected.getName(), actual.getName());
Julia Reynolds2c891c92017-03-17 14:23:47 -0400273 assertEquals(expected.getDescription(), actual.getDescription());
Julia Reynoldsf57de462016-11-23 11:31:46 -0500274 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
275 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
276 assertEquals(expected.getImportance(), actual.getImportance());
277 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
278 assertEquals(expected.getSound(), actual.getSound());
279 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
280 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
Julia Reynolds59e152e2017-01-25 17:42:53 -0500281 assertEquals(expected.getGroup(), actual.getGroup());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500282 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
Julia Reynolds529e3322017-02-06 08:33:01 -0500283 assertEquals(expected.getLightColor(), actual.getLightColor());
Julia Reynoldsf57de462016-11-23 11:31:46 -0500284 }
285
Julia Reynoldsd5286842017-03-02 15:37:10 -0500286 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
287 assertEquals(expected.getId(), actual.getId());
288 assertEquals(expected.getName(), actual.getName());
Julia Reynolds005c8b92017-08-24 10:35:53 -0400289 assertEquals(expected.getDescription(), actual.getDescription());
290 assertEquals(expected.isBlocked(), actual.isBlocked());
Julia Reynoldsd5286842017-03-02 15:37:10 -0500291 }
292
Julia Reynoldse0b25742017-05-08 12:55:24 -0400293 private NotificationChannel getChannel() {
294 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
295 }
296
Julia Reynolds005c8b92017-08-24 10:35:53 -0400297 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
298 for (NotificationChannel channel : channels) {
299 if (channel.getId().equals(id)) {
300 return channel;
301 }
302 }
303 return null;
304 }
305
Beverlyc36640f2018-05-21 16:14:15 -0400306 private void resetZenModeHelper() {
307 reset(mMockZenModeHelper);
308 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
309 }
310
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400311 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000312 public void testFindAfterRankingWithASplitGroup() throws Exception {
313 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
314 notificationList.add(mRecordGroupGSortA);
315 notificationList.add(mRecordGroupGSortB);
316 notificationList.add(mRecordNoGroup);
317 notificationList.add(mRecordNoGroupSortA);
318 mHelper.sort(notificationList);
319 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0);
320 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0);
321 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0);
322 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0);
323 }
324
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400325 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000326 public void testSortShouldNotThrowWithPlainNotifications() throws Exception {
327 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
328 notificationList.add(mRecordNoGroup);
329 notificationList.add(mRecordNoGroup2);
330 mHelper.sort(notificationList);
331 }
332
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400333 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000334 public void testSortShouldNotThrowOneSorted() throws Exception {
335 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
336 notificationList.add(mRecordNoGroup);
337 notificationList.add(mRecordNoGroupSortA);
338 mHelper.sort(notificationList);
339 }
340
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400341 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000342 public void testSortShouldNotThrowOneNotification() throws Exception {
343 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
344 notificationList.add(mRecordNoGroup);
345 mHelper.sort(notificationList);
346 }
347
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400348 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000349 public void testSortShouldNotThrowOneSortKey() throws Exception {
350 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
351 notificationList.add(mRecordGroupGSortB);
352 mHelper.sort(notificationList);
353 }
354
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400355 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000356 public void testSortShouldNotThrowOnEmptyList() throws Exception {
357 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
358 mHelper.sort(notificationList);
359 }
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400360
361 @Test
362 public void testChannelXml() throws Exception {
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400363 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
Julia Reynolds005c8b92017-08-24 10:35:53 -0400364 ncg.setBlocked(true);
365 ncg.setDescription("group desc");
Julia Reynoldsd5286842017-03-02 15:37:10 -0500366 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
Julia Reynolds85769912016-10-25 09:08:57 -0400367 NotificationChannel channel1 =
368 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
369 NotificationChannel channel2 =
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400370 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds2c891c92017-03-17 14:23:47 -0400371 channel2.setDescription("descriptions for all");
Julia Reynolds619a69f2017-01-27 15:11:38 -0500372 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500373 channel2.enableLights(true);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400374 channel2.setBypassDnd(true);
375 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Julia Reynoldsf57de462016-11-23 11:31:46 -0500376 channel2.enableVibration(true);
Julia Reynolds59e152e2017-01-25 17:42:53 -0500377 channel2.setGroup(ncg.getId());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500378 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds529e3322017-02-06 08:33:01 -0500379 channel2.setLightColor(Color.BLUE);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400380
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500381 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
382 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400383 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
384 mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400385
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500386 mHelper.setShowBadge(PKG, UID, true);
Rohan Shah590e1b22018-04-10 23:48:47 -0400387 mHelper.setAppImportanceLocked(PKG, UID);
Julia Reynolds924eed12017-01-19 09:52:07 -0500388
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500389 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400390 channel2.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500391 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400392
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400393 loadStreamXml(baos, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400394
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500395 assertTrue(mHelper.canShowBadge(PKG, UID));
Rohan Shah590e1b22018-04-10 23:48:47 -0400396 assertTrue(mHelper.getIsAppImportanceLocked(PKG, UID));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500397 assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500398 compareChannels(channel2,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500399 mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynolds74856c42017-02-08 14:47:23 -0500400
401 List<NotificationChannelGroup> actualGroups =
Julia Reynolds173a4822018-09-21 15:20:13 -0400402 mHelper.getNotificationChannelGroups(PKG, UID, false, true, false).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -0500403 boolean foundNcg = false;
404 for (NotificationChannelGroup actual : actualGroups) {
405 if (ncg.getId().equals(actual.getId())) {
406 foundNcg = true;
Julia Reynoldsd5286842017-03-02 15:37:10 -0500407 compareGroups(ncg, actual);
408 } else if (ncg2.getId().equals(actual.getId())) {
409 compareGroups(ncg2, actual);
Julia Reynolds74856c42017-02-08 14:47:23 -0500410 }
411 }
412 assertTrue(foundNcg);
413
414 boolean foundChannel2Group = false;
415 for (NotificationChannelGroup actual : actualGroups) {
416 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
417 foundChannel2Group = true;
418 break;
419 }
420 }
421 assertTrue(foundChannel2Group);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400422 }
Julia Reynolds85769912016-10-25 09:08:57 -0400423
424 @Test
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400425 public void testChannelXmlForBackup() throws Exception {
426 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
427 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
428 NotificationChannel channel1 =
429 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
430 NotificationChannel channel2 =
431 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
432 channel2.setDescription("descriptions for all");
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100433 channel2.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400434 channel2.enableLights(true);
435 channel2.setBypassDnd(true);
436 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
437 channel2.enableVibration(false);
438 channel2.setGroup(ncg.getId());
439 channel2.setLightColor(Color.BLUE);
Julia Reynolds745c1542017-05-26 14:43:47 -0400440 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
441 channel3.enableVibration(true);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400442
443 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
444 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400445 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
446 mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
447 mHelper.createNotificationChannel(PKG, UID, channel3, false, false);
448 mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true, false);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400449
450 mHelper.setShowBadge(PKG, UID, true);
451
452 mHelper.setImportance(UPDATED_PKG, UID2, IMPORTANCE_NONE);
453
454 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
Julia Reynolds745c1542017-05-26 14:43:47 -0400455 channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
456 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG, UPDATED_PKG},
457 new int[]{UID, UID2});
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400458
459 mHelper.setShowBadge(UPDATED_PKG, UID2, true);
460
461 loadStreamXml(baos, true);
462
463 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(UPDATED_PKG, UID2));
464 assertTrue(mHelper.canShowBadge(PKG, UID));
465 assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
466 compareChannels(channel2,
467 mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynolds745c1542017-05-26 14:43:47 -0400468 compareChannels(channel3,
469 mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400470
471 List<NotificationChannelGroup> actualGroups =
Julia Reynolds173a4822018-09-21 15:20:13 -0400472 mHelper.getNotificationChannelGroups(PKG, UID, false, true, false).getList();
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400473 boolean foundNcg = false;
474 for (NotificationChannelGroup actual : actualGroups) {
475 if (ncg.getId().equals(actual.getId())) {
476 foundNcg = true;
477 compareGroups(ncg, actual);
478 } else if (ncg2.getId().equals(actual.getId())) {
479 compareGroups(ncg2, actual);
480 }
481 }
482 assertTrue(foundNcg);
483
484 boolean foundChannel2Group = false;
485 for (NotificationChannelGroup actual : actualGroups) {
486 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
487 foundChannel2Group = true;
488 break;
489 }
490 }
491 assertTrue(foundChannel2Group);
492 }
493
494 @Test
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100495 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
496 NotificationChannel channel =
497 new NotificationChannel("id", "name", IMPORTANCE_LOW);
498 channel.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400499 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100500
501 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
502
503 // Testing that in restore we are given the canonical version
504 loadStreamXml(baos, true);
505 verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
506 }
507
508 @Test
509 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
510 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
511 Uri canonicalBasedOnLocal = localUri.buildUpon()
512 .appendQueryParameter("title", "Test")
513 .appendQueryParameter("canonical", "1")
514 .build();
515 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
516 .thenReturn(canonicalBasedOnLocal);
517 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
518 .thenReturn(localUri);
519 when(mTestIContentProvider.uncanonicalize(any(), eq(canonicalBasedOnLocal)))
520 .thenReturn(localUri);
521
522 NotificationChannel channel =
523 new NotificationChannel("id", "name", IMPORTANCE_LOW);
524 channel.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400525 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100526 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
527
528 loadStreamXml(baos, true);
529
530 NotificationChannel actualChannel = mHelper.getNotificationChannel(
531 PKG, UID, channel.getId(), false);
532 assertEquals(localUri, actualChannel.getSound());
533 }
534
535 @Test
536 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
537 Thread.sleep(3000);
538 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
539 .thenReturn(null);
540 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
541 .thenReturn(null);
542
543 NotificationChannel channel =
544 new NotificationChannel("id", "name", IMPORTANCE_LOW);
545 channel.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400546 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100547 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
548
549 loadStreamXml(baos, true);
550
551 NotificationChannel actualChannel = mHelper.getNotificationChannel(
552 PKG, UID, channel.getId(), false);
553 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
554 }
555
556
557 /**
558 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
559 * handle its restore properly.
560 */
561 @Test
562 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
563 // Not a local uncanonicalized uri, simulating that it fails to exist locally
564 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI))).thenReturn(null);
565 String id = "id";
566 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
567 + "<package name=\"com.android.server.notification\" show_badge=\"true\">\n"
568 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
569 + "sound=\"" + SOUND_URI + "\" "
570 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
571 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
572 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
573 + "</package>\n"
574 + "</ranking>\n";
575
576 loadByteArrayXml(backupWithUncanonicalizedSoundUri.getBytes(), true);
577
578 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG, UID, id, false);
579 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
580 }
581
582 @Test
583 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
584 NotificationChannel channel =
585 new NotificationChannel("id", "name", IMPORTANCE_LOW);
586 channel.setSound(null, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400587 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100588 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
589
590 loadStreamXml(baos, true);
591
592 NotificationChannel actualChannel = mHelper.getNotificationChannel(
593 PKG, UID, channel.getId(), false);
594 assertEquals(null, actualChannel.getSound());
595 }
596
597 @Test
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400598 public void testChannelXml_backup() throws Exception {
599 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
600 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
601 NotificationChannel channel1 =
602 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
603 NotificationChannel channel2 =
604 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
605 NotificationChannel channel3 =
606 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
607 channel3.setGroup(ncg.getId());
608
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500609 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
610 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds1fe10942018-03-28 12:46:51 -0400611 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
612 mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
613 mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400614
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500615 mHelper.deleteNotificationChannel(PKG, UID, channel1.getId());
616 mHelper.deleteNotificationChannelGroup(PKG, UID, ncg.getId());
617 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400618
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500619 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400620 channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500621 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400622
623 XmlPullParser parser = Xml.newPullParser();
624 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
625 null);
626 parser.nextTag();
627 mHelper.readXml(parser, true);
628
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500629 assertNull(mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
630 assertNull(mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
631 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG, UID));
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000632 //assertEquals(ncg2, mHelper.getNotificationChannelGroup(ncg2.getId(), PKG, UID));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500633 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400634 }
635
636 @Test
Julia Reynolds85769912016-10-25 09:08:57 -0400637 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400638 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
Julia Reynolds85769912016-10-25 09:08:57 -0400639 NotificationChannel.DEFAULT_CHANNEL_ID);
640
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400641 loadStreamXml(baos, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400642
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500643 final NotificationChannel updated = mHelper.getNotificationChannel(PKG, UID,
644 NotificationChannel.DEFAULT_CHANNEL_ID, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400645 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
646 assertFalse(updated.canBypassDnd());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500647 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
Julia Reynolds85769912016-10-25 09:08:57 -0400648 assertEquals(0, updated.getUserLockedFields());
649 }
650
651 @Test
Julia Reynoldsb3a04f02016-11-04 09:08:52 -0400652 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500653 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
654 NotificationChannel.DEFAULT_CHANNEL_ID, false);
655 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400656 mHelper.updateNotificationChannel(PKG, UID, defaultChannel, true);
Julia Reynoldsb3a04f02016-11-04 09:08:52 -0400657
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400658 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
Julia Reynolds85769912016-10-25 09:08:57 -0400659 NotificationChannel.DEFAULT_CHANNEL_ID);
660
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400661 loadStreamXml(baos, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400662
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500663 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
664 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Julia Reynolds85769912016-10-25 09:08:57 -0400665 }
666
Julia Reynolds85769912016-10-25 09:08:57 -0400667 @Test
668 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
Julia Reynolds1864ff52016-11-02 09:54:47 -0400669 final String preupgradeXml = "<ranking version=\"1\">\n"
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500670 + "<package name=\"" + PKG
671 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
Julia Reynolds619a69f2017-01-27 15:11:38 -0500672 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500673 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID + "\" />\n"
674 + "<package name=\"" + UPDATED_PKG + "\" uid=\"" + UID2 + "\" visibility=\""
Julia Reynolds619a69f2017-01-27 15:11:38 -0500675 + Notification.VISIBILITY_PRIVATE + "\" />\n"
676 + "</ranking>";
Julia Reynolds85769912016-10-25 09:08:57 -0400677 XmlPullParser parser = Xml.newPullParser();
Julia Reynolds1864ff52016-11-02 09:54:47 -0400678 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
Julia Reynolds619a69f2017-01-27 15:11:38 -0500679 null);
Julia Reynolds85769912016-10-25 09:08:57 -0400680 parser.nextTag();
681 mHelper.readXml(parser, false);
682
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500683 final NotificationChannel updated1 =
684 mHelper.getNotificationChannel(PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Julia Reynolds1864ff52016-11-02 09:54:47 -0400685 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
686 assertTrue(updated1.canBypassDnd());
687 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
Julia Reynolds85769912016-10-25 09:08:57 -0400688 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
Julia Reynolds619a69f2017-01-27 15:11:38 -0500689 | NotificationChannel.USER_LOCKED_PRIORITY
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500690 | NotificationChannel.USER_LOCKED_VISIBILITY,
691 updated1.getUserLockedFields());
Julia Reynolds1864ff52016-11-02 09:54:47 -0400692
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500693 // No Default Channel created for updated packages
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400694 assertEquals(null, mHelper.getNotificationChannel(UPDATED_PKG, UID2,
695 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500696 }
697
698 @Test
699 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
700 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
701 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
702 assertTrue(defaultChannel != null);
703 ByteArrayOutputStream baos =
704 writeXmlAndPurge(PKG, UID, false, NotificationChannel.DEFAULT_CHANNEL_ID);
705 // Load package at higher sdk.
706 final ApplicationInfo upgraded = new ApplicationInfo();
707 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
708 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400709 loadStreamXml(baos, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500710
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500711 // Default Channel should be gone.
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400712 assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
713 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500714 }
715
716 @Test
717 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
718 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400719 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500720 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
721 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
722
723 // Load package at higher sdk.
724 final ApplicationInfo upgraded = new ApplicationInfo();
725 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
726 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400727 loadStreamXml(baos, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500728
729 // Default Channel should be gone.
730 assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
731 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Julia Reynolds85769912016-10-25 09:08:57 -0400732 }
733
Julia Reynolds85769912016-10-25 09:08:57 -0400734 @Test
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400735 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
736 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
737 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
738 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400739 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400740
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400741 loadStreamXml(baos, false);
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400742
743 // Should still have the newly created channel that wasn't in the xml.
744 assertTrue(mHelper.getNotificationChannel(PKG, UID, "bananas", false) != null);
745 }
746
747 @Test
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500748 public void testCreateChannel_blocked() throws Exception {
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400749 mHelper.setImportance(PKG, UID, IMPORTANCE_NONE);
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500750
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500751 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400752 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500753 }
754
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400755 @Test
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400756 public void testCreateChannel_badImportance() throws Exception {
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400757 try {
758 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400759 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
760 true, false);
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400761 fail("Was allowed to create a channel with invalid importance");
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400762 } catch (IllegalArgumentException e) {
763 // yay
764 }
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400765 try {
766 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400767 new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
768 true, false);
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400769 fail("Was allowed to create a channel with invalid importance");
770 } catch (IllegalArgumentException e) {
771 // yay
772 }
773 try {
774 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400775 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
776 true, false);
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400777 fail("Was allowed to create a channel with invalid importance");
778 } catch (IllegalArgumentException e) {
779 // yay
780 }
781 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400782 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false);
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400783 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -0400784 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false);
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400785 }
786
Julia Reynolds173a4822018-09-21 15:20:13 -0400787 @Test
788 public void testGetChannelGroups_includeEmptyGroups() {
789 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
790 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
791 NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
792 mHelper.createNotificationChannelGroup(PKG, UID, ncgEmpty, true);
793
794 NotificationChannel channel1 =
795 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
796 channel1.setGroup(ncg.getId());
797 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
798
799 List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
800 PKG, UID, false, false, true).getList();
801
802 assertEquals(2, actual.size());
803 for (NotificationChannelGroup group : actual) {
804 if (Objects.equals(group.getId(), ncg.getId())) {
805 assertEquals(1, group.getChannels().size());
806 }
807 if (Objects.equals(group.getId(), ncgEmpty.getId())) {
808 assertEquals(0, group.getChannels().size());
809 }
810 }
811 }
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500812
813 @Test
Julia Reynolds85769912016-10-25 09:08:57 -0400814 public void testUpdate() throws Exception {
815 // no fields locked by user
816 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500817 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500818 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500819 channel.enableLights(true);
Julia Reynolds85769912016-10-25 09:08:57 -0400820 channel.setBypassDnd(true);
821 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
822
Julia Reynolds1fe10942018-03-28 12:46:51 -0400823 mHelper.createNotificationChannel(PKG, UID, channel, false, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400824
825 // same id, try to update all fields
826 final NotificationChannel channel2 =
827 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500828 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500829 channel2.enableLights(false);
Julia Reynolds85769912016-10-25 09:08:57 -0400830 channel2.setBypassDnd(false);
831 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
832
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400833 mHelper.updateNotificationChannel(PKG, UID, channel2, true);
Julia Reynolds85769912016-10-25 09:08:57 -0400834
835 // all fields should be changed
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500836 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel.getId(), false));
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400837
838 verify(mHandler, times(1)).requestSort();
Julia Reynolds85769912016-10-25 09:08:57 -0400839 }
840
841 @Test
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400842 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
843 mHelper.setImportance(PKG, UID, IMPORTANCE_UNSPECIFIED);
844 assertTrue(mHelper.canShowBadge(PKG, UID));
845 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
846 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
847 mHelper.getPackageVisibility(PKG, UID));
Rohan Shah590e1b22018-04-10 23:48:47 -0400848 assertFalse(mHelper.getIsAppImportanceLocked(PKG, UID));
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400849
850 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
851 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
852
853 defaultChannel.setShowBadge(false);
854 defaultChannel.setImportance(IMPORTANCE_NONE);
855 defaultChannel.setBypassDnd(true);
856 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
857
Rohan Shah590e1b22018-04-10 23:48:47 -0400858 mHelper.setAppImportanceLocked(PKG, UID);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400859 mHelper.updateNotificationChannel(PKG, UID, defaultChannel, true);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400860
861 // ensure app level fields are changed
862 assertFalse(mHelper.canShowBadge(PKG, UID));
863 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG, UID));
864 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG, UID));
865 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG, UID));
Rohan Shah590e1b22018-04-10 23:48:47 -0400866 assertTrue(mHelper.getIsAppImportanceLocked(PKG, UID));
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400867 }
868
869 @Test
870 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
871 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
872
Julia Reynolds1fe10942018-03-28 12:46:51 -0400873 mHelper.createNotificationChannel(PKG, UID, channel, false, false);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400874 assertTrue(mHelper.canShowBadge(PKG, UID));
875 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
876 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
877 mHelper.getPackageVisibility(PKG, UID));
878
879 channel.setShowBadge(false);
880 channel.setImportance(IMPORTANCE_NONE);
881 channel.setBypassDnd(true);
882 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
883
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400884 mHelper.updateNotificationChannel(PKG, UID, channel, true);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400885
886 // ensure app level fields are not changed
887 assertTrue(mHelper.canShowBadge(PKG, UID));
888 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
889 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
890 mHelper.getPackageVisibility(PKG, UID));
891 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
892 }
893
894 @Test
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500895 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
896 assertEquals(null, mHelper.getNotificationChannel(PKG, UID, "garbage", false));
Julia Reynolds85769912016-10-25 09:08:57 -0400897 }
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500898
899 @Test
900 public void testCreateChannel_CannotChangeHiddenFields() throws Exception {
901 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500902 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500903 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500904 channel.enableLights(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500905 channel.setBypassDnd(true);
906 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
907 channel.setShowBadge(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500908 int lockMask = 0;
909 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
910 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
911 }
912 channel.lockFields(lockMask);
913
Julia Reynolds1fe10942018-03-28 12:46:51 -0400914 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500915
916 NotificationChannel savedChannel =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500917 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500918
919 assertEquals(channel.getName(), savedChannel.getName());
920 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
921 assertFalse(savedChannel.canBypassDnd());
922 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
Julia Reynoldsf35e3972017-01-05 15:41:04 -0500923 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400924
925 verify(mHandler, never()).requestSort();
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500926 }
927
928 @Test
929 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() throws Exception {
930 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500931 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500932 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500933 channel.enableLights(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500934 channel.setBypassDnd(true);
935 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
936 channel.setShowBadge(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500937 int lockMask = 0;
938 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
939 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
940 }
941 channel.lockFields(lockMask);
942
Julia Reynolds1fe10942018-03-28 12:46:51 -0400943 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500944
945 NotificationChannel savedChannel =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500946 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500947
948 assertEquals(channel.getName(), savedChannel.getName());
949 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
950 assertFalse(savedChannel.canBypassDnd());
951 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
Julia Reynoldsf35e3972017-01-05 15:41:04 -0500952 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500953 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500954
955 @Test
Julia Reynoldse0b25742017-05-08 12:55:24 -0400956 public void testClearLockedFields() throws Exception {
957 final NotificationChannel channel = getChannel();
958 mHelper.clearLockedFields(channel);
959 assertEquals(0, channel.getUserLockedFields());
960
961 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
962 | NotificationChannel.USER_LOCKED_IMPORTANCE);
963 mHelper.clearLockedFields(channel);
964 assertEquals(0, channel.getUserLockedFields());
965 }
966
967 @Test
968 public void testLockFields_soundAndVibration() throws Exception {
Julia Reynolds1fe10942018-03-28 12:46:51 -0400969 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400970
971 final NotificationChannel update1 = getChannel();
972 update1.setSound(new Uri.Builder().scheme("test").build(),
973 new AudioAttributes.Builder().build());
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500974 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400975 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500976 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
977 | NotificationChannel.USER_LOCKED_SOUND,
Julia Reynoldse0b25742017-05-08 12:55:24 -0400978 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
979 .getUserLockedFields());
980
981 NotificationChannel update2 = getChannel();
982 update2.enableVibration(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400983 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500984 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
985 | NotificationChannel.USER_LOCKED_SOUND
Julia Reynoldse0b25742017-05-08 12:55:24 -0400986 | NotificationChannel.USER_LOCKED_VIBRATION,
987 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
988 .getUserLockedFields());
989 }
990
991 @Test
992 public void testLockFields_vibrationAndLights() throws Exception {
Julia Reynolds1fe10942018-03-28 12:46:51 -0400993 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400994
995 final NotificationChannel update1 = getChannel();
996 update1.setVibrationPattern(new long[]{7945, 46 ,246});
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400997 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400998 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
999 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
1000 .getUserLockedFields());
1001
1002 final NotificationChannel update2 = getChannel();
1003 update2.enableLights(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001004 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001005 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
1006 | NotificationChannel.USER_LOCKED_LIGHTS,
1007 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
1008 .getUserLockedFields());
1009 }
1010
1011 @Test
1012 public void testLockFields_lightsAndImportance() throws Exception {
Julia Reynolds1fe10942018-03-28 12:46:51 -04001013 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001014
1015 final NotificationChannel update1 = getChannel();
1016 update1.setLightColor(Color.GREEN);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001017 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001018 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
1019 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
1020 .getUserLockedFields());
1021
1022 final NotificationChannel update2 = getChannel();
1023 update2.setImportance(IMPORTANCE_DEFAULT);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001024 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001025 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
1026 | NotificationChannel.USER_LOCKED_IMPORTANCE,
1027 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
1028 .getUserLockedFields());
1029 }
1030
1031 @Test
1032 public void testLockFields_visibilityAndDndAndBadge() throws Exception {
Julia Reynolds1fe10942018-03-28 12:46:51 -04001033 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001034 assertEquals(0,
1035 mHelper.getNotificationChannel(PKG, UID, getChannel().getId(), false)
1036 .getUserLockedFields());
1037
1038 final NotificationChannel update1 = getChannel();
1039 update1.setBypassDnd(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001040 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001041 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
1042 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
1043 .getUserLockedFields());
1044
1045 final NotificationChannel update2 = getChannel();
1046 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001047 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001048 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1049 | NotificationChannel.USER_LOCKED_VISIBILITY,
1050 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
1051 .getUserLockedFields());
1052
1053 final NotificationChannel update3 = getChannel();
1054 update3.setShowBadge(false);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001055 mHelper.updateNotificationChannel(PKG, UID, update3, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001056 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1057 | NotificationChannel.USER_LOCKED_VISIBILITY
1058 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
1059 mHelper.getNotificationChannel(PKG, UID, update3.getId(), false)
1060 .getUserLockedFields());
1061 }
1062
1063 @Test
Julia Reynolds8e0eb372017-03-21 15:04:50 -04001064 public void testDeleteNonExistentChannel() throws Exception {
1065 mHelper.deleteNotificationChannelGroup(PKG, UID, "does not exist");
1066 }
1067
1068 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001069 public void testGetDeletedChannel() throws Exception {
Julia Reynoldse0b25742017-05-08 12:55:24 -04001070 NotificationChannel channel = getChannel();
Julia Reynolds619a69f2017-01-27 15:11:38 -05001071 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -05001072 channel.enableLights(true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001073 channel.setBypassDnd(true);
1074 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1075 channel.enableVibration(true);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001076 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001077
Julia Reynolds1fe10942018-03-28 12:46:51 -04001078 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001079 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001080
1081 // Does not return deleted channel
1082 NotificationChannel response =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001083 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001084 assertNull(response);
1085
1086 // Returns deleted channel
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001087 response = mHelper.getNotificationChannel(PKG, UID, channel.getId(), true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001088 compareChannels(channel, response);
1089 assertTrue(response.isDeleted());
1090 }
1091
1092 @Test
1093 public void testGetDeletedChannels() throws Exception {
1094 Map<String, NotificationChannel> channelMap = new HashMap<>();
1095 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001096 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001097 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -05001098 channel.enableLights(true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001099 channel.setBypassDnd(true);
1100 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1101 channel.enableVibration(true);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001102 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001103 channelMap.put(channel.getId(), channel);
1104 NotificationChannel channel2 =
1105 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1106 channelMap.put(channel2.getId(), channel2);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001107 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1108 mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001109
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001110 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001111
1112 // Returns only non-deleted channels
1113 List<NotificationChannel> channels =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001114 mHelper.getNotificationChannels(PKG, UID, false).getList();
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001115 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1116 for (NotificationChannel nc : channels) {
1117 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1118 compareChannels(channel2, nc);
1119 }
1120 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001121
1122 // Returns deleted channels too
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001123 channels = mHelper.getNotificationChannels(PKG, UID, true).getList();
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001124 assertEquals(3, channels.size()); // Includes default channel
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001125 for (NotificationChannel nc : channels) {
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001126 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1127 compareChannels(channelMap.get(nc.getId()), nc);
1128 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001129 }
1130 }
1131
1132 @Test
Julia Reynolds41103f42017-03-15 11:36:35 -04001133 public void testGetDeletedChannelCount() throws Exception {
1134 NotificationChannel channel =
1135 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1136 NotificationChannel channel2 =
1137 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1138 NotificationChannel channel3 =
Julia Reynoldsf2e499d2018-03-30 10:36:42 -04001139 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001140 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1141 mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
1142 mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
Julia Reynolds41103f42017-03-15 11:36:35 -04001143
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001144 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
1145 mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
Julia Reynolds41103f42017-03-15 11:36:35 -04001146
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001147 assertEquals(2, mHelper.getDeletedChannelCount(PKG, UID));
1148 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID2));
Julia Reynolds41103f42017-03-15 11:36:35 -04001149 }
1150
1151 @Test
Julia Reynoldsf2e499d2018-03-30 10:36:42 -04001152 public void testGetBlockedChannelCount() throws Exception {
1153 NotificationChannel channel =
1154 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1155 NotificationChannel channel2 =
1156 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
1157 NotificationChannel channel3 =
1158 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
1159 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1160 mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
1161 mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
1162
1163 mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
1164
1165 assertEquals(1, mHelper.getBlockedChannelCount(PKG, UID));
1166 assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID2));
1167 }
1168
1169 @Test
Beverly86d076f2018-04-17 14:44:52 -04001170 public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception {
1171 // create notification channel that can't bypass dnd
1172 // expected result: areChannelsBypassingDnd = false
Beverlyc36640f2018-05-21 16:14:15 -04001173 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
Beverly86d076f2018-04-17 14:44:52 -04001174 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
1175 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1176 assertFalse(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001177 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1178 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001179
Beverlyc36640f2018-05-21 16:14:15 -04001180 // create notification channel that can bypass dnd
Beverly86d076f2018-04-17 14:44:52 -04001181 // expected result: areChannelsBypassingDnd = true
1182 NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1183 channel2.setBypassDnd(true);
1184 mHelper.createNotificationChannel(PKG, UID, channel2, true, true);
1185 assertTrue(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001186 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1187 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001188
1189 // delete channels
1190 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
1191 assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
Beverlyc36640f2018-05-21 16:14:15 -04001192 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1193 resetZenModeHelper();
1194
Beverly86d076f2018-04-17 14:44:52 -04001195 mHelper.deleteNotificationChannel(PKG, UID, channel2.getId());
1196 assertFalse(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001197 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1198 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001199 }
1200
1201 @Test
1202 public void testUpdateCanChannelsBypassDnd() throws Exception {
1203 // create notification channel that can't bypass dnd
1204 // expected result: areChannelsBypassingDnd = false
Beverlyc36640f2018-05-21 16:14:15 -04001205 // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
Beverly86d076f2018-04-17 14:44:52 -04001206 NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
1207 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
1208 assertFalse(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001209 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1210 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001211
1212 // update channel so it CAN bypass dnd:
1213 // expected result: areChannelsBypassingDnd = true
1214 channel.setBypassDnd(true);
1215 mHelper.updateNotificationChannel(PKG, UID, channel, true);
1216 assertTrue(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001217 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1218 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001219
1220 // update channel so it can't bypass dnd:
1221 // expected result: areChannelsBypassingDnd = false
1222 channel.setBypassDnd(false);
1223 mHelper.updateNotificationChannel(PKG, UID, channel, true);
1224 assertFalse(mHelper.areChannelsBypassingDnd());
Beverlyc36640f2018-05-21 16:14:15 -04001225 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1226 resetZenModeHelper();
1227 }
1228
1229 @Test
1230 public void testSetupNewZenModeHelper_canBypass() {
1231 // start notification policy off with mAreChannelsBypassingDnd = true, but
1232 // RankingHelper should change to false
1233 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
1234 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND);
1235 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
1236 mHelper = new RankingHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
1237 mUsageStats, new String[] {ImportanceExtractor.class.getName()});
1238 assertFalse(mHelper.areChannelsBypassingDnd());
1239 verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
1240 resetZenModeHelper();
1241 }
1242
1243 @Test
1244 public void testSetupNewZenModeHelper_cannotBypass() {
1245 // start notification policy off with mAreChannelsBypassingDnd = false
1246 mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0);
1247 when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
1248 mHelper = new RankingHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
1249 mUsageStats, new String[] {ImportanceExtractor.class.getName()});
1250 assertFalse(mHelper.areChannelsBypassingDnd());
1251 verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
1252 resetZenModeHelper();
Beverly86d076f2018-04-17 14:44:52 -04001253 }
1254
1255 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001256 public void testCreateDeletedChannel() throws Exception {
Julia Reynolds619a69f2017-01-27 15:11:38 -05001257 long[] vibration = new long[]{100, 67, 145, 156};
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001258 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001259 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001260 channel.setVibrationPattern(vibration);
1261
Julia Reynolds1fe10942018-03-28 12:46:51 -04001262 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001263 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001264
1265 NotificationChannel newChannel = new NotificationChannel(
1266 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001267 newChannel.setVibrationPattern(new long[]{100});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001268
Julia Reynolds1fe10942018-03-28 12:46:51 -04001269 mHelper.createNotificationChannel(PKG, UID, newChannel, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001270
1271 // No long deleted, using old settings
1272 compareChannels(channel,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001273 mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001274 }
1275
1276 @Test
Julia Reynolds17717f52017-05-09 11:46:06 -04001277 public void testOnlyHasDefaultChannel() throws Exception {
1278 assertTrue(mHelper.onlyHasDefaultChannel(PKG, UID));
1279 assertFalse(mHelper.onlyHasDefaultChannel(UPDATED_PKG, UID2));
1280
Julia Reynolds1fe10942018-03-28 12:46:51 -04001281 mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
Julia Reynolds17717f52017-05-09 11:46:06 -04001282 assertFalse(mHelper.onlyHasDefaultChannel(PKG, UID));
1283 }
1284
1285 @Test
Julia Reynolds03fa85d2017-03-06 15:14:50 -05001286 public void testCreateChannel_defaultChannelId() throws Exception {
1287 try {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001288 mHelper.createNotificationChannel(PKG, UID, new NotificationChannel(
Julia Reynolds1fe10942018-03-28 12:46:51 -04001289 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
Julia Reynolds03fa85d2017-03-06 15:14:50 -05001290 fail("Allowed to create default channel");
1291 } catch (IllegalArgumentException e) {
1292 // pass
1293 }
1294 }
1295
1296 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001297 public void testCreateChannel_alreadyExists() throws Exception {
Julia Reynolds619a69f2017-01-27 15:11:38 -05001298 long[] vibration = new long[]{100, 67, 145, 156};
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001299 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001300 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001301 channel.setVibrationPattern(vibration);
1302
Julia Reynolds1fe10942018-03-28 12:46:51 -04001303 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001304
1305 NotificationChannel newChannel = new NotificationChannel(
1306 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001307 newChannel.setVibrationPattern(new long[]{100});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001308
Julia Reynolds1fe10942018-03-28 12:46:51 -04001309 mHelper.createNotificationChannel(PKG, UID, newChannel, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001310
1311 // Old settings not overridden
1312 compareChannels(channel,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001313 mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001314 }
1315
1316 @Test
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001317 public void testCreateChannel_noOverrideSound() throws Exception {
1318 Uri sound = new Uri.Builder().scheme("test").build();
1319 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1320 NotificationManager.IMPORTANCE_DEFAULT);
1321 channel.setSound(sound, mAudioAttributes);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001322 mHelper.createNotificationChannel(PKG, UID, channel, true, false);
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001323 assertEquals(sound, mHelper.getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001324 PKG, UID, channel.getId(), false).getSound());
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001325 }
1326
1327 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001328 public void testPermanentlyDeleteChannels() throws Exception {
1329 NotificationChannel channel1 =
1330 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1331 NotificationChannel channel2 =
Julia Reynolds74856c42017-02-08 14:47:23 -05001332 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001333
Julia Reynolds1fe10942018-03-28 12:46:51 -04001334 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
1335 mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001336
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001337 mHelper.permanentlyDeleteNotificationChannels(PKG, UID);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001338
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001339 // Only default channel remains
1340 assertEquals(1, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001341 }
1342
1343 @Test
Julia Reynolds9bfba592017-03-15 14:03:55 -04001344 public void testDeleteGroup() throws Exception {
1345 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1346 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1347 NotificationChannel nonGroupedNonDeletedChannel =
1348 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1349 NotificationChannel groupedButNotDeleted =
1350 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1351 groupedButNotDeleted.setGroup("not");
1352 NotificationChannel groupedAndDeleted =
1353 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1354 groupedAndDeleted.setGroup("totally");
1355
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001356 mHelper.createNotificationChannelGroup(PKG, UID, notDeleted, true);
1357 mHelper.createNotificationChannelGroup(PKG, UID, deleted, true);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001358 mHelper.createNotificationChannel(PKG, UID, nonGroupedNonDeletedChannel, true, false);
1359 mHelper.createNotificationChannel(PKG, UID, groupedAndDeleted, true, false);
1360 mHelper.createNotificationChannel(PKG, UID, groupedButNotDeleted, true, false);
Julia Reynolds9bfba592017-03-15 14:03:55 -04001361
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001362 mHelper.deleteNotificationChannelGroup(PKG, UID, deleted.getId());
Julia Reynolds9bfba592017-03-15 14:03:55 -04001363
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001364 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG, UID));
1365 assertNotNull(mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG, UID));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001366
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001367 assertNull(mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001368 compareChannels(groupedAndDeleted,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001369 mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), true));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001370
1371 compareChannels(groupedButNotDeleted,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001372 mHelper.getNotificationChannel(PKG, UID, groupedButNotDeleted.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001373 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001374 PKG, UID, nonGroupedNonDeletedChannel.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001375
1376 // notDeleted
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001377 assertEquals(1, mHelper.getNotificationChannelGroups(PKG, UID).size());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001378
1379 verify(mHandler, never()).requestSort();
Julia Reynolds9bfba592017-03-15 14:03:55 -04001380 }
1381
1382 @Test
Julia Reynolds2e9bf5f2017-05-03 13:23:30 -04001383 public void testOnUserRemoved() throws Exception {
1384 int[] user0Uids = {98, 235, 16, 3782};
1385 int[] user1Uids = new int[user0Uids.length];
1386 for (int i = 0; i < user0Uids.length; i++) {
1387 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1388
1389 final ApplicationInfo legacy = new ApplicationInfo();
1390 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1391 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
1392
1393 // create records with the default channel for all user 0 and user 1 uids
1394 mHelper.getImportance(PKG, user0Uids[i]);
1395 mHelper.getImportance(PKG, user1Uids[i]);
1396 }
1397
1398 mHelper.onUserRemoved(1);
1399
1400 // user 0 records remain
1401 for (int i = 0; i < user0Uids.length; i++) {
1402 assertEquals(1,
1403 mHelper.getNotificationChannels(PKG, user0Uids[i], false).getList().size());
1404 }
1405 // user 1 records are gone
1406 for (int i = 0; i < user1Uids.length; i++) {
1407 assertEquals(0,
1408 mHelper.getNotificationChannels(PKG, user1Uids[i], false).getList().size());
1409 }
1410 }
1411
1412 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001413 public void testOnPackageChanged_packageRemoval() throws Exception {
1414 // Deleted
1415 NotificationChannel channel1 =
1416 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001417 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001418
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001419 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001420
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001421 assertEquals(0, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001422
1423 // Not deleted
Julia Reynolds1fe10942018-03-28 12:46:51 -04001424 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001425
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001426 mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001427 assertEquals(2, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001428 }
Julia Reynolds924eed12017-01-19 09:52:07 -05001429
1430 @Test
Julia Reynolds59e152e2017-01-25 17:42:53 -05001431 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001432 mHelper.setImportance(PKG, UID, NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001433
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001434 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds59e152e2017-01-25 17:42:53 -05001435
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001436 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
Julia Reynolds59e152e2017-01-25 17:42:53 -05001437 }
1438
1439 @Test
1440 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1441 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001442 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001443 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001444 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001445
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001446 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds59e152e2017-01-25 17:42:53 -05001447
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001448 assertEquals(0,
Julia Reynolds173a4822018-09-21 15:20:13 -04001449 mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList().size());
Julia Reynolds59e152e2017-01-25 17:42:53 -05001450 }
1451
1452 @Test
Julia Reynoldsf26eb912017-05-22 15:47:06 -04001453 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1454 // create channel as api 26
Julia Reynolds1fe10942018-03-28 12:46:51 -04001455 mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true, false);
Julia Reynoldsf26eb912017-05-22 15:47:06 -04001456
1457 // install new app version targeting 25
1458 final ApplicationInfo legacy = new ApplicationInfo();
1459 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1460 when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(legacy);
1461 mHelper.onPackagesChanged(
1462 false, UserHandle.USER_SYSTEM, new String[]{UPDATED_PKG}, new int[]{UID2});
1463
1464 // make sure the default channel was readded
1465 //assertEquals(2, mHelper.getNotificationChannels(UPDATED_PKG, UID2, false).getList().size());
1466 assertNotNull(mHelper.getNotificationChannel(
1467 UPDATED_PKG, UID2, NotificationChannel.DEFAULT_CHANNEL_ID, false));
1468 }
1469
1470 @Test
Julia Reynolds924eed12017-01-19 09:52:07 -05001471 public void testRecordDefaults() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001472 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
1473 assertEquals(true, mHelper.canShowBadge(PKG, UID));
1474 assertEquals(1, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
Julia Reynolds924eed12017-01-19 09:52:07 -05001475 }
Julia Reynolds59e152e2017-01-25 17:42:53 -05001476
1477 @Test
1478 public void testCreateGroup() throws Exception {
1479 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001480 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
1481 assertEquals(ncg, mHelper.getNotificationChannelGroups(PKG, UID).iterator().next());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001482 verify(mHandler, never()).requestSort();
Julia Reynolds59e152e2017-01-25 17:42:53 -05001483 }
1484
1485 @Test
1486 public void testCannotCreateChannel_badGroup() throws Exception {
1487 NotificationChannel channel1 =
1488 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1489 channel1.setGroup("garbage");
1490 try {
Julia Reynolds1fe10942018-03-28 12:46:51 -04001491 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001492 fail("Created a channel with a bad group");
Julia Reynolds619a69f2017-01-27 15:11:38 -05001493 } catch (IllegalArgumentException e) {
1494 }
Julia Reynolds59e152e2017-01-25 17:42:53 -05001495 }
1496
1497 @Test
1498 public void testCannotCreateChannel_goodGroup() throws Exception {
1499 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001500 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001501 NotificationChannel channel1 =
1502 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1503 channel1.setGroup(ncg.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001504 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001505
1506 assertEquals(ncg.getId(),
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001507 mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false).getGroup());
Julia Reynolds59e152e2017-01-25 17:42:53 -05001508 }
1509
1510 @Test
1511 public void testGetChannelGroups() throws Exception {
Julia Reynoldsf02562a2017-01-26 13:33:56 -05001512 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001513 mHelper.createNotificationChannelGroup(PKG, UID, unused, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001514 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001515 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001516 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001517 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001518
1519 NotificationChannel channel1 =
1520 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1521 channel1.setGroup(ncg.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001522 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001523 NotificationChannel channel1a =
1524 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1525 channel1a.setGroup(ncg.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001526 mHelper.createNotificationChannel(PKG, UID, channel1a, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001527
1528 NotificationChannel channel2 =
1529 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1530 channel2.setGroup(ncg2.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001531 mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001532
1533 NotificationChannel channel3 =
1534 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001535 mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001536
1537 List<NotificationChannelGroup> actual =
Julia Reynolds173a4822018-09-21 15:20:13 -04001538 mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
Julia Reynolds59e152e2017-01-25 17:42:53 -05001539 assertEquals(3, actual.size());
Julia Reynolds619a69f2017-01-27 15:11:38 -05001540 for (NotificationChannelGroup group : actual) {
Julia Reynolds59e152e2017-01-25 17:42:53 -05001541 if (group.getId() == null) {
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001542 assertEquals(2, group.getChannels().size()); // misc channel too
1543 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1544 || channel3.getId().equals(group.getChannels().get(1).getId()));
Julia Reynolds59e152e2017-01-25 17:42:53 -05001545 } else if (group.getId().equals(ncg.getId())) {
1546 assertEquals(2, group.getChannels().size());
1547 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1548 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1549 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1550 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1551 } else {
1552 fail("expected channel not found");
1553 }
1554 } else if (group.getId().equals(ncg2.getId())) {
1555 assertEquals(1, group.getChannels().size());
1556 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1557 }
1558 }
1559 }
Julia Reynolds74856c42017-02-08 14:47:23 -05001560
1561 @Test
1562 public void testGetChannelGroups_noSideEffects() throws Exception {
1563 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001564 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds74856c42017-02-08 14:47:23 -05001565
1566 NotificationChannel channel1 =
1567 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1568 channel1.setGroup(ncg.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001569 mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
Julia Reynolds173a4822018-09-21 15:20:13 -04001570 mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -05001571
1572 channel1.setImportance(IMPORTANCE_LOW);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001573 mHelper.updateNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds74856c42017-02-08 14:47:23 -05001574
1575 List<NotificationChannelGroup> actual =
Julia Reynolds173a4822018-09-21 15:20:13 -04001576 mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -05001577
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001578 assertEquals(2, actual.size());
1579 for (NotificationChannelGroup group : actual) {
1580 if (Objects.equals(group.getId(), ncg.getId())) {
1581 assertEquals(1, group.getChannels().size());
1582 }
1583 }
Julia Reynolds74856c42017-02-08 14:47:23 -05001584 }
Julia Reynoldsd373d782017-03-03 13:32:57 -05001585
1586 @Test
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001587 public void testCreateChannel_updateName() throws Exception {
1588 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001589 mHelper.createNotificationChannel(PKG, UID, nc, true, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001590 NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001591 assertEquals("hello", actual.getName());
1592
1593 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001594 mHelper.createNotificationChannel(PKG, UID, nc, true, false);
Julia Reynoldsd373d782017-03-03 13:32:57 -05001595
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001596 actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001597 assertEquals("goodbye", actual.getName());
1598 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001599
1600 verify(mHandler, times(1)).requestSort();
Julia Reynoldsd373d782017-03-03 13:32:57 -05001601 }
1602
1603 @Test
Julia Reynolds005c8b92017-08-24 10:35:53 -04001604 public void testCreateChannel_addToGroup() throws Exception {
1605 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
1606 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1607 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001608 mHelper.createNotificationChannel(PKG, UID, nc, true, false);
Julia Reynolds005c8b92017-08-24 10:35:53 -04001609 NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
1610 assertNull(actual.getGroup());
1611
1612 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1613 nc.setGroup(group.getId());
Julia Reynolds1fe10942018-03-28 12:46:51 -04001614 mHelper.createNotificationChannel(PKG, UID, nc, true, false);
Julia Reynolds005c8b92017-08-24 10:35:53 -04001615
1616 actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
1617 assertNotNull(actual.getGroup());
1618 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1619
1620 verify(mHandler, times(1)).requestSort();
1621 }
1622
1623 @Test
Julia Reynoldsd373d782017-03-03 13:32:57 -05001624 public void testDumpChannelsJson() throws Exception {
1625 final ApplicationInfo upgrade = new ApplicationInfo();
1626 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
1627 try {
1628 when(mPm.getApplicationInfoAsUser(
1629 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
1630 } catch (PackageManager.NameNotFoundException e) {
1631 }
1632 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
1633 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
1634 for (int i = 0; i < numPackages; i++) {
1635 String pkgName = "pkg" + i;
1636 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
1637 for (int j = 0; j < numChannels; j++) {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001638 mHelper.createNotificationChannel(pkgName, UID,
Julia Reynolds1fe10942018-03-28 12:46:51 -04001639 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
Julia Reynoldsd373d782017-03-03 13:32:57 -05001640 }
1641 expectedChannels.put(pkgName, numChannels);
1642 }
1643
1644 // delete the first channel of the first package
1645 String pkg = expectedChannels.keyAt(0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001646 mHelper.deleteNotificationChannel("pkg" + 0, UID, "0");
Julia Reynoldsd373d782017-03-03 13:32:57 -05001647 // dump should not include deleted channels
1648 int count = expectedChannels.get(pkg);
1649 expectedChannels.put(pkg, count - 1);
1650
1651 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
1652 assertEquals(numPackages, actual.length());
1653 for (int i = 0; i < numPackages; i++) {
1654 JSONObject object = actual.getJSONObject(i);
1655 assertTrue(expectedChannels.containsKey(object.get("packageName")));
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -04001656 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
Julia Reynoldsd373d782017-03-03 13:32:57 -05001657 object.getInt("channelCount"));
1658 }
1659 }
Chris Wren89aa2262017-05-05 18:05:56 -04001660
1661 @Test
1662 public void testBadgingOverrideTrue() throws Exception {
1663 Secure.putIntForUser(getContext().getContentResolver(),
1664 Secure.NOTIFICATION_BADGING, 1,
1665 USER.getIdentifier());
1666 mHelper.updateBadgingEnabled(); // would be called by settings observer
1667 assertTrue(mHelper.badgingEnabled(USER));
1668 }
1669
1670 @Test
1671 public void testBadgingOverrideFalse() throws Exception {
1672 Secure.putIntForUser(getContext().getContentResolver(),
1673 Secure.NOTIFICATION_BADGING, 0,
1674 USER.getIdentifier());
1675 mHelper.updateBadgingEnabled(); // would be called by settings observer
1676 assertFalse(mHelper.badgingEnabled(USER));
1677 }
1678
1679 @Test
Chris Wren13f157f2017-05-12 15:02:06 -04001680 public void testBadgingForUserAll() throws Exception {
1681 try {
1682 mHelper.badgingEnabled(UserHandle.ALL);
1683 } catch (Exception e) {
1684 fail("just don't throw");
1685 }
1686 }
1687
1688 @Test
Chris Wren89aa2262017-05-05 18:05:56 -04001689 public void testBadgingOverrideUserIsolation() throws Exception {
1690 Secure.putIntForUser(getContext().getContentResolver(),
1691 Secure.NOTIFICATION_BADGING, 0,
1692 USER.getIdentifier());
1693 Secure.putIntForUser(getContext().getContentResolver(),
1694 Secure.NOTIFICATION_BADGING, 1,
1695 USER2.getIdentifier());
1696 mHelper.updateBadgingEnabled(); // would be called by settings observer
1697 assertFalse(mHelper.badgingEnabled(USER));
1698 assertTrue(mHelper.badgingEnabled(USER2));
1699 }
Julia Reynolds816797a2017-08-11 15:47:09 -04001700
1701 @Test
1702 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
1703 String newLabel = "bananas!";
1704 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
1705 NotificationChannel.DEFAULT_CHANNEL_ID, false);
1706 assertFalse(newLabel.equals(defaultChannel.getName()));
1707
1708 Resources res = mock(Resources.class);
1709 when(mContext.getResources()).thenReturn(res);
1710 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
1711 .thenReturn(newLabel);
1712
1713 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
1714
1715 assertEquals(newLabel, mHelper.getNotificationChannel(PKG, UID,
1716 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
1717 }
Julia Reynolds005c8b92017-08-24 10:35:53 -04001718
1719 @Test
1720 public void testIsGroupBlocked_noGroup() throws Exception {
1721 assertFalse(mHelper.isGroupBlocked(PKG, UID, null));
1722
1723 assertFalse(mHelper.isGroupBlocked(PKG, UID, "non existent group"));
1724 }
1725
1726 @Test
1727 public void testIsGroupBlocked_notBlocked() throws Exception {
1728 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1729 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1730
1731 assertFalse(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1732 }
1733
1734 @Test
1735 public void testIsGroupBlocked_blocked() throws Exception {
1736 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1737 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1738 group.setBlocked(true);
1739 mHelper.createNotificationChannelGroup(PKG, UID, group, false);
1740
1741 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1742 }
1743
1744 @Test
1745 public void testIsGroup_appCannotResetBlock() throws Exception {
1746 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1747 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1748 NotificationChannelGroup group2 = group.clone();
1749 group2.setBlocked(true);
1750 mHelper.createNotificationChannelGroup(PKG, UID, group2, false);
1751 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1752
1753 NotificationChannelGroup group3 = group.clone();
1754 group3.setBlocked(false);
1755 mHelper.createNotificationChannelGroup(PKG, UID, group3, true);
1756 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1757 }
1758
1759 @Test
1760 public void testGetNotificationChannelGroupWithChannels() throws Exception {
1761 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
1762 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
1763 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1764 mHelper.createNotificationChannelGroup(PKG, UID, other, true);
1765
1766 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
1767 a.setGroup(group.getId());
1768 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
1769 b.setGroup(other.getId());
1770 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
1771 c.setGroup(group.getId());
1772 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
1773
Julia Reynolds1fe10942018-03-28 12:46:51 -04001774 mHelper.createNotificationChannel(PKG, UID, a, true, false);
1775 mHelper.createNotificationChannel(PKG, UID, b, true, false);
1776 mHelper.createNotificationChannel(PKG, UID, c, true, false);
1777 mHelper.createNotificationChannel(PKG, UID, d, true, false);
Julia Reynolds005c8b92017-08-24 10:35:53 -04001778 mHelper.deleteNotificationChannel(PKG, UID, c.getId());
1779
1780 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
1781 PKG, UID, group.getId(), true);
1782 assertEquals(2, retrieved.getChannels().size());
1783 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
1784 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
1785
1786 retrieved = mHelper.getNotificationChannelGroupWithChannels(
1787 PKG, UID, group.getId(), false);
1788 assertEquals(1, retrieved.getChannels().size());
1789 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
1790 }
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001791
1792 @Test
Julia Reynolds7f6681d2018-05-01 12:28:56 -04001793 public void testAndroidPkgCannotBypassDnd_creation() {
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001794 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1795 test.setBypassDnd(true);
1796
Julia Reynolds1fe10942018-03-28 12:46:51 -04001797 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001798
Julia Reynolds7f6681d2018-05-01 12:28:56 -04001799 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001800 .canBypassDnd());
1801 }
1802
1803 @Test
Julia Reynolds1fe10942018-03-28 12:46:51 -04001804 public void testDndPkgCanBypassDnd_creation() {
1805 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1806 test.setBypassDnd(true);
1807
1808 mHelper.createNotificationChannel(PKG, UID, test, true, true);
1809
1810 assertTrue(mHelper.getNotificationChannel(PKG, UID, "A", false).canBypassDnd());
1811 }
1812
1813 @Test
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001814 public void testNormalPkgCannotBypassDnd_creation() {
1815 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1816 test.setBypassDnd(true);
1817
Julia Reynolds1fe10942018-03-28 12:46:51 -04001818 mHelper.createNotificationChannel(PKG, 1000, test, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001819
1820 assertFalse(mHelper.getNotificationChannel(PKG, 1000, "A", false).canBypassDnd());
1821 }
1822
1823 @Test
Julia Reynolds7f6681d2018-05-01 12:28:56 -04001824 public void testAndroidPkgCannotBypassDnd_update() throws Exception {
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001825 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001826 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001827
1828 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1829 update.setBypassDnd(true);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001830 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001831
Julia Reynolds7f6681d2018-05-01 12:28:56 -04001832 assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001833 .canBypassDnd());
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001834 }
1835
1836 @Test
Julia Reynolds1fe10942018-03-28 12:46:51 -04001837 public void testDndPkgCanBypassDnd_update() throws Exception {
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001838 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001839 mHelper.createNotificationChannel(PKG, UID, test, true, true);
1840
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001841 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1842 update.setBypassDnd(true);
Julia Reynolds1fe10942018-03-28 12:46:51 -04001843 mHelper.createNotificationChannel(PKG, UID, update, true, true);
1844
1845 assertTrue(mHelper.getNotificationChannel(PKG, UID, "A", false).canBypassDnd());
1846 }
1847
1848 @Test
1849 public void testNormalPkgCannotBypassDnd_update() {
1850 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1851 mHelper.createNotificationChannel(PKG, 1000, test, true, false);
1852 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1853 update.setBypassDnd(true);
1854 mHelper.createNotificationChannel(PKG, 1000, update, true, false);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001855 assertFalse(mHelper.getNotificationChannel(PKG, 1000, "A", false).canBypassDnd());
1856 }
Julia Reynoldse273f082018-04-12 13:48:49 -04001857
1858 @Test
1859 public void testGetBlockedAppCount_noApps() {
1860 assertEquals(0, mHelper.getBlockedAppCount(0));
1861 }
1862
1863 @Test
1864 public void testGetBlockedAppCount_noAppsForUserId() {
1865 mHelper.setEnabled(PKG, 100, false);
1866 assertEquals(0, mHelper.getBlockedAppCount(9));
1867 }
1868
1869 @Test
1870 public void testGetBlockedAppCount_appsForUserId() {
1871 mHelper.setEnabled(PKG, 1020, false);
1872 mHelper.setEnabled(PKG, 1030, false);
1873 mHelper.setEnabled(PKG, 1060, false);
1874 mHelper.setEnabled(PKG, 1000, true);
1875 assertEquals(3, mHelper.getBlockedAppCount(0));
1876 }
Chris Wren1031c972014-07-23 13:11:45 +00001877}