blob: bcba15df8756df3ce743276a8f4ad15feb223724 [file] [log] [blame]
Julia Reynolds22f02b32016-12-01 15:05:13 -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 */
16
17package com.android.server.notification;
18
Julia Reynolds503ed942017-10-04 16:04:56 -040019import static android.service.notification.NotificationListenerService.Ranking
20 .USER_SENTIMENT_NEGATIVE;
21import static android.service.notification.NotificationListenerService.Ranking
22 .USER_SENTIMENT_NEUTRAL;
23import static android.service.notification.NotificationListenerService.Ranking
24 .USER_SENTIMENT_POSITIVE;
25
Julia Reynolds22f02b32016-12-01 15:05:13 -050026import static org.junit.Assert.assertEquals;
Julia Reynolds94a38b32018-04-20 13:33:36 -040027import static org.junit.Assert.assertNotNull;
28import static org.mockito.ArgumentMatchers.any;
29import static org.mockito.ArgumentMatchers.anyInt;
30import static org.mockito.Mockito.mock;
31import static org.mockito.Mockito.when;
Julia Reynolds22f02b32016-12-01 15:05:13 -050032
Julia Reynolds94a38b32018-04-20 13:33:36 -040033import android.app.INotificationManager;
Tony Mak628cb932018-06-19 18:30:41 +010034import android.app.Notification;
Julia Reynolds22f02b32016-12-01 15:05:13 -050035import android.app.NotificationChannel;
Tony Mak628cb932018-06-19 18:30:41 +010036import android.app.PendingIntent;
Julia Reynolds22f02b32016-12-01 15:05:13 -050037import android.content.Intent;
38import android.os.Binder;
39import android.os.Bundle;
40import android.os.IBinder;
41import android.service.notification.NotificationListenerService;
42import android.service.notification.NotificationListenerService.Ranking;
43import android.service.notification.NotificationRankingUpdate;
44import android.service.notification.SnoozeCriterion;
45import android.support.test.runner.AndroidJUnit4;
46import android.test.suitebuilder.annotation.SmallTest;
47
Jason Monk74f5e362017-12-06 08:56:33 -050048import com.android.server.UiServiceTestCase;
49
Julia Reynolds22f02b32016-12-01 15:05:13 -050050import org.junit.Test;
51import org.junit.runner.RunWith;
52
53import java.util.ArrayList;
54import java.util.List;
55
56@SmallTest
57@RunWith(AndroidJUnit4.class)
Jason Monk74f5e362017-12-06 08:56:33 -050058public class NotificationListenerServiceTest extends UiServiceTestCase {
Julia Reynolds22f02b32016-12-01 15:05:13 -050059
60 private String[] mKeys = new String[] { "key", "key1", "key2", "key3"};
61
62 @Test
Julia Reynolds94a38b32018-04-20 13:33:36 -040063 public void testGetActiveNotifications_notNull() throws Exception {
64 TestListenerService service = new TestListenerService();
65 INotificationManager noMan = service.getNoMan();
66 when(noMan.getActiveNotificationsFromListener(any(), any(), anyInt())).thenReturn(null);
67
68 assertNotNull(service.getActiveNotifications());
69 assertNotNull(service.getActiveNotifications(NotificationListenerService.TRIM_FULL));
70 assertNotNull(service.getActiveNotifications(new String[0]));
71 assertNotNull(service.getActiveNotifications(
72 new String[0], NotificationListenerService.TRIM_LIGHT));
73 }
74
75 @Test
Julia Reynolds22f02b32016-12-01 15:05:13 -050076 public void testRanking() throws Exception {
77 TestListenerService service = new TestListenerService();
78 service.applyUpdateLocked(generateUpdate());
79 for (int i = 0; i < mKeys.length; i++) {
80 String key = mKeys[i];
81 Ranking ranking = new Ranking();
82 service.getCurrentRanking().getRanking(key, ranking);
83 assertEquals(getVisibilityOverride(i), ranking.getVisibilityOverride());
84 assertEquals(getOverrideGroupKey(key), ranking.getOverrideGroupKey());
85 assertEquals(!isIntercepted(i), ranking.matchesInterruptionFilter());
86 assertEquals(getSuppressedVisualEffects(i), ranking.getSuppressedVisualEffects());
87 assertEquals(getImportance(i), ranking.getImportance());
88 assertEquals(getExplanation(key), ranking.getImportanceExplanation());
89 assertEquals(getChannel(key, i), ranking.getChannel());
90 assertEquals(getPeople(key, i), ranking.getAdditionalPeople());
91 assertEquals(getSnoozeCriteria(key, i), ranking.getSnoozeCriteria());
Julia Reynolds924eed12017-01-19 09:52:07 -050092 assertEquals(getShowBadge(i), ranking.canShowBadge());
Julia Reynolds503ed942017-10-04 16:04:56 -040093 assertEquals(getUserSentiment(i), ranking.getUserSentiment());
Beverly5a20a5e2018-03-06 15:02:44 -050094 assertEquals(getHidden(i), ranking.isSuspended());
Gus Prevasa3226492018-10-23 11:10:09 -040095 assertEquals(audiblyAlerted(i), ranking.audiblyAlerted());
Tony Mak628cb932018-06-19 18:30:41 +010096 assertActionsEqual(getSmartActions(key, i), ranking.getSmartActions());
Tony Makc9acf672018-07-20 13:58:24 +020097 assertEquals(getSmartReplies(key, i), ranking.getSmartReplies());
Julia Reynolds22f02b32016-12-01 15:05:13 -050098 }
99 }
100
101 private NotificationRankingUpdate generateUpdate() {
102 List<String> interceptedKeys = new ArrayList<>();
103 Bundle visibilityOverrides = new Bundle();
104 Bundle overrideGroupKeys = new Bundle();
105 Bundle suppressedVisualEffects = new Bundle();
106 Bundle explanation = new Bundle();
Julia Reynolds924eed12017-01-19 09:52:07 -0500107 Bundle channels = new Bundle();
Julia Reynolds22f02b32016-12-01 15:05:13 -0500108 Bundle overridePeople = new Bundle();
109 Bundle snoozeCriteria = new Bundle();
Julia Reynolds924eed12017-01-19 09:52:07 -0500110 Bundle showBadge = new Bundle();
Julia Reynolds22f02b32016-12-01 15:05:13 -0500111 int[] importance = new int[mKeys.length];
Julia Reynolds503ed942017-10-04 16:04:56 -0400112 Bundle userSentiment = new Bundle();
Beverly5a20a5e2018-03-06 15:02:44 -0500113 Bundle mHidden = new Bundle();
Tony Mak628cb932018-06-19 18:30:41 +0100114 Bundle smartActions = new Bundle();
Tony Makc9acf672018-07-20 13:58:24 +0200115 Bundle smartReplies = new Bundle();
Gus Prevasa3226492018-10-23 11:10:09 -0400116 Bundle audiblyAlerted = new Bundle();
Gus Prevas9abc5062018-10-31 16:11:04 -0400117 Bundle noisy = new Bundle();
Julia Reynolds22f02b32016-12-01 15:05:13 -0500118
119 for (int i = 0; i < mKeys.length; i++) {
120 String key = mKeys[i];
121 visibilityOverrides.putInt(key, getVisibilityOverride(i));
122 overrideGroupKeys.putString(key, getOverrideGroupKey(key));
123 if (isIntercepted(i)) {
124 interceptedKeys.add(key);
125 }
126 suppressedVisualEffects.putInt(key, getSuppressedVisualEffects(i));
127 importance[i] = getImportance(i);
128 explanation.putString(key, getExplanation(key));
Julia Reynolds924eed12017-01-19 09:52:07 -0500129 channels.putParcelable(key, getChannel(key, i));
Julia Reynolds22f02b32016-12-01 15:05:13 -0500130 overridePeople.putStringArrayList(key, getPeople(key, i));
131 snoozeCriteria.putParcelableArrayList(key, getSnoozeCriteria(key, i));
Julia Reynolds924eed12017-01-19 09:52:07 -0500132 showBadge.putBoolean(key, getShowBadge(i));
Julia Reynolds503ed942017-10-04 16:04:56 -0400133 userSentiment.putInt(key, getUserSentiment(i));
Beverly5a20a5e2018-03-06 15:02:44 -0500134 mHidden.putBoolean(key, getHidden(i));
Tony Mak628cb932018-06-19 18:30:41 +0100135 smartActions.putParcelableArrayList(key, getSmartActions(key, i));
Tony Makc9acf672018-07-20 13:58:24 +0200136 smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i));
Gus Prevasa3226492018-10-23 11:10:09 -0400137 audiblyAlerted.putBoolean(key, audiblyAlerted(i));
Gus Prevas9abc5062018-10-31 16:11:04 -0400138 noisy.putBoolean(key, getNoisy(i));
Julia Reynolds22f02b32016-12-01 15:05:13 -0500139 }
140 NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
141 interceptedKeys.toArray(new String[0]), visibilityOverrides,
142 suppressedVisualEffects, importance, explanation, overrideGroupKeys,
Tony Mak628cb932018-06-19 18:30:41 +0100143 channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden,
Gus Prevas9abc5062018-10-31 16:11:04 -0400144 smartActions, smartReplies, audiblyAlerted, noisy);
Julia Reynolds22f02b32016-12-01 15:05:13 -0500145 return update;
146 }
147
148 private int getVisibilityOverride(int index) {
149 return index * 9;
150 }
151
152 private String getOverrideGroupKey(String key) {
153 return key + key;
154 }
155
156 private boolean isIntercepted(int index) {
157 return index % 2 == 0;
158 }
159
160 private int getSuppressedVisualEffects(int index) {
161 return index * 2;
162 }
163
164 private int getImportance(int index) {
165 return index;
166 }
167
168 private String getExplanation(String key) {
169 return key + "explain";
170 }
171
172 private NotificationChannel getChannel(String key, int index) {
173 return new NotificationChannel(key, key, getImportance(index));
174 }
175
Julia Reynolds924eed12017-01-19 09:52:07 -0500176 private boolean getShowBadge(int index) {
177 return index % 3 == 0;
178 }
179
Julia Reynolds503ed942017-10-04 16:04:56 -0400180 private int getUserSentiment(int index) {
181 switch(index % 3) {
182 case 0:
183 return USER_SENTIMENT_NEGATIVE;
184 case 1:
185 return USER_SENTIMENT_NEUTRAL;
186 case 2:
187 return USER_SENTIMENT_POSITIVE;
188 }
189 return USER_SENTIMENT_NEUTRAL;
190 }
191
Beverly5a20a5e2018-03-06 15:02:44 -0500192 private boolean getHidden(int index) {
193 return index % 2 == 0;
194 }
195
Gus Prevasa3226492018-10-23 11:10:09 -0400196 private boolean audiblyAlerted(int index) {
197 return index < 2;
198 }
199
Gus Prevas9abc5062018-10-31 16:11:04 -0400200 private boolean getNoisy(int index) {
201 return index < 1;
202 }
203
Julia Reynolds22f02b32016-12-01 15:05:13 -0500204 private ArrayList<String> getPeople(String key, int index) {
205 ArrayList<String> people = new ArrayList<>();
206 for (int i = 0; i < index; i++) {
207 people.add(i + key);
208 }
209 return people;
210 }
211
212 private ArrayList<SnoozeCriterion> getSnoozeCriteria(String key, int index) {
213 ArrayList<SnoozeCriterion> snooze = new ArrayList<>();
214 for (int i = 0; i < index; i++) {
215 snooze.add(new SnoozeCriterion(key + i, getExplanation(key), key));
216 }
217 return snooze;
218 }
219
Tony Mak628cb932018-06-19 18:30:41 +0100220 private ArrayList<Notification.Action> getSmartActions(String key, int index) {
221 ArrayList<Notification.Action> actions = new ArrayList<>();
222 for (int i = 0; i < index; i++) {
223 PendingIntent intent = PendingIntent.getBroadcast(
224 getContext(),
225 index /*requestCode*/,
226 new Intent("ACTION_" + key),
227 0 /*flags*/);
228 actions.add(new Notification.Action.Builder(null /*icon*/, key, intent).build());
229 }
230 return actions;
231 }
232
Tony Makc9acf672018-07-20 13:58:24 +0200233 private ArrayList<CharSequence> getSmartReplies(String key, int index) {
234 ArrayList<CharSequence> choices = new ArrayList<>();
235 for (int i = 0; i < index; i++) {
236 choices.add("choice_" + key + "_" + i);
237 }
238 return choices;
239 }
240
Tony Mak628cb932018-06-19 18:30:41 +0100241 private void assertActionsEqual(
242 List<Notification.Action> expecteds, List<Notification.Action> actuals) {
243 assertEquals(expecteds.size(), actuals.size());
244 for (int i = 0; i < expecteds.size(); i++) {
245 Notification.Action expected = expecteds.get(i);
246 Notification.Action actual = actuals.get(i);
247 assertEquals(expected.title, actual.title);
248 }
249 }
250
Julia Reynolds22f02b32016-12-01 15:05:13 -0500251 public static class TestListenerService extends NotificationListenerService {
252 private final IBinder binder = new LocalBinder();
253
254 public TestListenerService() {
Julia Reynolds94a38b32018-04-20 13:33:36 -0400255 mWrapper = mock(NotificationListenerWrapper.class);
256 mNoMan = mock(INotificationManager.class);
257 }
Julia Reynolds22f02b32016-12-01 15:05:13 -0500258
Julia Reynolds94a38b32018-04-20 13:33:36 -0400259 INotificationManager getNoMan() {
260 return mNoMan;
Julia Reynolds22f02b32016-12-01 15:05:13 -0500261 }
262
263 @Override
264 public IBinder onBind(Intent intent) {
265 super.onBind(intent);
266 return binder;
267 }
268
269 public class LocalBinder extends Binder {
270 TestListenerService getService() {
271 return TestListenerService.this;
272 }
273 }
274 }
275}