diff options
author | Hari Raj Vijayakumar <hariraj.vijayakumar@vantiva.net> | 2023-10-22 00:53:28 +0530 |
---|---|---|
committer | Dmitri Plotnikov <dplotnikov@google.com> | 2023-11-17 10:56:02 -0800 |
commit | 3e988f0df8efa22541c94b265e08ad34ffaec43c (patch) | |
tree | cf5caeba6852ea1f65f3e5b7cda78a37aff58117 /apex | |
parent | 3a4dedd81f45e869e7b9914b2b6e78f167ea61b4 (diff) | |
download | base-3e988f0df8efa22541c94b265e08ad34ffaec43c.tar.gz |
Fix AlarmManager high CPU issue
- clampPositive assumes negative value is due to overflow and so sets
to MAX_VALUE. However it also possible that negative value occurs
due to addition of negative value(of higher magnitude) with positive
of lower magnitude. In issue case, NTP sync causes RTC to move
forward thus pushing whenElapsed to negative range. This means
maxWhenElapsed would also be negative but is clamped to MAX_VALUE
causing AlarmManager to go into infinite loop.
Bug: b/308389917
Test: manual
Change-Id: I946333b86b2658ec1b70cb1e3110f5eae1b81486
Diffstat (limited to 'apex')
-rw-r--r-- | apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java | 8 | ||||
-rw-r--r-- | apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java | 18 |
2 files changed, 19 insertions, 7 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java index a720bafee1d3..6f8014faf91a 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java @@ -22,7 +22,7 @@ import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; import static com.android.server.alarm.AlarmManagerService.PRIORITY_NORMAL; -import static com.android.server.alarm.AlarmManagerService.clampPositive; +import static com.android.server.alarm.AlarmManagerService.addClampPositive; import android.app.AlarmManager; import android.app.IAlarmListener; @@ -148,7 +148,7 @@ class Alarm { mPolicyWhenElapsed[REQUESTER_POLICY_INDEX] = requestedWhenElapsed; mWhenElapsed = requestedWhenElapsed; this.windowLength = windowLength; - mMaxWhenElapsed = clampPositive(requestedWhenElapsed + windowLength); + mMaxWhenElapsed = addClampPositive(requestedWhenElapsed, windowLength); repeatInterval = interval; operation = op; listener = rec; @@ -244,8 +244,8 @@ class Alarm { final long oldMaxWhenElapsed = mMaxWhenElapsed; // windowLength should always be >= 0 here. - final long maxRequestedElapsed = clampPositive( - mPolicyWhenElapsed[REQUESTER_POLICY_INDEX] + windowLength); + final long maxRequestedElapsed = addClampPositive( + mPolicyWhenElapsed[REQUESTER_POLICY_INDEX], windowLength); mMaxWhenElapsed = Math.max(maxRequestedElapsed, mWhenElapsed); return (oldWhenElapsed != mWhenElapsed) || (oldMaxWhenElapsed != mMaxWhenElapsed); 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 384a480af4e9..1bd8da8256c3 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -1417,15 +1417,15 @@ public class AlarmManagerService extends SystemService { if (futurity < MIN_FUZZABLE_INTERVAL) { futurity = 0; } - long maxElapsed = triggerAtTime + (long) (0.75 * futurity); + long maxElapsed = addClampPositive(triggerAtTime, (long) (0.75 * futurity)); // For non-repeating alarms, window is capped at a maximum of one hour from the requested // delivery time. This allows for inexact-while-idle alarms to be slightly more reliable. // In practice, the delivery window should generally be much smaller than that // when the device is not idling. if (interval == 0) { - maxElapsed = Math.min(maxElapsed, triggerAtTime + INTERVAL_HOUR); + maxElapsed = Math.min(maxElapsed, addClampPositive(triggerAtTime, INTERVAL_HOUR)); } - return clampPositive(maxElapsed); + return maxElapsed; } // The RTC clock has moved arbitrarily, so we need to recalculate all the RTC alarm deliveries. @@ -1512,6 +1512,18 @@ public class AlarmManagerService extends SystemService { return (val >= 0) ? val : Long.MAX_VALUE; } + static long addClampPositive(long val1, long val2) { + long val = val1 + val2; + if (val >= 0) { + return val; + } else if (val1 >= 0 && val2 >= 0) { + /* Both are +ve, so overflow happened. */ + return Long.MAX_VALUE; + } else { + return 0; + } + } + /** * Sends alarms that were blocked due to user applied background restrictions - either because * the user lifted those or the uid came to foreground. |