blob: f652c5afd203caedb85947adfbb83f76072cfdb2 [file] [log] [blame]
Julia Reynolds8f488d32016-10-14 10:59:01 -04001/*
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
Julia Reynoldsa13b3e22017-08-10 16:58:54 -040018import static junit.framework.Assert.assertEquals;
19import static junit.framework.Assert.assertNotNull;
20
Julia Reynolds8f488d32016-10-14 10:59:01 -040021import static org.mockito.Matchers.anyInt;
22import static org.mockito.Matchers.anyString;
23import static org.mockito.Matchers.eq;
24import static org.mockito.Mockito.never;
25import static org.mockito.Mockito.times;
26import static org.mockito.Mockito.verify;
27
Brett Chabot84151d92019-02-27 15:37:59 -080028import android.app.Notification;
29import android.os.UserHandle;
30import android.service.notification.StatusBarNotification;
31import android.test.suitebuilder.annotation.SmallTest;
32
33import androidx.test.runner.AndroidJUnit4;
34
35import com.android.server.UiServiceTestCase;
36
Julia Reynolds8f488d32016-10-14 10:59:01 -040037import org.junit.Before;
38import org.junit.Test;
39import org.junit.runner.RunWith;
40import org.mockito.Mock;
Julia Reynoldsf4af65b2016-12-20 17:05:12 -050041import org.mockito.Mockito;
Julia Reynolds8f488d32016-10-14 10:59:01 -040042import org.mockito.MockitoAnnotations;
43
Julia Reynolds8f488d32016-10-14 10:59:01 -040044import java.util.ArrayList;
Julia Reynoldsa13b3e22017-08-10 16:58:54 -040045import java.util.LinkedHashSet;
Julia Reynolds8f488d32016-10-14 10:59:01 -040046import java.util.List;
Julia Reynoldsa13b3e22017-08-10 16:58:54 -040047import java.util.Map;
Julia Reynolds8f488d32016-10-14 10:59:01 -040048
49@SmallTest
50@RunWith(AndroidJUnit4.class)
Jason Monk74f5e362017-12-06 08:56:33 -050051public class GroupHelperTest extends UiServiceTestCase {
Julia Reynolds8f488d32016-10-14 10:59:01 -040052 private @Mock GroupHelper.Callback mCallback;
53
Adora Zhang48dd614a82018-06-25 19:18:41 -070054 private final static int AUTOGROUP_AT_COUNT = 4;
Julia Reynolds8f488d32016-10-14 10:59:01 -040055 private GroupHelper mGroupHelper;
56
Julia Reynolds8f488d32016-10-14 10:59:01 -040057 @Before
58 public void setUp() {
59 MockitoAnnotations.initMocks(this);
60
Adora Zhang48dd614a82018-06-25 19:18:41 -070061 mGroupHelper = new GroupHelper(AUTOGROUP_AT_COUNT, mCallback);
Julia Reynolds8f488d32016-10-14 10:59:01 -040062 }
63
64 private StatusBarNotification getSbn(String pkg, int id, String tag,
65 UserHandle user, String groupKey) {
Geoffrey Pitschaf759c52017-02-15 09:35:38 -050066 Notification.Builder nb = new Notification.Builder(getContext(), "test_channel_id")
Julia Reynolds8f488d32016-10-14 10:59:01 -040067 .setContentTitle("A")
68 .setWhen(1205);
69 if (groupKey != null) {
70 nb.setGroup(groupKey);
71 }
Julia Reynolds924eed12017-01-19 09:52:07 -050072 return new StatusBarNotification(pkg, pkg, id, tag, 0, 0, nb.build(), user, null,
Julia Reynolds423b9fc2016-11-09 09:51:08 -050073 System.currentTimeMillis());
Julia Reynolds8f488d32016-10-14 10:59:01 -040074 }
75
76 private StatusBarNotification getSbn(String pkg, int id, String tag,
77 UserHandle user) {
78 return getSbn(pkg, id, tag, user, null);
79 }
80
81 @Test
82 public void testNoGroup_postingUnderLimit() throws Exception {
83 final String pkg = "package";
Adora Zhang48dd614a82018-06-25 19:18:41 -070084 for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
Julia Reynoldsa13b3e22017-08-10 16:58:54 -040085 mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
86 false);
Julia Reynolds8f488d32016-10-14 10:59:01 -040087 }
88 verify(mCallback, never()).addAutoGroupSummary(
89 eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
90 verify(mCallback, never()).addAutoGroup(anyString());
91 verify(mCallback, never()).removeAutoGroup(anyString());
92 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
93 }
94
95 @Test
96 public void testNoGroup_multiPackage() throws Exception {
97 final String pkg = "package";
98 final String pkg2 = "package2";
Adora Zhang48dd614a82018-06-25 19:18:41 -070099 for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400100 mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
101 false);
Julia Reynolds8f488d32016-10-14 10:59:01 -0400102 }
103 mGroupHelper.onNotificationPosted(
Adora Zhang48dd614a82018-06-25 19:18:41 -0700104 getSbn(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
Julia Reynolds8f488d32016-10-14 10:59:01 -0400105 verify(mCallback, never()).addAutoGroupSummary(
106 eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
107 verify(mCallback, never()).addAutoGroup(anyString());
108 verify(mCallback, never()).removeAutoGroup(anyString());
109 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
110 }
111
112 @Test
113 public void testNoGroup_multiUser() throws Exception {
114 final String pkg = "package";
Adora Zhang48dd614a82018-06-25 19:18:41 -0700115 for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400116 mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
117 false);
Julia Reynolds8f488d32016-10-14 10:59:01 -0400118 }
119 mGroupHelper.onNotificationPosted(
Adora Zhang48dd614a82018-06-25 19:18:41 -0700120 getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.ALL), false);
Julia Reynolds8f488d32016-10-14 10:59:01 -0400121 verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
122 verify(mCallback, never()).addAutoGroup(anyString());
123 verify(mCallback, never()).removeAutoGroup(anyString());
124 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
125 }
126
127 @Test
128 public void testNoGroup_someAreGrouped() throws Exception {
129 final String pkg = "package";
Adora Zhang48dd614a82018-06-25 19:18:41 -0700130 for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400131 mGroupHelper.onNotificationPosted(
132 getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
Julia Reynolds8f488d32016-10-14 10:59:01 -0400133 }
134 mGroupHelper.onNotificationPosted(
Adora Zhang48dd614a82018-06-25 19:18:41 -0700135 getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"), false);
Julia Reynolds8f488d32016-10-14 10:59:01 -0400136 verify(mCallback, never()).addAutoGroupSummary(
137 eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
138 verify(mCallback, never()).addAutoGroup(anyString());
139 verify(mCallback, never()).removeAutoGroup(anyString());
140 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
141 }
142
143
144 @Test
145 public void testPostingOverLimit() throws Exception {
146 final String pkg = "package";
Adora Zhang48dd614a82018-06-25 19:18:41 -0700147 for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400148 mGroupHelper.onNotificationPosted(
149 getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
Julia Reynolds8f488d32016-10-14 10:59:01 -0400150 }
151 verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
Adora Zhang48dd614a82018-06-25 19:18:41 -0700152 verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
Julia Reynolds8f488d32016-10-14 10:59:01 -0400153 verify(mCallback, never()).removeAutoGroup(anyString());
154 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
155 }
156
157 @Test
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500158 public void testDropToZeroRemoveGroup() throws Exception {
Julia Reynolds8f488d32016-10-14 10:59:01 -0400159 final String pkg = "package";
160 List<StatusBarNotification> posted = new ArrayList<>();
Adora Zhang48dd614a82018-06-25 19:18:41 -0700161 for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
Julia Reynolds8f488d32016-10-14 10:59:01 -0400162 final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
163 posted.add(sbn);
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400164 mGroupHelper.onNotificationPosted(sbn, false);
Julia Reynolds8f488d32016-10-14 10:59:01 -0400165 }
Julia Reynolds8f488d32016-10-14 10:59:01 -0400166 verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
Adora Zhang48dd614a82018-06-25 19:18:41 -0700167 verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500168 verify(mCallback, never()).removeAutoGroup(anyString());
169 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
170 Mockito.reset(mCallback);
171
Adora Zhang48dd614a82018-06-25 19:18:41 -0700172 for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500173 mGroupHelper.onNotificationRemoved(posted.remove(0));
174 }
175 verify(mCallback, never()).removeAutoGroup(anyString());
176 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
177 Mockito.reset(mCallback);
178
179 mGroupHelper.onNotificationRemoved(posted.remove(0));
180 verify(mCallback, never()).removeAutoGroup(anyString());
181 verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
182 }
183
184 @Test
185 public void testAppStartsGrouping() throws Exception {
186 final String pkg = "package";
187 List<StatusBarNotification> posted = new ArrayList<>();
Adora Zhang48dd614a82018-06-25 19:18:41 -0700188 for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500189 final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
190 posted.add(sbn);
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400191 mGroupHelper.onNotificationPosted(sbn, false);
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500192 }
193 verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
Adora Zhang48dd614a82018-06-25 19:18:41 -0700194 verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500195 verify(mCallback, never()).removeAutoGroup(anyString());
196 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
197 Mockito.reset(mCallback);
198
199 int i = 0;
Adora Zhang48dd614a82018-06-25 19:18:41 -0700200 for (i = 0; i < AUTOGROUP_AT_COUNT - 2; i++) {
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500201 final StatusBarNotification sbn =
202 getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400203 mGroupHelper.onNotificationPosted(sbn, false);
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500204 }
Adora Zhang48dd614a82018-06-25 19:18:41 -0700205 verify(mCallback, times(AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500206 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
207 Mockito.reset(mCallback);
208
Adora Zhang48dd614a82018-06-25 19:18:41 -0700209 for (; i < AUTOGROUP_AT_COUNT; i++) {
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500210 final StatusBarNotification sbn =
211 getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400212 mGroupHelper.onNotificationPosted(sbn, false);
Julia Reynoldsf4af65b2016-12-20 17:05:12 -0500213 }
214 verify(mCallback, times(2)).removeAutoGroup(anyString());
Julia Reynolds8f488d32016-10-14 10:59:01 -0400215 verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
216 }
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400217
218 @Test
219 public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled()
220 throws Exception {
221 final String pkg = "package";
222 List<StatusBarNotification> posted = new ArrayList<>();
Adora Zhang48dd614a82018-06-25 19:18:41 -0700223 for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400224 final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
225 posted.add(sbn);
226 mGroupHelper.onNotificationPosted(sbn, false);
227 }
228 verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
Adora Zhang48dd614a82018-06-25 19:18:41 -0700229 verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
Julia Reynoldsa13b3e22017-08-10 16:58:54 -0400230 verify(mCallback, never()).removeAutoGroup(anyString());
231 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
232 Mockito.reset(mCallback);
233
234 for (int i = posted.size() - 2; i >= 0; i--) {
235 mGroupHelper.onNotificationRemoved(posted.remove(i));
236 }
237 verify(mCallback, never()).removeAutoGroup(anyString());
238 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
239 Mockito.reset(mCallback);
240
241 // only one child remains
242 Map<String, LinkedHashSet<String>> ungroupedForUser =
243 mGroupHelper.mUngroupedNotifications.get(UserHandle.USER_SYSTEM);
244 assertNotNull(ungroupedForUser);
245 assertEquals(1, ungroupedForUser.get(pkg).size());
246
247 // Add new notification; it should be autogrouped even though the total count is
248 // < AUTOGROUP_AT_COUNT
249 final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
250 posted.add(sbn);
251 mGroupHelper.onNotificationPosted(sbn, true);
252 verify(mCallback, times(posted.size())).addAutoGroup(anyString());
253 verify(mCallback, never()).removeAutoGroup(anyString());
254 verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
255 }
Julia Reynolds8f488d32016-10-14 10:59:01 -0400256}