1 /*
2  * Copyright (C) 2020 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 
17 package com.android.deskclock.timer;
18 
19 import android.content.ComponentName;
20 import android.content.Intent;
21 
22 import androidx.test.core.app.ApplicationProvider;
23 import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;
24 import androidx.test.platform.app.InstrumentationRegistry;
25 
26 import com.android.deskclock.data.DataModel;
27 import com.android.deskclock.data.Timer;
28 
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 
34 import java.util.ArrayList;
35 import java.util.List;
36 
37 import static android.app.Service.START_NOT_STICKY;
38 import static org.junit.Assert.assertEquals;
39 import static org.junit.Assert.assertNotNull;
40 
41 @RunWith(AndroidJUnit4ClassRunner.class)
42 public class TimerServiceTest {
43 
44     private TimerService timerService;
45     private DataModel dataModel;
46 
47     @Before
setUp()48     public void setUp() {
49         dataModel = DataModel.getDataModel();
50         timerService = new TimerService();
51         timerService.onCreate();
52     }
53 
54     @After
tearDown()55     public void tearDown() {
56         clearTimers();
57         dataModel = null;
58         timerService = null;
59     }
60 
clearTimers()61     private void clearTimers() {
62         Runnable clearTimersRunnable = () -> {
63             final List<Timer> timers = new ArrayList<>(DataModel.getDataModel().getTimers());
64             for (Timer timer : timers) {
65                 DataModel.getDataModel().removeTimer(timer);
66             }
67         };
68         InstrumentationRegistry.getInstrumentation().runOnMainSync(clearTimersRunnable);
69     }
70 
71     @Test
verifyIntentsHonored_whileTimersFire()72     public void verifyIntentsHonored_whileTimersFire() {
73         Runnable testRunnable = () -> {
74             Timer timer1 = dataModel.addTimer(60000L, null, false);
75             Timer timer2 = dataModel.addTimer(60000L, null, false);
76             dataModel.startTimer(timer1);
77             dataModel.startTimer(timer2);
78             timer1 = dataModel.getTimer(timer1.getId());
79             timer2 = dataModel.getTimer(timer2.getId());
80 
81             // Expire the first timer.
82             dataModel.expireTimer(null, timer1);
83 
84             // Have TimerService honor the Intent.
85             assertEquals(START_NOT_STICKY,
86                     timerService.onStartCommand(getTimerServiceIntent(), 0, 0));
87 
88             // Expire the second timer.
89             dataModel.expireTimer(null, timer2);
90 
91             // Have TimerService honor the Intent which updates the firing timers.
92             assertEquals(START_NOT_STICKY,
93                     timerService.onStartCommand(getTimerServiceIntent(), 0, 1));
94 
95             // Reset timer 1.
96             dataModel.resetTimer(dataModel.getTimer(timer1.getId()));
97 
98             // Have TimerService honor the Intent which updates the firing timers.
99             assertEquals(START_NOT_STICKY,
100                     timerService.onStartCommand(getTimerServiceIntent(), 0, 2));
101 
102             // Remove timer 2.
103             dataModel.removeTimer(dataModel.getTimer(timer2.getId()));
104         };
105         InstrumentationRegistry.getInstrumentation().runOnMainSync(testRunnable);
106     }
107 
108     @Test
verifyIntentsHonored_ifNoTimersAreExpired()109     public void verifyIntentsHonored_ifNoTimersAreExpired() {
110         Runnable testRunnable = () -> {
111             Timer timer = dataModel.addTimer(60000L, null, false);
112             dataModel.startTimer(timer);
113             timer = dataModel.getTimer(timer.getId());
114 
115             // Expire the timer.
116             dataModel.expireTimer(null, timer);
117 
118             final Intent timerServiceIntent = getTimerServiceIntent();
119 
120             // Reset the timer before TimerService starts.
121             dataModel.resetTimer(dataModel.getTimer(timer.getId()));
122 
123             // Have TimerService honor the Intent.
124             assertEquals(START_NOT_STICKY, timerService.onStartCommand(timerServiceIntent, 0, 0));
125         };
126         InstrumentationRegistry.getInstrumentation().runOnMainSync(testRunnable);
127     }
128 
getTimerServiceIntent()129     private Intent getTimerServiceIntent() {
130         Intent serviceIntent = new Intent(ApplicationProvider.getApplicationContext(),
131                 TimerService.class);
132 
133         final ComponentName component = serviceIntent.getComponent();
134         assertNotNull(component);
135         assertEquals(TimerService.class.getName(), component.getClassName());
136 
137         return serviceIntent;
138     }
139 }
140