diff options
author | Suprabh Shukla <suprabh@google.com> | 2021-07-12 12:53:02 -0700 |
---|---|---|
committer | Suprabh Shukla <suprabh@google.com> | 2021-07-13 16:19:23 -0700 |
commit | 4e05326a55ce38e4f5ea4b2de263128c3bd05727 (patch) | |
tree | 8b5b0ec461c8989da7db7e04cf467c36d4fef6fa /apex | |
parent | 09cb5879a1feaf43d673e966914b674391dd0453 (diff) |
Separating alarm history for lower quota
Using a separate container for lower allow-while-idle quota to avoid out
of quota issues. Using the same container means that the lower quota is
out whenever higher quota is used for alarms from the same app.
Lower quota - currently once per 9 minutes - is used in the
following cases:
- Inexact allow-while-idle alarms. This means the same app can use
alarms using high quota and low quota simultaneously.
- When the caller is targeting < S.
- When the caller is in the power save allowlist, but does not have the
permission - for exact alarms.
Test: atest CtsAlarmManagerTestCases
Test: atest FrameworkMockingServicesTests:com.android.server.alarm
Bug: 190788800
Change-Id: Iba46fdd36dc04843e9256827b0754d21cfff89c9
Diffstat (limited to 'apex')
-rw-r--r-- | apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java | 33 |
1 files changed, 26 insertions, 7 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 ed80ddbd2cd7..9f529548833d 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -256,6 +256,7 @@ public class AlarmManagerService extends SystemService { AlarmHandler mHandler; AppWakeupHistory mAppWakeupHistory; AppWakeupHistory mAllowWhileIdleHistory; + AppWakeupHistory mAllowWhileIdleCompatHistory; private final SparseLongArray mLastPriorityAlarmDispatch = new SparseLongArray(); private final SparseArray<RingBuffer<RemovedAlarm>> mRemovalHistory = new SparseArray<>(); ClockReceiver mClockReceiver; @@ -1633,6 +1634,7 @@ public class AlarmManagerService extends SystemService { mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW); mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR); + mAllowWhileIdleCompatHistory = new AppWakeupHistory(INTERVAL_HOUR); mNextWakeup = mNextNonWakeup = 0; @@ -2142,20 +2144,23 @@ public class AlarmManagerService extends SystemService { final int userId = UserHandle.getUserId(alarm.creatorUid); final int quota; final long window; + final AppWakeupHistory history; if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) { quota = mConstants.ALLOW_WHILE_IDLE_QUOTA; window = mConstants.ALLOW_WHILE_IDLE_WINDOW; + history = mAllowWhileIdleHistory; } else { quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; + history = mAllowWhileIdleCompatHistory; } - final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow( + final int dispatchesInHistory = history.getTotalWakeupsInWindow( alarm.sourcePackage, userId); - if (dispatchesInWindow < quota) { + if (dispatchesInHistory < quota) { // fine to go out immediately. batterySaverPolicyElapsed = nowElapsed; } else { - batterySaverPolicyElapsed = mAllowWhileIdleHistory.getNthLastWakeupForPackage( + batterySaverPolicyElapsed = history.getNthLastWakeupForPackage( alarm.sourcePackage, userId, quota) + window; } } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) { @@ -2201,20 +2206,23 @@ public class AlarmManagerService extends SystemService { final int userId = UserHandle.getUserId(alarm.creatorUid); final int quota; final long window; + final AppWakeupHistory history; if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) { quota = mConstants.ALLOW_WHILE_IDLE_QUOTA; window = mConstants.ALLOW_WHILE_IDLE_WINDOW; + history = mAllowWhileIdleHistory; } else { quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; + history = mAllowWhileIdleCompatHistory; } - final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow( + final int dispatchesInHistory = history.getTotalWakeupsInWindow( alarm.sourcePackage, userId); - if (dispatchesInWindow < quota) { + if (dispatchesInHistory < quota) { // fine to go out immediately. deviceIdlePolicyTime = nowElapsed; } else { - final long whenInQuota = mAllowWhileIdleHistory.getNthLastWakeupForPackage( + final long whenInQuota = history.getNthLastWakeupForPackage( alarm.sourcePackage, userId, quota) + window; deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed()); } @@ -2502,6 +2510,7 @@ public class AlarmManagerService extends SystemService { Binder.getCallingPid(), callingUid, "AlarmManager.setPrioritized"); // The API doesn't allow using both together. flags &= ~FLAG_ALLOW_WHILE_IDLE; + // Prioritized alarms don't need any extra permission to be exact. } else if (exact || allowWhileIdle) { final boolean needsPermission; boolean lowerQuota; @@ -2992,6 +3001,10 @@ public class AlarmManagerService extends SystemService { mAllowWhileIdleHistory.dump(pw, nowELAPSED); pw.println(); + pw.println("Allow while idle compat history:"); + mAllowWhileIdleCompatHistory.dump(pw, nowELAPSED); + pw.println(); + if (mLastPriorityAlarmDispatch.size() > 0) { pw.println("Last priority alarm dispatches:"); pw.increaseIndent(); @@ -4553,6 +4566,7 @@ public class AlarmManagerService extends SystemService { removeUserLocked(userHandle); mAppWakeupHistory.removeForUser(userHandle); mAllowWhileIdleHistory.removeForUser(userHandle); + mAllowWhileIdleCompatHistory.removeForUser(userHandle); } return; case Intent.ACTION_UID_REMOVED: @@ -4588,6 +4602,8 @@ public class AlarmManagerService extends SystemService { // package-removed and package-restarted case mAppWakeupHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); mAllowWhileIdleHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); + mAllowWhileIdleCompatHistory.removeForPackage(pkg, + UserHandle.getUserId(uid)); removeLocked(uid, REMOVE_REASON_UNDEFINED); } else { // external-applications-unavailable case @@ -4965,7 +4981,10 @@ public class AlarmManagerService extends SystemService { if (isAllowedWhileIdleRestricted(alarm)) { // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm while the // device was in doze or battery saver. - mAllowWhileIdleHistory.recordAlarmForPackage(alarm.sourcePackage, + final AppWakeupHistory history = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) + ? mAllowWhileIdleHistory + : mAllowWhileIdleCompatHistory; + history.recordAlarmForPackage(alarm.sourcePackage, UserHandle.getUserId(alarm.creatorUid), nowELAPSED); mAlarmStore.updateAlarmDeliveries(a -> { if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) { |