1 package org.robolectric.shadows; 2 3 import static android.app.AlarmManager.INTERVAL_HOUR; 4 import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; 5 import static android.os.Build.VERSION_CODES.KITKAT; 6 import static android.os.Build.VERSION_CODES.LOLLIPOP; 7 import static android.os.Build.VERSION_CODES.M; 8 import static org.assertj.core.api.Assertions.assertThat; 9 import static org.robolectric.Shadows.shadowOf; 10 11 import android.app.Activity; 12 import android.app.AlarmManager; 13 import android.app.AlarmManager.AlarmClockInfo; 14 import android.app.PendingIntent; 15 import android.content.Context; 16 import android.content.Intent; 17 import java.util.Date; 18 import org.junit.Before; 19 import org.junit.Test; 20 import org.junit.runner.RunWith; 21 import org.robolectric.Robolectric; 22 import org.robolectric.RobolectricTestRunner; 23 import org.robolectric.RuntimeEnvironment; 24 import org.robolectric.annotation.Config; 25 26 @RunWith(RobolectricTestRunner.class) 27 public class ShadowAlarmManagerTest { 28 29 private Context context; 30 private Activity activity; 31 private AlarmManager alarmManager; 32 private ShadowAlarmManager shadowAlarmManager; 33 34 @Before setUp()35 public void setUp() { 36 context = RuntimeEnvironment.application; 37 alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 38 shadowAlarmManager = shadowOf(alarmManager); 39 activity = Robolectric.setupActivity(Activity.class); 40 } 41 42 @Test set_shouldRegisterAlarm()43 public void set_shouldRegisterAlarm() { 44 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 45 alarmManager.set(AlarmManager.ELAPSED_REALTIME, 0, 46 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 47 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNotNull(); 48 } 49 50 @Test 51 @Config(minSdk = M) setAndAllowWhileIdle_shouldRegisterAlarm()52 public void setAndAllowWhileIdle_shouldRegisterAlarm() { 53 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 54 alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, 0, 55 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 56 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNotNull(); 57 } 58 59 @Test 60 @Config(minSdk = M) setExactAndAllowWhileIdle_shouldRegisterAlarm()61 public void setExactAndAllowWhileIdle_shouldRegisterAlarm() { 62 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 63 alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, 0, 64 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 65 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNotNull(); 66 } 67 68 @Test 69 @Config(minSdk = KITKAT) setExact_shouldRegisterAlarm_forApi19()70 public void setExact_shouldRegisterAlarm_forApi19() { 71 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 72 alarmManager.setExact(AlarmManager.ELAPSED_REALTIME, 0, 73 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 74 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNotNull(); 75 } 76 77 @Test 78 @Config(minSdk = KITKAT) setWindow_shouldRegisterAlarm_forApi19()79 public void setWindow_shouldRegisterAlarm_forApi19() { 80 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 81 alarmManager.setWindow(AlarmManager.ELAPSED_REALTIME, 0, 1, 82 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 83 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNotNull(); 84 } 85 86 @Test setRepeating_shouldRegisterAlarm()87 public void setRepeating_shouldRegisterAlarm() { 88 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 89 alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 0, INTERVAL_HOUR, 90 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 91 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNotNull(); 92 } 93 94 @Test set_shouldReplaceAlarmsWithSameIntentReceiver()95 public void set_shouldReplaceAlarmsWithSameIntentReceiver() { 96 alarmManager.set(AlarmManager.ELAPSED_REALTIME, 500, 97 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 98 alarmManager.set(AlarmManager.ELAPSED_REALTIME, 1000, 99 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 100 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(1); 101 } 102 103 @Test set_shouldReplaceDuplicates()104 public void set_shouldReplaceDuplicates() { 105 alarmManager.set(AlarmManager.ELAPSED_REALTIME, 0, 106 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 107 alarmManager.set(AlarmManager.ELAPSED_REALTIME, 0, 108 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 109 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(1); 110 } 111 112 @Test setRepeating_shouldReplaceDuplicates()113 public void setRepeating_shouldReplaceDuplicates() { 114 alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 0, INTERVAL_HOUR, 115 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 116 alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 0, INTERVAL_HOUR, 117 PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), 0)); 118 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(1); 119 } 120 121 @Test shouldSupportGetNextScheduledAlarm()122 public void shouldSupportGetNextScheduledAlarm() { 123 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 124 125 long now = new Date().getTime(); 126 Intent intent = new Intent(activity, activity.getClass()); 127 PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0); 128 alarmManager.set(AlarmManager.ELAPSED_REALTIME, now, pendingIntent); 129 130 ShadowAlarmManager.ScheduledAlarm scheduledAlarm = shadowAlarmManager.getNextScheduledAlarm(); 131 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 132 assertScheduledAlarm(now, pendingIntent, scheduledAlarm); 133 } 134 135 @Test getNextScheduledAlarm_shouldReturnRepeatingAlarms()136 public void getNextScheduledAlarm_shouldReturnRepeatingAlarms() { 137 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 138 139 long now = new Date().getTime(); 140 Intent intent = new Intent(activity, activity.getClass()); 141 PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0); 142 alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, now, INTERVAL_HOUR, pendingIntent); 143 144 ShadowAlarmManager.ScheduledAlarm scheduledAlarm = shadowAlarmManager.getNextScheduledAlarm(); 145 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 146 assertRepeatingScheduledAlarm(now, INTERVAL_HOUR, pendingIntent, scheduledAlarm); 147 } 148 149 @Test peekNextScheduledAlarm_shouldReturnNextAlarm()150 public void peekNextScheduledAlarm_shouldReturnNextAlarm() { 151 assertThat(shadowAlarmManager.getNextScheduledAlarm()).isNull(); 152 153 long now = new Date().getTime(); 154 Intent intent = new Intent(activity, activity.getClass()); 155 PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0); 156 alarmManager.set(AlarmManager.ELAPSED_REALTIME, now, pendingIntent); 157 158 ShadowAlarmManager.ScheduledAlarm scheduledAlarm = shadowAlarmManager.peekNextScheduledAlarm(); 159 assertThat(shadowAlarmManager.peekNextScheduledAlarm()).isNotNull(); 160 assertScheduledAlarm(now, pendingIntent, scheduledAlarm); 161 } 162 163 @Test cancel_removesMatchingPendingIntents()164 public void cancel_removesMatchingPendingIntents() { 165 Intent intent = new Intent(context, String.class); 166 PendingIntent pendingIntent = 167 PendingIntent.getBroadcast(context, 0, intent, FLAG_UPDATE_CURRENT); 168 alarmManager.set(AlarmManager.RTC, 1337, pendingIntent); 169 170 Intent intent2 = new Intent(context, Integer.class); 171 PendingIntent pendingIntent2 = 172 PendingIntent.getBroadcast(context, 0, intent2, FLAG_UPDATE_CURRENT); 173 alarmManager.set(AlarmManager.RTC, 1337, pendingIntent2); 174 175 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(2); 176 177 Intent intent3 = new Intent(context, String.class); 178 PendingIntent pendingIntent3 = 179 PendingIntent.getBroadcast(context, 0, intent3, FLAG_UPDATE_CURRENT); 180 alarmManager.cancel(pendingIntent3); 181 182 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(1); 183 } 184 185 @Test cancel_removesMatchingPendingIntentsWithActions()186 public void cancel_removesMatchingPendingIntentsWithActions() { 187 Intent newIntent = new Intent("someAction"); 188 PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, 0); 189 190 alarmManager.set(AlarmManager.RTC, 1337, pendingIntent); 191 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(1); 192 193 alarmManager.cancel(PendingIntent.getBroadcast(context, 0, new Intent("anotherAction"), 0)); 194 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(1); 195 196 alarmManager.cancel(PendingIntent.getBroadcast(context, 0, new Intent("someAction"), 0)); 197 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(0); 198 } 199 200 @Test schedule_useRequestCodeToMatchExistingPendingIntents()201 public void schedule_useRequestCodeToMatchExistingPendingIntents() throws Exception { 202 Intent intent = new Intent("ACTION!"); 203 PendingIntent pI = PendingIntent.getService(RuntimeEnvironment.application, 1, intent, 0); 204 AlarmManager alarmManager = 205 (AlarmManager) RuntimeEnvironment.application.getSystemService(Context.ALARM_SERVICE); 206 alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10, pI); 207 208 PendingIntent pI2 = PendingIntent.getService(RuntimeEnvironment.application, 2, intent, 0); 209 alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10, pI2); 210 211 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(2); 212 } 213 214 @Test cancel_useRequestCodeToMatchExistingPendingIntents()215 public void cancel_useRequestCodeToMatchExistingPendingIntents() throws Exception { 216 Intent intent = new Intent("ACTION!"); 217 PendingIntent pI = PendingIntent.getService(RuntimeEnvironment.application, 1, intent, 0); 218 AlarmManager alarmManager = 219 (AlarmManager) RuntimeEnvironment.application.getSystemService(Context.ALARM_SERVICE); 220 alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10, pI); 221 222 PendingIntent pI2 = PendingIntent.getService(RuntimeEnvironment.application, 2, intent, 0); 223 alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10, pI2); 224 225 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(2); 226 227 alarmManager.cancel(pI); 228 assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(1); 229 assertThat(shadowAlarmManager.getNextScheduledAlarm().operation).isEqualTo(pI2); 230 } 231 232 @Test 233 @Config(minSdk = LOLLIPOP) getNextAlarmClockInfo()234 public void getNextAlarmClockInfo() { 235 assertThat(alarmManager.getNextAlarmClock()).isNull(); 236 assertThat(shadowAlarmManager.peekNextScheduledAlarm()).isNull(); 237 238 // Schedule an alarm. 239 PendingIntent show = PendingIntent.getBroadcast(context, 0, new Intent("showAction"), 0); 240 PendingIntent operation = PendingIntent.getBroadcast(context, 0, new Intent("opAction"), 0); 241 AlarmClockInfo info = new AlarmClockInfo(1000, show); 242 alarmManager.setAlarmClock(info, operation); 243 244 AlarmClockInfo next = alarmManager.getNextAlarmClock(); 245 assertThat(next).isNotNull(); 246 assertThat(next.getTriggerTime()).isEqualTo(1000); 247 assertThat(next.getShowIntent()).isSameAs(show); 248 assertThat(shadowAlarmManager.peekNextScheduledAlarm().operation).isSameAs(operation); 249 250 // Schedule another alarm sooner. 251 PendingIntent show2 = PendingIntent.getBroadcast(context, 0, new Intent("showAction2"), 0); 252 PendingIntent operation2 = PendingIntent.getBroadcast(context, 0, new Intent("opAction2"), 0); 253 AlarmClockInfo info2 = new AlarmClockInfo(500, show2); 254 alarmManager.setAlarmClock(info2, operation2); 255 256 next = alarmManager.getNextAlarmClock(); 257 assertThat(next).isNotNull(); 258 assertThat(next.getTriggerTime()).isEqualTo(500); 259 assertThat(next.getShowIntent()).isSameAs(show2); 260 assertThat(shadowAlarmManager.peekNextScheduledAlarm().operation).isSameAs(operation2); 261 262 // Remove the soonest alarm. 263 alarmManager.cancel(operation2); 264 265 next = alarmManager.getNextAlarmClock(); 266 assertThat(next).isNotNull(); 267 assertThat(next.getTriggerTime()).isEqualTo(1000); 268 assertThat(next.getShowIntent()).isSameAs(show); 269 assertThat(shadowAlarmManager.peekNextScheduledAlarm().operation).isSameAs(operation); 270 271 // Remove the sole alarm. 272 alarmManager.cancel(operation); 273 274 assertThat(alarmManager.getNextAlarmClock()).isNull(); 275 assertThat(shadowAlarmManager.peekNextScheduledAlarm()).isNull(); 276 } 277 assertScheduledAlarm(long now, PendingIntent pendingIntent, ShadowAlarmManager.ScheduledAlarm scheduledAlarm)278 private void assertScheduledAlarm(long now, PendingIntent pendingIntent, 279 ShadowAlarmManager.ScheduledAlarm scheduledAlarm) { 280 assertRepeatingScheduledAlarm(now, 0L, pendingIntent, scheduledAlarm); 281 } 282 assertRepeatingScheduledAlarm(long now, long interval, PendingIntent pendingIntent, ShadowAlarmManager.ScheduledAlarm scheduledAlarm)283 private void assertRepeatingScheduledAlarm(long now, long interval, PendingIntent pendingIntent, 284 ShadowAlarmManager.ScheduledAlarm scheduledAlarm) { 285 assertThat(scheduledAlarm).isNotNull(); 286 assertThat(scheduledAlarm.operation).isNotNull(); 287 assertThat(scheduledAlarm.operation).isSameAs(pendingIntent); 288 assertThat(scheduledAlarm.type).isEqualTo(AlarmManager.ELAPSED_REALTIME); 289 assertThat(scheduledAlarm.triggerAtTime).isEqualTo(now); 290 assertThat(scheduledAlarm.interval).isEqualTo(interval); 291 } 292 } 293