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 17 package com.android.server.notification; 18 19 import static android.service.notification.NotificationListenerService.Ranking 20 .USER_SENTIMENT_NEGATIVE; 21 import static android.service.notification.NotificationListenerService.Ranking 22 .USER_SENTIMENT_NEUTRAL; 23 import static android.service.notification.NotificationListenerService.Ranking 24 .USER_SENTIMENT_POSITIVE; 25 26 import static org.junit.Assert.assertEquals; 27 import static org.junit.Assert.assertNotNull; 28 import static org.mockito.ArgumentMatchers.any; 29 import static org.mockito.ArgumentMatchers.anyInt; 30 import static org.mockito.Mockito.mock; 31 import static org.mockito.Mockito.when; 32 33 import android.app.INotificationManager; 34 import android.app.NotificationChannel; 35 import android.content.Intent; 36 import android.os.Binder; 37 import android.os.Bundle; 38 import android.os.IBinder; 39 import android.service.notification.NotificationListenerService; 40 import android.service.notification.NotificationListenerService.Ranking; 41 import android.service.notification.NotificationRankingUpdate; 42 import android.service.notification.SnoozeCriterion; 43 import android.service.notification.StatusBarNotification; 44 import android.support.test.runner.AndroidJUnit4; 45 import android.test.suitebuilder.annotation.SmallTest; 46 47 import com.android.server.UiServiceTestCase; 48 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 52 import java.util.ArrayList; 53 import java.util.List; 54 55 @SmallTest 56 @RunWith(AndroidJUnit4.class) 57 public class NotificationListenerServiceTest extends UiServiceTestCase { 58 59 private String[] mKeys = new String[] { "key", "key1", "key2", "key3"}; 60 61 @Test 62 public void testGetActiveNotifications_notNull() throws Exception { 63 TestListenerService service = new TestListenerService(); 64 INotificationManager noMan = service.getNoMan(); 65 when(noMan.getActiveNotificationsFromListener(any(), any(), anyInt())).thenReturn(null); 66 67 assertNotNull(service.getActiveNotifications()); 68 assertNotNull(service.getActiveNotifications(NotificationListenerService.TRIM_FULL)); 69 assertNotNull(service.getActiveNotifications(new String[0])); 70 assertNotNull(service.getActiveNotifications( 71 new String[0], NotificationListenerService.TRIM_LIGHT)); 72 } 73 74 @Test 75 public void testRanking() throws Exception { 76 TestListenerService service = new TestListenerService(); 77 service.applyUpdateLocked(generateUpdate()); 78 for (int i = 0; i < mKeys.length; i++) { 79 String key = mKeys[i]; 80 Ranking ranking = new Ranking(); 81 service.getCurrentRanking().getRanking(key, ranking); 82 assertEquals(getVisibilityOverride(i), ranking.getVisibilityOverride()); 83 assertEquals(getOverrideGroupKey(key), ranking.getOverrideGroupKey()); 84 assertEquals(!isIntercepted(i), ranking.matchesInterruptionFilter()); 85 assertEquals(getSuppressedVisualEffects(i), ranking.getSuppressedVisualEffects()); 86 assertEquals(getImportance(i), ranking.getImportance()); 87 assertEquals(getExplanation(key), ranking.getImportanceExplanation()); 88 assertEquals(getChannel(key, i), ranking.getChannel()); 89 assertEquals(getPeople(key, i), ranking.getAdditionalPeople()); 90 assertEquals(getSnoozeCriteria(key, i), ranking.getSnoozeCriteria()); 91 assertEquals(getShowBadge(i), ranking.canShowBadge()); 92 assertEquals(getUserSentiment(i), ranking.getUserSentiment()); 93 assertEquals(getHidden(i), ranking.isSuspended()); 94 } 95 } 96 97 private NotificationRankingUpdate generateUpdate() { 98 List<String> interceptedKeys = new ArrayList<>(); 99 Bundle visibilityOverrides = new Bundle(); 100 Bundle overrideGroupKeys = new Bundle(); 101 Bundle suppressedVisualEffects = new Bundle(); 102 Bundle explanation = new Bundle(); 103 Bundle channels = new Bundle(); 104 Bundle overridePeople = new Bundle(); 105 Bundle snoozeCriteria = new Bundle(); 106 Bundle showBadge = new Bundle(); 107 int[] importance = new int[mKeys.length]; 108 Bundle userSentiment = new Bundle(); 109 Bundle mHidden = new Bundle(); 110 111 for (int i = 0; i < mKeys.length; i++) { 112 String key = mKeys[i]; 113 visibilityOverrides.putInt(key, getVisibilityOverride(i)); 114 overrideGroupKeys.putString(key, getOverrideGroupKey(key)); 115 if (isIntercepted(i)) { 116 interceptedKeys.add(key); 117 } 118 suppressedVisualEffects.putInt(key, getSuppressedVisualEffects(i)); 119 importance[i] = getImportance(i); 120 explanation.putString(key, getExplanation(key)); 121 channels.putParcelable(key, getChannel(key, i)); 122 overridePeople.putStringArrayList(key, getPeople(key, i)); 123 snoozeCriteria.putParcelableArrayList(key, getSnoozeCriteria(key, i)); 124 showBadge.putBoolean(key, getShowBadge(i)); 125 userSentiment.putInt(key, getUserSentiment(i)); 126 mHidden.putBoolean(key, getHidden(i)); 127 } 128 NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys, 129 interceptedKeys.toArray(new String[0]), visibilityOverrides, 130 suppressedVisualEffects, importance, explanation, overrideGroupKeys, 131 channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden); 132 return update; 133 } 134 135 private int getVisibilityOverride(int index) { 136 return index * 9; 137 } 138 139 private String getOverrideGroupKey(String key) { 140 return key + key; 141 } 142 143 private boolean isIntercepted(int index) { 144 return index % 2 == 0; 145 } 146 147 private int getSuppressedVisualEffects(int index) { 148 return index * 2; 149 } 150 151 private int getImportance(int index) { 152 return index; 153 } 154 155 private String getExplanation(String key) { 156 return key + "explain"; 157 } 158 159 private NotificationChannel getChannel(String key, int index) { 160 return new NotificationChannel(key, key, getImportance(index)); 161 } 162 163 private boolean getShowBadge(int index) { 164 return index % 3 == 0; 165 } 166 167 private int getUserSentiment(int index) { 168 switch(index % 3) { 169 case 0: 170 return USER_SENTIMENT_NEGATIVE; 171 case 1: 172 return USER_SENTIMENT_NEUTRAL; 173 case 2: 174 return USER_SENTIMENT_POSITIVE; 175 } 176 return USER_SENTIMENT_NEUTRAL; 177 } 178 179 private boolean getHidden(int index) { 180 return index % 2 == 0; 181 } 182 183 private ArrayList<String> getPeople(String key, int index) { 184 ArrayList<String> people = new ArrayList<>(); 185 for (int i = 0; i < index; i++) { 186 people.add(i + key); 187 } 188 return people; 189 } 190 191 private ArrayList<SnoozeCriterion> getSnoozeCriteria(String key, int index) { 192 ArrayList<SnoozeCriterion> snooze = new ArrayList<>(); 193 for (int i = 0; i < index; i++) { 194 snooze.add(new SnoozeCriterion(key + i, getExplanation(key), key)); 195 } 196 return snooze; 197 } 198 199 public static class TestListenerService extends NotificationListenerService { 200 private final IBinder binder = new LocalBinder(); 201 202 public TestListenerService() { 203 mWrapper = mock(NotificationListenerWrapper.class); 204 mNoMan = mock(INotificationManager.class); 205 } 206 207 INotificationManager getNoMan() { 208 return mNoMan; 209 } 210 211 @Override 212 public IBinder onBind(Intent intent) { 213 super.onBind(intent); 214 return binder; 215 } 216 217 public class LocalBinder extends Binder { 218 TestListenerService getService() { 219 return TestListenerService.this; 220 } 221 } 222 } 223 } 224