1/* 2 * Copyright (C) 2017 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; 17 18import static android.app.AlarmManager.RTC; 19import static android.app.AlarmManager.RTC_WAKEUP; 20 21import static org.junit.Assert.assertEquals; 22 23import android.support.test.filters.SmallTest; 24import android.support.test.runner.AndroidJUnit4; 25import android.util.SparseArray; 26 27import com.android.internal.util.ObjectUtils; 28import com.android.server.AlarmManagerService.Alarm; 29 30import org.junit.Test; 31import org.junit.runner.RunWith; 32 33import java.util.ArrayList; 34 35@SmallTest 36@RunWith(AndroidJUnit4.class) 37public class AlarmManagerServiceTest { 38 private SparseArray<ArrayList<Alarm>> addPendingAlarm( 39 SparseArray<ArrayList<Alarm>> all, int uid, String name, boolean removeIt) { 40 ArrayList<Alarm> uidAlarms = all.get(uid); 41 if (uidAlarms == null) { 42 all.put(uid, uidAlarms = new ArrayList<>()); 43 } 44 // Details don't matter. 45 uidAlarms.add(new Alarm( 46 removeIt ? RTC : RTC_WAKEUP, 47 0, 0, 0, 0, 0, null, null, null, null, 0, null, uid, name)); 48 return all; 49 } 50 51 private static String toString(SparseArray<ArrayList<Alarm>> pendingAlarms) { 52 final StringBuilder sb = new StringBuilder(); 53 54 String sep = ""; 55 for (int i = 0; i < pendingAlarms.size(); i++) { 56 sb.append(sep); 57 sep = ", "; 58 sb.append("["); 59 sb.append(pendingAlarms.keyAt(i)); 60 sb.append(": "); 61 sb.append(toString(pendingAlarms.valueAt(i))); 62 sb.append("]"); 63 } 64 return sb.toString(); 65 } 66 67 private static String toString(ArrayList<Alarm> alarms) { 68 final StringBuilder sb = new StringBuilder(); 69 70 alarms.sort((a, b) -> ObjectUtils.compare(a.packageName, b.packageName)); 71 72 String sep = ""; 73 for (Alarm a : alarms) { 74 sb.append(sep); 75 sep = ", "; 76 sb.append(a.packageName); 77 } 78 return sb.toString(); 79 } 80 81 private void runCheckAllPendingAlarms( 82 SparseArray<ArrayList<Alarm>> pending, ArrayList<Alarm> alarmsToDeliver) { 83 // RTC_WAKEUP alarms are restricted. 84 AlarmManagerService.findAllUnrestrictedPendingBackgroundAlarmsLockedInner(pending, 85 alarmsToDeliver, alarm -> alarm.type == RTC_WAKEUP); 86 } 87 88 @Test 89 public void findAllUnrestrictedPendingBackgroundAlarmsLockedInner_empty() { 90 SparseArray<ArrayList<Alarm>> pending = new SparseArray<>(); 91 92 final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); 93 94 runCheckAllPendingAlarms(pending, alarmsToDeliver); 95 96 assertEquals("", toString(pending)); 97 assertEquals("", toString(alarmsToDeliver)); 98 } 99 100 @Test 101 public void findAllUnrestrictedPendingBackgroundAlarmsLockedInner_single_remove() { 102 SparseArray<ArrayList<Alarm>> pending = new SparseArray<>(); 103 104 addPendingAlarm(pending, 100001, "a1", false); 105 106 final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); 107 108 runCheckAllPendingAlarms(pending, alarmsToDeliver); 109 110 assertEquals("[100001: a1]", toString(pending)); 111 assertEquals("", toString(alarmsToDeliver)); 112 } 113 114 @Test 115 public void findAllUnrestrictedPendingBackgroundAlarmsLockedInner_single_nonremove() { 116 SparseArray<ArrayList<Alarm>> pending = new SparseArray<>(); 117 118 addPendingAlarm(pending, 100001, "a1", true); 119 120 final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); 121 runCheckAllPendingAlarms(pending, alarmsToDeliver); 122 123 124 assertEquals("", toString(pending)); 125 assertEquals("a1", toString(alarmsToDeliver)); 126 } 127 128 @Test 129 public void findAllUnrestrictedPendingBackgroundAlarmsLockedInner_complex() { 130 SparseArray<ArrayList<Alarm>> pending = new SparseArray<>(); 131 132 addPendingAlarm(pending, 100001, "a11", false); 133 addPendingAlarm(pending, 100001, "a12", true); 134 addPendingAlarm(pending, 100001, "a13", false); 135 addPendingAlarm(pending, 100001, "a14", true); 136 137 addPendingAlarm(pending, 100002, "a21", false); 138 139 addPendingAlarm(pending, 100003, "a31", true); 140 141 addPendingAlarm(pending, 100004, "a41", false); 142 addPendingAlarm(pending, 100004, "a42", false); 143 144 addPendingAlarm(pending, 100005, "a51", true); 145 addPendingAlarm(pending, 100005, "a52", true); 146 147 addPendingAlarm(pending, 100006, "a61", true); 148 addPendingAlarm(pending, 100006, "a62", false); 149 addPendingAlarm(pending, 100006, "a63", true); 150 addPendingAlarm(pending, 100006, "a64", false); 151 152 final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); 153 runCheckAllPendingAlarms(pending, alarmsToDeliver); 154 155 156 assertEquals("[100001: a11, a13], [100002: a21], [100004: a41, a42], [100006: a62, a64]", 157 toString(pending)); 158 assertEquals("a12, a14, a31, a51, a52, a61, a63", toString(alarmsToDeliver)); 159 } 160 161 @Test 162 public void findAllUnrestrictedPendingBackgroundAlarmsLockedInner_complex_allRemove() { 163 SparseArray<ArrayList<Alarm>> pending = new SparseArray<>(); 164 165 addPendingAlarm(pending, 100001, "a11", true); 166 addPendingAlarm(pending, 100001, "a12", true); 167 addPendingAlarm(pending, 100001, "a13", true); 168 addPendingAlarm(pending, 100001, "a14", true); 169 170 addPendingAlarm(pending, 100002, "a21", true); 171 172 addPendingAlarm(pending, 100003, "a31", true); 173 174 addPendingAlarm(pending, 100004, "a41", true); 175 addPendingAlarm(pending, 100004, "a42", true); 176 177 addPendingAlarm(pending, 100005, "a51", true); 178 addPendingAlarm(pending, 100005, "a52", true); 179 180 addPendingAlarm(pending, 100006, "a61", true); 181 addPendingAlarm(pending, 100006, "a62", true); 182 addPendingAlarm(pending, 100006, "a63", true); 183 addPendingAlarm(pending, 100006, "a64", true); 184 185 final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); 186 runCheckAllPendingAlarms(pending, alarmsToDeliver); 187 188 189 assertEquals("", toString(pending)); 190 assertEquals("a11, a12, a13, a14, a21, a31, a41, a42, a51, a52, a61, a62, a63, a64", 191 toString(alarmsToDeliver)); 192 } 193} 194