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.server.alarm; 18 19 import static android.app.AlarmManager.ELAPSED_REALTIME; 20 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE; 21 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT; 22 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; 23 import static android.app.AlarmManager.FLAG_STANDALONE; 24 import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE; 25 import static android.app.AlarmManager.RTC_WAKEUP; 26 27 import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX; 28 import static com.android.server.alarm.Alarm.NUM_POLICIES; 29 import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX; 30 import static com.android.server.alarm.AlarmManagerService.isExemptFromAppStandby; 31 import static com.android.server.alarm.AlarmManagerService.isExemptFromTare; 32 import static com.android.server.alarm.Constants.TEST_CALLING_PACKAGE; 33 import static com.android.server.alarm.Constants.TEST_CALLING_UID; 34 35 import static org.junit.Assert.assertEquals; 36 import static org.junit.Assert.assertFalse; 37 import static org.junit.Assert.assertTrue; 38 import static org.mockito.Mockito.mock; 39 import static org.mockito.Mockito.when; 40 41 import android.app.AlarmManager; 42 import android.app.PendingIntent; 43 import android.platform.test.annotations.Presubmit; 44 45 import androidx.test.runner.AndroidJUnit4; 46 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 50 import java.util.Random; 51 52 @Presubmit 53 @RunWith(AndroidJUnit4.class) 54 public class AlarmTest { 55 createDefaultAlarm(long requestedElapsed, long windowLength, int flags)56 private Alarm createDefaultAlarm(long requestedElapsed, long windowLength, int flags) { 57 return new Alarm(ELAPSED_REALTIME, 0, requestedElapsed, windowLength, 0, 58 createAlarmSender(), null, null, null, flags, null, TEST_CALLING_UID, 59 TEST_CALLING_PACKAGE, null, 0); 60 } 61 createAlarmClock(long requestedRtc)62 private Alarm createAlarmClock(long requestedRtc) { 63 final AlarmManager.AlarmClockInfo info = mock(AlarmManager.AlarmClockInfo.class); 64 return new Alarm(RTC_WAKEUP, requestedRtc, requestedRtc, 0, 0, createAlarmSender(), 65 null, null, null, FLAG_WAKE_FROM_IDLE | FLAG_STANDALONE, info, TEST_CALLING_UID, 66 TEST_CALLING_PACKAGE, null, 0); 67 } 68 createAlarmSender()69 private PendingIntent createAlarmSender() { 70 final PendingIntent alarmPi = mock(PendingIntent.class); 71 when(alarmPi.getCreatorPackage()).thenReturn(TEST_CALLING_PACKAGE); 72 when(alarmPi.getCreatorUid()).thenReturn(TEST_CALLING_UID); 73 return alarmPi; 74 } 75 76 @Test initSetsOnlyRequesterPolicy()77 public void initSetsOnlyRequesterPolicy() { 78 final Alarm a = createDefaultAlarm(4567, 2, 0); 79 80 for (int i = 0; i < NUM_POLICIES; i++) { 81 if (i == REQUESTER_POLICY_INDEX) { 82 assertEquals(4567, a.getPolicyElapsed(i)); 83 } else { 84 assertEquals(0, a.getPolicyElapsed(i)); 85 } 86 } 87 } 88 89 /** 90 * Generates a long matrix {@code A} of size {@code NxN}, with the property that the {@code i}th 91 * row will have the {@code i}th element largest in that row. 92 * 93 * In other words, {@code A[i][i]} will be the maximum of {@code A[i][j]} over all {@code j}, 94 * {@code 0<=j<N}. 95 */ generatePolicyTestMatrix(int n)96 private static long[][] generatePolicyTestMatrix(int n) { 97 final long[][] data = new long[n][n]; 98 final Random random = new Random(971); 99 for (int i = 0; i < n; i++) { 100 data[i][i] = 1; 101 for (int j = 0; j < n; j++) { 102 if (i != j) { 103 data[i][j] = random.nextInt(1 << 20); 104 data[i][i] += data[i][j]; 105 } 106 } 107 } 108 return data; 109 } 110 111 @Test whenElapsed()112 public void whenElapsed() { 113 final Alarm a = createDefaultAlarm(0, 0, 0); 114 115 final long[][] uniqueData = generatePolicyTestMatrix(NUM_POLICIES); 116 for (int i = 0; i < NUM_POLICIES; i++) { 117 for (int j = 0; j < NUM_POLICIES; j++) { 118 a.setPolicyElapsed(j, uniqueData[i][j]); 119 } 120 assertEquals(uniqueData[i][i], a.getWhenElapsed()); 121 } 122 123 for (int i = 0; i < NUM_POLICIES; i++) { 124 a.setPolicyElapsed(i, 3); 125 } 126 assertEquals(3, a.getWhenElapsed()); 127 } 128 129 @Test maxWhenElapsed()130 public void maxWhenElapsed() { 131 final Alarm a = createDefaultAlarm(10, 12, 0); 132 assertEquals(22, a.getMaxWhenElapsed()); 133 134 a.setPolicyElapsed(REQUESTER_POLICY_INDEX, 15); 135 assertEquals(27, a.getMaxWhenElapsed()); 136 137 a.setPolicyElapsed(REQUESTER_POLICY_INDEX, 2); 138 assertEquals(14, a.getMaxWhenElapsed()); 139 140 for (int i = 0; i < NUM_POLICIES; i++) { 141 if (i == REQUESTER_POLICY_INDEX) { 142 continue; 143 } 144 a.setPolicyElapsed(i, 17); 145 // getWhenElapsed is 17, so getMaxWhenElapsed will return 17 too. 146 assertEquals(17, a.getMaxWhenElapsed()); 147 148 a.setPolicyElapsed(i, 5); 149 assertEquals(14, a.getMaxWhenElapsed()); 150 } 151 } 152 153 @Test setPolicyElapsedExact()154 public void setPolicyElapsedExact() { 155 final Alarm exactAlarm = createDefaultAlarm(10, 0, 0); 156 157 assertTrue(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 4)); 158 assertTrue(exactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 10)); 159 160 assertFalse(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 8)); 161 assertFalse(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 10)); 162 assertFalse(exactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 8)); 163 164 assertTrue(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 7)); 165 166 } 167 168 @Test setPolicyElapsedInexact()169 public void setPolicyElapsedInexact() { 170 final Alarm inexactAlarm = createDefaultAlarm(10, 5, 0); 171 172 assertTrue(inexactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 4)); 173 assertTrue(inexactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 10)); 174 175 // whenElapsed won't change, but maxWhenElapsed will. 176 assertTrue(inexactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 8)); 177 assertTrue(inexactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 10)); 178 179 assertFalse(inexactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 8)); 180 } 181 182 @Test isExemptFromStandby()183 public void isExemptFromStandby() { 184 final long anything = 35412; // Arbitrary number, doesn't matter for this test. 185 186 assertFalse("Basic alarm exempt", isExemptFromAppStandby( 187 createDefaultAlarm(anything, anything, 0))); 188 assertFalse("FLAG_ALLOW_WHILE_IDLE_COMPAT exempt", isExemptFromAppStandby( 189 createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_COMPAT))); 190 191 assertTrue("ALLOW_WHILE_IDLE not exempt", isExemptFromAppStandby( 192 createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE))); 193 assertTrue("ALLOW_WHILE_IDLE_UNRESTRICTED not exempt", isExemptFromAppStandby( 194 createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED))); 195 assertTrue("Alarm clock not exempt", isExemptFromAppStandby(createAlarmClock(anything))); 196 } 197 198 @Test testIsExemptFromTare()199 public void testIsExemptFromTare() { 200 final long anything = 54321; // Arbitrary number, doesn't matter for this test. 201 202 assertFalse("Basic alarm exempt", isExemptFromTare( 203 createDefaultAlarm(anything, anything, 0))); 204 assertFalse("FLAG_ALLOW_WHILE_IDLE_COMPAT exempt", isExemptFromTare( 205 createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_COMPAT))); 206 assertFalse("ALLOW_WHILE_IDLE exempt", isExemptFromTare( 207 createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE))); 208 209 assertTrue("ALLOW_WHILE_IDLE_UNRESTRICTED not exempt", isExemptFromTare( 210 createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED))); 211 assertTrue("Alarm clock not exempt", isExemptFromTare(createAlarmClock(anything))); 212 } 213 214 @Test snapshotImmutable()215 public void snapshotImmutable() { 216 final Alarm a = createDefaultAlarm(0, 0, 0); 217 218 final Random random = new Random(234); 219 final long[] policyElapsed = new long[NUM_POLICIES]; 220 for (int i = 0; i < NUM_POLICIES; i++) { 221 a.setPolicyElapsed(i, policyElapsed[i] = random.nextInt(1 << 10)); 222 } 223 224 final Alarm.Snapshot snapshot = new Alarm.Snapshot(a); 225 226 for (int i = 0; i < NUM_POLICIES; i++) { 227 assertEquals(policyElapsed[i], snapshot.mPolicyWhenElapsed[i]); 228 } 229 230 for (int i = 0; i < NUM_POLICIES; i++) { 231 a.setPolicyElapsed(i, policyElapsed[i] + 5 + i); 232 assertEquals(policyElapsed[i], snapshot.mPolicyWhenElapsed[i]); 233 } 234 } 235 } 236