GroupHelperTest.java revision 74f5e36f49b32baef90bf31bbbaf487c18002944
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 */
16package com.android.server.notification;
17
18import static junit.framework.Assert.assertEquals;
19import static junit.framework.Assert.assertNotNull;
20
21import 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
28import org.junit.Before;
29import org.junit.Test;
30import org.junit.runner.RunWith;
31import org.mockito.Mock;
32import org.mockito.Mockito;
33import org.mockito.MockitoAnnotations;
34
35import android.app.Notification;
36import android.os.UserHandle;
37import android.service.notification.StatusBarNotification;
38import android.support.test.runner.AndroidJUnit4;
39import android.test.suitebuilder.annotation.SmallTest;
40
41import com.android.server.UiServiceTestCase;
42
43import java.util.ArrayList;
44import java.util.LinkedHashSet;
45import java.util.List;
46import java.util.Map;
47
48@SmallTest
49@RunWith(AndroidJUnit4.class)
50public class GroupHelperTest extends UiServiceTestCase {
51    private @Mock GroupHelper.Callback mCallback;
52
53    private GroupHelper mGroupHelper;
54
55    @Before
56    public void setUp() {
57        MockitoAnnotations.initMocks(this);
58
59        mGroupHelper = new GroupHelper(mCallback);
60    }
61
62    private StatusBarNotification getSbn(String pkg, int id, String tag,
63            UserHandle user, String groupKey) {
64        Notification.Builder nb = new Notification.Builder(getContext(), "test_channel_id")
65                .setContentTitle("A")
66                .setWhen(1205);
67        if (groupKey != null) {
68            nb.setGroup(groupKey);
69        }
70        return new StatusBarNotification(pkg, pkg, id, tag, 0, 0, nb.build(), user, null,
71                System.currentTimeMillis());
72    }
73
74    private StatusBarNotification getSbn(String pkg, int id, String tag,
75            UserHandle user) {
76        return getSbn(pkg, id, tag, user, null);
77    }
78
79    @Test
80    public void testNoGroup_postingUnderLimit() throws Exception {
81        final String pkg = "package";
82        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
83            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
84                    false);
85        }
86        verify(mCallback, never()).addAutoGroupSummary(
87                eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
88        verify(mCallback, never()).addAutoGroup(anyString());
89        verify(mCallback, never()).removeAutoGroup(anyString());
90        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
91    }
92
93    @Test
94    public void testNoGroup_multiPackage() throws Exception {
95        final String pkg = "package";
96        final String pkg2 = "package2";
97        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
98            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
99                    false);
100        }
101        mGroupHelper.onNotificationPosted(
102                getSbn(pkg2, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
103        verify(mCallback, never()).addAutoGroupSummary(
104                eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
105        verify(mCallback, never()).addAutoGroup(anyString());
106        verify(mCallback, never()).removeAutoGroup(anyString());
107        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
108    }
109
110    @Test
111    public void testNoGroup_multiUser() throws Exception {
112        final String pkg = "package";
113        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
114            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
115                    false);
116        }
117        mGroupHelper.onNotificationPosted(
118                getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.ALL),
119                false);
120        verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
121        verify(mCallback, never()).addAutoGroup(anyString());
122        verify(mCallback, never()).removeAutoGroup(anyString());
123        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
124    }
125
126    @Test
127    public void testNoGroup_someAreGrouped() throws Exception {
128        final String pkg = "package";
129        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
130            mGroupHelper.onNotificationPosted(
131                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
132        }
133        mGroupHelper.onNotificationPosted(
134                getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"),
135                false);
136        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";
147        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
148            mGroupHelper.onNotificationPosted(
149                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
150        }
151        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
152        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
153        verify(mCallback, never()).removeAutoGroup(anyString());
154        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
155    }
156
157    @Test
158    public void testDropToZeroRemoveGroup() throws Exception {
159        final String pkg = "package";
160        List<StatusBarNotification> posted = new ArrayList<>();
161        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
162            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
163            posted.add(sbn);
164            mGroupHelper.onNotificationPosted(sbn, false);
165        }
166        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
167        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
168        verify(mCallback, never()).removeAutoGroup(anyString());
169        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
170        Mockito.reset(mCallback);
171
172        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
173            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<>();
188        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
189            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
190            posted.add(sbn);
191            mGroupHelper.onNotificationPosted(sbn, false);
192        }
193        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
194        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
195        verify(mCallback, never()).removeAutoGroup(anyString());
196        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
197        Mockito.reset(mCallback);
198
199        int i = 0;
200        for (i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 2; i++) {
201            final StatusBarNotification sbn =
202                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
203            mGroupHelper.onNotificationPosted(sbn, false);
204        }
205        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
206        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
207        Mockito.reset(mCallback);
208
209        for (; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
210            final StatusBarNotification sbn =
211                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
212            mGroupHelper.onNotificationPosted(sbn, false);
213        }
214        verify(mCallback, times(2)).removeAutoGroup(anyString());
215        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
216    }
217
218    @Test
219    public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled()
220            throws Exception {
221        final String pkg = "package";
222        List<StatusBarNotification> posted = new ArrayList<>();
223        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
224            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());
229        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
230        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    }
256}
257