blob: 9ebce71e8900e9204d17ccb32cf6fe1560061dc6 [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;
36import static org.mockito.Mockito.mock;
37import static org.mockito.Mockito.never;
38import static org.mockito.Mockito.times;
39import static org.mockito.Mockito.verify;
40import static org.mockito.Mockito.when;
41
Chris Wren1031c972014-07-23 13:11:45 +000042import android.app.Notification;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040043import android.app.NotificationChannel;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010044import android.app.NotificationChannelGroup;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040045import android.app.NotificationManager;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010046import android.content.ContentProvider;
47import android.content.Context;
48import android.content.IContentProvider;
Julia Reynolds85769912016-10-25 09:08:57 -040049import android.content.pm.ApplicationInfo;
50import android.content.pm.PackageManager;
Julia Reynolds816797a2017-08-11 15:47:09 -040051import android.content.res.Resources;
Julia Reynolds529e3322017-02-06 08:33:01 -050052import android.graphics.Color;
Julia Reynolds619a69f2017-01-27 15:11:38 -050053import android.media.AudioAttributes;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040054import android.net.Uri;
Julia Reynolds85769912016-10-25 09:08:57 -040055import android.os.Build;
Chris Wren1031c972014-07-23 13:11:45 +000056import android.os.UserHandle;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010057import android.provider.Settings;
Chris Wren89aa2262017-05-05 18:05:56 -040058import android.provider.Settings.Secure;
Chris Wren1031c972014-07-23 13:11:45 +000059import android.service.notification.StatusBarNotification;
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040060import android.support.test.InstrumentationRegistry;
61import android.support.test.runner.AndroidJUnit4;
Chris Wren1031c972014-07-23 13:11:45 +000062import android.test.suitebuilder.annotation.SmallTest;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010063import android.testing.TestableContentResolver;
Julia Reynoldsd373d782017-03-03 13:32:57 -050064import android.util.ArrayMap;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040065import android.util.Xml;
Chris Wren1031c972014-07-23 13:11:45 +000066
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010067import com.android.internal.util.FastXmlSerializer;
Jason Monk74f5e362017-12-06 08:56:33 -050068import com.android.server.UiServiceTestCase;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010069
70import org.json.JSONArray;
71import org.json.JSONObject;
72import org.junit.Before;
73import org.junit.Test;
74import org.junit.runner.RunWith;
75import org.mockito.Mock;
76import org.mockito.MockitoAnnotations;
77import org.xmlpull.v1.XmlPullParser;
78import org.xmlpull.v1.XmlSerializer;
79
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040080import java.io.BufferedInputStream;
81import java.io.BufferedOutputStream;
82import java.io.ByteArrayInputStream;
83import java.io.ByteArrayOutputStream;
Chris Wren1031c972014-07-23 13:11:45 +000084import java.util.ArrayList;
Julia Reynoldsf57de462016-11-23 11:31:46 -050085import java.util.Arrays;
Julia Reynolds4036e8d2017-01-13 09:50:05 -050086import java.util.HashMap;
87import java.util.List;
88import java.util.Map;
Julia Reynolds74856c42017-02-08 14:47:23 -050089import java.util.Objects;
Julia Reynoldsd373d782017-03-03 13:32:57 -050090import java.util.concurrent.ThreadLocalRandom;
Chris Wren1031c972014-07-23 13:11:45 +000091
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040092@SmallTest
93@RunWith(AndroidJUnit4.class)
Jason Monk74f5e362017-12-06 08:56:33 -050094public class RankingHelperTest extends UiServiceTestCase {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -050095 private static final String PKG = "com.android.server.notification";
96 private static final int UID = 0;
Julia Reynolds5fe2eae2017-05-22 08:45:27 -040097 private static final UserHandle USER = UserHandle.of(0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -050098 private static final String UPDATED_PKG = "updatedPkg";
Julia Reynolds5fe2eae2017-05-22 08:45:27 -040099 private static final int UID2 = 1111;
100 private static final UserHandle USER2 = UserHandle.of(10);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500101 private static final String TEST_CHANNEL_ID = "test_channel_id";
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100102 private static final String TEST_AUTHORITY = "test";
103 private static final Uri SOUND_URI =
104 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
105 private static final Uri CANONICAL_SOUND_URI =
106 Uri.parse("content://" + TEST_AUTHORITY
107 + "/internal/audio/media/10?title=Test&canonical=1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500108
109 @Mock NotificationUsageStats mUsageStats;
110 @Mock RankingHandler mHandler;
111 @Mock PackageManager mPm;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100112 @Mock IContentProvider mTestIContentProvider;
Julia Reynoldse0b25742017-05-08 12:55:24 -0400113 @Mock Context mContext;
Chris Wren1031c972014-07-23 13:11:45 +0000114
115 private Notification mNotiGroupGSortA;
116 private Notification mNotiGroupGSortB;
117 private Notification mNotiNoGroup;
118 private Notification mNotiNoGroup2;
119 private Notification mNotiNoGroupSortA;
120 private NotificationRecord mRecordGroupGSortA;
121 private NotificationRecord mRecordGroupGSortB;
122 private NotificationRecord mRecordNoGroup;
123 private NotificationRecord mRecordNoGroup2;
124 private NotificationRecord mRecordNoGroupSortA;
125 private RankingHelper mHelper;
Julia Reynolds619a69f2017-01-27 15:11:38 -0500126 private AudioAttributes mAudioAttributes;
Chris Wren1031c972014-07-23 13:11:45 +0000127
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400128 @Before
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500129 public void setUp() throws Exception {
Chris Wren5eab2b72015-06-16 13:56:22 -0400130 MockitoAnnotations.initMocks(this);
Chris Wren1031c972014-07-23 13:11:45 +0000131 UserHandle user = UserHandle.ALL;
132
Julia Reynolds85769912016-10-25 09:08:57 -0400133 final ApplicationInfo legacy = new ApplicationInfo();
134 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Julia Reynolds1864ff52016-11-02 09:54:47 -0400135 final ApplicationInfo upgrade = new ApplicationInfo();
Dan Sandlere103b782017-05-17 16:07:56 -0700136 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500137 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
138 when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
139 when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
Julia Reynoldsf26eb912017-05-22 15:47:06 -0400140 when(mPm.getPackageUidAsUser(eq(UPDATED_PKG), anyInt())).thenReturn(UID2);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400141 when(mContext.getResources()).thenReturn(
142 InstrumentationRegistry.getContext().getResources());
Julia Reynolds816797a2017-08-11 15:47:09 -0400143 when(mContext.getContentResolver()).thenReturn(
144 InstrumentationRegistry.getContext().getContentResolver());
Julia Reynoldse0b25742017-05-08 12:55:24 -0400145 when(mContext.getPackageManager()).thenReturn(mPm);
146 when(mContext.getApplicationInfo()).thenReturn(legacy);
Chris Wren89aa2262017-05-05 18:05:56 -0400147 // most tests assume badging is enabled
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100148 TestableContentResolver contentResolver = getContext().getContentResolver();
149 contentResolver.setFallbackToExisting(false);
150 Secure.putIntForUser(contentResolver,
Chris Wren89aa2262017-05-05 18:05:56 -0400151 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID));
Julia Reynoldse0b25742017-05-08 12:55:24 -0400152
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100153 ContentProvider testContentProvider = mock(ContentProvider.class);
154 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
155 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
156
157 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
158 .thenReturn(CANONICAL_SOUND_URI);
159 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
160 .thenReturn(CANONICAL_SOUND_URI);
161 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
162 .thenReturn(SOUND_URI);
163
Julia Reynoldse0b25742017-05-08 12:55:24 -0400164 mHelper = new RankingHelper(getContext(), mPm, mHandler, mUsageStats,
165 new String[] {ImportanceExtractor.class.getName()});
166
167 mNotiGroupGSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
168 .setContentTitle("A")
169 .setGroup("G")
170 .setSortKey("A")
171 .setWhen(1205)
172 .build();
173 mRecordGroupGSortA = new NotificationRecord(mContext, new StatusBarNotification(
174 PKG, PKG, 1, null, 0, 0, mNotiGroupGSortA, user,
175 null, System.currentTimeMillis()), getDefaultChannel());
176
177 mNotiGroupGSortB = new Notification.Builder(mContext, TEST_CHANNEL_ID)
178 .setContentTitle("B")
179 .setGroup("G")
180 .setSortKey("B")
181 .setWhen(1200)
182 .build();
183 mRecordGroupGSortB = new NotificationRecord(mContext, new StatusBarNotification(
184 PKG, PKG, 1, null, 0, 0, mNotiGroupGSortB, user,
185 null, System.currentTimeMillis()), getDefaultChannel());
186
187 mNotiNoGroup = new Notification.Builder(mContext, TEST_CHANNEL_ID)
188 .setContentTitle("C")
189 .setWhen(1201)
190 .build();
191 mRecordNoGroup = new NotificationRecord(mContext, new StatusBarNotification(
192 PKG, PKG, 1, null, 0, 0, mNotiNoGroup, user,
193 null, System.currentTimeMillis()), getDefaultChannel());
194
195 mNotiNoGroup2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
196 .setContentTitle("D")
197 .setWhen(1202)
198 .build();
199 mRecordNoGroup2 = new NotificationRecord(mContext, new StatusBarNotification(
200 PKG, PKG, 1, null, 0, 0, mNotiNoGroup2, user,
201 null, System.currentTimeMillis()), getDefaultChannel());
202
203 mNotiNoGroupSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
204 .setContentTitle("E")
205 .setWhen(1201)
206 .setSortKey("A")
207 .build();
208 mRecordNoGroupSortA = new NotificationRecord(mContext, new StatusBarNotification(
209 PKG, PKG, 1, null, 0, 0, mNotiNoGroupSortA, user,
210 null, System.currentTimeMillis()), getDefaultChannel());
211
212 mAudioAttributes = new AudioAttributes.Builder()
213 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
214 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
215 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
216 .build();
Chris Wren1031c972014-07-23 13:11:45 +0000217 }
218
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400219 private NotificationChannel getDefaultChannel() {
Julia Reynolds85769912016-10-25 09:08:57 -0400220 return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
Julia Reynolds74856c42017-02-08 14:47:23 -0500221 IMPORTANCE_LOW);
Julia Reynolds85769912016-10-25 09:08:57 -0400222 }
223
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400224 private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, boolean forBackup,
225 String... channelIds)
Julia Reynolds85769912016-10-25 09:08:57 -0400226 throws Exception {
227 XmlSerializer serializer = new FastXmlSerializer();
228 ByteArrayOutputStream baos = new ByteArrayOutputStream();
229 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
230 serializer.startDocument(null, true);
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400231 mHelper.writeXml(serializer, forBackup);
Julia Reynolds85769912016-10-25 09:08:57 -0400232 serializer.endDocument();
233 serializer.flush();
Julia Reynolds85769912016-10-25 09:08:57 -0400234 for (String channelId : channelIds) {
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500235 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
Julia Reynolds85769912016-10-25 09:08:57 -0400236 }
237 return baos;
238 }
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400239
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400240 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore) throws Exception {
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100241 loadByteArrayXml(stream.toByteArray(), forRestore);
242 }
243
244 private void loadByteArrayXml(byte[] byteArray, boolean forRestore) throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500245 XmlPullParser parser = Xml.newPullParser();
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100246 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500247 parser.nextTag();
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400248 mHelper.readXml(parser, forRestore);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500249 }
250
Julia Reynoldsf57de462016-11-23 11:31:46 -0500251 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
252 assertEquals(expected.getId(), actual.getId());
253 assertEquals(expected.getName(), actual.getName());
Julia Reynolds2c891c92017-03-17 14:23:47 -0400254 assertEquals(expected.getDescription(), actual.getDescription());
Julia Reynoldsf57de462016-11-23 11:31:46 -0500255 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
256 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
257 assertEquals(expected.getImportance(), actual.getImportance());
258 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
259 assertEquals(expected.getSound(), actual.getSound());
260 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
261 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
Julia Reynolds59e152e2017-01-25 17:42:53 -0500262 assertEquals(expected.getGroup(), actual.getGroup());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500263 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
Julia Reynolds529e3322017-02-06 08:33:01 -0500264 assertEquals(expected.getLightColor(), actual.getLightColor());
Julia Reynoldsf57de462016-11-23 11:31:46 -0500265 }
266
Julia Reynoldsd5286842017-03-02 15:37:10 -0500267 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
268 assertEquals(expected.getId(), actual.getId());
269 assertEquals(expected.getName(), actual.getName());
Julia Reynolds005c8b92017-08-24 10:35:53 -0400270 assertEquals(expected.getDescription(), actual.getDescription());
271 assertEquals(expected.isBlocked(), actual.isBlocked());
Julia Reynoldsd5286842017-03-02 15:37:10 -0500272 }
273
Julia Reynoldse0b25742017-05-08 12:55:24 -0400274 private NotificationChannel getChannel() {
275 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
276 }
277
Julia Reynolds005c8b92017-08-24 10:35:53 -0400278 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
279 for (NotificationChannel channel : channels) {
280 if (channel.getId().equals(id)) {
281 return channel;
282 }
283 }
284 return null;
285 }
286
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400287 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000288 public void testFindAfterRankingWithASplitGroup() throws Exception {
289 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
290 notificationList.add(mRecordGroupGSortA);
291 notificationList.add(mRecordGroupGSortB);
292 notificationList.add(mRecordNoGroup);
293 notificationList.add(mRecordNoGroupSortA);
294 mHelper.sort(notificationList);
295 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0);
296 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0);
297 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0);
298 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0);
299 }
300
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400301 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000302 public void testSortShouldNotThrowWithPlainNotifications() throws Exception {
303 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
304 notificationList.add(mRecordNoGroup);
305 notificationList.add(mRecordNoGroup2);
306 mHelper.sort(notificationList);
307 }
308
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400309 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000310 public void testSortShouldNotThrowOneSorted() throws Exception {
311 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
312 notificationList.add(mRecordNoGroup);
313 notificationList.add(mRecordNoGroupSortA);
314 mHelper.sort(notificationList);
315 }
316
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400317 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000318 public void testSortShouldNotThrowOneNotification() throws Exception {
319 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
320 notificationList.add(mRecordNoGroup);
321 mHelper.sort(notificationList);
322 }
323
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400324 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000325 public void testSortShouldNotThrowOneSortKey() throws Exception {
326 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
327 notificationList.add(mRecordGroupGSortB);
328 mHelper.sort(notificationList);
329 }
330
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400331 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000332 public void testSortShouldNotThrowOnEmptyList() throws Exception {
333 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
334 mHelper.sort(notificationList);
335 }
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400336
337 @Test
338 public void testChannelXml() throws Exception {
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400339 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
Julia Reynolds005c8b92017-08-24 10:35:53 -0400340 ncg.setBlocked(true);
341 ncg.setDescription("group desc");
Julia Reynoldsd5286842017-03-02 15:37:10 -0500342 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
Julia Reynolds85769912016-10-25 09:08:57 -0400343 NotificationChannel channel1 =
344 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
345 NotificationChannel channel2 =
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400346 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds2c891c92017-03-17 14:23:47 -0400347 channel2.setDescription("descriptions for all");
Julia Reynolds619a69f2017-01-27 15:11:38 -0500348 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500349 channel2.enableLights(true);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400350 channel2.setBypassDnd(true);
351 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Julia Reynoldsf57de462016-11-23 11:31:46 -0500352 channel2.enableVibration(true);
Julia Reynolds59e152e2017-01-25 17:42:53 -0500353 channel2.setGroup(ncg.getId());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500354 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds529e3322017-02-06 08:33:01 -0500355 channel2.setLightColor(Color.BLUE);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400356
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500357 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
358 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
359 mHelper.createNotificationChannel(PKG, UID, channel1, true);
360 mHelper.createNotificationChannel(PKG, UID, channel2, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400361
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500362 mHelper.setShowBadge(PKG, UID, true);
Julia Reynolds924eed12017-01-19 09:52:07 -0500363
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500364 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400365 channel2.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500366 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400367
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400368 loadStreamXml(baos, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400369
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500370 assertTrue(mHelper.canShowBadge(PKG, UID));
371 assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500372 compareChannels(channel2,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500373 mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynolds74856c42017-02-08 14:47:23 -0500374
375 List<NotificationChannelGroup> actualGroups =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500376 mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -0500377 boolean foundNcg = false;
378 for (NotificationChannelGroup actual : actualGroups) {
379 if (ncg.getId().equals(actual.getId())) {
380 foundNcg = true;
Julia Reynoldsd5286842017-03-02 15:37:10 -0500381 compareGroups(ncg, actual);
382 } else if (ncg2.getId().equals(actual.getId())) {
383 compareGroups(ncg2, actual);
Julia Reynolds74856c42017-02-08 14:47:23 -0500384 }
385 }
386 assertTrue(foundNcg);
387
388 boolean foundChannel2Group = false;
389 for (NotificationChannelGroup actual : actualGroups) {
390 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
391 foundChannel2Group = true;
392 break;
393 }
394 }
395 assertTrue(foundChannel2Group);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400396 }
Julia Reynolds85769912016-10-25 09:08:57 -0400397
398 @Test
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400399 public void testChannelXmlForBackup() throws Exception {
400 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
401 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
402 NotificationChannel channel1 =
403 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
404 NotificationChannel channel2 =
405 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
406 channel2.setDescription("descriptions for all");
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100407 channel2.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400408 channel2.enableLights(true);
409 channel2.setBypassDnd(true);
410 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
411 channel2.enableVibration(false);
412 channel2.setGroup(ncg.getId());
413 channel2.setLightColor(Color.BLUE);
Julia Reynolds745c1542017-05-26 14:43:47 -0400414 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
415 channel3.enableVibration(true);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400416
417 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
418 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
419 mHelper.createNotificationChannel(PKG, UID, channel1, true);
420 mHelper.createNotificationChannel(PKG, UID, channel2, false);
Julia Reynolds745c1542017-05-26 14:43:47 -0400421 mHelper.createNotificationChannel(PKG, UID, channel3, false);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400422 mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true);
423
424 mHelper.setShowBadge(PKG, UID, true);
425
426 mHelper.setImportance(UPDATED_PKG, UID2, IMPORTANCE_NONE);
427
428 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
Julia Reynolds745c1542017-05-26 14:43:47 -0400429 channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
430 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG, UPDATED_PKG},
431 new int[]{UID, UID2});
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400432
433 mHelper.setShowBadge(UPDATED_PKG, UID2, true);
434
435 loadStreamXml(baos, true);
436
437 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(UPDATED_PKG, UID2));
438 assertTrue(mHelper.canShowBadge(PKG, UID));
439 assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
440 compareChannels(channel2,
441 mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynolds745c1542017-05-26 14:43:47 -0400442 compareChannels(channel3,
443 mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400444
445 List<NotificationChannelGroup> actualGroups =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500446 mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400447 boolean foundNcg = false;
448 for (NotificationChannelGroup actual : actualGroups) {
449 if (ncg.getId().equals(actual.getId())) {
450 foundNcg = true;
451 compareGroups(ncg, actual);
452 } else if (ncg2.getId().equals(actual.getId())) {
453 compareGroups(ncg2, actual);
454 }
455 }
456 assertTrue(foundNcg);
457
458 boolean foundChannel2Group = false;
459 for (NotificationChannelGroup actual : actualGroups) {
460 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
461 foundChannel2Group = true;
462 break;
463 }
464 }
465 assertTrue(foundChannel2Group);
466 }
467
468 @Test
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100469 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
470 NotificationChannel channel =
471 new NotificationChannel("id", "name", IMPORTANCE_LOW);
472 channel.setSound(SOUND_URI, mAudioAttributes);
473 mHelper.createNotificationChannel(PKG, UID, channel, true);
474
475 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
476
477 // Testing that in restore we are given the canonical version
478 loadStreamXml(baos, true);
479 verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
480 }
481
482 @Test
483 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
484 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
485 Uri canonicalBasedOnLocal = localUri.buildUpon()
486 .appendQueryParameter("title", "Test")
487 .appendQueryParameter("canonical", "1")
488 .build();
489 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
490 .thenReturn(canonicalBasedOnLocal);
491 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
492 .thenReturn(localUri);
493 when(mTestIContentProvider.uncanonicalize(any(), eq(canonicalBasedOnLocal)))
494 .thenReturn(localUri);
495
496 NotificationChannel channel =
497 new NotificationChannel("id", "name", IMPORTANCE_LOW);
498 channel.setSound(SOUND_URI, mAudioAttributes);
499 mHelper.createNotificationChannel(PKG, UID, channel, true);
500 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
501
502 loadStreamXml(baos, true);
503
504 NotificationChannel actualChannel = mHelper.getNotificationChannel(
505 PKG, UID, channel.getId(), false);
506 assertEquals(localUri, actualChannel.getSound());
507 }
508
509 @Test
510 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
511 Thread.sleep(3000);
512 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
513 .thenReturn(null);
514 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
515 .thenReturn(null);
516
517 NotificationChannel channel =
518 new NotificationChannel("id", "name", IMPORTANCE_LOW);
519 channel.setSound(SOUND_URI, mAudioAttributes);
520 mHelper.createNotificationChannel(PKG, UID, channel, true);
521 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
522
523 loadStreamXml(baos, true);
524
525 NotificationChannel actualChannel = mHelper.getNotificationChannel(
526 PKG, UID, channel.getId(), false);
527 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
528 }
529
530
531 /**
532 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
533 * handle its restore properly.
534 */
535 @Test
536 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
537 // Not a local uncanonicalized uri, simulating that it fails to exist locally
538 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI))).thenReturn(null);
539 String id = "id";
540 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
541 + "<package name=\"com.android.server.notification\" show_badge=\"true\">\n"
542 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
543 + "sound=\"" + SOUND_URI + "\" "
544 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
545 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
546 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
547 + "</package>\n"
548 + "</ranking>\n";
549
550 loadByteArrayXml(backupWithUncanonicalizedSoundUri.getBytes(), true);
551
552 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG, UID, id, false);
553 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
554 }
555
556 @Test
557 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
558 NotificationChannel channel =
559 new NotificationChannel("id", "name", IMPORTANCE_LOW);
560 channel.setSound(null, mAudioAttributes);
561 mHelper.createNotificationChannel(PKG, UID, channel, true);
562 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
563
564 loadStreamXml(baos, true);
565
566 NotificationChannel actualChannel = mHelper.getNotificationChannel(
567 PKG, UID, channel.getId(), false);
568 assertEquals(null, actualChannel.getSound());
569 }
570
571 @Test
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400572 public void testChannelXml_backup() throws Exception {
573 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
574 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
575 NotificationChannel channel1 =
576 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
577 NotificationChannel channel2 =
578 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
579 NotificationChannel channel3 =
580 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
581 channel3.setGroup(ncg.getId());
582
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500583 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
584 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
585 mHelper.createNotificationChannel(PKG, UID, channel1, true);
586 mHelper.createNotificationChannel(PKG, UID, channel2, false);
587 mHelper.createNotificationChannel(PKG, UID, channel3, true);
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400588
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500589 mHelper.deleteNotificationChannel(PKG, UID, channel1.getId());
590 mHelper.deleteNotificationChannelGroup(PKG, UID, ncg.getId());
591 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400592
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500593 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400594 channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500595 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400596
597 XmlPullParser parser = Xml.newPullParser();
598 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
599 null);
600 parser.nextTag();
601 mHelper.readXml(parser, true);
602
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500603 assertNull(mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
604 assertNull(mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
605 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG, UID));
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000606 //assertEquals(ncg2, mHelper.getNotificationChannelGroup(ncg2.getId(), PKG, UID));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500607 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400608 }
609
610 @Test
Julia Reynolds85769912016-10-25 09:08:57 -0400611 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400612 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
Julia Reynolds85769912016-10-25 09:08:57 -0400613 NotificationChannel.DEFAULT_CHANNEL_ID);
614
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400615 loadStreamXml(baos, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400616
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500617 final NotificationChannel updated = mHelper.getNotificationChannel(PKG, UID,
618 NotificationChannel.DEFAULT_CHANNEL_ID, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400619 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
620 assertFalse(updated.canBypassDnd());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500621 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
Julia Reynolds85769912016-10-25 09:08:57 -0400622 assertEquals(0, updated.getUserLockedFields());
623 }
624
625 @Test
Julia Reynoldsb3a04f02016-11-04 09:08:52 -0400626 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500627 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
628 NotificationChannel.DEFAULT_CHANNEL_ID, false);
629 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400630 mHelper.updateNotificationChannel(PKG, UID, defaultChannel, true);
Julia Reynoldsb3a04f02016-11-04 09:08:52 -0400631
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400632 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
Julia Reynolds85769912016-10-25 09:08:57 -0400633 NotificationChannel.DEFAULT_CHANNEL_ID);
634
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400635 loadStreamXml(baos, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400636
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500637 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
638 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Julia Reynolds85769912016-10-25 09:08:57 -0400639 }
640
Julia Reynolds85769912016-10-25 09:08:57 -0400641 @Test
642 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
Julia Reynolds1864ff52016-11-02 09:54:47 -0400643 final String preupgradeXml = "<ranking version=\"1\">\n"
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500644 + "<package name=\"" + PKG
645 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
Julia Reynolds619a69f2017-01-27 15:11:38 -0500646 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500647 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID + "\" />\n"
648 + "<package name=\"" + UPDATED_PKG + "\" uid=\"" + UID2 + "\" visibility=\""
Julia Reynolds619a69f2017-01-27 15:11:38 -0500649 + Notification.VISIBILITY_PRIVATE + "\" />\n"
650 + "</ranking>";
Julia Reynolds85769912016-10-25 09:08:57 -0400651 XmlPullParser parser = Xml.newPullParser();
Julia Reynolds1864ff52016-11-02 09:54:47 -0400652 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
Julia Reynolds619a69f2017-01-27 15:11:38 -0500653 null);
Julia Reynolds85769912016-10-25 09:08:57 -0400654 parser.nextTag();
655 mHelper.readXml(parser, false);
656
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500657 final NotificationChannel updated1 =
658 mHelper.getNotificationChannel(PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Julia Reynolds1864ff52016-11-02 09:54:47 -0400659 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
660 assertTrue(updated1.canBypassDnd());
661 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
Julia Reynolds85769912016-10-25 09:08:57 -0400662 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
Julia Reynolds619a69f2017-01-27 15:11:38 -0500663 | NotificationChannel.USER_LOCKED_PRIORITY
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500664 | NotificationChannel.USER_LOCKED_VISIBILITY,
665 updated1.getUserLockedFields());
Julia Reynolds1864ff52016-11-02 09:54:47 -0400666
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500667 // No Default Channel created for updated packages
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400668 assertEquals(null, mHelper.getNotificationChannel(UPDATED_PKG, UID2,
669 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500670 }
671
672 @Test
673 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
674 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
675 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
676 assertTrue(defaultChannel != null);
677 ByteArrayOutputStream baos =
678 writeXmlAndPurge(PKG, UID, false, NotificationChannel.DEFAULT_CHANNEL_ID);
679 // Load package at higher sdk.
680 final ApplicationInfo upgraded = new ApplicationInfo();
681 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
682 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400683 loadStreamXml(baos, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500684
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500685 // Default Channel should be gone.
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400686 assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
687 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500688 }
689
690 @Test
691 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
692 mHelper.createNotificationChannel(PKG, UID,
693 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
694 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
695 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
696
697 // Load package at higher sdk.
698 final ApplicationInfo upgraded = new ApplicationInfo();
699 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
700 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400701 loadStreamXml(baos, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500702
703 // Default Channel should be gone.
704 assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
705 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Julia Reynolds85769912016-10-25 09:08:57 -0400706 }
707
Julia Reynolds85769912016-10-25 09:08:57 -0400708 @Test
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400709 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
710 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
711 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
712 mHelper.createNotificationChannel(PKG, UID,
713 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
714
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400715 loadStreamXml(baos, false);
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400716
717 // Should still have the newly created channel that wasn't in the xml.
718 assertTrue(mHelper.getNotificationChannel(PKG, UID, "bananas", false) != null);
719 }
720
721 @Test
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500722 public void testCreateChannel_blocked() throws Exception {
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400723 mHelper.setImportance(PKG, UID, IMPORTANCE_NONE);
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500724
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500725 mHelper.createNotificationChannel(PKG, UID,
726 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500727 }
728
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400729 @Test
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400730 public void testCreateChannel_badImportance() throws Exception {
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400731 try {
732 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400733 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1), true);
734 fail("Was allowed to create a channel with invalid importance");
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400735 } catch (IllegalArgumentException e) {
736 // yay
737 }
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400738 try {
739 mHelper.createNotificationChannel(PKG, UID,
740 new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED), true);
741 fail("Was allowed to create a channel with invalid importance");
742 } catch (IllegalArgumentException e) {
743 // yay
744 }
745 try {
746 mHelper.createNotificationChannel(PKG, UID,
747 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1), true);
748 fail("Was allowed to create a channel with invalid importance");
749 } catch (IllegalArgumentException e) {
750 // yay
751 }
752 mHelper.createNotificationChannel(PKG, UID,
753 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true);
754 mHelper.createNotificationChannel(PKG, UID,
755 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true);
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400756 }
757
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500758
759 @Test
Julia Reynolds85769912016-10-25 09:08:57 -0400760 public void testUpdate() throws Exception {
761 // no fields locked by user
762 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500763 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500764 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500765 channel.enableLights(true);
Julia Reynolds85769912016-10-25 09:08:57 -0400766 channel.setBypassDnd(true);
767 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
768
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500769 mHelper.createNotificationChannel(PKG, UID, channel, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400770
771 // same id, try to update all fields
772 final NotificationChannel channel2 =
773 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500774 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500775 channel2.enableLights(false);
Julia Reynolds85769912016-10-25 09:08:57 -0400776 channel2.setBypassDnd(false);
777 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
778
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400779 mHelper.updateNotificationChannel(PKG, UID, channel2, true);
Julia Reynolds85769912016-10-25 09:08:57 -0400780
781 // all fields should be changed
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500782 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel.getId(), false));
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400783
784 verify(mHandler, times(1)).requestSort();
Julia Reynolds85769912016-10-25 09:08:57 -0400785 }
786
787 @Test
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400788 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
789 mHelper.setImportance(PKG, UID, IMPORTANCE_UNSPECIFIED);
790 assertTrue(mHelper.canShowBadge(PKG, UID));
791 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
792 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
793 mHelper.getPackageVisibility(PKG, UID));
794
795 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
796 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
797
798 defaultChannel.setShowBadge(false);
799 defaultChannel.setImportance(IMPORTANCE_NONE);
800 defaultChannel.setBypassDnd(true);
801 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
802
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400803 mHelper.updateNotificationChannel(PKG, UID, defaultChannel, true);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400804
805 // ensure app level fields are changed
806 assertFalse(mHelper.canShowBadge(PKG, UID));
807 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG, UID));
808 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG, UID));
809 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG, UID));
810 }
811
812 @Test
813 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
814 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
815
816 mHelper.createNotificationChannel(PKG, UID, channel, false);
817 assertTrue(mHelper.canShowBadge(PKG, UID));
818 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
819 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
820 mHelper.getPackageVisibility(PKG, UID));
821
822 channel.setShowBadge(false);
823 channel.setImportance(IMPORTANCE_NONE);
824 channel.setBypassDnd(true);
825 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
826
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400827 mHelper.updateNotificationChannel(PKG, UID, channel, true);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400828
829 // ensure app level fields are not changed
830 assertTrue(mHelper.canShowBadge(PKG, UID));
831 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
832 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
833 mHelper.getPackageVisibility(PKG, UID));
834 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
835 }
836
837 @Test
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500838 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
839 assertEquals(null, mHelper.getNotificationChannel(PKG, UID, "garbage", false));
Julia Reynolds85769912016-10-25 09:08:57 -0400840 }
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500841
842 @Test
843 public void testCreateChannel_CannotChangeHiddenFields() throws Exception {
844 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500845 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500846 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500847 channel.enableLights(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500848 channel.setBypassDnd(true);
849 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
850 channel.setShowBadge(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500851 int lockMask = 0;
852 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
853 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
854 }
855 channel.lockFields(lockMask);
856
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500857 mHelper.createNotificationChannel(PKG, UID, channel, true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500858
859 NotificationChannel savedChannel =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500860 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500861
862 assertEquals(channel.getName(), savedChannel.getName());
863 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
864 assertFalse(savedChannel.canBypassDnd());
865 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
Julia Reynoldsf35e3972017-01-05 15:41:04 -0500866 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400867
868 verify(mHandler, never()).requestSort();
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500869 }
870
871 @Test
872 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() throws Exception {
873 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500874 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500875 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500876 channel.enableLights(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500877 channel.setBypassDnd(true);
878 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
879 channel.setShowBadge(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500880 int lockMask = 0;
881 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
882 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
883 }
884 channel.lockFields(lockMask);
885
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500886 mHelper.createNotificationChannel(PKG, UID, channel, true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500887
888 NotificationChannel savedChannel =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500889 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500890
891 assertEquals(channel.getName(), savedChannel.getName());
892 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
893 assertFalse(savedChannel.canBypassDnd());
894 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
Julia Reynoldsf35e3972017-01-05 15:41:04 -0500895 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500896 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500897
898 @Test
Julia Reynoldse0b25742017-05-08 12:55:24 -0400899 public void testClearLockedFields() throws Exception {
900 final NotificationChannel channel = getChannel();
901 mHelper.clearLockedFields(channel);
902 assertEquals(0, channel.getUserLockedFields());
903
904 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
905 | NotificationChannel.USER_LOCKED_IMPORTANCE);
906 mHelper.clearLockedFields(channel);
907 assertEquals(0, channel.getUserLockedFields());
908 }
909
910 @Test
911 public void testLockFields_soundAndVibration() throws Exception {
912 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
913
914 final NotificationChannel update1 = getChannel();
915 update1.setSound(new Uri.Builder().scheme("test").build(),
916 new AudioAttributes.Builder().build());
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500917 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400918 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500919 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
920 | NotificationChannel.USER_LOCKED_SOUND,
Julia Reynoldse0b25742017-05-08 12:55:24 -0400921 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
922 .getUserLockedFields());
923
924 NotificationChannel update2 = getChannel();
925 update2.enableVibration(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400926 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500927 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
928 | NotificationChannel.USER_LOCKED_SOUND
Julia Reynoldse0b25742017-05-08 12:55:24 -0400929 | NotificationChannel.USER_LOCKED_VIBRATION,
930 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
931 .getUserLockedFields());
932 }
933
934 @Test
935 public void testLockFields_vibrationAndLights() throws Exception {
936 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
937
938 final NotificationChannel update1 = getChannel();
939 update1.setVibrationPattern(new long[]{7945, 46 ,246});
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400940 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400941 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
942 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
943 .getUserLockedFields());
944
945 final NotificationChannel update2 = getChannel();
946 update2.enableLights(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400947 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400948 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
949 | NotificationChannel.USER_LOCKED_LIGHTS,
950 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
951 .getUserLockedFields());
952 }
953
954 @Test
955 public void testLockFields_lightsAndImportance() throws Exception {
956 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
957
958 final NotificationChannel update1 = getChannel();
959 update1.setLightColor(Color.GREEN);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400960 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400961 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
962 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
963 .getUserLockedFields());
964
965 final NotificationChannel update2 = getChannel();
966 update2.setImportance(IMPORTANCE_DEFAULT);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400967 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400968 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
969 | NotificationChannel.USER_LOCKED_IMPORTANCE,
970 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
971 .getUserLockedFields());
972 }
973
974 @Test
975 public void testLockFields_visibilityAndDndAndBadge() throws Exception {
976 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
977 assertEquals(0,
978 mHelper.getNotificationChannel(PKG, UID, getChannel().getId(), false)
979 .getUserLockedFields());
980
981 final NotificationChannel update1 = getChannel();
982 update1.setBypassDnd(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400983 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400984 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
985 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
986 .getUserLockedFields());
987
988 final NotificationChannel update2 = getChannel();
989 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400990 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400991 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
992 | NotificationChannel.USER_LOCKED_VISIBILITY,
993 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
994 .getUserLockedFields());
995
996 final NotificationChannel update3 = getChannel();
997 update3.setShowBadge(false);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400998 mHelper.updateNotificationChannel(PKG, UID, update3, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400999 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1000 | NotificationChannel.USER_LOCKED_VISIBILITY
1001 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
1002 mHelper.getNotificationChannel(PKG, UID, update3.getId(), false)
1003 .getUserLockedFields());
1004 }
1005
1006 @Test
Julia Reynolds8e0eb372017-03-21 15:04:50 -04001007 public void testDeleteNonExistentChannel() throws Exception {
1008 mHelper.deleteNotificationChannelGroup(PKG, UID, "does not exist");
1009 }
1010
1011 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001012 public void testGetDeletedChannel() throws Exception {
Julia Reynoldse0b25742017-05-08 12:55:24 -04001013 NotificationChannel channel = getChannel();
Julia Reynolds619a69f2017-01-27 15:11:38 -05001014 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -05001015 channel.enableLights(true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001016 channel.setBypassDnd(true);
1017 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1018 channel.enableVibration(true);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001019 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001020
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001021 mHelper.createNotificationChannel(PKG, UID, channel, true);
1022 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001023
1024 // Does not return deleted channel
1025 NotificationChannel response =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001026 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001027 assertNull(response);
1028
1029 // Returns deleted channel
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001030 response = mHelper.getNotificationChannel(PKG, UID, channel.getId(), true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001031 compareChannels(channel, response);
1032 assertTrue(response.isDeleted());
1033 }
1034
1035 @Test
1036 public void testGetDeletedChannels() throws Exception {
1037 Map<String, NotificationChannel> channelMap = new HashMap<>();
1038 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001039 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001040 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -05001041 channel.enableLights(true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001042 channel.setBypassDnd(true);
1043 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1044 channel.enableVibration(true);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001045 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001046 channelMap.put(channel.getId(), channel);
1047 NotificationChannel channel2 =
1048 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1049 channelMap.put(channel2.getId(), channel2);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001050 mHelper.createNotificationChannel(PKG, UID, channel, true);
1051 mHelper.createNotificationChannel(PKG, UID, channel2, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001052
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001053 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001054
1055 // Returns only non-deleted channels
1056 List<NotificationChannel> channels =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001057 mHelper.getNotificationChannels(PKG, UID, false).getList();
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001058 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1059 for (NotificationChannel nc : channels) {
1060 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1061 compareChannels(channel2, nc);
1062 }
1063 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001064
1065 // Returns deleted channels too
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001066 channels = mHelper.getNotificationChannels(PKG, UID, true).getList();
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001067 assertEquals(3, channels.size()); // Includes default channel
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001068 for (NotificationChannel nc : channels) {
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001069 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1070 compareChannels(channelMap.get(nc.getId()), nc);
1071 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001072 }
1073 }
1074
1075 @Test
Julia Reynolds41103f42017-03-15 11:36:35 -04001076 public void testGetDeletedChannelCount() throws Exception {
1077 NotificationChannel channel =
1078 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1079 NotificationChannel channel2 =
1080 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1081 NotificationChannel channel3 =
1082 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001083 mHelper.createNotificationChannel(PKG, UID, channel, true);
1084 mHelper.createNotificationChannel(PKG, UID, channel2, true);
1085 mHelper.createNotificationChannel(PKG, UID, channel3, true);
Julia Reynolds41103f42017-03-15 11:36:35 -04001086
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001087 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
1088 mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
Julia Reynolds41103f42017-03-15 11:36:35 -04001089
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001090 assertEquals(2, mHelper.getDeletedChannelCount(PKG, UID));
1091 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID2));
Julia Reynolds41103f42017-03-15 11:36:35 -04001092 }
1093
1094 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001095 public void testCreateDeletedChannel() throws Exception {
Julia Reynolds619a69f2017-01-27 15:11:38 -05001096 long[] vibration = new long[]{100, 67, 145, 156};
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001097 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001098 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001099 channel.setVibrationPattern(vibration);
1100
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001101 mHelper.createNotificationChannel(PKG, UID, channel, true);
1102 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001103
1104 NotificationChannel newChannel = new NotificationChannel(
1105 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001106 newChannel.setVibrationPattern(new long[]{100});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001107
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001108 mHelper.createNotificationChannel(PKG, UID, newChannel, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001109
1110 // No long deleted, using old settings
1111 compareChannels(channel,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001112 mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001113 }
1114
1115 @Test
Julia Reynolds17717f52017-05-09 11:46:06 -04001116 public void testOnlyHasDefaultChannel() throws Exception {
1117 assertTrue(mHelper.onlyHasDefaultChannel(PKG, UID));
1118 assertFalse(mHelper.onlyHasDefaultChannel(UPDATED_PKG, UID2));
1119
1120 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
1121 assertFalse(mHelper.onlyHasDefaultChannel(PKG, UID));
1122 }
1123
1124 @Test
Julia Reynolds03fa85d2017-03-06 15:14:50 -05001125 public void testCreateChannel_defaultChannelId() throws Exception {
1126 try {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001127 mHelper.createNotificationChannel(PKG, UID, new NotificationChannel(
Julia Reynolds03fa85d2017-03-06 15:14:50 -05001128 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true);
1129 fail("Allowed to create default channel");
1130 } catch (IllegalArgumentException e) {
1131 // pass
1132 }
1133 }
1134
1135 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001136 public void testCreateChannel_alreadyExists() throws Exception {
Julia Reynolds619a69f2017-01-27 15:11:38 -05001137 long[] vibration = new long[]{100, 67, 145, 156};
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001138 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001139 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001140 channel.setVibrationPattern(vibration);
1141
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001142 mHelper.createNotificationChannel(PKG, UID, channel, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001143
1144 NotificationChannel newChannel = new NotificationChannel(
1145 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001146 newChannel.setVibrationPattern(new long[]{100});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001147
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001148 mHelper.createNotificationChannel(PKG, UID, newChannel, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001149
1150 // Old settings not overridden
1151 compareChannels(channel,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001152 mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001153 }
1154
1155 @Test
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001156 public void testCreateChannel_noOverrideSound() throws Exception {
1157 Uri sound = new Uri.Builder().scheme("test").build();
1158 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1159 NotificationManager.IMPORTANCE_DEFAULT);
1160 channel.setSound(sound, mAudioAttributes);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001161 mHelper.createNotificationChannel(PKG, UID, channel, true);
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001162 assertEquals(sound, mHelper.getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001163 PKG, UID, channel.getId(), false).getSound());
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001164 }
1165
1166 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001167 public void testPermanentlyDeleteChannels() throws Exception {
1168 NotificationChannel channel1 =
1169 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1170 NotificationChannel channel2 =
Julia Reynolds74856c42017-02-08 14:47:23 -05001171 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001172
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001173 mHelper.createNotificationChannel(PKG, UID, channel1, true);
1174 mHelper.createNotificationChannel(PKG, UID, channel2, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001175
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001176 mHelper.permanentlyDeleteNotificationChannels(PKG, UID);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001177
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001178 // Only default channel remains
1179 assertEquals(1, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001180 }
1181
1182 @Test
Julia Reynolds9bfba592017-03-15 14:03:55 -04001183 public void testDeleteGroup() throws Exception {
1184 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1185 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1186 NotificationChannel nonGroupedNonDeletedChannel =
1187 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1188 NotificationChannel groupedButNotDeleted =
1189 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1190 groupedButNotDeleted.setGroup("not");
1191 NotificationChannel groupedAndDeleted =
1192 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1193 groupedAndDeleted.setGroup("totally");
1194
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001195 mHelper.createNotificationChannelGroup(PKG, UID, notDeleted, true);
1196 mHelper.createNotificationChannelGroup(PKG, UID, deleted, true);
1197 mHelper.createNotificationChannel(PKG, UID, nonGroupedNonDeletedChannel, true);
1198 mHelper.createNotificationChannel(PKG, UID, groupedAndDeleted, true);
1199 mHelper.createNotificationChannel(PKG, UID, groupedButNotDeleted, true);
Julia Reynolds9bfba592017-03-15 14:03:55 -04001200
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001201 mHelper.deleteNotificationChannelGroup(PKG, UID, deleted.getId());
Julia Reynolds9bfba592017-03-15 14:03:55 -04001202
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001203 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG, UID));
1204 assertNotNull(mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG, UID));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001205
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001206 assertNull(mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001207 compareChannels(groupedAndDeleted,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001208 mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), true));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001209
1210 compareChannels(groupedButNotDeleted,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001211 mHelper.getNotificationChannel(PKG, UID, groupedButNotDeleted.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001212 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001213 PKG, UID, nonGroupedNonDeletedChannel.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001214
1215 // notDeleted
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001216 assertEquals(1, mHelper.getNotificationChannelGroups(PKG, UID).size());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001217
1218 verify(mHandler, never()).requestSort();
Julia Reynolds9bfba592017-03-15 14:03:55 -04001219 }
1220
1221 @Test
Julia Reynolds2e9bf5f2017-05-03 13:23:30 -04001222 public void testOnUserRemoved() throws Exception {
1223 int[] user0Uids = {98, 235, 16, 3782};
1224 int[] user1Uids = new int[user0Uids.length];
1225 for (int i = 0; i < user0Uids.length; i++) {
1226 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1227
1228 final ApplicationInfo legacy = new ApplicationInfo();
1229 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1230 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
1231
1232 // create records with the default channel for all user 0 and user 1 uids
1233 mHelper.getImportance(PKG, user0Uids[i]);
1234 mHelper.getImportance(PKG, user1Uids[i]);
1235 }
1236
1237 mHelper.onUserRemoved(1);
1238
1239 // user 0 records remain
1240 for (int i = 0; i < user0Uids.length; i++) {
1241 assertEquals(1,
1242 mHelper.getNotificationChannels(PKG, user0Uids[i], false).getList().size());
1243 }
1244 // user 1 records are gone
1245 for (int i = 0; i < user1Uids.length; i++) {
1246 assertEquals(0,
1247 mHelper.getNotificationChannels(PKG, user1Uids[i], false).getList().size());
1248 }
1249 }
1250
1251 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001252 public void testOnPackageChanged_packageRemoval() throws Exception {
1253 // Deleted
1254 NotificationChannel channel1 =
1255 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001256 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001257
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001258 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001259
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001260 assertEquals(0, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001261
1262 // Not deleted
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001263 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001264
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001265 mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001266 assertEquals(2, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001267 }
Julia Reynolds924eed12017-01-19 09:52:07 -05001268
1269 @Test
Julia Reynolds59e152e2017-01-25 17:42:53 -05001270 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001271 mHelper.setImportance(PKG, UID, NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001272
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001273 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds59e152e2017-01-25 17:42:53 -05001274
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001275 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
Julia Reynolds59e152e2017-01-25 17:42:53 -05001276 }
1277
1278 @Test
1279 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1280 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001281 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001282 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001283 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001284
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001285 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds59e152e2017-01-25 17:42:53 -05001286
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001287 assertEquals(0,
1288 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList().size());
Julia Reynolds59e152e2017-01-25 17:42:53 -05001289 }
1290
1291 @Test
Julia Reynoldsf26eb912017-05-22 15:47:06 -04001292 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1293 // create channel as api 26
1294 mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true);
1295
1296 // install new app version targeting 25
1297 final ApplicationInfo legacy = new ApplicationInfo();
1298 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1299 when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(legacy);
1300 mHelper.onPackagesChanged(
1301 false, UserHandle.USER_SYSTEM, new String[]{UPDATED_PKG}, new int[]{UID2});
1302
1303 // make sure the default channel was readded
1304 //assertEquals(2, mHelper.getNotificationChannels(UPDATED_PKG, UID2, false).getList().size());
1305 assertNotNull(mHelper.getNotificationChannel(
1306 UPDATED_PKG, UID2, NotificationChannel.DEFAULT_CHANNEL_ID, false));
1307 }
1308
1309 @Test
Julia Reynolds924eed12017-01-19 09:52:07 -05001310 public void testRecordDefaults() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001311 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
1312 assertEquals(true, mHelper.canShowBadge(PKG, UID));
1313 assertEquals(1, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
Julia Reynolds924eed12017-01-19 09:52:07 -05001314 }
Julia Reynolds59e152e2017-01-25 17:42:53 -05001315
1316 @Test
1317 public void testCreateGroup() throws Exception {
1318 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001319 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
1320 assertEquals(ncg, mHelper.getNotificationChannelGroups(PKG, UID).iterator().next());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001321 verify(mHandler, never()).requestSort();
Julia Reynolds59e152e2017-01-25 17:42:53 -05001322 }
1323
1324 @Test
1325 public void testCannotCreateChannel_badGroup() throws Exception {
1326 NotificationChannel channel1 =
1327 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1328 channel1.setGroup("garbage");
1329 try {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001330 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001331 fail("Created a channel with a bad group");
Julia Reynolds619a69f2017-01-27 15:11:38 -05001332 } catch (IllegalArgumentException e) {
1333 }
Julia Reynolds59e152e2017-01-25 17:42:53 -05001334 }
1335
1336 @Test
1337 public void testCannotCreateChannel_goodGroup() throws Exception {
1338 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001339 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001340 NotificationChannel channel1 =
1341 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1342 channel1.setGroup(ncg.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001343 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001344
1345 assertEquals(ncg.getId(),
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001346 mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false).getGroup());
Julia Reynolds59e152e2017-01-25 17:42:53 -05001347 }
1348
1349 @Test
1350 public void testGetChannelGroups() throws Exception {
Julia Reynoldsf02562a2017-01-26 13:33:56 -05001351 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001352 mHelper.createNotificationChannelGroup(PKG, UID, unused, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001353 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001354 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001355 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001356 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001357
1358 NotificationChannel channel1 =
1359 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1360 channel1.setGroup(ncg.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001361 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001362 NotificationChannel channel1a =
1363 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1364 channel1a.setGroup(ncg.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001365 mHelper.createNotificationChannel(PKG, UID, channel1a, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001366
1367 NotificationChannel channel2 =
1368 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1369 channel2.setGroup(ncg2.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001370 mHelper.createNotificationChannel(PKG, UID, channel2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001371
1372 NotificationChannel channel3 =
1373 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001374 mHelper.createNotificationChannel(PKG, UID, channel3, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001375
1376 List<NotificationChannelGroup> actual =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001377 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds59e152e2017-01-25 17:42:53 -05001378 assertEquals(3, actual.size());
Julia Reynolds619a69f2017-01-27 15:11:38 -05001379 for (NotificationChannelGroup group : actual) {
Julia Reynolds59e152e2017-01-25 17:42:53 -05001380 if (group.getId() == null) {
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001381 assertEquals(2, group.getChannels().size()); // misc channel too
1382 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1383 || channel3.getId().equals(group.getChannels().get(1).getId()));
Julia Reynolds59e152e2017-01-25 17:42:53 -05001384 } else if (group.getId().equals(ncg.getId())) {
1385 assertEquals(2, group.getChannels().size());
1386 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1387 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1388 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1389 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1390 } else {
1391 fail("expected channel not found");
1392 }
1393 } else if (group.getId().equals(ncg2.getId())) {
1394 assertEquals(1, group.getChannels().size());
1395 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1396 }
1397 }
1398 }
Julia Reynolds74856c42017-02-08 14:47:23 -05001399
1400 @Test
1401 public void testGetChannelGroups_noSideEffects() throws Exception {
1402 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001403 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds74856c42017-02-08 14:47:23 -05001404
1405 NotificationChannel channel1 =
1406 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1407 channel1.setGroup(ncg.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001408 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001409 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -05001410
1411 channel1.setImportance(IMPORTANCE_LOW);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001412 mHelper.updateNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds74856c42017-02-08 14:47:23 -05001413
1414 List<NotificationChannelGroup> actual =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001415 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -05001416
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001417 assertEquals(2, actual.size());
1418 for (NotificationChannelGroup group : actual) {
1419 if (Objects.equals(group.getId(), ncg.getId())) {
1420 assertEquals(1, group.getChannels().size());
1421 }
1422 }
Julia Reynolds74856c42017-02-08 14:47:23 -05001423 }
Julia Reynoldsd373d782017-03-03 13:32:57 -05001424
1425 @Test
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001426 public void testCreateChannel_updateName() throws Exception {
1427 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001428 mHelper.createNotificationChannel(PKG, UID, nc, true);
1429 NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001430 assertEquals("hello", actual.getName());
1431
1432 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001433 mHelper.createNotificationChannel(PKG, UID, nc, true);
Julia Reynoldsd373d782017-03-03 13:32:57 -05001434
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001435 actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001436 assertEquals("goodbye", actual.getName());
1437 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001438
1439 verify(mHandler, times(1)).requestSort();
Julia Reynoldsd373d782017-03-03 13:32:57 -05001440 }
1441
1442 @Test
Julia Reynolds005c8b92017-08-24 10:35:53 -04001443 public void testCreateChannel_addToGroup() throws Exception {
1444 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
1445 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1446 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
1447 mHelper.createNotificationChannel(PKG, UID, nc, true);
1448 NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
1449 assertNull(actual.getGroup());
1450
1451 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1452 nc.setGroup(group.getId());
1453 mHelper.createNotificationChannel(PKG, UID, nc, true);
1454
1455 actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
1456 assertNotNull(actual.getGroup());
1457 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1458
1459 verify(mHandler, times(1)).requestSort();
1460 }
1461
1462 @Test
Julia Reynoldsd373d782017-03-03 13:32:57 -05001463 public void testDumpChannelsJson() throws Exception {
1464 final ApplicationInfo upgrade = new ApplicationInfo();
1465 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
1466 try {
1467 when(mPm.getApplicationInfoAsUser(
1468 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
1469 } catch (PackageManager.NameNotFoundException e) {
1470 }
1471 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
1472 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
1473 for (int i = 0; i < numPackages; i++) {
1474 String pkgName = "pkg" + i;
1475 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
1476 for (int j = 0; j < numChannels; j++) {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001477 mHelper.createNotificationChannel(pkgName, UID,
Julia Reynoldsd373d782017-03-03 13:32:57 -05001478 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true);
1479 }
1480 expectedChannels.put(pkgName, numChannels);
1481 }
1482
1483 // delete the first channel of the first package
1484 String pkg = expectedChannels.keyAt(0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001485 mHelper.deleteNotificationChannel("pkg" + 0, UID, "0");
Julia Reynoldsd373d782017-03-03 13:32:57 -05001486 // dump should not include deleted channels
1487 int count = expectedChannels.get(pkg);
1488 expectedChannels.put(pkg, count - 1);
1489
1490 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
1491 assertEquals(numPackages, actual.length());
1492 for (int i = 0; i < numPackages; i++) {
1493 JSONObject object = actual.getJSONObject(i);
1494 assertTrue(expectedChannels.containsKey(object.get("packageName")));
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -04001495 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
Julia Reynoldsd373d782017-03-03 13:32:57 -05001496 object.getInt("channelCount"));
1497 }
1498 }
Chris Wren89aa2262017-05-05 18:05:56 -04001499
1500 @Test
1501 public void testBadgingOverrideTrue() throws Exception {
1502 Secure.putIntForUser(getContext().getContentResolver(),
1503 Secure.NOTIFICATION_BADGING, 1,
1504 USER.getIdentifier());
1505 mHelper.updateBadgingEnabled(); // would be called by settings observer
1506 assertTrue(mHelper.badgingEnabled(USER));
1507 }
1508
1509 @Test
1510 public void testBadgingOverrideFalse() throws Exception {
1511 Secure.putIntForUser(getContext().getContentResolver(),
1512 Secure.NOTIFICATION_BADGING, 0,
1513 USER.getIdentifier());
1514 mHelper.updateBadgingEnabled(); // would be called by settings observer
1515 assertFalse(mHelper.badgingEnabled(USER));
1516 }
1517
1518 @Test
Chris Wren13f157f2017-05-12 15:02:06 -04001519 public void testBadgingForUserAll() throws Exception {
1520 try {
1521 mHelper.badgingEnabled(UserHandle.ALL);
1522 } catch (Exception e) {
1523 fail("just don't throw");
1524 }
1525 }
1526
1527 @Test
Chris Wren89aa2262017-05-05 18:05:56 -04001528 public void testBadgingOverrideUserIsolation() throws Exception {
1529 Secure.putIntForUser(getContext().getContentResolver(),
1530 Secure.NOTIFICATION_BADGING, 0,
1531 USER.getIdentifier());
1532 Secure.putIntForUser(getContext().getContentResolver(),
1533 Secure.NOTIFICATION_BADGING, 1,
1534 USER2.getIdentifier());
1535 mHelper.updateBadgingEnabled(); // would be called by settings observer
1536 assertFalse(mHelper.badgingEnabled(USER));
1537 assertTrue(mHelper.badgingEnabled(USER2));
1538 }
Julia Reynolds816797a2017-08-11 15:47:09 -04001539
1540 @Test
1541 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
1542 String newLabel = "bananas!";
1543 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
1544 NotificationChannel.DEFAULT_CHANNEL_ID, false);
1545 assertFalse(newLabel.equals(defaultChannel.getName()));
1546
1547 Resources res = mock(Resources.class);
1548 when(mContext.getResources()).thenReturn(res);
1549 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
1550 .thenReturn(newLabel);
1551
1552 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
1553
1554 assertEquals(newLabel, mHelper.getNotificationChannel(PKG, UID,
1555 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
1556 }
Julia Reynolds005c8b92017-08-24 10:35:53 -04001557
1558 @Test
1559 public void testIsGroupBlocked_noGroup() throws Exception {
1560 assertFalse(mHelper.isGroupBlocked(PKG, UID, null));
1561
1562 assertFalse(mHelper.isGroupBlocked(PKG, UID, "non existent group"));
1563 }
1564
1565 @Test
1566 public void testIsGroupBlocked_notBlocked() throws Exception {
1567 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1568 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1569
1570 assertFalse(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1571 }
1572
1573 @Test
1574 public void testIsGroupBlocked_blocked() throws Exception {
1575 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1576 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1577 group.setBlocked(true);
1578 mHelper.createNotificationChannelGroup(PKG, UID, group, false);
1579
1580 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1581 }
1582
1583 @Test
1584 public void testIsGroup_appCannotResetBlock() throws Exception {
1585 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1586 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1587 NotificationChannelGroup group2 = group.clone();
1588 group2.setBlocked(true);
1589 mHelper.createNotificationChannelGroup(PKG, UID, group2, false);
1590 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1591
1592 NotificationChannelGroup group3 = group.clone();
1593 group3.setBlocked(false);
1594 mHelper.createNotificationChannelGroup(PKG, UID, group3, true);
1595 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1596 }
1597
1598 @Test
1599 public void testGetNotificationChannelGroupWithChannels() throws Exception {
1600 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
1601 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
1602 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1603 mHelper.createNotificationChannelGroup(PKG, UID, other, true);
1604
1605 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
1606 a.setGroup(group.getId());
1607 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
1608 b.setGroup(other.getId());
1609 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
1610 c.setGroup(group.getId());
1611 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
1612
1613 mHelper.createNotificationChannel(PKG, UID, a, true);
1614 mHelper.createNotificationChannel(PKG, UID, b, true);
1615 mHelper.createNotificationChannel(PKG, UID, c, true);
1616 mHelper.createNotificationChannel(PKG, UID, d, true);
1617 mHelper.deleteNotificationChannel(PKG, UID, c.getId());
1618
1619 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
1620 PKG, UID, group.getId(), true);
1621 assertEquals(2, retrieved.getChannels().size());
1622 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
1623 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
1624
1625 retrieved = mHelper.getNotificationChannelGroupWithChannels(
1626 PKG, UID, group.getId(), false);
1627 assertEquals(1, retrieved.getChannels().size());
1628 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
1629 }
Chris Wren1031c972014-07-23 13:11:45 +00001630}