blob: 09d88fd8c87caafb18f2c526ee55a9788ab5d817 [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;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -040050import android.content.pm.PackageInfo;
Julia Reynolds85769912016-10-25 09:08:57 -040051import android.content.pm.PackageManager;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -040052import android.content.pm.Signature;
Julia Reynolds816797a2017-08-11 15:47:09 -040053import android.content.res.Resources;
Julia Reynolds529e3322017-02-06 08:33:01 -050054import android.graphics.Color;
Julia Reynolds619a69f2017-01-27 15:11:38 -050055import android.media.AudioAttributes;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040056import android.net.Uri;
Julia Reynolds85769912016-10-25 09:08:57 -040057import android.os.Build;
Chris Wren1031c972014-07-23 13:11:45 +000058import android.os.UserHandle;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010059import android.provider.Settings;
Chris Wren89aa2262017-05-05 18:05:56 -040060import android.provider.Settings.Secure;
Chris Wren1031c972014-07-23 13:11:45 +000061import android.service.notification.StatusBarNotification;
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040062import android.support.test.InstrumentationRegistry;
63import android.support.test.runner.AndroidJUnit4;
Chris Wren1031c972014-07-23 13:11:45 +000064import android.test.suitebuilder.annotation.SmallTest;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010065import android.testing.TestableContentResolver;
Julia Reynoldsd373d782017-03-03 13:32:57 -050066import android.util.ArrayMap;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040067import android.util.Xml;
Chris Wren1031c972014-07-23 13:11:45 +000068
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010069import com.android.internal.util.FastXmlSerializer;
Jason Monk74f5e362017-12-06 08:56:33 -050070import com.android.server.UiServiceTestCase;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +010071
72import org.json.JSONArray;
73import org.json.JSONObject;
74import org.junit.Before;
75import org.junit.Test;
76import org.junit.runner.RunWith;
77import org.mockito.Mock;
78import org.mockito.MockitoAnnotations;
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlSerializer;
81
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040082import java.io.BufferedInputStream;
83import java.io.BufferedOutputStream;
84import java.io.ByteArrayInputStream;
85import java.io.ByteArrayOutputStream;
Chris Wren1031c972014-07-23 13:11:45 +000086import java.util.ArrayList;
Julia Reynoldsf57de462016-11-23 11:31:46 -050087import java.util.Arrays;
Julia Reynolds4036e8d2017-01-13 09:50:05 -050088import java.util.HashMap;
89import java.util.List;
90import java.util.Map;
Julia Reynolds74856c42017-02-08 14:47:23 -050091import java.util.Objects;
Julia Reynoldsd373d782017-03-03 13:32:57 -050092import java.util.concurrent.ThreadLocalRandom;
Chris Wren1031c972014-07-23 13:11:45 +000093
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040094@SmallTest
95@RunWith(AndroidJUnit4.class)
Jason Monk74f5e362017-12-06 08:56:33 -050096public class RankingHelperTest extends UiServiceTestCase {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -050097 private static final String PKG = "com.android.server.notification";
98 private static final int UID = 0;
Julia Reynolds5fe2eae2017-05-22 08:45:27 -040099 private static final UserHandle USER = UserHandle.of(0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500100 private static final String UPDATED_PKG = "updatedPkg";
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400101 private static final int UID2 = 1111;
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400102 private static final String SYSTEM_PKG = "android";
103 private static final int SYSTEM_UID= 1000;
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400104 private static final UserHandle USER2 = UserHandle.of(10);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500105 private static final String TEST_CHANNEL_ID = "test_channel_id";
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100106 private static final String TEST_AUTHORITY = "test";
107 private static final Uri SOUND_URI =
108 Uri.parse("content://" + TEST_AUTHORITY + "/internal/audio/media/10");
109 private static final Uri CANONICAL_SOUND_URI =
110 Uri.parse("content://" + TEST_AUTHORITY
111 + "/internal/audio/media/10?title=Test&canonical=1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500112
113 @Mock NotificationUsageStats mUsageStats;
114 @Mock RankingHandler mHandler;
115 @Mock PackageManager mPm;
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100116 @Mock IContentProvider mTestIContentProvider;
Julia Reynoldse0b25742017-05-08 12:55:24 -0400117 @Mock Context mContext;
Chris Wren1031c972014-07-23 13:11:45 +0000118
119 private Notification mNotiGroupGSortA;
120 private Notification mNotiGroupGSortB;
121 private Notification mNotiNoGroup;
122 private Notification mNotiNoGroup2;
123 private Notification mNotiNoGroupSortA;
124 private NotificationRecord mRecordGroupGSortA;
125 private NotificationRecord mRecordGroupGSortB;
126 private NotificationRecord mRecordNoGroup;
127 private NotificationRecord mRecordNoGroup2;
128 private NotificationRecord mRecordNoGroupSortA;
129 private RankingHelper mHelper;
Julia Reynolds619a69f2017-01-27 15:11:38 -0500130 private AudioAttributes mAudioAttributes;
Chris Wren1031c972014-07-23 13:11:45 +0000131
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400132 @Before
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500133 public void setUp() throws Exception {
Chris Wren5eab2b72015-06-16 13:56:22 -0400134 MockitoAnnotations.initMocks(this);
Chris Wren1031c972014-07-23 13:11:45 +0000135 UserHandle user = UserHandle.ALL;
136
Julia Reynolds85769912016-10-25 09:08:57 -0400137 final ApplicationInfo legacy = new ApplicationInfo();
138 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
Julia Reynolds1864ff52016-11-02 09:54:47 -0400139 final ApplicationInfo upgrade = new ApplicationInfo();
Dan Sandlere103b782017-05-17 16:07:56 -0700140 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500141 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
142 when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400143 when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500144 when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
Julia Reynoldsf26eb912017-05-22 15:47:06 -0400145 when(mPm.getPackageUidAsUser(eq(UPDATED_PKG), anyInt())).thenReturn(UID2);
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -0400146 when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
147 PackageInfo info = mock(PackageInfo.class);
148 info.signatures = new Signature[] {mock(Signature.class)};
149 when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
150 when(mPm.getPackageInfoAsUser(eq(PKG), anyInt(), anyInt()))
151 .thenReturn(mock(PackageInfo.class));
Julia Reynoldse0b25742017-05-08 12:55:24 -0400152 when(mContext.getResources()).thenReturn(
153 InstrumentationRegistry.getContext().getResources());
Julia Reynolds816797a2017-08-11 15:47:09 -0400154 when(mContext.getContentResolver()).thenReturn(
155 InstrumentationRegistry.getContext().getContentResolver());
Julia Reynoldse0b25742017-05-08 12:55:24 -0400156 when(mContext.getPackageManager()).thenReturn(mPm);
157 when(mContext.getApplicationInfo()).thenReturn(legacy);
Chris Wren89aa2262017-05-05 18:05:56 -0400158 // most tests assume badging is enabled
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100159 TestableContentResolver contentResolver = getContext().getContentResolver();
160 contentResolver.setFallbackToExisting(false);
161 Secure.putIntForUser(contentResolver,
Chris Wren89aa2262017-05-05 18:05:56 -0400162 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID));
Julia Reynoldse0b25742017-05-08 12:55:24 -0400163
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100164 ContentProvider testContentProvider = mock(ContentProvider.class);
165 when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
166 contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
167
168 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
169 .thenReturn(CANONICAL_SOUND_URI);
170 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
171 .thenReturn(CANONICAL_SOUND_URI);
172 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
173 .thenReturn(SOUND_URI);
174
Julia Reynoldsc861a3d2018-02-15 10:34:49 -0500175 mHelper = new RankingHelper(getContext(), mPm, mHandler, mock(ZenModeHelper.class),
176 mUsageStats, new String[] {ImportanceExtractor.class.getName()});
Julia Reynoldse0b25742017-05-08 12:55:24 -0400177
178 mNotiGroupGSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
179 .setContentTitle("A")
180 .setGroup("G")
181 .setSortKey("A")
182 .setWhen(1205)
183 .build();
184 mRecordGroupGSortA = new NotificationRecord(mContext, new StatusBarNotification(
185 PKG, PKG, 1, null, 0, 0, mNotiGroupGSortA, user,
186 null, System.currentTimeMillis()), getDefaultChannel());
187
188 mNotiGroupGSortB = new Notification.Builder(mContext, TEST_CHANNEL_ID)
189 .setContentTitle("B")
190 .setGroup("G")
191 .setSortKey("B")
192 .setWhen(1200)
193 .build();
194 mRecordGroupGSortB = new NotificationRecord(mContext, new StatusBarNotification(
195 PKG, PKG, 1, null, 0, 0, mNotiGroupGSortB, user,
196 null, System.currentTimeMillis()), getDefaultChannel());
197
198 mNotiNoGroup = new Notification.Builder(mContext, TEST_CHANNEL_ID)
199 .setContentTitle("C")
200 .setWhen(1201)
201 .build();
202 mRecordNoGroup = new NotificationRecord(mContext, new StatusBarNotification(
203 PKG, PKG, 1, null, 0, 0, mNotiNoGroup, user,
204 null, System.currentTimeMillis()), getDefaultChannel());
205
206 mNotiNoGroup2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
207 .setContentTitle("D")
208 .setWhen(1202)
209 .build();
210 mRecordNoGroup2 = new NotificationRecord(mContext, new StatusBarNotification(
211 PKG, PKG, 1, null, 0, 0, mNotiNoGroup2, user,
212 null, System.currentTimeMillis()), getDefaultChannel());
213
214 mNotiNoGroupSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
215 .setContentTitle("E")
216 .setWhen(1201)
217 .setSortKey("A")
218 .build();
219 mRecordNoGroupSortA = new NotificationRecord(mContext, new StatusBarNotification(
220 PKG, PKG, 1, null, 0, 0, mNotiNoGroupSortA, user,
221 null, System.currentTimeMillis()), getDefaultChannel());
222
223 mAudioAttributes = new AudioAttributes.Builder()
224 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
225 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
226 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
227 .build();
Chris Wren1031c972014-07-23 13:11:45 +0000228 }
229
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400230 private NotificationChannel getDefaultChannel() {
Julia Reynolds85769912016-10-25 09:08:57 -0400231 return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
Julia Reynolds74856c42017-02-08 14:47:23 -0500232 IMPORTANCE_LOW);
Julia Reynolds85769912016-10-25 09:08:57 -0400233 }
234
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400235 private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, boolean forBackup,
236 String... channelIds)
Julia Reynolds85769912016-10-25 09:08:57 -0400237 throws Exception {
238 XmlSerializer serializer = new FastXmlSerializer();
239 ByteArrayOutputStream baos = new ByteArrayOutputStream();
240 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
241 serializer.startDocument(null, true);
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400242 mHelper.writeXml(serializer, forBackup);
Julia Reynolds85769912016-10-25 09:08:57 -0400243 serializer.endDocument();
244 serializer.flush();
Julia Reynolds85769912016-10-25 09:08:57 -0400245 for (String channelId : channelIds) {
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500246 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId);
Julia Reynolds85769912016-10-25 09:08:57 -0400247 }
248 return baos;
249 }
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400250
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400251 private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore) throws Exception {
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100252 loadByteArrayXml(stream.toByteArray(), forRestore);
253 }
254
255 private void loadByteArrayXml(byte[] byteArray, boolean forRestore) throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500256 XmlPullParser parser = Xml.newPullParser();
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100257 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500258 parser.nextTag();
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400259 mHelper.readXml(parser, forRestore);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500260 }
261
Julia Reynoldsf57de462016-11-23 11:31:46 -0500262 private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
263 assertEquals(expected.getId(), actual.getId());
264 assertEquals(expected.getName(), actual.getName());
Julia Reynolds2c891c92017-03-17 14:23:47 -0400265 assertEquals(expected.getDescription(), actual.getDescription());
Julia Reynoldsf57de462016-11-23 11:31:46 -0500266 assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
267 assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
268 assertEquals(expected.getImportance(), actual.getImportance());
269 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
270 assertEquals(expected.getSound(), actual.getSound());
271 assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
272 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
Julia Reynolds59e152e2017-01-25 17:42:53 -0500273 assertEquals(expected.getGroup(), actual.getGroup());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500274 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes());
Julia Reynolds529e3322017-02-06 08:33:01 -0500275 assertEquals(expected.getLightColor(), actual.getLightColor());
Julia Reynoldsf57de462016-11-23 11:31:46 -0500276 }
277
Julia Reynoldsd5286842017-03-02 15:37:10 -0500278 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) {
279 assertEquals(expected.getId(), actual.getId());
280 assertEquals(expected.getName(), actual.getName());
Julia Reynolds005c8b92017-08-24 10:35:53 -0400281 assertEquals(expected.getDescription(), actual.getDescription());
282 assertEquals(expected.isBlocked(), actual.isBlocked());
Julia Reynoldsd5286842017-03-02 15:37:10 -0500283 }
284
Julia Reynoldse0b25742017-05-08 12:55:24 -0400285 private NotificationChannel getChannel() {
286 return new NotificationChannel("id", "name", IMPORTANCE_LOW);
287 }
288
Julia Reynolds005c8b92017-08-24 10:35:53 -0400289 private NotificationChannel findChannel(List<NotificationChannel> channels, String id) {
290 for (NotificationChannel channel : channels) {
291 if (channel.getId().equals(id)) {
292 return channel;
293 }
294 }
295 return null;
296 }
297
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400298 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000299 public void testFindAfterRankingWithASplitGroup() throws Exception {
300 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
301 notificationList.add(mRecordGroupGSortA);
302 notificationList.add(mRecordGroupGSortB);
303 notificationList.add(mRecordNoGroup);
304 notificationList.add(mRecordNoGroupSortA);
305 mHelper.sort(notificationList);
306 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0);
307 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0);
308 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0);
309 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0);
310 }
311
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400312 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000313 public void testSortShouldNotThrowWithPlainNotifications() throws Exception {
314 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
315 notificationList.add(mRecordNoGroup);
316 notificationList.add(mRecordNoGroup2);
317 mHelper.sort(notificationList);
318 }
319
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400320 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000321 public void testSortShouldNotThrowOneSorted() throws Exception {
322 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
323 notificationList.add(mRecordNoGroup);
324 notificationList.add(mRecordNoGroupSortA);
325 mHelper.sort(notificationList);
326 }
327
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400328 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000329 public void testSortShouldNotThrowOneNotification() throws Exception {
330 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
331 notificationList.add(mRecordNoGroup);
332 mHelper.sort(notificationList);
333 }
334
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400335 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000336 public void testSortShouldNotThrowOneSortKey() throws Exception {
337 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
338 notificationList.add(mRecordGroupGSortB);
339 mHelper.sort(notificationList);
340 }
341
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400342 @Test
Chris Wren1031c972014-07-23 13:11:45 +0000343 public void testSortShouldNotThrowOnEmptyList() throws Exception {
344 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
345 mHelper.sort(notificationList);
346 }
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400347
348 @Test
349 public void testChannelXml() throws Exception {
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400350 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
Julia Reynolds005c8b92017-08-24 10:35:53 -0400351 ncg.setBlocked(true);
352 ncg.setDescription("group desc");
Julia Reynoldsd5286842017-03-02 15:37:10 -0500353 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
Julia Reynolds85769912016-10-25 09:08:57 -0400354 NotificationChannel channel1 =
355 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
356 NotificationChannel channel2 =
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400357 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds2c891c92017-03-17 14:23:47 -0400358 channel2.setDescription("descriptions for all");
Julia Reynolds619a69f2017-01-27 15:11:38 -0500359 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500360 channel2.enableLights(true);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400361 channel2.setBypassDnd(true);
362 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Julia Reynoldsf57de462016-11-23 11:31:46 -0500363 channel2.enableVibration(true);
Julia Reynolds59e152e2017-01-25 17:42:53 -0500364 channel2.setGroup(ncg.getId());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500365 channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds529e3322017-02-06 08:33:01 -0500366 channel2.setLightColor(Color.BLUE);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400367
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500368 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
369 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
370 mHelper.createNotificationChannel(PKG, UID, channel1, true);
371 mHelper.createNotificationChannel(PKG, UID, channel2, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400372
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500373 mHelper.setShowBadge(PKG, UID, true);
Julia Reynolds924eed12017-01-19 09:52:07 -0500374
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500375 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400376 channel2.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500377 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400378
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400379 loadStreamXml(baos, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400380
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500381 assertTrue(mHelper.canShowBadge(PKG, UID));
382 assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500383 compareChannels(channel2,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500384 mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynolds74856c42017-02-08 14:47:23 -0500385
386 List<NotificationChannelGroup> actualGroups =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500387 mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -0500388 boolean foundNcg = false;
389 for (NotificationChannelGroup actual : actualGroups) {
390 if (ncg.getId().equals(actual.getId())) {
391 foundNcg = true;
Julia Reynoldsd5286842017-03-02 15:37:10 -0500392 compareGroups(ncg, actual);
393 } else if (ncg2.getId().equals(actual.getId())) {
394 compareGroups(ncg2, actual);
Julia Reynolds74856c42017-02-08 14:47:23 -0500395 }
396 }
397 assertTrue(foundNcg);
398
399 boolean foundChannel2Group = false;
400 for (NotificationChannelGroup actual : actualGroups) {
401 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
402 foundChannel2Group = true;
403 break;
404 }
405 }
406 assertTrue(foundChannel2Group);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400407 }
Julia Reynolds85769912016-10-25 09:08:57 -0400408
409 @Test
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400410 public void testChannelXmlForBackup() throws Exception {
411 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
412 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
413 NotificationChannel channel1 =
414 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
415 NotificationChannel channel2 =
416 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
417 channel2.setDescription("descriptions for all");
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100418 channel2.setSound(SOUND_URI, mAudioAttributes);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400419 channel2.enableLights(true);
420 channel2.setBypassDnd(true);
421 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
422 channel2.enableVibration(false);
423 channel2.setGroup(ncg.getId());
424 channel2.setLightColor(Color.BLUE);
Julia Reynolds745c1542017-05-26 14:43:47 -0400425 NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
426 channel3.enableVibration(true);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400427
428 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
429 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
430 mHelper.createNotificationChannel(PKG, UID, channel1, true);
431 mHelper.createNotificationChannel(PKG, UID, channel2, false);
Julia Reynolds745c1542017-05-26 14:43:47 -0400432 mHelper.createNotificationChannel(PKG, UID, channel3, false);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400433 mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true);
434
435 mHelper.setShowBadge(PKG, UID, true);
436
437 mHelper.setImportance(UPDATED_PKG, UID2, IMPORTANCE_NONE);
438
439 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
Julia Reynolds745c1542017-05-26 14:43:47 -0400440 channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
441 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG, UPDATED_PKG},
442 new int[]{UID, UID2});
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400443
444 mHelper.setShowBadge(UPDATED_PKG, UID2, true);
445
446 loadStreamXml(baos, true);
447
448 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(UPDATED_PKG, UID2));
449 assertTrue(mHelper.canShowBadge(PKG, UID));
450 assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
451 compareChannels(channel2,
452 mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynolds745c1542017-05-26 14:43:47 -0400453 compareChannels(channel3,
454 mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400455
456 List<NotificationChannelGroup> actualGroups =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500457 mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400458 boolean foundNcg = false;
459 for (NotificationChannelGroup actual : actualGroups) {
460 if (ncg.getId().equals(actual.getId())) {
461 foundNcg = true;
462 compareGroups(ncg, actual);
463 } else if (ncg2.getId().equals(actual.getId())) {
464 compareGroups(ncg2, actual);
465 }
466 }
467 assertTrue(foundNcg);
468
469 boolean foundChannel2Group = false;
470 for (NotificationChannelGroup actual : actualGroups) {
471 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
472 foundChannel2Group = true;
473 break;
474 }
475 }
476 assertTrue(foundChannel2Group);
477 }
478
479 @Test
Bernardo Rufinoc27bb6a2017-10-03 13:55:10 +0100480 public void testBackupXml_backupCanonicalizedSoundUri() throws Exception {
481 NotificationChannel channel =
482 new NotificationChannel("id", "name", IMPORTANCE_LOW);
483 channel.setSound(SOUND_URI, mAudioAttributes);
484 mHelper.createNotificationChannel(PKG, UID, channel, true);
485
486 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
487
488 // Testing that in restore we are given the canonical version
489 loadStreamXml(baos, true);
490 verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
491 }
492
493 @Test
494 public void testRestoreXml_withExistentCanonicalizedSoundUri() throws Exception {
495 Uri localUri = Uri.parse("content://" + TEST_AUTHORITY + "/local/url");
496 Uri canonicalBasedOnLocal = localUri.buildUpon()
497 .appendQueryParameter("title", "Test")
498 .appendQueryParameter("canonical", "1")
499 .build();
500 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
501 .thenReturn(canonicalBasedOnLocal);
502 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
503 .thenReturn(localUri);
504 when(mTestIContentProvider.uncanonicalize(any(), eq(canonicalBasedOnLocal)))
505 .thenReturn(localUri);
506
507 NotificationChannel channel =
508 new NotificationChannel("id", "name", IMPORTANCE_LOW);
509 channel.setSound(SOUND_URI, mAudioAttributes);
510 mHelper.createNotificationChannel(PKG, UID, channel, true);
511 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
512
513 loadStreamXml(baos, true);
514
515 NotificationChannel actualChannel = mHelper.getNotificationChannel(
516 PKG, UID, channel.getId(), false);
517 assertEquals(localUri, actualChannel.getSound());
518 }
519
520 @Test
521 public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
522 Thread.sleep(3000);
523 when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
524 .thenReturn(null);
525 when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
526 .thenReturn(null);
527
528 NotificationChannel channel =
529 new NotificationChannel("id", "name", IMPORTANCE_LOW);
530 channel.setSound(SOUND_URI, mAudioAttributes);
531 mHelper.createNotificationChannel(PKG, UID, channel, true);
532 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
533
534 loadStreamXml(baos, true);
535
536 NotificationChannel actualChannel = mHelper.getNotificationChannel(
537 PKG, UID, channel.getId(), false);
538 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
539 }
540
541
542 /**
543 * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
544 * handle its restore properly.
545 */
546 @Test
547 public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
548 // Not a local uncanonicalized uri, simulating that it fails to exist locally
549 when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI))).thenReturn(null);
550 String id = "id";
551 String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
552 + "<package name=\"com.android.server.notification\" show_badge=\"true\">\n"
553 + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
554 + "sound=\"" + SOUND_URI + "\" "
555 + "usage=\"6\" content_type=\"0\" flags=\"1\" show_badge=\"true\" />\n"
556 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" usage=\"5\" "
557 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
558 + "</package>\n"
559 + "</ranking>\n";
560
561 loadByteArrayXml(backupWithUncanonicalizedSoundUri.getBytes(), true);
562
563 NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG, UID, id, false);
564 assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
565 }
566
567 @Test
568 public void testBackupRestoreXml_withNullSoundUri() throws Exception {
569 NotificationChannel channel =
570 new NotificationChannel("id", "name", IMPORTANCE_LOW);
571 channel.setSound(null, mAudioAttributes);
572 mHelper.createNotificationChannel(PKG, UID, channel, true);
573 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
574
575 loadStreamXml(baos, true);
576
577 NotificationChannel actualChannel = mHelper.getNotificationChannel(
578 PKG, UID, channel.getId(), false);
579 assertEquals(null, actualChannel.getSound());
580 }
581
582 @Test
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400583 public void testChannelXml_backup() throws Exception {
584 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
585 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
586 NotificationChannel channel1 =
587 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
588 NotificationChannel channel2 =
589 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
590 NotificationChannel channel3 =
591 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
592 channel3.setGroup(ncg.getId());
593
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500594 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
595 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
596 mHelper.createNotificationChannel(PKG, UID, channel1, true);
597 mHelper.createNotificationChannel(PKG, UID, channel2, false);
598 mHelper.createNotificationChannel(PKG, UID, channel3, true);
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400599
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500600 mHelper.deleteNotificationChannel(PKG, UID, channel1.getId());
601 mHelper.deleteNotificationChannelGroup(PKG, UID, ncg.getId());
602 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400603
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500604 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel1.getId(),
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400605 channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500606 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG}, new int[]{UID});
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400607
608 XmlPullParser parser = Xml.newPullParser();
609 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
610 null);
611 parser.nextTag();
612 mHelper.readXml(parser, true);
613
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500614 assertNull(mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
615 assertNull(mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
616 assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG, UID));
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000617 //assertEquals(ncg2, mHelper.getNotificationChannelGroup(ncg2.getId(), PKG, UID));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500618 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
Julia Reynoldsd0a5b162017-03-18 13:42:09 -0400619 }
620
621 @Test
Julia Reynolds85769912016-10-25 09:08:57 -0400622 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400623 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
Julia Reynolds85769912016-10-25 09:08:57 -0400624 NotificationChannel.DEFAULT_CHANNEL_ID);
625
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400626 loadStreamXml(baos, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400627
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500628 final NotificationChannel updated = mHelper.getNotificationChannel(PKG, UID,
629 NotificationChannel.DEFAULT_CHANNEL_ID, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400630 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
631 assertFalse(updated.canBypassDnd());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500632 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
Julia Reynolds85769912016-10-25 09:08:57 -0400633 assertEquals(0, updated.getUserLockedFields());
634 }
635
636 @Test
Julia Reynoldsb3a04f02016-11-04 09:08:52 -0400637 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500638 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
639 NotificationChannel.DEFAULT_CHANNEL_ID, false);
640 defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400641 mHelper.updateNotificationChannel(PKG, UID, defaultChannel, true);
Julia Reynoldsb3a04f02016-11-04 09:08:52 -0400642
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400643 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
Julia Reynolds85769912016-10-25 09:08:57 -0400644 NotificationChannel.DEFAULT_CHANNEL_ID);
645
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400646 loadStreamXml(baos, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400647
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500648 assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
649 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
Julia Reynolds85769912016-10-25 09:08:57 -0400650 }
651
Julia Reynolds85769912016-10-25 09:08:57 -0400652 @Test
653 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
Julia Reynolds1864ff52016-11-02 09:54:47 -0400654 final String preupgradeXml = "<ranking version=\"1\">\n"
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500655 + "<package name=\"" + PKG
656 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
Julia Reynolds619a69f2017-01-27 15:11:38 -0500657 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500658 + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID + "\" />\n"
659 + "<package name=\"" + UPDATED_PKG + "\" uid=\"" + UID2 + "\" visibility=\""
Julia Reynolds619a69f2017-01-27 15:11:38 -0500660 + Notification.VISIBILITY_PRIVATE + "\" />\n"
661 + "</ranking>";
Julia Reynolds85769912016-10-25 09:08:57 -0400662 XmlPullParser parser = Xml.newPullParser();
Julia Reynolds1864ff52016-11-02 09:54:47 -0400663 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
Julia Reynolds619a69f2017-01-27 15:11:38 -0500664 null);
Julia Reynolds85769912016-10-25 09:08:57 -0400665 parser.nextTag();
666 mHelper.readXml(parser, false);
667
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500668 final NotificationChannel updated1 =
669 mHelper.getNotificationChannel(PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
Julia Reynolds1864ff52016-11-02 09:54:47 -0400670 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
671 assertTrue(updated1.canBypassDnd());
672 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
Julia Reynolds85769912016-10-25 09:08:57 -0400673 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
Julia Reynolds619a69f2017-01-27 15:11:38 -0500674 | NotificationChannel.USER_LOCKED_PRIORITY
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500675 | NotificationChannel.USER_LOCKED_VISIBILITY,
676 updated1.getUserLockedFields());
Julia Reynolds1864ff52016-11-02 09:54:47 -0400677
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500678 // No Default Channel created for updated packages
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400679 assertEquals(null, mHelper.getNotificationChannel(UPDATED_PKG, UID2,
680 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500681 }
682
683 @Test
684 public void testChannelXml_upgradeDeletesDefaultChannel() throws Exception {
685 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
686 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
687 assertTrue(defaultChannel != null);
688 ByteArrayOutputStream baos =
689 writeXmlAndPurge(PKG, UID, false, NotificationChannel.DEFAULT_CHANNEL_ID);
690 // Load package at higher sdk.
691 final ApplicationInfo upgraded = new ApplicationInfo();
692 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
693 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400694 loadStreamXml(baos, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500695
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500696 // Default Channel should be gone.
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -0400697 assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
698 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500699 }
700
701 @Test
702 public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
703 mHelper.createNotificationChannel(PKG, UID,
704 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
705 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
706 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
707
708 // Load package at higher sdk.
709 final ApplicationInfo upgraded = new ApplicationInfo();
710 upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
711 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400712 loadStreamXml(baos, false);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500713
714 // Default Channel should be gone.
715 assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
716 NotificationChannel.DEFAULT_CHANNEL_ID, false));
Julia Reynolds85769912016-10-25 09:08:57 -0400717 }
718
Julia Reynolds85769912016-10-25 09:08:57 -0400719 @Test
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400720 public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
721 ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
722 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
723 mHelper.createNotificationChannel(PKG, UID,
724 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
725
Julia Reynolds5fe2eae2017-05-22 08:45:27 -0400726 loadStreamXml(baos, false);
Geoffrey Pitsch6eccf002017-04-05 12:33:59 -0400727
728 // Should still have the newly created channel that wasn't in the xml.
729 assertTrue(mHelper.getNotificationChannel(PKG, UID, "bananas", false) != null);
730 }
731
732 @Test
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500733 public void testCreateChannel_blocked() throws Exception {
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400734 mHelper.setImportance(PKG, UID, IMPORTANCE_NONE);
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500735
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500736 mHelper.createNotificationChannel(PKG, UID,
737 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
Julia Reynolds32c97ef2016-11-28 10:47:18 -0500738 }
739
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400740 @Test
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400741 public void testCreateChannel_badImportance() throws Exception {
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400742 try {
743 mHelper.createNotificationChannel(PKG, UID,
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400744 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1), true);
745 fail("Was allowed to create a channel with invalid importance");
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400746 } catch (IllegalArgumentException e) {
747 // yay
748 }
Julia Reynolds3e50bf62017-05-24 16:33:32 -0400749 try {
750 mHelper.createNotificationChannel(PKG, UID,
751 new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED), true);
752 fail("Was allowed to create a channel with invalid importance");
753 } catch (IllegalArgumentException e) {
754 // yay
755 }
756 try {
757 mHelper.createNotificationChannel(PKG, UID,
758 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1), true);
759 fail("Was allowed to create a channel with invalid importance");
760 } catch (IllegalArgumentException e) {
761 // yay
762 }
763 mHelper.createNotificationChannel(PKG, UID,
764 new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true);
765 mHelper.createNotificationChannel(PKG, UID,
766 new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true);
Julia Reynoldsd8c0ac42017-04-23 13:11:40 -0400767 }
768
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500769
770 @Test
Julia Reynolds85769912016-10-25 09:08:57 -0400771 public void testUpdate() throws Exception {
772 // no fields locked by user
773 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500774 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500775 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500776 channel.enableLights(true);
Julia Reynolds85769912016-10-25 09:08:57 -0400777 channel.setBypassDnd(true);
778 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
779
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500780 mHelper.createNotificationChannel(PKG, UID, channel, false);
Julia Reynolds85769912016-10-25 09:08:57 -0400781
782 // same id, try to update all fields
783 final NotificationChannel channel2 =
784 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500785 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500786 channel2.enableLights(false);
Julia Reynolds85769912016-10-25 09:08:57 -0400787 channel2.setBypassDnd(false);
788 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
789
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400790 mHelper.updateNotificationChannel(PKG, UID, channel2, true);
Julia Reynolds85769912016-10-25 09:08:57 -0400791
792 // all fields should be changed
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500793 assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel.getId(), false));
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400794
795 verify(mHandler, times(1)).requestSort();
Julia Reynolds85769912016-10-25 09:08:57 -0400796 }
797
798 @Test
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400799 public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
800 mHelper.setImportance(PKG, UID, IMPORTANCE_UNSPECIFIED);
801 assertTrue(mHelper.canShowBadge(PKG, UID));
802 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
803 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
804 mHelper.getPackageVisibility(PKG, UID));
805
806 NotificationChannel defaultChannel = mHelper.getNotificationChannel(
807 PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
808
809 defaultChannel.setShowBadge(false);
810 defaultChannel.setImportance(IMPORTANCE_NONE);
811 defaultChannel.setBypassDnd(true);
812 defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
813
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400814 mHelper.updateNotificationChannel(PKG, UID, defaultChannel, true);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400815
816 // ensure app level fields are changed
817 assertFalse(mHelper.canShowBadge(PKG, UID));
818 assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG, UID));
819 assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG, UID));
820 assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG, UID));
821 }
822
823 @Test
824 public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
825 final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
826
827 mHelper.createNotificationChannel(PKG, UID, channel, false);
828 assertTrue(mHelper.canShowBadge(PKG, UID));
829 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
830 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
831 mHelper.getPackageVisibility(PKG, UID));
832
833 channel.setShowBadge(false);
834 channel.setImportance(IMPORTANCE_NONE);
835 channel.setBypassDnd(true);
836 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
837
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400838 mHelper.updateNotificationChannel(PKG, UID, channel, true);
Julia Reynoldsfa04e142017-04-23 13:32:01 -0400839
840 // ensure app level fields are not changed
841 assertTrue(mHelper.canShowBadge(PKG, UID));
842 assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
843 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
844 mHelper.getPackageVisibility(PKG, UID));
845 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
846 }
847
848 @Test
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500849 public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
850 assertEquals(null, mHelper.getNotificationChannel(PKG, UID, "garbage", false));
Julia Reynolds85769912016-10-25 09:08:57 -0400851 }
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500852
853 @Test
854 public void testCreateChannel_CannotChangeHiddenFields() throws Exception {
855 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500856 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500857 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500858 channel.enableLights(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500859 channel.setBypassDnd(true);
860 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
861 channel.setShowBadge(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500862 int lockMask = 0;
863 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
864 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
865 }
866 channel.lockFields(lockMask);
867
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500868 mHelper.createNotificationChannel(PKG, UID, channel, true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500869
870 NotificationChannel savedChannel =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500871 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500872
873 assertEquals(channel.getName(), savedChannel.getName());
874 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
875 assertFalse(savedChannel.canBypassDnd());
876 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
Julia Reynoldsf35e3972017-01-05 15:41:04 -0500877 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400878
879 verify(mHandler, never()).requestSort();
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500880 }
881
882 @Test
883 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() throws Exception {
884 final NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -0500885 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500886 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -0500887 channel.enableLights(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500888 channel.setBypassDnd(true);
889 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
890 channel.setShowBadge(true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500891 int lockMask = 0;
892 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
893 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
894 }
895 channel.lockFields(lockMask);
896
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500897 mHelper.createNotificationChannel(PKG, UID, channel, true);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500898
899 NotificationChannel savedChannel =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500900 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500901
902 assertEquals(channel.getName(), savedChannel.getName());
903 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
904 assertFalse(savedChannel.canBypassDnd());
905 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
Julia Reynoldsf35e3972017-01-05 15:41:04 -0500906 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500907 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -0500908
909 @Test
Julia Reynoldse0b25742017-05-08 12:55:24 -0400910 public void testClearLockedFields() throws Exception {
911 final NotificationChannel channel = getChannel();
912 mHelper.clearLockedFields(channel);
913 assertEquals(0, channel.getUserLockedFields());
914
915 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
916 | NotificationChannel.USER_LOCKED_IMPORTANCE);
917 mHelper.clearLockedFields(channel);
918 assertEquals(0, channel.getUserLockedFields());
919 }
920
921 @Test
922 public void testLockFields_soundAndVibration() throws Exception {
923 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
924
925 final NotificationChannel update1 = getChannel();
926 update1.setSound(new Uri.Builder().scheme("test").build(),
927 new AudioAttributes.Builder().build());
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500928 update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400929 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500930 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
931 | NotificationChannel.USER_LOCKED_SOUND,
Julia Reynoldse0b25742017-05-08 12:55:24 -0400932 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
933 .getUserLockedFields());
934
935 NotificationChannel update2 = getChannel();
936 update2.enableVibration(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400937 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500938 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
939 | NotificationChannel.USER_LOCKED_SOUND
Julia Reynoldse0b25742017-05-08 12:55:24 -0400940 | NotificationChannel.USER_LOCKED_VIBRATION,
941 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
942 .getUserLockedFields());
943 }
944
945 @Test
946 public void testLockFields_vibrationAndLights() throws Exception {
947 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
948
949 final NotificationChannel update1 = getChannel();
950 update1.setVibrationPattern(new long[]{7945, 46 ,246});
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400951 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400952 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
953 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
954 .getUserLockedFields());
955
956 final NotificationChannel update2 = getChannel();
957 update2.enableLights(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400958 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400959 assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
960 | NotificationChannel.USER_LOCKED_LIGHTS,
961 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
962 .getUserLockedFields());
963 }
964
965 @Test
966 public void testLockFields_lightsAndImportance() throws Exception {
967 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
968
969 final NotificationChannel update1 = getChannel();
970 update1.setLightColor(Color.GREEN);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400971 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400972 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
973 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
974 .getUserLockedFields());
975
976 final NotificationChannel update2 = getChannel();
977 update2.setImportance(IMPORTANCE_DEFAULT);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400978 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400979 assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
980 | NotificationChannel.USER_LOCKED_IMPORTANCE,
981 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
982 .getUserLockedFields());
983 }
984
985 @Test
986 public void testLockFields_visibilityAndDndAndBadge() throws Exception {
987 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
988 assertEquals(0,
989 mHelper.getNotificationChannel(PKG, UID, getChannel().getId(), false)
990 .getUserLockedFields());
991
992 final NotificationChannel update1 = getChannel();
993 update1.setBypassDnd(true);
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400994 mHelper.updateNotificationChannel(PKG, UID, update1, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -0400995 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
996 mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
997 .getUserLockedFields());
998
999 final NotificationChannel update2 = getChannel();
1000 update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001001 mHelper.updateNotificationChannel(PKG, UID, update2, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001002 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1003 | NotificationChannel.USER_LOCKED_VISIBILITY,
1004 mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
1005 .getUserLockedFields());
1006
1007 final NotificationChannel update3 = getChannel();
1008 update3.setShowBadge(false);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001009 mHelper.updateNotificationChannel(PKG, UID, update3, true);
Julia Reynoldse0b25742017-05-08 12:55:24 -04001010 assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
1011 | NotificationChannel.USER_LOCKED_VISIBILITY
1012 | NotificationChannel.USER_LOCKED_SHOW_BADGE,
1013 mHelper.getNotificationChannel(PKG, UID, update3.getId(), false)
1014 .getUserLockedFields());
1015 }
1016
1017 @Test
Julia Reynolds8e0eb372017-03-21 15:04:50 -04001018 public void testDeleteNonExistentChannel() throws Exception {
1019 mHelper.deleteNotificationChannelGroup(PKG, UID, "does not exist");
1020 }
1021
1022 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001023 public void testGetDeletedChannel() throws Exception {
Julia Reynoldse0b25742017-05-08 12:55:24 -04001024 NotificationChannel channel = getChannel();
Julia Reynolds619a69f2017-01-27 15:11:38 -05001025 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -05001026 channel.enableLights(true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001027 channel.setBypassDnd(true);
1028 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
1029 channel.enableVibration(true);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001030 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001031
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001032 mHelper.createNotificationChannel(PKG, UID, channel, true);
1033 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001034
1035 // Does not return deleted channel
1036 NotificationChannel response =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001037 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001038 assertNull(response);
1039
1040 // Returns deleted channel
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001041 response = mHelper.getNotificationChannel(PKG, UID, channel.getId(), true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001042 compareChannels(channel, response);
1043 assertTrue(response.isDeleted());
1044 }
1045
1046 @Test
1047 public void testGetDeletedChannels() throws Exception {
1048 Map<String, NotificationChannel> channelMap = new HashMap<>();
1049 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001050 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001051 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
Julia Reynolds529e3322017-02-06 08:33:01 -05001052 channel.enableLights(true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001053 channel.setBypassDnd(true);
1054 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
1055 channel.enableVibration(true);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001056 channel.setVibrationPattern(new long[]{100, 67, 145, 156});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001057 channelMap.put(channel.getId(), channel);
1058 NotificationChannel channel2 =
1059 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1060 channelMap.put(channel2.getId(), channel2);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001061 mHelper.createNotificationChannel(PKG, UID, channel, true);
1062 mHelper.createNotificationChannel(PKG, UID, channel2, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001063
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001064 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001065
1066 // Returns only non-deleted channels
1067 List<NotificationChannel> channels =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001068 mHelper.getNotificationChannels(PKG, UID, false).getList();
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001069 assertEquals(2, channels.size()); // Default channel + non-deleted channel
1070 for (NotificationChannel nc : channels) {
1071 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1072 compareChannels(channel2, nc);
1073 }
1074 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001075
1076 // Returns deleted channels too
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001077 channels = mHelper.getNotificationChannels(PKG, UID, true).getList();
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001078 assertEquals(3, channels.size()); // Includes default channel
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001079 for (NotificationChannel nc : channels) {
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001080 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
1081 compareChannels(channelMap.get(nc.getId()), nc);
1082 }
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001083 }
1084 }
1085
1086 @Test
Julia Reynolds41103f42017-03-15 11:36:35 -04001087 public void testGetDeletedChannelCount() throws Exception {
1088 NotificationChannel channel =
1089 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
1090 NotificationChannel channel2 =
1091 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
1092 NotificationChannel channel3 =
1093 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001094 mHelper.createNotificationChannel(PKG, UID, channel, true);
1095 mHelper.createNotificationChannel(PKG, UID, channel2, true);
1096 mHelper.createNotificationChannel(PKG, UID, channel3, true);
Julia Reynolds41103f42017-03-15 11:36:35 -04001097
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001098 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
1099 mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
Julia Reynolds41103f42017-03-15 11:36:35 -04001100
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001101 assertEquals(2, mHelper.getDeletedChannelCount(PKG, UID));
1102 assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID2));
Julia Reynolds41103f42017-03-15 11:36:35 -04001103 }
1104
1105 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001106 public void testCreateDeletedChannel() throws Exception {
Julia Reynolds619a69f2017-01-27 15:11:38 -05001107 long[] vibration = new long[]{100, 67, 145, 156};
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001108 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001109 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001110 channel.setVibrationPattern(vibration);
1111
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001112 mHelper.createNotificationChannel(PKG, UID, channel, true);
1113 mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001114
1115 NotificationChannel newChannel = new NotificationChannel(
1116 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001117 newChannel.setVibrationPattern(new long[]{100});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001118
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001119 mHelper.createNotificationChannel(PKG, UID, newChannel, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001120
1121 // No long deleted, using old settings
1122 compareChannels(channel,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001123 mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001124 }
1125
1126 @Test
Julia Reynolds17717f52017-05-09 11:46:06 -04001127 public void testOnlyHasDefaultChannel() throws Exception {
1128 assertTrue(mHelper.onlyHasDefaultChannel(PKG, UID));
1129 assertFalse(mHelper.onlyHasDefaultChannel(UPDATED_PKG, UID2));
1130
1131 mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
1132 assertFalse(mHelper.onlyHasDefaultChannel(PKG, UID));
1133 }
1134
1135 @Test
Julia Reynolds03fa85d2017-03-06 15:14:50 -05001136 public void testCreateChannel_defaultChannelId() throws Exception {
1137 try {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001138 mHelper.createNotificationChannel(PKG, UID, new NotificationChannel(
Julia Reynolds03fa85d2017-03-06 15:14:50 -05001139 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true);
1140 fail("Allowed to create default channel");
1141 } catch (IllegalArgumentException e) {
1142 // pass
1143 }
1144 }
1145
1146 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001147 public void testCreateChannel_alreadyExists() throws Exception {
Julia Reynolds619a69f2017-01-27 15:11:38 -05001148 long[] vibration = new long[]{100, 67, 145, 156};
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001149 NotificationChannel channel =
Julia Reynolds74856c42017-02-08 14:47:23 -05001150 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001151 channel.setVibrationPattern(vibration);
1152
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001153 mHelper.createNotificationChannel(PKG, UID, channel, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001154
1155 NotificationChannel newChannel = new NotificationChannel(
1156 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds619a69f2017-01-27 15:11:38 -05001157 newChannel.setVibrationPattern(new long[]{100});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001158
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001159 mHelper.createNotificationChannel(PKG, UID, newChannel, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001160
1161 // Old settings not overridden
1162 compareChannels(channel,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001163 mHelper.getNotificationChannel(PKG, UID, newChannel.getId(), false));
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001164 }
1165
1166 @Test
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001167 public void testCreateChannel_noOverrideSound() throws Exception {
1168 Uri sound = new Uri.Builder().scheme("test").build();
1169 final NotificationChannel channel = new NotificationChannel("id2", "name2",
1170 NotificationManager.IMPORTANCE_DEFAULT);
1171 channel.setSound(sound, mAudioAttributes);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001172 mHelper.createNotificationChannel(PKG, UID, channel, true);
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001173 assertEquals(sound, mHelper.getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001174 PKG, UID, channel.getId(), false).getSound());
Julia Reynolds31b2baa2017-02-22 12:18:45 -05001175 }
1176
1177 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001178 public void testPermanentlyDeleteChannels() throws Exception {
1179 NotificationChannel channel1 =
1180 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1181 NotificationChannel channel2 =
Julia Reynolds74856c42017-02-08 14:47:23 -05001182 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001183
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001184 mHelper.createNotificationChannel(PKG, UID, channel1, true);
1185 mHelper.createNotificationChannel(PKG, UID, channel2, false);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001186
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001187 mHelper.permanentlyDeleteNotificationChannels(PKG, UID);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001188
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001189 // Only default channel remains
1190 assertEquals(1, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001191 }
1192
1193 @Test
Julia Reynolds9bfba592017-03-15 14:03:55 -04001194 public void testDeleteGroup() throws Exception {
1195 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
1196 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
1197 NotificationChannel nonGroupedNonDeletedChannel =
1198 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
1199 NotificationChannel groupedButNotDeleted =
1200 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
1201 groupedButNotDeleted.setGroup("not");
1202 NotificationChannel groupedAndDeleted =
1203 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
1204 groupedAndDeleted.setGroup("totally");
1205
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001206 mHelper.createNotificationChannelGroup(PKG, UID, notDeleted, true);
1207 mHelper.createNotificationChannelGroup(PKG, UID, deleted, true);
1208 mHelper.createNotificationChannel(PKG, UID, nonGroupedNonDeletedChannel, true);
1209 mHelper.createNotificationChannel(PKG, UID, groupedAndDeleted, true);
1210 mHelper.createNotificationChannel(PKG, UID, groupedButNotDeleted, true);
Julia Reynolds9bfba592017-03-15 14:03:55 -04001211
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001212 mHelper.deleteNotificationChannelGroup(PKG, UID, deleted.getId());
Julia Reynolds9bfba592017-03-15 14:03:55 -04001213
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001214 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG, UID));
1215 assertNotNull(mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG, UID));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001216
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001217 assertNull(mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001218 compareChannels(groupedAndDeleted,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001219 mHelper.getNotificationChannel(PKG, UID, groupedAndDeleted.getId(), true));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001220
1221 compareChannels(groupedButNotDeleted,
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001222 mHelper.getNotificationChannel(PKG, UID, groupedButNotDeleted.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001223 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001224 PKG, UID, nonGroupedNonDeletedChannel.getId(), false));
Julia Reynolds9bfba592017-03-15 14:03:55 -04001225
1226 // notDeleted
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001227 assertEquals(1, mHelper.getNotificationChannelGroups(PKG, UID).size());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001228
1229 verify(mHandler, never()).requestSort();
Julia Reynolds9bfba592017-03-15 14:03:55 -04001230 }
1231
1232 @Test
Julia Reynolds2e9bf5f2017-05-03 13:23:30 -04001233 public void testOnUserRemoved() throws Exception {
1234 int[] user0Uids = {98, 235, 16, 3782};
1235 int[] user1Uids = new int[user0Uids.length];
1236 for (int i = 0; i < user0Uids.length; i++) {
1237 user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
1238
1239 final ApplicationInfo legacy = new ApplicationInfo();
1240 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1241 when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
1242
1243 // create records with the default channel for all user 0 and user 1 uids
1244 mHelper.getImportance(PKG, user0Uids[i]);
1245 mHelper.getImportance(PKG, user1Uids[i]);
1246 }
1247
1248 mHelper.onUserRemoved(1);
1249
1250 // user 0 records remain
1251 for (int i = 0; i < user0Uids.length; i++) {
1252 assertEquals(1,
1253 mHelper.getNotificationChannels(PKG, user0Uids[i], false).getList().size());
1254 }
1255 // user 1 records are gone
1256 for (int i = 0; i < user1Uids.length; i++) {
1257 assertEquals(0,
1258 mHelper.getNotificationChannels(PKG, user1Uids[i], false).getList().size());
1259 }
1260 }
1261
1262 @Test
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001263 public void testOnPackageChanged_packageRemoval() throws Exception {
1264 // Deleted
1265 NotificationChannel channel1 =
1266 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001267 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001268
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001269 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001270
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001271 assertEquals(0, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001272
1273 // Not deleted
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001274 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001275
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001276 mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001277 assertEquals(2, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
Julia Reynolds4036e8d2017-01-13 09:50:05 -05001278 }
Julia Reynolds924eed12017-01-19 09:52:07 -05001279
1280 @Test
Julia Reynolds59e152e2017-01-25 17:42:53 -05001281 public void testOnPackageChanged_packageRemoval_importance() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001282 mHelper.setImportance(PKG, UID, NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001283
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001284 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds59e152e2017-01-25 17:42:53 -05001285
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001286 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
Julia Reynolds59e152e2017-01-25 17:42:53 -05001287 }
1288
1289 @Test
1290 public void testOnPackageChanged_packageRemoval_groups() throws Exception {
1291 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001292 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001293 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001294 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001295
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001296 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
Julia Reynolds59e152e2017-01-25 17:42:53 -05001297
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001298 assertEquals(0,
1299 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList().size());
Julia Reynolds59e152e2017-01-25 17:42:53 -05001300 }
1301
1302 @Test
Julia Reynoldsf26eb912017-05-22 15:47:06 -04001303 public void testOnPackageChange_downgradeTargetSdk() throws Exception {
1304 // create channel as api 26
1305 mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true);
1306
1307 // install new app version targeting 25
1308 final ApplicationInfo legacy = new ApplicationInfo();
1309 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
1310 when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(legacy);
1311 mHelper.onPackagesChanged(
1312 false, UserHandle.USER_SYSTEM, new String[]{UPDATED_PKG}, new int[]{UID2});
1313
1314 // make sure the default channel was readded
1315 //assertEquals(2, mHelper.getNotificationChannels(UPDATED_PKG, UID2, false).getList().size());
1316 assertNotNull(mHelper.getNotificationChannel(
1317 UPDATED_PKG, UID2, NotificationChannel.DEFAULT_CHANNEL_ID, false));
1318 }
1319
1320 @Test
Julia Reynolds924eed12017-01-19 09:52:07 -05001321 public void testRecordDefaults() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001322 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
1323 assertEquals(true, mHelper.canShowBadge(PKG, UID));
1324 assertEquals(1, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
Julia Reynolds924eed12017-01-19 09:52:07 -05001325 }
Julia Reynolds59e152e2017-01-25 17:42:53 -05001326
1327 @Test
1328 public void testCreateGroup() throws Exception {
1329 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001330 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
1331 assertEquals(ncg, mHelper.getNotificationChannelGroups(PKG, UID).iterator().next());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001332 verify(mHandler, never()).requestSort();
Julia Reynolds59e152e2017-01-25 17:42:53 -05001333 }
1334
1335 @Test
1336 public void testCannotCreateChannel_badGroup() throws Exception {
1337 NotificationChannel channel1 =
1338 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1339 channel1.setGroup("garbage");
1340 try {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001341 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001342 fail("Created a channel with a bad group");
Julia Reynolds619a69f2017-01-27 15:11:38 -05001343 } catch (IllegalArgumentException e) {
1344 }
Julia Reynolds59e152e2017-01-25 17:42:53 -05001345 }
1346
1347 @Test
1348 public void testCannotCreateChannel_goodGroup() throws Exception {
1349 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001350 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001351 NotificationChannel channel1 =
1352 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1353 channel1.setGroup(ncg.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001354 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001355
1356 assertEquals(ncg.getId(),
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001357 mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false).getGroup());
Julia Reynolds59e152e2017-01-25 17:42:53 -05001358 }
1359
1360 @Test
1361 public void testGetChannelGroups() throws Exception {
Julia Reynoldsf02562a2017-01-26 13:33:56 -05001362 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001363 mHelper.createNotificationChannelGroup(PKG, UID, unused, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001364 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001365 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001366 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001367 mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001368
1369 NotificationChannel channel1 =
1370 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1371 channel1.setGroup(ncg.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001372 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001373 NotificationChannel channel1a =
1374 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
1375 channel1a.setGroup(ncg.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001376 mHelper.createNotificationChannel(PKG, UID, channel1a, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001377
1378 NotificationChannel channel2 =
1379 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
1380 channel2.setGroup(ncg2.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001381 mHelper.createNotificationChannel(PKG, UID, channel2, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001382
1383 NotificationChannel channel3 =
1384 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001385 mHelper.createNotificationChannel(PKG, UID, channel3, true);
Julia Reynolds59e152e2017-01-25 17:42:53 -05001386
1387 List<NotificationChannelGroup> actual =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001388 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds59e152e2017-01-25 17:42:53 -05001389 assertEquals(3, actual.size());
Julia Reynolds619a69f2017-01-27 15:11:38 -05001390 for (NotificationChannelGroup group : actual) {
Julia Reynolds59e152e2017-01-25 17:42:53 -05001391 if (group.getId() == null) {
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001392 assertEquals(2, group.getChannels().size()); // misc channel too
1393 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
1394 || channel3.getId().equals(group.getChannels().get(1).getId()));
Julia Reynolds59e152e2017-01-25 17:42:53 -05001395 } else if (group.getId().equals(ncg.getId())) {
1396 assertEquals(2, group.getChannels().size());
1397 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
1398 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
1399 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
1400 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
1401 } else {
1402 fail("expected channel not found");
1403 }
1404 } else if (group.getId().equals(ncg2.getId())) {
1405 assertEquals(1, group.getChannels().size());
1406 assertEquals(channel2.getId(), group.getChannels().get(0).getId());
1407 }
1408 }
1409 }
Julia Reynolds74856c42017-02-08 14:47:23 -05001410
1411 @Test
1412 public void testGetChannelGroups_noSideEffects() throws Exception {
1413 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001414 mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
Julia Reynolds74856c42017-02-08 14:47:23 -05001415
1416 NotificationChannel channel1 =
1417 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
1418 channel1.setGroup(ncg.getId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001419 mHelper.createNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001420 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -05001421
1422 channel1.setImportance(IMPORTANCE_LOW);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001423 mHelper.updateNotificationChannel(PKG, UID, channel1, true);
Julia Reynolds74856c42017-02-08 14:47:23 -05001424
1425 List<NotificationChannelGroup> actual =
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001426 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
Julia Reynolds74856c42017-02-08 14:47:23 -05001427
Geoffrey Pitscha22f6442017-05-05 16:47:38 +00001428 assertEquals(2, actual.size());
1429 for (NotificationChannelGroup group : actual) {
1430 if (Objects.equals(group.getId(), ncg.getId())) {
1431 assertEquals(1, group.getChannels().size());
1432 }
1433 }
Julia Reynolds74856c42017-02-08 14:47:23 -05001434 }
Julia Reynoldsd373d782017-03-03 13:32:57 -05001435
1436 @Test
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001437 public void testCreateChannel_updateName() throws Exception {
1438 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001439 mHelper.createNotificationChannel(PKG, UID, nc, true);
1440 NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001441 assertEquals("hello", actual.getName());
1442
1443 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001444 mHelper.createNotificationChannel(PKG, UID, nc, true);
Julia Reynoldsd373d782017-03-03 13:32:57 -05001445
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001446 actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
Julia Reynolds1d97e6a2017-03-13 15:05:40 -04001447 assertEquals("goodbye", actual.getName());
1448 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04001449
1450 verify(mHandler, times(1)).requestSort();
Julia Reynoldsd373d782017-03-03 13:32:57 -05001451 }
1452
1453 @Test
Julia Reynolds005c8b92017-08-24 10:35:53 -04001454 public void testCreateChannel_addToGroup() throws Exception {
1455 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
1456 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1457 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
1458 mHelper.createNotificationChannel(PKG, UID, nc, true);
1459 NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
1460 assertNull(actual.getGroup());
1461
1462 nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
1463 nc.setGroup(group.getId());
1464 mHelper.createNotificationChannel(PKG, UID, nc, true);
1465
1466 actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
1467 assertNotNull(actual.getGroup());
1468 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance());
1469
1470 verify(mHandler, times(1)).requestSort();
1471 }
1472
1473 @Test
Julia Reynoldsd373d782017-03-03 13:32:57 -05001474 public void testDumpChannelsJson() throws Exception {
1475 final ApplicationInfo upgrade = new ApplicationInfo();
1476 upgrade.targetSdkVersion = Build.VERSION_CODES.O;
1477 try {
1478 when(mPm.getApplicationInfoAsUser(
1479 anyString(), anyInt(), anyInt())).thenReturn(upgrade);
1480 } catch (PackageManager.NameNotFoundException e) {
1481 }
1482 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>();
1483 int numPackages = ThreadLocalRandom.current().nextInt(1, 5);
1484 for (int i = 0; i < numPackages; i++) {
1485 String pkgName = "pkg" + i;
1486 int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
1487 for (int j = 0; j < numChannels; j++) {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001488 mHelper.createNotificationChannel(pkgName, UID,
Julia Reynoldsd373d782017-03-03 13:32:57 -05001489 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true);
1490 }
1491 expectedChannels.put(pkgName, numChannels);
1492 }
1493
1494 // delete the first channel of the first package
1495 String pkg = expectedChannels.keyAt(0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001496 mHelper.deleteNotificationChannel("pkg" + 0, UID, "0");
Julia Reynoldsd373d782017-03-03 13:32:57 -05001497 // dump should not include deleted channels
1498 int count = expectedChannels.get(pkg);
1499 expectedChannels.put(pkg, count - 1);
1500
1501 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter());
1502 assertEquals(numPackages, actual.length());
1503 for (int i = 0; i < numPackages; i++) {
1504 JSONObject object = actual.getJSONObject(i);
1505 assertTrue(expectedChannels.containsKey(object.get("packageName")));
Geoffrey Pitsch5644ccd2017-04-17 11:33:24 -04001506 assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
Julia Reynoldsd373d782017-03-03 13:32:57 -05001507 object.getInt("channelCount"));
1508 }
1509 }
Chris Wren89aa2262017-05-05 18:05:56 -04001510
1511 @Test
1512 public void testBadgingOverrideTrue() throws Exception {
1513 Secure.putIntForUser(getContext().getContentResolver(),
1514 Secure.NOTIFICATION_BADGING, 1,
1515 USER.getIdentifier());
1516 mHelper.updateBadgingEnabled(); // would be called by settings observer
1517 assertTrue(mHelper.badgingEnabled(USER));
1518 }
1519
1520 @Test
1521 public void testBadgingOverrideFalse() throws Exception {
1522 Secure.putIntForUser(getContext().getContentResolver(),
1523 Secure.NOTIFICATION_BADGING, 0,
1524 USER.getIdentifier());
1525 mHelper.updateBadgingEnabled(); // would be called by settings observer
1526 assertFalse(mHelper.badgingEnabled(USER));
1527 }
1528
1529 @Test
Chris Wren13f157f2017-05-12 15:02:06 -04001530 public void testBadgingForUserAll() throws Exception {
1531 try {
1532 mHelper.badgingEnabled(UserHandle.ALL);
1533 } catch (Exception e) {
1534 fail("just don't throw");
1535 }
1536 }
1537
1538 @Test
Chris Wren89aa2262017-05-05 18:05:56 -04001539 public void testBadgingOverrideUserIsolation() throws Exception {
1540 Secure.putIntForUser(getContext().getContentResolver(),
1541 Secure.NOTIFICATION_BADGING, 0,
1542 USER.getIdentifier());
1543 Secure.putIntForUser(getContext().getContentResolver(),
1544 Secure.NOTIFICATION_BADGING, 1,
1545 USER2.getIdentifier());
1546 mHelper.updateBadgingEnabled(); // would be called by settings observer
1547 assertFalse(mHelper.badgingEnabled(USER));
1548 assertTrue(mHelper.badgingEnabled(USER2));
1549 }
Julia Reynolds816797a2017-08-11 15:47:09 -04001550
1551 @Test
1552 public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
1553 String newLabel = "bananas!";
1554 final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
1555 NotificationChannel.DEFAULT_CHANNEL_ID, false);
1556 assertFalse(newLabel.equals(defaultChannel.getName()));
1557
1558 Resources res = mock(Resources.class);
1559 when(mContext.getResources()).thenReturn(res);
1560 when(res.getString(com.android.internal.R.string.default_notification_channel_label))
1561 .thenReturn(newLabel);
1562
1563 mHelper.onLocaleChanged(mContext, USER.getIdentifier());
1564
1565 assertEquals(newLabel, mHelper.getNotificationChannel(PKG, UID,
1566 NotificationChannel.DEFAULT_CHANNEL_ID, false).getName());
1567 }
Julia Reynolds005c8b92017-08-24 10:35:53 -04001568
1569 @Test
1570 public void testIsGroupBlocked_noGroup() throws Exception {
1571 assertFalse(mHelper.isGroupBlocked(PKG, UID, null));
1572
1573 assertFalse(mHelper.isGroupBlocked(PKG, UID, "non existent group"));
1574 }
1575
1576 @Test
1577 public void testIsGroupBlocked_notBlocked() throws Exception {
1578 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1579 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1580
1581 assertFalse(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1582 }
1583
1584 @Test
1585 public void testIsGroupBlocked_blocked() throws Exception {
1586 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1587 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1588 group.setBlocked(true);
1589 mHelper.createNotificationChannelGroup(PKG, UID, group, false);
1590
1591 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1592 }
1593
1594 @Test
1595 public void testIsGroup_appCannotResetBlock() throws Exception {
1596 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
1597 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1598 NotificationChannelGroup group2 = group.clone();
1599 group2.setBlocked(true);
1600 mHelper.createNotificationChannelGroup(PKG, UID, group2, false);
1601 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1602
1603 NotificationChannelGroup group3 = group.clone();
1604 group3.setBlocked(false);
1605 mHelper.createNotificationChannelGroup(PKG, UID, group3, true);
1606 assertTrue(mHelper.isGroupBlocked(PKG, UID, group.getId()));
1607 }
1608
1609 @Test
1610 public void testGetNotificationChannelGroupWithChannels() throws Exception {
1611 NotificationChannelGroup group = new NotificationChannelGroup("group", "");
1612 NotificationChannelGroup other = new NotificationChannelGroup("something else", "");
1613 mHelper.createNotificationChannelGroup(PKG, UID, group, true);
1614 mHelper.createNotificationChannelGroup(PKG, UID, other, true);
1615
1616 NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
1617 a.setGroup(group.getId());
1618 NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
1619 b.setGroup(other.getId());
1620 NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
1621 c.setGroup(group.getId());
1622 NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
1623
1624 mHelper.createNotificationChannel(PKG, UID, a, true);
1625 mHelper.createNotificationChannel(PKG, UID, b, true);
1626 mHelper.createNotificationChannel(PKG, UID, c, true);
1627 mHelper.createNotificationChannel(PKG, UID, d, true);
1628 mHelper.deleteNotificationChannel(PKG, UID, c.getId());
1629
1630 NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
1631 PKG, UID, group.getId(), true);
1632 assertEquals(2, retrieved.getChannels().size());
1633 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
1634 compareChannels(c, findChannel(retrieved.getChannels(), c.getId()));
1635
1636 retrieved = mHelper.getNotificationChannelGroupWithChannels(
1637 PKG, UID, group.getId(), false);
1638 assertEquals(1, retrieved.getChannels().size());
1639 compareChannels(a, findChannel(retrieved.getChannels(), a.getId()));
1640 }
Julia Reynoldsbcc62ea2018-03-19 10:26:32 -04001641
1642 @Test
1643 public void testAndroidPkgCanBypassDnd_creation() {
1644
1645 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1646 test.setBypassDnd(true);
1647
1648 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true);
1649
1650 assertTrue(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
1651 .canBypassDnd());
1652 }
1653
1654 @Test
1655 public void testNormalPkgCannotBypassDnd_creation() {
1656 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1657 test.setBypassDnd(true);
1658
1659 mHelper.createNotificationChannel(PKG, 1000, test, true);
1660
1661 assertFalse(mHelper.getNotificationChannel(PKG, 1000, "A", false).canBypassDnd());
1662 }
1663
1664 @Test
1665 public void testAndroidPkgCanBypassDnd_update() throws Exception {
1666 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1667 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true);
1668
1669 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1670 update.setBypassDnd(true);
1671 mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true);
1672
1673 assertTrue(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
1674 .canBypassDnd());
1675
1676 // setup + 1st check
1677 verify(mPm, times(2)).getPackageInfoAsUser(any(), anyInt(), anyInt());
1678 }
1679
1680 @Test
1681 public void testNormalPkgCannotBypassDnd_update() {
1682 NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1683 mHelper.createNotificationChannel(PKG, 1000, test, true);
1684 NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
1685 update.setBypassDnd(true);
1686 mHelper.createNotificationChannel(PKG, 1000, update, true);
1687 assertFalse(mHelper.getNotificationChannel(PKG, 1000, "A", false).canBypassDnd());
1688 }
Chris Wren1031c972014-07-23 13:11:45 +00001689}