From 8be77a14ab4e9a63e52c672bdfc3d2e8f9907eca Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Tue, 13 Sep 2022 20:43:32 +0000 Subject: [PATCH] Fix long comparison overflow issue in AlarmQueue. Bug: 247097209 Test: atest FrameworksMockingServicesTests:AlarmQueueTest Change-Id: Ib3fd31ca7dc37c18499052d8d4f03814568c11c2 Merged-In: I8e07157fef57f6047414e9c8b46da0dac91c6714 --- .../com/android/server/utils/AlarmQueue.java | 6 +++++- .../android/server/utils/AlarmQueueTest.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/utils/AlarmQueue.java b/services/core/java/com/android/server/utils/AlarmQueue.java index 3f4def6d60ab7..c9bfc8d74ecd4 100644 --- a/services/core/java/com/android/server/utils/AlarmQueue.java +++ b/services/core/java/com/android/server/utils/AlarmQueue.java @@ -34,6 +34,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import java.util.Comparator; import java.util.PriorityQueue; import java.util.function.Predicate; @@ -58,8 +59,11 @@ public abstract class AlarmQueue implements AlarmManager.OnAlarmListener { * The pair is the key and its associated alarm time (in the elapsed realtime timebase). */ private static class AlarmPriorityQueue extends PriorityQueue> { + private static final Comparator> sTimeComparator = + (o1, o2) -> Long.compare(o1.second, o2.second); + AlarmPriorityQueue() { - super(1, (o1, o2) -> (int) (o1.second - o2.second)); + super(1, sTimeComparator); } /** diff --git a/services/tests/mockingservicestests/src/com/android/server/utils/AlarmQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/utils/AlarmQueueTest.java index 849e6730ac116..00d7541a79dcf 100644 --- a/services/tests/mockingservicestests/src/com/android/server/utils/AlarmQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/utils/AlarmQueueTest.java @@ -155,6 +155,27 @@ public class AlarmQueueTest { anyInt(), eq(nowElapsed + HOUR_IN_MILLIS), eq(ALARM_TAG), any(), any()); } + @Test + public void testAddingLargeAlarmTimes() { + final AlarmQueue alarmQueue = createAlarmQueue(true, 0); + final long nowElapsed = mInjector.getElapsedRealtime(); + + InOrder inOrder = inOrder(mAlarmManager); + + alarmQueue.addAlarm("com.android.test.1", Long.MAX_VALUE - 5); + inOrder.verify(mAlarmManager, timeout(1000).times(1)) + .setExact(anyInt(), eq(Long.MAX_VALUE - 5), eq(ALARM_TAG), any(), any()); + alarmQueue.addAlarm("com.android.test.2", Long.MAX_VALUE - 4); + inOrder.verify(mAlarmManager, never()) + .setExact(anyInt(), anyLong(), eq(ALARM_TAG), any(), any()); + alarmQueue.addAlarm("com.android.test.3", nowElapsed + 5); + inOrder.verify(mAlarmManager, timeout(1000).times(1)) + .setExact(anyInt(), eq(nowElapsed + 5), eq(ALARM_TAG), any(), any()); + alarmQueue.addAlarm("com.android.test.4", nowElapsed + 6); + inOrder.verify(mAlarmManager, never()) + .setExact(anyInt(), anyLong(), eq(ALARM_TAG), any(), any()); + } + /** * Verify that updating the alarm time for a key will result in the AlarmManager alarm changing, * if needed.