SnoozeHelperTest.java revision 4024b6696ce1be3b29194b8dc21e3d1f97776e69
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 org.junit.Before;
19import org.junit.Test;
20import org.junit.runner.RunWith;
21import org.mockito.ArgumentCaptor;
22import org.mockito.Mock;
23import org.mockito.MockitoAnnotations;
24
25import android.app.AlarmManager;
26import android.app.Notification;
27import android.app.NotificationChannel;
28import android.app.NotificationManager;
29import android.app.PendingIntent;
30import android.content.Context;
31import android.os.SystemClock;
32import android.os.UserHandle;
33import android.service.notification.StatusBarNotification;
34import android.support.test.InstrumentationRegistry;
35import android.support.test.runner.AndroidJUnit4;
36import android.test.suitebuilder.annotation.SmallTest;
37
38import static junit.framework.Assert.assertEquals;
39import static junit.framework.Assert.assertFalse;
40import static junit.framework.Assert.assertTrue;
41import static org.mockito.Matchers.any;
42import static org.mockito.Matchers.anyInt;
43import static org.mockito.Matchers.anyLong;
44import static org.mockito.Matchers.eq;
45import static org.mockito.Mockito.never;
46import static org.mockito.Mockito.times;
47import static org.mockito.Mockito.verify;
48import static org.mockito.Mockito.when;
49
50
51@SmallTest
52@RunWith(AndroidJUnit4.class)
53public class SnoozeHelperTest {
54    @Mock SnoozeHelper.Callback mCallback;
55    @Mock AlarmManager mAm;
56    @Mock ManagedServices.UserProfiles mUserProfiles;
57
58    private SnoozeHelper mSnoozeHelper;
59
60    private Context getContext() {
61        return InstrumentationRegistry.getTargetContext();
62    }
63
64    @Before
65    public void setUp() {
66        MockitoAnnotations.initMocks(this);
67
68        mSnoozeHelper = new SnoozeHelper(getContext(), mCallback, mUserProfiles);
69        mSnoozeHelper.setAlarmManager(mAm);
70    }
71
72    @Test
73    public void testSnoozeForTime() throws Exception {
74        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
75        mSnoozeHelper.snooze(r, 1000);
76        ArgumentCaptor<Long> captor = ArgumentCaptor.forClass(Long.class);
77        verify(mAm, times(1)).setExactAndAllowWhileIdle(
78                anyInt(), captor.capture(), any(PendingIntent.class));
79        long actualSnoozedUntilDuration = captor.getValue() - SystemClock.elapsedRealtime();
80        assertTrue(Math.abs(actualSnoozedUntilDuration - 1000) < 25);
81        assertTrue(mSnoozeHelper.isSnoozed(
82                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
83    }
84
85    @Test
86    public void testSnooze() throws Exception {
87        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
88        mSnoozeHelper.snooze(r);
89        verify(mAm, never()).setExactAndAllowWhileIdle(
90                anyInt(), anyLong(), any(PendingIntent.class));
91        assertTrue(mSnoozeHelper.isSnoozed(
92                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
93    }
94
95    @Test
96    public void testCancelByApp() throws Exception {
97        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
98        NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
99        mSnoozeHelper.snooze(r, 1000);
100        mSnoozeHelper.snooze(r2 , 1000);
101        assertTrue(mSnoozeHelper.isSnoozed(
102                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
103        assertTrue(mSnoozeHelper.isSnoozed(
104                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
105
106        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.sbn.getPackageName(), "one", 1);
107        // 3 = one for each snooze, above + one for cancel itself.
108        verify(mAm, times(3)).cancel(any(PendingIntent.class));
109        assertFalse(mSnoozeHelper.isSnoozed(
110                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
111        assertTrue(mSnoozeHelper.isSnoozed(
112                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
113    }
114
115    @Test
116    public void testCancelAllForUser() throws Exception {
117        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
118        NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
119        NotificationRecord r3 = getNotificationRecord("pkg", 3, "three", UserHandle.ALL);
120        mSnoozeHelper.snooze(r,  1000);
121        mSnoozeHelper.snooze(r2, 1000);
122        mSnoozeHelper.snooze(r3, 1000);
123        assertTrue(mSnoozeHelper.isSnoozed(
124                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
125        assertTrue(mSnoozeHelper.isSnoozed(
126                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
127        assertTrue(mSnoozeHelper.isSnoozed(
128                UserHandle.USER_ALL, r3.sbn.getPackageName(), r3.getKey()));
129
130        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, false);
131        // 5 = once for each snooze above (3) + once for each notification canceled (2).
132        verify(mAm, times(5)).cancel(any(PendingIntent.class));
133        assertFalse(mSnoozeHelper.isSnoozed(
134                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
135        assertFalse(mSnoozeHelper.isSnoozed(
136                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
137        assertTrue(mSnoozeHelper.isSnoozed(
138                UserHandle.USER_ALL, r3.sbn.getPackageName(), r3.getKey()));
139    }
140
141    @Test
142    public void testCancelAllByApp() throws Exception {
143        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
144        NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
145        NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
146        mSnoozeHelper.snooze(r, 1000);
147        mSnoozeHelper.snooze(r2, 1000);
148        mSnoozeHelper.snooze(r3, 1000);
149        assertTrue(mSnoozeHelper.isSnoozed(
150                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
151        assertTrue(mSnoozeHelper.isSnoozed(
152                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
153        assertTrue(mSnoozeHelper.isSnoozed(
154                UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey()));
155
156        mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, "pkg2");
157        // 4 = once for each snooze above (3) + once for each notification canceled (1).
158        verify(mAm, times(4)).cancel(any(PendingIntent.class));
159        assertTrue(mSnoozeHelper.isSnoozed(
160                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
161        assertTrue(mSnoozeHelper.isSnoozed(
162                UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
163        assertFalse(mSnoozeHelper.isSnoozed(
164                UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey()));
165    }
166
167    @Test
168    public void testRepost() throws Exception {
169        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
170        mSnoozeHelper.snooze(r, 1000);
171        NotificationRecord r2 = getNotificationRecord("pkg", 2, "one", UserHandle.ALL);
172        mSnoozeHelper.snooze(r2, 1000);
173        mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
174        verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
175    }
176
177    @Test
178    public void testRepost_noUser() throws Exception {
179        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
180        mSnoozeHelper.snooze(r, 1000);
181        NotificationRecord r2 = getNotificationRecord("pkg", 2, "one", UserHandle.ALL);
182        mSnoozeHelper.snooze(r2, 1000);
183        mSnoozeHelper.repost(r.getKey());
184        verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
185    }
186
187    @Test
188    public void testUpdate() throws Exception {
189        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
190        mSnoozeHelper.snooze(r , 1000);
191        r.getNotification().category = "NEW CATEGORY";
192
193        mSnoozeHelper.update(UserHandle.USER_SYSTEM, r);
194        verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class));
195
196        mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
197        verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
198    }
199
200    @Test
201    public void testGetSnoozedByUser() throws Exception {
202        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
203        NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
204        NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
205        NotificationRecord r4 = getNotificationRecord("pkg2", 3, "three", UserHandle.CURRENT);
206        mSnoozeHelper.snooze(r, 1000);
207        mSnoozeHelper.snooze(r2, 1000);
208        mSnoozeHelper.snooze(r3, 1000);
209        mSnoozeHelper.snooze(r4, 1000);
210        when(mUserProfiles.getCurrentProfileIds()).thenReturn(
211                new int[] {UserHandle.USER_SYSTEM});
212        assertEquals(3, mSnoozeHelper.getSnoozed().size());
213        when(mUserProfiles.getCurrentProfileIds()).thenReturn(
214                new int[] {UserHandle.USER_CURRENT});
215        assertEquals(1, mSnoozeHelper.getSnoozed().size());
216    }
217
218    @Test
219    public void testGetSnoozedByUser_managedProfiles() throws Exception {
220        when(mUserProfiles.getCurrentProfileIds()).thenReturn(
221                new int[] {UserHandle.USER_SYSTEM, UserHandle.USER_CURRENT});
222        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
223        NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
224        NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
225        NotificationRecord r4 = getNotificationRecord("pkg2", 3, "three", UserHandle.CURRENT);
226        mSnoozeHelper.snooze(r, 1000);
227        mSnoozeHelper.snooze(r2, 1000);
228        mSnoozeHelper.snooze(r3, 1000);
229        mSnoozeHelper.snooze(r4, 1000);
230        assertEquals(4, mSnoozeHelper.getSnoozed().size());
231    }
232
233    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
234            UserHandle user) {
235        Notification n = new Notification.Builder(getContext())
236                .setContentTitle("A")
237                .setGroup("G")
238                .setSortKey("A")
239                .setWhen(1205)
240                .build();
241        return new NotificationRecord(getContext(), new StatusBarNotification(
242                pkg, pkg, id, tag, 0, 0, n, user, null,
243                System.currentTimeMillis()), getDefaultChannel());
244    }
245
246    private NotificationChannel getDefaultChannel() {
247        return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
248                NotificationManager.IMPORTANCE_LOW);
249    }
250
251}
252