Home | History | Annotate | Download | only in notification
      1 package com.android.server.notification;
      2 
      3 import static org.junit.Assert.assertEquals;
      4 import static org.junit.Assert.assertFalse;
      5 import static org.junit.Assert.assertTrue;
      6 import static org.mockito.Mockito.spy;
      7 
      8 import android.content.Intent;
      9 import android.net.Uri;
     10 import android.service.notification.Condition;
     11 import android.service.notification.ScheduleCalendar;
     12 import android.service.notification.ZenModeConfig;
     13 import android.support.test.filters.SmallTest;
     14 import android.support.test.runner.AndroidJUnit4;
     15 import android.testing.AndroidTestingRunner;
     16 import android.testing.TestableLooper.RunWithLooper;
     17 
     18 import com.android.server.UiServiceTestCase;
     19 
     20 import org.junit.Before;
     21 import org.junit.Test;
     22 import org.junit.runner.RunWith;
     23 import org.mockito.MockitoAnnotations;
     24 
     25 import java.util.Calendar;
     26 import java.util.GregorianCalendar;
     27 
     28 @RunWith(AndroidTestingRunner.class)
     29 @SmallTest
     30 @RunWithLooper
     31 public class ScheduleConditionProviderTest extends UiServiceTestCase {
     32 
     33     ScheduleConditionProvider mService;
     34 
     35     @Before
     36     public void setUp() throws Exception {
     37         MockitoAnnotations.initMocks(this);
     38 
     39         Intent startIntent =
     40                 new Intent("com.android.server.notification.ScheduleConditionProvider");
     41         startIntent.setPackage("android");
     42         ScheduleConditionProvider service = new ScheduleConditionProvider();
     43         service.attach(
     44                 getContext(),
     45                 null,               // ActivityThread not actually used in Service
     46                 ScheduleConditionProvider.class.getName(),
     47                 null,               // token not needed when not talking with the activity manager
     48                 null,
     49                 null                // mocked services don't talk with the activity manager
     50                 );
     51         service.onCreate();
     52         service.onBind(startIntent);
     53         mService = spy(service);
     54    }
     55 
     56     @Test
     57     public void testIsValidConditionId_incomplete() throws Exception {
     58         Uri badConditionId = Uri.EMPTY;
     59         assertFalse(mService.isValidConditionId(badConditionId));
     60         assertEquals(Condition.STATE_ERROR,
     61                 mService.evaluateSubscriptionLocked(badConditionId, null, 0, 1000).state);
     62     }
     63 
     64     @Test
     65     public void testIsValidConditionId() throws Exception {
     66         ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
     67         info.days = new int[] {1, 2, 4};
     68         info.startHour = 8;
     69         info.startMinute = 56;
     70         info.nextAlarm = 1000;
     71         info.exitAtAlarm = true;
     72         info.endHour = 12;
     73         info.endMinute = 9;
     74         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
     75         assertTrue(mService.isValidConditionId(conditionId));
     76     }
     77 
     78     @Test
     79     public void testEvaluateSubscription_noAlarmExit_InSchedule() {
     80         Calendar now = getNow();
     81 
     82         // Schedule - 1 hour long; starts now
     83         ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
     84         info.days = new int[] {Calendar.FRIDAY};
     85         info.startHour = now.get(Calendar.HOUR_OF_DAY);
     86         info.startMinute = now.get(Calendar.MINUTE);
     87         info.nextAlarm = 0;
     88         info.exitAtAlarm = false;
     89         info.endHour = now.get(Calendar.HOUR_OF_DAY) + 1;
     90         info.endMinute = info.startMinute;
     91         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
     92         ScheduleCalendar cal = new ScheduleCalendar();
     93         cal.setSchedule(info);
     94         assertTrue(cal.isInSchedule(now.getTimeInMillis()));
     95 
     96         Condition condition = mService.evaluateSubscriptionLocked(
     97                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
     98 
     99         assertEquals(Condition.STATE_TRUE, condition.state);
    100     }
    101 
    102     @Test
    103     public void testEvaluateSubscription_noAlarmExit_InScheduleSnoozed() {
    104         Calendar now = getNow();
    105 
    106         // Schedule - 1 hour long; starts now
    107         ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
    108         info.days = new int[] {Calendar.FRIDAY};
    109         info.startHour = now.get(Calendar.HOUR_OF_DAY);
    110         info.startMinute = now.get(Calendar.MINUTE);
    111         info.nextAlarm = 0;
    112         info.exitAtAlarm = false;
    113         info.endHour = now.get(Calendar.HOUR_OF_DAY) + 1;
    114         info.endMinute = info.startMinute;
    115         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
    116         ScheduleCalendar cal = new ScheduleCalendar();
    117         cal.setSchedule(info);
    118         assertTrue(cal.isInSchedule(now.getTimeInMillis()));
    119 
    120         mService.addSnoozed(conditionId);
    121 
    122         Condition condition = mService.evaluateSubscriptionLocked(
    123                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
    124 
    125         assertEquals(Condition.STATE_FALSE, condition.state);
    126     }
    127 
    128     @Test
    129     public void testEvaluateSubscription_noAlarmExit_beforeSchedule() {
    130         Calendar now = new GregorianCalendar();
    131         now.set(Calendar.HOUR_OF_DAY, 14);
    132         now.set(Calendar.MINUTE, 15);
    133         now.set(Calendar.SECOND, 59);
    134         now.set(Calendar.MILLISECOND, 0);
    135         now.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
    136 
    137         // Schedule - 1 hour long; starts in 1 second
    138         ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
    139         info.days = new int[] {Calendar.FRIDAY};
    140         info.startHour = now.get(Calendar.HOUR_OF_DAY);
    141         info.startMinute = now.get(Calendar.MINUTE) + 1;
    142         info.nextAlarm = 0;
    143         info.exitAtAlarm = false;
    144         info.endHour = now.get(Calendar.HOUR_OF_DAY) + 1;
    145         info.endMinute = info.startMinute;
    146         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
    147         ScheduleCalendar cal = new ScheduleCalendar();
    148         cal.setSchedule(info);
    149 
    150         Condition condition = mService.evaluateSubscriptionLocked(
    151                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
    152 
    153         assertEquals(Condition.STATE_FALSE, condition.state);
    154     }
    155 
    156     @Test
    157     public void testEvaluateSubscription_noAlarmExit_endSchedule() {
    158         Calendar now = getNow();
    159 
    160         // Schedule - 1 hour long; ends now
    161         ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
    162         info.days = new int[] {Calendar.FRIDAY};
    163         info.startHour = now.get(Calendar.HOUR_OF_DAY) - 1;
    164         info.startMinute = now.get(Calendar.MINUTE);
    165         info.nextAlarm = 0;
    166         info.exitAtAlarm = false;
    167         info.endHour = now.get(Calendar.HOUR_OF_DAY);
    168         info.endMinute = now.get(Calendar.MINUTE);
    169         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
    170         ScheduleCalendar cal = new ScheduleCalendar();
    171         cal.setSchedule(info);
    172 
    173         Condition condition = mService.evaluateSubscriptionLocked(
    174                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
    175 
    176         assertEquals(Condition.STATE_FALSE, condition.state);
    177     }
    178 
    179     @Test
    180     public void testEvaluateSubscription_alarmSetBeforeInSchedule() {
    181         Calendar now = getNow();
    182 
    183         // Schedule - 1 hour long; starts now, ends with alarm
    184         ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
    185         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
    186         ScheduleCalendar cal = new ScheduleCalendar();
    187         cal.setSchedule(info);
    188 
    189         // an hour before start, update with an alarm that will fire during the schedule
    190         mService.evaluateSubscriptionLocked(
    191                 conditionId, cal, now.getTimeInMillis() - 1000, now.getTimeInMillis() + 1000);
    192 
    193         // at start, should be in dnd
    194         Condition condition = mService.evaluateSubscriptionLocked(
    195                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
    196         assertEquals(Condition.STATE_TRUE, condition.state);
    197 
    198         // at alarm fire time, should exit dnd
    199         assertTrue(cal.isInSchedule(now.getTimeInMillis() + 1000));
    200         assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
    201                 cal.shouldExitForAlarm(now.getTimeInMillis() + 1000));
    202         condition = mService.evaluateSubscriptionLocked(
    203                 conditionId, cal, now.getTimeInMillis() + 1000, 0);
    204         assertEquals(Condition.STATE_FALSE, condition.state);
    205     }
    206 
    207     @Test
    208     public void testEvaluateSubscription_alarmSetInSchedule() {
    209         Calendar now = getNow();
    210 
    211         // Schedule - 1 hour long; starts now, ends with alarm
    212         ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
    213         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
    214         ScheduleCalendar cal = new ScheduleCalendar();
    215         cal.setSchedule(info);
    216 
    217         // at start, should be in dnd
    218         Condition condition = mService.evaluateSubscriptionLocked(
    219                 conditionId, cal, now.getTimeInMillis(), 0);
    220         assertEquals(Condition.STATE_TRUE, condition.state);
    221 
    222         // in schedule, update with alarm time, should be in dnd
    223         condition = mService.evaluateSubscriptionLocked(
    224                 conditionId, cal, now.getTimeInMillis() + 500, now.getTimeInMillis() + 1000);
    225         assertEquals(Condition.STATE_TRUE, condition.state);
    226 
    227         // at alarm fire time, should exit dnd
    228         assertTrue(cal.isInSchedule(now.getTimeInMillis() + 1000));
    229         assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
    230                 cal.shouldExitForAlarm(now.getTimeInMillis() + 1000));
    231         condition = mService.evaluateSubscriptionLocked(
    232                 conditionId, cal, now.getTimeInMillis() + 1000, 0);
    233         assertEquals(Condition.STATE_FALSE, condition.state);
    234     }
    235 
    236     @Test
    237     public void testEvaluateSubscription_earlierAlarmSet() {
    238         Calendar now = getNow();
    239 
    240         // Schedule - 1 hour long; starts now, ends with alarm
    241         ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
    242         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
    243         ScheduleCalendar cal = new ScheduleCalendar();
    244         cal.setSchedule(info);
    245 
    246         // at start, should be in dnd, alarm in 2000 ms
    247         Condition condition = mService.evaluateSubscriptionLocked(
    248                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 2000);
    249         assertEquals(Condition.STATE_TRUE, condition.state);
    250 
    251         // in schedule, update with earlier alarm time, should be in dnd
    252         condition = mService.evaluateSubscriptionLocked(
    253                 conditionId, cal, now.getTimeInMillis() + 500, now.getTimeInMillis() + 1000);
    254         assertEquals(Condition.STATE_TRUE, condition.state);
    255 
    256         // at earliest alarm fire time, should exit dnd
    257         assertTrue(cal.isInSchedule(now.getTimeInMillis() + 1000));
    258         assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
    259                 cal.shouldExitForAlarm(now.getTimeInMillis() + 1000));
    260         condition = mService.evaluateSubscriptionLocked(
    261                 conditionId, cal, now.getTimeInMillis() + 1000, 0);
    262         assertEquals(Condition.STATE_FALSE, condition.state);
    263     }
    264 
    265     @Test
    266     public void testEvaluateSubscription_laterAlarmSet() {
    267         Calendar now = getNow();
    268 
    269         // Schedule - 1 hour long; starts now, ends with alarm
    270         ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
    271         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
    272         ScheduleCalendar cal = new ScheduleCalendar();
    273         cal.setSchedule(info);
    274 
    275         // at start, should be in dnd, alarm in 500 ms
    276         Condition condition = mService.evaluateSubscriptionLocked(
    277                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 500);
    278         assertEquals(Condition.STATE_TRUE, condition.state);
    279 
    280         // in schedule, update with later alarm time, should be in dnd
    281         condition = mService.evaluateSubscriptionLocked(
    282                 conditionId, cal, now.getTimeInMillis() + 250, now.getTimeInMillis() + 1000);
    283         assertEquals(Condition.STATE_TRUE, condition.state);
    284 
    285         // at earliest alarm fire time, should exit dnd
    286         assertTrue(cal.isInSchedule(now.getTimeInMillis() + 500));
    287         assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
    288                 cal.shouldExitForAlarm(now.getTimeInMillis() + 500));
    289         condition = mService.evaluateSubscriptionLocked(
    290                 conditionId, cal, now.getTimeInMillis() + 500, 0);
    291         assertEquals(Condition.STATE_FALSE, condition.state);
    292     }
    293 
    294     @Test
    295     public void testEvaluateSubscription_alarmCanceled() {
    296         Calendar now = getNow();
    297 
    298         // Schedule - 1 hour long; starts now, ends with alarm
    299         ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
    300         Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
    301         ScheduleCalendar cal = new ScheduleCalendar();
    302         cal.setSchedule(info);
    303 
    304         // at start, should be in dnd, alarm in 500 ms
    305         Condition condition = mService.evaluateSubscriptionLocked(
    306                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 500);
    307         assertEquals(Condition.STATE_TRUE, condition.state);
    308 
    309         // in schedule, cancel alarm
    310         condition = mService.evaluateSubscriptionLocked(
    311                 conditionId, cal, now.getTimeInMillis() + 250, 0);
    312         assertEquals(Condition.STATE_TRUE, condition.state);
    313 
    314         // at previous alarm time, should not exit DND
    315         assertTrue(cal.isInSchedule(now.getTimeInMillis() + 500));
    316         assertFalse(cal.shouldExitForAlarm(now.getTimeInMillis() + 500));
    317         condition = mService.evaluateSubscriptionLocked(
    318                 conditionId, cal, now.getTimeInMillis() + 500, 0);
    319         assertEquals(Condition.STATE_TRUE, condition.state);
    320 
    321         // end of schedule, exit DND
    322         now.add(Calendar.HOUR_OF_DAY, 1);
    323         condition = mService.evaluateSubscriptionLocked(conditionId, cal, now.getTimeInMillis(), 0);
    324         assertEquals(Condition.STATE_FALSE, condition.state);
    325     }
    326 
    327     private Calendar getNow() {
    328         Calendar now = new GregorianCalendar();
    329         now.set(Calendar.HOUR_OF_DAY, 14);
    330         now.set(Calendar.MINUTE, 16);
    331         now.set(Calendar.SECOND, 0);
    332         now.set(Calendar.MILLISECOND, 0);
    333         now.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
    334         return now;
    335     }
    336 
    337     private ZenModeConfig.ScheduleInfo getScheduleEndsInHour(Calendar now) {
    338         ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
    339         info.days = new int[] {Calendar.FRIDAY};
    340         info.startHour = now.get(Calendar.HOUR_OF_DAY);
    341         info.startMinute = now.get(Calendar.MINUTE);
    342         info.exitAtAlarm = true;
    343         info.endHour = now.get(Calendar.HOUR_OF_DAY) + 1;
    344         info.endMinute = now.get(Calendar.MINUTE);
    345         return info;
    346     }
    347 }
    348