Home | History | Annotate | Download | only in notification
      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 package com.android.server.notification;
     17 
     18 import org.junit.Before;
     19 import org.junit.Test;
     20 import org.junit.runner.RunWith;
     21 import org.mockito.ArgumentCaptor;
     22 import org.mockito.Mock;
     23 import org.mockito.MockitoAnnotations;
     24 
     25 import android.app.AlarmManager;
     26 import android.app.Notification;
     27 import android.app.NotificationChannel;
     28 import android.app.NotificationManager;
     29 import android.app.PendingIntent;
     30 import android.os.SystemClock;
     31 import android.os.UserHandle;
     32 import android.service.notification.StatusBarNotification;
     33 import android.support.test.runner.AndroidJUnit4;
     34 import android.test.suitebuilder.annotation.SmallTest;
     35 
     36 import static junit.framework.Assert.assertEquals;
     37 import static junit.framework.Assert.assertFalse;
     38 import static junit.framework.Assert.assertTrue;
     39 import static org.mockito.Matchers.any;
     40 import static org.mockito.Matchers.anyInt;
     41 import static org.mockito.Matchers.anyLong;
     42 import static org.mockito.Matchers.eq;
     43 import static org.mockito.Mockito.never;
     44 import static org.mockito.Mockito.times;
     45 import static org.mockito.Mockito.verify;
     46 import static org.mockito.Mockito.when;
     47 
     48 import com.android.server.UiServiceTestCase;
     49 
     50 
     51 @SmallTest
     52 @RunWith(AndroidJUnit4.class)
     53 public class SnoozeHelperTest extends UiServiceTestCase {
     54     private static final String TEST_CHANNEL_ID = "test_channel_id";
     55 
     56     @Mock SnoozeHelper.Callback mCallback;
     57     @Mock AlarmManager mAm;
     58     @Mock ManagedServices.UserProfiles mUserProfiles;
     59 
     60     private SnoozeHelper mSnoozeHelper;
     61 
     62     @Before
     63     public void setUp() {
     64         MockitoAnnotations.initMocks(this);
     65 
     66         mSnoozeHelper = new SnoozeHelper(getContext(), mCallback, mUserProfiles);
     67         mSnoozeHelper.setAlarmManager(mAm);
     68     }
     69 
     70     @Test
     71     public void testSnoozeForTime() throws Exception {
     72         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
     73         mSnoozeHelper.snooze(r, 1000);
     74         ArgumentCaptor<Long> captor = ArgumentCaptor.forClass(Long.class);
     75         verify(mAm, times(1)).setExactAndAllowWhileIdle(
     76                 anyInt(), captor.capture(), any(PendingIntent.class));
     77         long actualSnoozedUntilDuration = captor.getValue() - SystemClock.elapsedRealtime();
     78         assertTrue(Math.abs(actualSnoozedUntilDuration - 1000) < 25);
     79         assertTrue(mSnoozeHelper.isSnoozed(
     80                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
     81     }
     82 
     83     @Test
     84     public void testSnooze() throws Exception {
     85         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
     86         mSnoozeHelper.snooze(r);
     87         verify(mAm, never()).setExactAndAllowWhileIdle(
     88                 anyInt(), anyLong(), any(PendingIntent.class));
     89         assertTrue(mSnoozeHelper.isSnoozed(
     90                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
     91     }
     92 
     93     @Test
     94     public void testCancelByApp() throws Exception {
     95         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
     96         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
     97         mSnoozeHelper.snooze(r, 1000);
     98         mSnoozeHelper.snooze(r2 , 1000);
     99         assertTrue(mSnoozeHelper.isSnoozed(
    100                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    101         assertTrue(mSnoozeHelper.isSnoozed(
    102                 UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
    103 
    104         mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.sbn.getPackageName(), "one", 1);
    105         // 2 = one for each snooze, above, zero for the cancel.
    106         verify(mAm, times(2)).cancel(any(PendingIntent.class));
    107         assertTrue(mSnoozeHelper.isSnoozed(
    108                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    109         assertTrue(mSnoozeHelper.isSnoozed(
    110                 UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
    111     }
    112 
    113     @Test
    114     public void testCancelAllForUser() throws Exception {
    115         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    116         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
    117         NotificationRecord r3 = getNotificationRecord("pkg", 3, "three", UserHandle.ALL);
    118         mSnoozeHelper.snooze(r,  1000);
    119         mSnoozeHelper.snooze(r2, 1000);
    120         mSnoozeHelper.snooze(r3, 1000);
    121         assertTrue(mSnoozeHelper.isSnoozed(
    122                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    123         assertTrue(mSnoozeHelper.isSnoozed(
    124                 UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
    125         assertTrue(mSnoozeHelper.isSnoozed(
    126                 UserHandle.USER_ALL, r3.sbn.getPackageName(), r3.getKey()));
    127 
    128         mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, false);
    129         // 3 = once for each snooze above (3), only.
    130         verify(mAm, times(3)).cancel(any(PendingIntent.class));
    131         assertTrue(mSnoozeHelper.isSnoozed(
    132                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    133         assertTrue(mSnoozeHelper.isSnoozed(
    134                 UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
    135         assertTrue(mSnoozeHelper.isSnoozed(
    136                 UserHandle.USER_ALL, r3.sbn.getPackageName(), r3.getKey()));
    137     }
    138 
    139     @Test
    140     public void testCancelAllByApp() throws Exception {
    141         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    142         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
    143         NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
    144         mSnoozeHelper.snooze(r, 1000);
    145         mSnoozeHelper.snooze(r2, 1000);
    146         mSnoozeHelper.snooze(r3, 1000);
    147         assertTrue(mSnoozeHelper.isSnoozed(
    148                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    149         assertTrue(mSnoozeHelper.isSnoozed(
    150                 UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
    151         assertTrue(mSnoozeHelper.isSnoozed(
    152                 UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey()));
    153 
    154         mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, "pkg2");
    155         // 3 = once for each snooze above (3), only.
    156         verify(mAm, times(3)).cancel(any(PendingIntent.class));
    157         assertTrue(mSnoozeHelper.isSnoozed(
    158                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    159         assertTrue(mSnoozeHelper.isSnoozed(
    160                 UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
    161         assertTrue(mSnoozeHelper.isSnoozed(
    162                 UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey()));
    163     }
    164 
    165     @Test
    166     public void testCancelDoesNotUnsnooze() throws Exception {
    167         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    168         mSnoozeHelper.snooze(r, 1000);
    169         assertTrue(mSnoozeHelper.isSnoozed(
    170                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    171 
    172         mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.sbn.getPackageName(), "one", 1);
    173 
    174         assertTrue(mSnoozeHelper.isSnoozed(
    175                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    176     }
    177 
    178     @Test
    179     public void testCancelDoesNotRepost() throws Exception {
    180         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    181         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
    182         mSnoozeHelper.snooze(r, 1000);
    183         mSnoozeHelper.snooze(r2 , 1000);
    184         assertTrue(mSnoozeHelper.isSnoozed(
    185                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    186         assertTrue(mSnoozeHelper.isSnoozed(
    187                 UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey()));
    188 
    189         mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.sbn.getPackageName(), "one", 1);
    190 
    191         mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
    192         verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r);
    193     }
    194 
    195     @Test
    196     public void testRepost() throws Exception {
    197         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    198         mSnoozeHelper.snooze(r, 1000);
    199         NotificationRecord r2 = getNotificationRecord("pkg", 2, "one", UserHandle.ALL);
    200         mSnoozeHelper.snooze(r2, 1000);
    201         mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
    202         verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
    203     }
    204 
    205     @Test
    206     public void testRepost_noUser() throws Exception {
    207         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    208         mSnoozeHelper.snooze(r, 1000);
    209         NotificationRecord r2 = getNotificationRecord("pkg", 2, "one", UserHandle.ALL);
    210         mSnoozeHelper.snooze(r2, 1000);
    211         mSnoozeHelper.repost(r.getKey());
    212         verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
    213     }
    214 
    215     @Test
    216     public void testUpdate() throws Exception {
    217         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    218         mSnoozeHelper.snooze(r , 1000);
    219         r.getNotification().category = "NEW CATEGORY";
    220 
    221         mSnoozeHelper.update(UserHandle.USER_SYSTEM, r);
    222         verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class));
    223 
    224         mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
    225         verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
    226     }
    227 
    228     @Test
    229     public void testGetSnoozedByUser() throws Exception {
    230         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    231         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
    232         NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
    233         NotificationRecord r4 = getNotificationRecord("pkg2", 3, "three", UserHandle.CURRENT);
    234         mSnoozeHelper.snooze(r, 1000);
    235         mSnoozeHelper.snooze(r2, 1000);
    236         mSnoozeHelper.snooze(r3, 1000);
    237         mSnoozeHelper.snooze(r4, 1000);
    238         when(mUserProfiles.getCurrentProfileIds()).thenReturn(
    239                 new int[] {UserHandle.USER_SYSTEM});
    240         assertEquals(3, mSnoozeHelper.getSnoozed().size());
    241         when(mUserProfiles.getCurrentProfileIds()).thenReturn(
    242                 new int[] {UserHandle.USER_CURRENT});
    243         assertEquals(1, mSnoozeHelper.getSnoozed().size());
    244     }
    245 
    246     @Test
    247     public void testGetSnoozedByUser_managedProfiles() throws Exception {
    248         when(mUserProfiles.getCurrentProfileIds()).thenReturn(
    249                 new int[] {UserHandle.USER_SYSTEM, UserHandle.USER_CURRENT});
    250         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
    251         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
    252         NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
    253         NotificationRecord r4 = getNotificationRecord("pkg2", 3, "three", UserHandle.CURRENT);
    254         mSnoozeHelper.snooze(r, 1000);
    255         mSnoozeHelper.snooze(r2, 1000);
    256         mSnoozeHelper.snooze(r3, 1000);
    257         mSnoozeHelper.snooze(r4, 1000);
    258         assertEquals(4, mSnoozeHelper.getSnoozed().size());
    259     }
    260 
    261     @Test
    262     public void repostGroupSummary_onlyFellowGroupChildren() throws Exception {
    263         NotificationRecord r = getNotificationRecord(
    264                 "pkg", 1, "one", UserHandle.SYSTEM, "group1", false);
    265         NotificationRecord r2 = getNotificationRecord(
    266                 "pkg", 2, "two", UserHandle.SYSTEM, "group1", false);
    267         mSnoozeHelper.snooze(r, 1000);
    268         mSnoozeHelper.snooze(r2, 1000);
    269         mSnoozeHelper.repostGroupSummary("pkg", UserHandle.USER_SYSTEM, "group1");
    270 
    271         verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r);
    272     }
    273 
    274     @Test
    275     public void repostGroupSummary_repostsSummary() throws Exception {
    276         when(mUserProfiles.getCurrentProfileIds()).thenReturn(
    277                 new int[] {UserHandle.USER_SYSTEM});
    278         NotificationRecord r = getNotificationRecord(
    279                 "pkg", 1, "one", UserHandle.SYSTEM, "group1", true);
    280         NotificationRecord r2 = getNotificationRecord(
    281                 "pkg", 2, "two", UserHandle.SYSTEM, "group1", false);
    282         mSnoozeHelper.snooze(r, 1000);
    283         mSnoozeHelper.snooze(r2, 1000);
    284         assertEquals(2, mSnoozeHelper.getSnoozed().size());
    285         assertEquals(2, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size());
    286 
    287         mSnoozeHelper.repostGroupSummary("pkg", UserHandle.USER_SYSTEM, r.getGroupKey());
    288 
    289         verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
    290         verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r2);
    291 
    292         assertEquals(1, mSnoozeHelper.getSnoozed().size());
    293         assertEquals(1, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size());
    294     }
    295 
    296     private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
    297             UserHandle user, String groupKey, boolean groupSummary) {
    298         Notification n = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
    299                 .setContentTitle("A")
    300                 .setGroup("G")
    301                 .setSortKey("A")
    302                 .setWhen(1205)
    303                 .setGroup(groupKey)
    304                 .setGroupSummary(groupSummary)
    305                 .build();
    306         final NotificationChannel notificationChannel = new NotificationChannel(
    307                 TEST_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_LOW);
    308         return new NotificationRecord(getContext(), new StatusBarNotification(
    309                 pkg, pkg, id, tag, 0, 0, n, user, null,
    310                 System.currentTimeMillis()), notificationChannel);
    311     }
    312 
    313     private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
    314             UserHandle user) {
    315         return getNotificationRecord(pkg, id, tag, user, null, false);
    316     }
    317 }
    318