1 /* 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 */ 16 package com.android.server.notification; 17 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.mockito.Matchers.anyInt; 22 import static org.mockito.Matchers.anyString; 23 import static org.mockito.Matchers.eq; 24 import static org.mockito.Mockito.when; 25 26 import android.app.Notification; 27 import android.app.NotificationChannel; 28 import android.app.NotificationManager; 29 import android.content.Context; 30 import android.content.pm.ApplicationInfo; 31 import android.content.pm.PackageManager; 32 import android.media.session.MediaSession; 33 import android.os.Build; 34 import android.os.UserHandle; 35 import android.provider.Settings; 36 import android.service.notification.StatusBarNotification; 37 import android.telecom.TelecomManager; 38 import android.support.test.runner.AndroidJUnit4; 39 import android.test.suitebuilder.annotation.SmallTest; 40 41 import com.android.server.UiServiceTestCase; 42 43 import org.junit.Before; 44 import org.junit.Test; 45 import org.junit.runner.RunWith; 46 import org.mockito.Mock; 47 import org.mockito.MockitoAnnotations; 48 49 import java.util.ArrayList; 50 import java.util.Collections; 51 import java.util.List; 52 53 @SmallTest 54 @RunWith(AndroidJUnit4.class) 55 public class NotificationComparatorTest extends UiServiceTestCase { 56 @Mock Context mContext; 57 @Mock TelecomManager mTm; 58 @Mock RankingHandler handler; 59 @Mock PackageManager mPm; 60 61 private final String callPkg = "com.android.server.notification"; 62 private final int callUid = 10; 63 private String smsPkg; 64 private final int smsUid = 11; 65 private final String pkg2 = "pkg2"; 66 private final int uid2 = 1111111; 67 private static final String TEST_CHANNEL_ID = "test_channel_id"; 68 69 private NotificationRecord mRecordMinCall; 70 private NotificationRecord mRecordHighCall; 71 private NotificationRecord mRecordDefaultMedia; 72 private NotificationRecord mRecordEmail; 73 private NotificationRecord mRecordInlineReply; 74 private NotificationRecord mRecordSms; 75 private NotificationRecord mRecordStarredContact; 76 private NotificationRecord mRecordContact; 77 private NotificationRecord mRecordUrgent; 78 private NotificationRecord mRecordCheater; 79 private NotificationRecord mRecordCheaterColorized; 80 private NotificationRecord mNoMediaSessionMedia; 81 private NotificationRecord mRecordColorized; 82 private NotificationRecord mRecordColorizedCall; 83 84 @Before 85 public void setUp() { 86 MockitoAnnotations.initMocks(this); 87 int userId = UserHandle.myUserId(); 88 89 when(mContext.getResources()).thenReturn(getContext().getResources()); 90 when(mContext.getContentResolver()).thenReturn(getContext().getContentResolver()); 91 when(mContext.getPackageManager()).thenReturn(mPm); 92 when(mContext.getSystemService(eq(Context.TELECOM_SERVICE))).thenReturn(mTm); 93 when(mTm.getDefaultDialerPackage()).thenReturn(callPkg); 94 final ApplicationInfo legacy = new ApplicationInfo(); 95 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1; 96 try { 97 when(mPm.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())).thenReturn(legacy); 98 when(mContext.getApplicationInfo()).thenReturn(legacy); 99 } catch (PackageManager.NameNotFoundException e) { 100 // let's hope not 101 } 102 103 smsPkg = Settings.Secure.getString(mContext.getContentResolver(), 104 Settings.Secure.SMS_DEFAULT_APPLICATION); 105 106 Notification n1 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 107 .setCategory(Notification.CATEGORY_CALL) 108 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true) 109 .build(); 110 mRecordMinCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg, 111 callPkg, 1, "minCall", callUid, callUid, n1, 112 new UserHandle(userId), "", 2000), getDefaultChannel()); 113 mRecordMinCall.setUserImportance(NotificationManager.IMPORTANCE_MIN); 114 115 Notification n2 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 116 .setCategory(Notification.CATEGORY_CALL) 117 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true) 118 .build(); 119 mRecordHighCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg, 120 callPkg, 1, "highcall", callUid, callUid, n2, 121 new UserHandle(userId), "", 1999), getDefaultChannel()); 122 mRecordHighCall.setUserImportance(NotificationManager.IMPORTANCE_HIGH); 123 124 Notification n3 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 125 .setStyle(new Notification.MediaStyle() 126 .setMediaSession(new MediaSession.Token(null))) 127 .build(); 128 mRecordDefaultMedia = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 129 pkg2, 1, "media", uid2, uid2, n3, new UserHandle(userId), 130 "", 1499), getDefaultChannel()); 131 mRecordDefaultMedia.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT); 132 133 Notification n4 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 134 .setStyle(new Notification.MessagingStyle("sender!")).build(); 135 mRecordInlineReply = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 136 pkg2, 1, "inlinereply", uid2, uid2, n4, new UserHandle(userId), 137 "", 1599), getDefaultChannel()); 138 mRecordInlineReply.setUserImportance(NotificationManager.IMPORTANCE_HIGH); 139 mRecordInlineReply.setPackagePriority(Notification.PRIORITY_MAX); 140 141 if (smsPkg != null) { 142 Notification n5 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 143 .setCategory(Notification.CATEGORY_MESSAGE).build(); 144 mRecordSms = new NotificationRecord(mContext, new StatusBarNotification(smsPkg, 145 smsPkg, 1, "sms", smsUid, smsUid, n5, new UserHandle(userId), 146 "", 1299), getDefaultChannel()); 147 mRecordSms.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT); 148 } 149 150 Notification n6 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build(); 151 mRecordStarredContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 152 pkg2, 1, "starred", uid2, uid2, n6, new UserHandle(userId), 153 "", 1259), getDefaultChannel()); 154 mRecordStarredContact.setContactAffinity(ValidateNotificationPeople.STARRED_CONTACT); 155 mRecordStarredContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT); 156 157 Notification n7 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build(); 158 mRecordContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 159 pkg2, 1, "contact", uid2, uid2, n7, new UserHandle(userId), 160 "", 1259), getDefaultChannel()); 161 mRecordContact.setContactAffinity(ValidateNotificationPeople.VALID_CONTACT); 162 mRecordContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT); 163 164 Notification n8 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build(); 165 mRecordUrgent = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 166 pkg2, 1, "urgent", uid2, uid2, n8, new UserHandle(userId), 167 "", 1258), getDefaultChannel()); 168 mRecordUrgent.setUserImportance(NotificationManager.IMPORTANCE_HIGH); 169 170 Notification n9 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 171 .setCategory(Notification.CATEGORY_MESSAGE) 172 .setFlag(Notification.FLAG_ONGOING_EVENT 173 |Notification.FLAG_FOREGROUND_SERVICE, true) 174 .build(); 175 mRecordCheater = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 176 pkg2, 1, "cheater", uid2, uid2, n9, new UserHandle(userId), 177 "", 9258), getDefaultChannel()); 178 mRecordCheater.setUserImportance(NotificationManager.IMPORTANCE_LOW); 179 mRecordCheater.setPackagePriority(Notification.PRIORITY_MAX); 180 181 Notification n10 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 182 .setStyle(new Notification.InboxStyle().setSummaryText("message!")).build(); 183 mRecordEmail = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 184 pkg2, 1, "email", uid2, uid2, n10, new UserHandle(userId), 185 "", 1599), getDefaultChannel()); 186 mRecordEmail.setUserImportance(NotificationManager.IMPORTANCE_HIGH); 187 188 Notification n11 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 189 .setCategory(Notification.CATEGORY_MESSAGE) 190 .setColorized(true) 191 .build(); 192 mRecordCheaterColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 193 pkg2, 1, "cheater", uid2, uid2, n11, new UserHandle(userId), 194 "", 9258), getDefaultChannel()); 195 mRecordCheaterColorized.setUserImportance(NotificationManager.IMPORTANCE_LOW); 196 197 Notification n12 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 198 .setCategory(Notification.CATEGORY_MESSAGE) 199 .setColorized(true) 200 .setStyle(new Notification.MediaStyle()) 201 .build(); 202 mNoMediaSessionMedia = new NotificationRecord(mContext, new StatusBarNotification( 203 pkg2, pkg2, 1, "cheater", uid2, uid2, n12, new UserHandle(userId), 204 "", 9258), getDefaultChannel()); 205 mNoMediaSessionMedia.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT); 206 207 Notification n13 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 208 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true) 209 .setColorized(true /* colorized */) 210 .build(); 211 mRecordColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2, 212 pkg2, 1, "colorized", uid2, uid2, n13, 213 new UserHandle(userId), "", 1999), getDefaultChannel()); 214 mRecordHighCall.setUserImportance(NotificationManager.IMPORTANCE_HIGH); 215 216 Notification n14 = new Notification.Builder(mContext, TEST_CHANNEL_ID) 217 .setCategory(Notification.CATEGORY_CALL) 218 .setColorized(true) 219 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true) 220 .build(); 221 mRecordColorizedCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg, 222 callPkg, 1, "colorizedCall", callUid, callUid, n14, 223 new UserHandle(userId), "", 1999), getDefaultChannel()); 224 mRecordColorizedCall.setUserImportance(NotificationManager.IMPORTANCE_HIGH); 225 } 226 227 @Test 228 public void testOrdering() throws Exception { 229 final List<NotificationRecord> expected = new ArrayList<>(); 230 expected.add(mRecordColorizedCall); 231 expected.add(mRecordDefaultMedia); 232 expected.add(mRecordColorized); 233 expected.add(mRecordHighCall); 234 expected.add(mRecordInlineReply); 235 if (mRecordSms != null) { 236 expected.add(mRecordSms); 237 } 238 expected.add(mRecordStarredContact); 239 expected.add(mRecordContact); 240 expected.add(mRecordEmail); 241 expected.add(mRecordUrgent); 242 expected.add(mNoMediaSessionMedia); 243 expected.add(mRecordCheater); 244 expected.add(mRecordCheaterColorized); 245 expected.add(mRecordMinCall); 246 247 List<NotificationRecord> actual = new ArrayList<>(); 248 actual.addAll(expected); 249 Collections.shuffle(actual); 250 251 Collections.sort(actual, new NotificationComparator(mContext)); 252 253 assertEquals(expected, actual); 254 } 255 256 @Test 257 public void testMessaging() throws Exception { 258 NotificationComparator comp = new NotificationComparator(mContext); 259 assertTrue(comp.isImportantMessaging(mRecordInlineReply)); 260 if (mRecordSms != null) { 261 assertTrue(comp.isImportantMessaging(mRecordSms)); 262 } 263 assertFalse(comp.isImportantMessaging(mRecordEmail)); 264 assertFalse(comp.isImportantMessaging(mRecordCheater)); 265 } 266 267 @Test 268 public void testPeople() throws Exception { 269 NotificationComparator comp = new NotificationComparator(mContext); 270 assertTrue(comp.isImportantPeople(mRecordStarredContact)); 271 assertTrue(comp.isImportantPeople(mRecordContact)); 272 } 273 274 private NotificationChannel getDefaultChannel() { 275 return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name", 276 NotificationManager.IMPORTANCE_LOW); 277 } 278 } 279