blob: a328568da7ed9d762b5472b882158954d5ee1797 [file] [log] [blame]
Julia Reynolds4a02afb2016-12-13 13:39:52 -05001/*
2 * Copyright (C) 2016 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
Gus Prevas2c963d22018-12-03 15:49:06 -050018import static org.hamcrest.Matchers.contains;
Julia Reynolds4a02afb2016-12-13 13:39:52 -050019import static org.junit.Assert.assertFalse;
Gus Prevas2c963d22018-12-03 15:49:06 -050020import static org.junit.Assert.assertThat;
Julia Reynolds4a02afb2016-12-13 13:39:52 -050021import static org.junit.Assert.assertTrue;
22import static org.mockito.Matchers.anyInt;
23import static org.mockito.Matchers.anyString;
24import static org.mockito.Matchers.eq;
25import static org.mockito.Mockito.when;
Alex Mang730d9492019-12-03 18:06:09 -080026import static org.mockito.Mockito.spy;
Julia Reynolds4a02afb2016-12-13 13:39:52 -050027
28import android.app.Notification;
29import android.app.NotificationChannel;
30import android.app.NotificationManager;
31import android.content.Context;
32import android.content.pm.ApplicationInfo;
33import android.content.pm.PackageManager;
34import android.media.session.MediaSession;
35import android.os.Build;
36import android.os.UserHandle;
37import android.provider.Settings;
38import android.service.notification.StatusBarNotification;
Gus Prevas2c963d22018-12-03 15:49:06 -050039import android.telecom.TelecomManager;
Julia Reynolds4a02afb2016-12-13 13:39:52 -050040import android.test.suitebuilder.annotation.SmallTest;
41
Brett Chabot84151d92019-02-27 15:37:59 -080042import androidx.test.runner.AndroidJUnit4;
43
Jason Monk74f5e362017-12-06 08:56:33 -050044import com.android.server.UiServiceTestCase;
45
Julia Reynolds4a02afb2016-12-13 13:39:52 -050046import org.junit.Before;
47import org.junit.Test;
48import org.junit.runner.RunWith;
49import org.mockito.Mock;
50import org.mockito.MockitoAnnotations;
51
52import java.util.ArrayList;
53import java.util.Collections;
54import java.util.List;
55
56@SmallTest
57@RunWith(AndroidJUnit4.class)
Jason Monk74f5e362017-12-06 08:56:33 -050058public class NotificationComparatorTest extends UiServiceTestCase {
Julia Reynolds4a02afb2016-12-13 13:39:52 -050059 @Mock Context mContext;
60 @Mock TelecomManager mTm;
61 @Mock RankingHandler handler;
62 @Mock PackageManager mPm;
63
64 private final String callPkg = "com.android.server.notification";
65 private final int callUid = 10;
66 private String smsPkg;
67 private final int smsUid = 11;
68 private final String pkg2 = "pkg2";
69 private final int uid2 = 1111111;
Geoffrey Pitschaf759c52017-02-15 09:35:38 -050070 private static final String TEST_CHANNEL_ID = "test_channel_id";
Julia Reynolds4a02afb2016-12-13 13:39:52 -050071
Lyn Han405e0b72019-08-13 16:07:55 -070072 private NotificationRecord mRecordMinCallNonInterruptive;
Julia Reynolds4a02afb2016-12-13 13:39:52 -050073 private NotificationRecord mRecordMinCall;
74 private NotificationRecord mRecordHighCall;
75 private NotificationRecord mRecordDefaultMedia;
76 private NotificationRecord mRecordEmail;
77 private NotificationRecord mRecordInlineReply;
78 private NotificationRecord mRecordSms;
79 private NotificationRecord mRecordStarredContact;
80 private NotificationRecord mRecordContact;
81 private NotificationRecord mRecordUrgent;
82 private NotificationRecord mRecordCheater;
Julia Reynolds889280c2017-04-12 12:27:00 -040083 private NotificationRecord mRecordCheaterColorized;
Selim Cinekc6c639cb2017-05-05 19:49:22 -070084 private NotificationRecord mNoMediaSessionMedia;
Julia Reynolds472f01c2018-01-18 09:25:44 -050085 private NotificationRecord mRecordColorized;
86 private NotificationRecord mRecordColorizedCall;
Julia Reynolds4a02afb2016-12-13 13:39:52 -050087
88 @Before
89 public void setUp() {
90 MockitoAnnotations.initMocks(this);
91 int userId = UserHandle.myUserId();
92
Chris Wren89aa2262017-05-05 18:05:56 -040093 when(mContext.getResources()).thenReturn(getContext().getResources());
94 when(mContext.getContentResolver()).thenReturn(getContext().getContentResolver());
Julia Reynolds4a02afb2016-12-13 13:39:52 -050095 when(mContext.getPackageManager()).thenReturn(mPm);
96 when(mContext.getSystemService(eq(Context.TELECOM_SERVICE))).thenReturn(mTm);
97 when(mTm.getDefaultDialerPackage()).thenReturn(callPkg);
98 final ApplicationInfo legacy = new ApplicationInfo();
99 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
100 try {
101 when(mPm.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())).thenReturn(legacy);
102 when(mContext.getApplicationInfo()).thenReturn(legacy);
103 } catch (PackageManager.NameNotFoundException e) {
104 // let's hope not
105 }
106
107 smsPkg = Settings.Secure.getString(mContext.getContentResolver(),
108 Settings.Secure.SMS_DEFAULT_APPLICATION);
109
Lyn Han405e0b72019-08-13 16:07:55 -0700110 Notification nonInterruptiveNotif = new Notification.Builder(mContext, TEST_CHANNEL_ID)
111 .setCategory(Notification.CATEGORY_CALL)
112 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
113 .build();
114 mRecordMinCallNonInterruptive = new NotificationRecord(mContext,
115 new StatusBarNotification(callPkg,
116 callPkg, 1, "mRecordMinCallNonInterruptive", callUid, callUid,
117 nonInterruptiveNotif,
118 new UserHandle(userId), "", 2000), getDefaultChannel());
119 mRecordMinCallNonInterruptive.setSystemImportance(NotificationManager.IMPORTANCE_MIN);
120 mRecordMinCallNonInterruptive.setInterruptive(false);
121
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500122 Notification n1 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500123 .setCategory(Notification.CATEGORY_CALL)
124 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
125 .build();
126 mRecordMinCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
Julia Reynolds924eed12017-01-19 09:52:07 -0500127 callPkg, 1, "minCall", callUid, callUid, n1,
128 new UserHandle(userId), "", 2000), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400129 mRecordMinCall.setSystemImportance(NotificationManager.IMPORTANCE_MIN);
Lyn Han405e0b72019-08-13 16:07:55 -0700130 mRecordMinCall.setInterruptive(true);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500131
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500132 Notification n2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500133 .setCategory(Notification.CATEGORY_CALL)
134 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
135 .build();
136 mRecordHighCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
Julia Reynolds924eed12017-01-19 09:52:07 -0500137 callPkg, 1, "highcall", callUid, callUid, n2,
138 new UserHandle(userId), "", 1999), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400139 mRecordHighCall.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500140
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500141 Notification n3 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500142 .setStyle(new Notification.MediaStyle()
143 .setMediaSession(new MediaSession.Token(null)))
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500144 .build();
145 mRecordDefaultMedia = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
Julia Reynolds924eed12017-01-19 09:52:07 -0500146 pkg2, 1, "media", uid2, uid2, n3, new UserHandle(userId),
147 "", 1499), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400148 mRecordDefaultMedia.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500149
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500150 Notification n4 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500151 .setStyle(new Notification.MessagingStyle("sender!")).build();
152 mRecordInlineReply = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
Julia Reynolds924eed12017-01-19 09:52:07 -0500153 pkg2, 1, "inlinereply", uid2, uid2, n4, new UserHandle(userId),
154 "", 1599), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400155 mRecordInlineReply.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500156 mRecordInlineReply.setPackagePriority(Notification.PRIORITY_MAX);
157
Kristian Monsen05f34792018-04-09 10:27:16 +0200158 if (smsPkg != null) {
159 Notification n5 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
160 .setCategory(Notification.CATEGORY_MESSAGE).build();
161 mRecordSms = new NotificationRecord(mContext, new StatusBarNotification(smsPkg,
162 smsPkg, 1, "sms", smsUid, smsUid, n5, new UserHandle(userId),
163 "", 1299), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400164 mRecordSms.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
Kristian Monsen05f34792018-04-09 10:27:16 +0200165 }
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500166
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500167 Notification n6 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500168 mRecordStarredContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
Julia Reynolds924eed12017-01-19 09:52:07 -0500169 pkg2, 1, "starred", uid2, uid2, n6, new UserHandle(userId),
170 "", 1259), getDefaultChannel());
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500171 mRecordStarredContact.setContactAffinity(ValidateNotificationPeople.STARRED_CONTACT);
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400172 mRecordStarredContact.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500173
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500174 Notification n7 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500175 mRecordContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
Julia Reynolds924eed12017-01-19 09:52:07 -0500176 pkg2, 1, "contact", uid2, uid2, n7, new UserHandle(userId),
177 "", 1259), getDefaultChannel());
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500178 mRecordContact.setContactAffinity(ValidateNotificationPeople.VALID_CONTACT);
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400179 mRecordContact.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500180
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500181 Notification n8 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500182 mRecordUrgent = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
Julia Reynolds924eed12017-01-19 09:52:07 -0500183 pkg2, 1, "urgent", uid2, uid2, n8, new UserHandle(userId),
184 "", 1258), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400185 mRecordUrgent.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500186
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500187 Notification n9 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500188 .setCategory(Notification.CATEGORY_MESSAGE)
189 .setFlag(Notification.FLAG_ONGOING_EVENT
190 |Notification.FLAG_FOREGROUND_SERVICE, true)
191 .build();
192 mRecordCheater = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
Julia Reynolds924eed12017-01-19 09:52:07 -0500193 pkg2, 1, "cheater", uid2, uid2, n9, new UserHandle(userId),
194 "", 9258), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400195 mRecordCheater.setSystemImportance(NotificationManager.IMPORTANCE_LOW);
Julia Reynolds889280c2017-04-12 12:27:00 -0400196 mRecordCheater.setPackagePriority(Notification.PRIORITY_MAX);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500197
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500198 Notification n10 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500199 .setStyle(new Notification.InboxStyle().setSummaryText("message!")).build();
200 mRecordEmail = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
Julia Reynolds924eed12017-01-19 09:52:07 -0500201 pkg2, 1, "email", uid2, uid2, n10, new UserHandle(userId),
202 "", 1599), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400203 mRecordEmail.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds889280c2017-04-12 12:27:00 -0400204
205 Notification n11 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
206 .setCategory(Notification.CATEGORY_MESSAGE)
207 .setColorized(true)
208 .build();
209 mRecordCheaterColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
210 pkg2, 1, "cheater", uid2, uid2, n11, new UserHandle(userId),
211 "", 9258), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400212 mRecordCheaterColorized.setSystemImportance(NotificationManager.IMPORTANCE_LOW);
Selim Cinekc6c639cb2017-05-05 19:49:22 -0700213
214 Notification n12 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
215 .setCategory(Notification.CATEGORY_MESSAGE)
216 .setColorized(true)
217 .setStyle(new Notification.MediaStyle())
218 .build();
219 mNoMediaSessionMedia = new NotificationRecord(mContext, new StatusBarNotification(
220 pkg2, pkg2, 1, "cheater", uid2, uid2, n12, new UserHandle(userId),
221 "", 9258), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400222 mNoMediaSessionMedia.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
Julia Reynolds472f01c2018-01-18 09:25:44 -0500223
224 Notification n13 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
225 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
226 .setColorized(true /* colorized */)
227 .build();
228 mRecordColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
229 pkg2, 1, "colorized", uid2, uid2, n13,
230 new UserHandle(userId), "", 1999), getDefaultChannel());
Gus Prevas2c963d22018-12-03 15:49:06 -0500231 mRecordColorized.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds472f01c2018-01-18 09:25:44 -0500232
233 Notification n14 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
234 .setCategory(Notification.CATEGORY_CALL)
235 .setColorized(true)
236 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
237 .build();
238 mRecordColorizedCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
239 callPkg, 1, "colorizedCall", callUid, callUid, n14,
240 new UserHandle(userId), "", 1999), getDefaultChannel());
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400241 mRecordColorizedCall.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500242 }
243
244 @Test
Gus Prevas2c963d22018-12-03 15:49:06 -0500245 public void testOrdering() {
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500246 final List<NotificationRecord> expected = new ArrayList<>();
Julia Reynolds472f01c2018-01-18 09:25:44 -0500247 expected.add(mRecordColorizedCall);
Julia Reynolds472f01c2018-01-18 09:25:44 -0500248 expected.add(mRecordColorized);
Gus Prevas2c963d22018-12-03 15:49:06 -0500249 expected.add(mRecordDefaultMedia);
Julia Reynolds472f01c2018-01-18 09:25:44 -0500250 expected.add(mRecordHighCall);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500251 expected.add(mRecordInlineReply);
Kristian Monsen05f34792018-04-09 10:27:16 +0200252 if (mRecordSms != null) {
253 expected.add(mRecordSms);
254 }
Selim Cinek3f146d02017-02-06 13:32:47 -0800255 expected.add(mRecordStarredContact);
256 expected.add(mRecordContact);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500257 expected.add(mRecordEmail);
258 expected.add(mRecordUrgent);
Selim Cinekc6c639cb2017-05-05 19:49:22 -0700259 expected.add(mNoMediaSessionMedia);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500260 expected.add(mRecordCheater);
Julia Reynolds889280c2017-04-12 12:27:00 -0400261 expected.add(mRecordCheaterColorized);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500262 expected.add(mRecordMinCall);
Lyn Han405e0b72019-08-13 16:07:55 -0700263 expected.add(mRecordMinCallNonInterruptive);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500264
265 List<NotificationRecord> actual = new ArrayList<>();
266 actual.addAll(expected);
267 Collections.shuffle(actual);
268
269 Collections.sort(actual, new NotificationComparator(mContext));
270
Gus Prevas2c963d22018-12-03 15:49:06 -0500271 assertThat(actual, contains(expected.toArray()));
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500272 }
273
274 @Test
Alex Mang730d9492019-12-03 18:06:09 -0800275 public void testRankingScoreOverrides() {
276 NotificationComparator comp = new NotificationComparator(mContext);
277 NotificationRecord recordMinCallNonInterruptive = spy(mRecordMinCallNonInterruptive);
278 assertTrue(comp.compare(mRecordMinCall, recordMinCallNonInterruptive) < 0);
279
280 when(recordMinCallNonInterruptive.getRankingScore()).thenReturn(1f);
281 assertTrue(comp.compare(mRecordMinCall, recordMinCallNonInterruptive) > 0);
282 assertTrue(comp.compare(mRecordCheater, recordMinCallNonInterruptive) > 0);
283 assertTrue(comp.compare(mRecordColorizedCall, recordMinCallNonInterruptive) < 0);
284 }
285
286 @Test
Gus Prevas2c963d22018-12-03 15:49:06 -0500287 public void testMessaging() {
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500288 NotificationComparator comp = new NotificationComparator(mContext);
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500289 assertTrue(comp.isImportantMessaging(mRecordInlineReply));
Kristian Monsen05f34792018-04-09 10:27:16 +0200290 if (mRecordSms != null) {
291 assertTrue(comp.isImportantMessaging(mRecordSms));
292 }
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500293 assertFalse(comp.isImportantMessaging(mRecordEmail));
294 assertFalse(comp.isImportantMessaging(mRecordCheater));
295 }
296
Selim Cinek3f146d02017-02-06 13:32:47 -0800297 @Test
Gus Prevas2c963d22018-12-03 15:49:06 -0500298 public void testPeople() {
Selim Cinek3f146d02017-02-06 13:32:47 -0800299 NotificationComparator comp = new NotificationComparator(mContext);
300 assertTrue(comp.isImportantPeople(mRecordStarredContact));
301 assertTrue(comp.isImportantPeople(mRecordContact));
302 }
303
Julia Reynolds4a02afb2016-12-13 13:39:52 -0500304 private NotificationChannel getDefaultChannel() {
305 return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
306 NotificationManager.IMPORTANCE_LOW);
307 }
308}