summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Suprabh Shukla <suprabh@google.com> 2020-12-23 17:20:15 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-12-23 17:20:15 +0000
commit0f267888c9e5a81712c7d7a34fae86729f0e8449 (patch)
treeb1ed6272279e9ac121702cf2809257556bce679c
parentb6cf567c4cb27bb6b8f4eaf7dbf6f33883d86dc1 (diff)
parent2c2e1bf150f203cfb5299ba0e2a69f33cbec1aa8 (diff)
Merge "Copy the list before passing to deliverAlarms"
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java3
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java33
2 files changed, 35 insertions, 1 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 20c77da53f2c..7842d487dfb2 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -3061,7 +3061,8 @@ public class AlarmManagerService extends SystemService {
if (mMaxDelayTime < thisDelayTime) {
mMaxDelayTime = thisDelayTime;
}
- deliverAlarmsLocked(mPendingNonWakeupAlarms, nowELAPSED);
+ final ArrayList<Alarm> triggerList = new ArrayList<>(mPendingNonWakeupAlarms);
+ deliverAlarmsLocked(triggerList, nowELAPSED);
mPendingNonWakeupAlarms.clear();
}
if (mNonInteractiveStartTime > 0) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 8e4942e1ad5c..8edac4f8ce58 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -121,6 +121,7 @@ import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
@Presubmit
@RunWith(AndroidJUnit4.class)
@@ -1133,6 +1134,38 @@ public class AlarmManagerServiceTest {
}
}
+ /**
+ * This tests that all non wakeup alarms are sent even when the mPendingNonWakeupAlarms gets
+ * modified before the send is complete. This avoids bugs like b/175701084.
+ */
+ @Test
+ public void allNonWakeupAlarmsSentAtomically() throws Exception {
+ final int numAlarms = 5;
+ final AtomicInteger alarmsFired = new AtomicInteger(0);
+ for (int i = 0; i < numAlarms; i++) {
+ final IAlarmListener listener = new IAlarmListener.Stub() {
+ @Override
+ public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
+ alarmsFired.incrementAndGet();
+ mService.mPendingNonWakeupAlarms.clear();
+ }
+ };
+ setTestAlarmWithListener(ELAPSED_REALTIME, mNowElapsedTest + i + 5, listener);
+ }
+ doReturn(true).when(mService).checkAllowNonWakeupDelayLocked(anyLong());
+ // Advance time past all expirations.
+ mNowElapsedTest += numAlarms + 5;
+ mTestTimer.expire();
+ assertEquals(numAlarms, mService.mPendingNonWakeupAlarms.size());
+
+ // All of these alarms should be sent on interactive state change to true
+ mService.interactiveStateChangedLocked(false);
+ mService.interactiveStateChangedLocked(true);
+
+ assertEquals(numAlarms, alarmsFired.get());
+ assertEquals(0, mService.mPendingNonWakeupAlarms.size());
+ }
+
@Test
public void alarmCountOnPendingNonWakeupAlarmsRemoved() throws Exception {
final int numAlarms = 10;