Loading apex/jobscheduler/framework/java/android/app/AlarmManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,11 @@ public class AlarmManager { * scheduled as exact. Applications are strongly discouraged from using exact * alarms unnecessarily as they reduce the OS's ability to minimize battery use. * * <p> * Starting with {@link Build.VERSION_CODES#S}, apps require the * {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this * API. * * @param type type of alarm. * @param triggerAtMillis time in milliseconds that the alarm should go * off, using the appropriate clock (depending on the alarm type). Loading @@ -558,6 +563,7 @@ public class AlarmManager { * @see #RTC * @see #RTC_WAKEUP */ @RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true) public void setExact(@AlarmType int type, long triggerAtMillis, PendingIntent operation) { setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, operation, null, null, null, null, null); Loading @@ -571,7 +577,13 @@ public class AlarmManager { * The OnAlarmListener's {@link OnAlarmListener#onAlarm() onAlarm()} method will be * invoked via the specified target Handler, or on the application's main looper * if {@code null} is passed as the {@code targetHandler} parameter. * * <p> * Starting with {@link Build.VERSION_CODES#S}, apps require the * {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this * API. */ @RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true) public void setExact(@AlarmType int type, long triggerAtMillis, String tag, OnAlarmListener listener, Handler targetHandler) { setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, null, listener, tag, Loading apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +43 −38 Original line number Diff line number Diff line Loading @@ -388,6 +388,8 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting static final String KEY_MAX_INTERVAL = "max_interval"; @VisibleForTesting static final String KEY_MIN_WINDOW = "min_window"; @VisibleForTesting static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION = "allow_while_idle_whitelist_duration"; @VisibleForTesting Loading Loading @@ -428,11 +430,13 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting static final String KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW = "allow_while_idle_compat_window"; private static final String KEY_CRASH_NON_CLOCK_APPS = "crash_non_clock_apps"; @VisibleForTesting static final String KEY_CRASH_NON_CLOCK_APPS = "crash_non_clock_apps"; private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; private static final long DEFAULT_MAX_INTERVAL = 365 * INTERVAL_DAY; private static final long DEFAULT_MIN_WINDOW = 10_000; private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10 * 1000; private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000; private static final int DEFAULT_MAX_ALARMS_PER_UID = 500; Loading Loading @@ -475,6 +479,9 @@ public class AlarmManagerService extends SystemService { // Maximum alarm recurrence interval public long MAX_INTERVAL = DEFAULT_MAX_INTERVAL; // Minimum window size for inexact alarms public long MIN_WINDOW = DEFAULT_MIN_WINDOW; // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE. public long ALLOW_WHILE_IDLE_WHITELIST_DURATION = DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION; Loading Loading @@ -575,6 +582,9 @@ public class AlarmManagerService extends SystemService { ALLOW_WHILE_IDLE_QUOTA = 1; } break; case KEY_MIN_WINDOW: MIN_WINDOW = properties.getLong(KEY_MIN_WINDOW, DEFAULT_MIN_WINDOW); break; case KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA: ALLOW_WHILE_IDLE_COMPAT_QUOTA = properties.getInt( KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, Loading Loading @@ -738,6 +748,11 @@ public class AlarmManagerService extends SystemService { TimeUtils.formatDuration(MAX_INTERVAL, pw); pw.println(); pw.print(KEY_MIN_WINDOW); pw.print("="); TimeUtils.formatDuration(MIN_WINDOW, pw); pw.println(); pw.print(KEY_LISTENER_TIMEOUT); pw.print("="); TimeUtils.formatDuration(LISTENER_TIMEOUT, pw); Loading Loading @@ -1642,6 +1657,7 @@ public class AlarmManagerService extends SystemService { // Fix this window in place, so that as time approaches we don't collapse it. windowLength = maxElapsed - triggerElapsed; } else { windowLength = Math.max(windowLength, mConstants.MIN_WINDOW); maxElapsed = triggerElapsed + windowLength; } synchronized (mLock) { Loading Loading @@ -1981,8 +1997,10 @@ public class AlarmManagerService extends SystemService { * Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact, * allow-while-idle alarms. */ boolean isExemptFromPermission(int uid) { return (UserHandle.isSameApp(mSystemUiUid, uid) || mLocalDeviceIdleController == null boolean isExemptFromExactAlarmPermission(int uid) { return (UserHandle.isSameApp(mSystemUiUid, uid) || UserHandle.isCore(uid) || mLocalDeviceIdleController == null || mLocalDeviceIdleController.isAppOnWhitelist(UserHandle.getAppId(uid))); } Loading @@ -2002,54 +2020,43 @@ public class AlarmManagerService extends SystemService { mAppOps.checkPackage(callingUid, callingPackage); final boolean allowWhileIdle = (flags & FLAG_ALLOW_WHILE_IDLE) != 0; final boolean exact = (windowLength == AlarmManager.WINDOW_EXACT); Bundle idleOptions = null; if (alarmClock != null || allowWhileIdle) { // make sure the caller is allowed to use the requested kind of alarm, and also // decide what broadcast options to use. // decide what quota and broadcast options to use. Bundle idleOptions = null; if (exact || allowWhileIdle) { final boolean needsPermission; boolean lowQuota; boolean lowerQuota; if (CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, callingPackage, UserHandle.getUserHandleForUid(callingUid))) { if (windowLength != AlarmManager.WINDOW_EXACT) { needsPermission = false; lowQuota = true; idleOptions = isExemptFromPermission(callingUid) ? mOptsWithFgs.toBundle() : mOptsWithoutFgs.toBundle(); } else if (alarmClock != null) { needsPermission = true; lowQuota = false; idleOptions = mOptsWithFgs.toBundle(); } else { needsPermission = true; lowQuota = false; idleOptions = mOptsWithFgs.toBundle(); } needsPermission = exact; lowerQuota = !exact; idleOptions = exact ? mOptsWithFgs.toBundle() : mOptsWithoutFgs.toBundle(); } else { needsPermission = false; lowQuota = allowWhileIdle; lowerQuota = allowWhileIdle; idleOptions = allowWhileIdle ? mOptsWithFgs.toBundle() : null; } if (needsPermission && !canScheduleExactAlarms()) { if (alarmClock == null && isExemptFromPermission(callingUid)) { // If the app is on the full system allow-list (not except-idle), we still // allow the alarms, but with a lower quota to keep pre-S compatibility. lowQuota = true; } else { if (alarmClock != null || !isExemptFromExactAlarmPermission(callingUid)) { final String errorMessage = "Caller " + callingPackage + " needs to hold " + Manifest.permission.SCHEDULE_EXACT_ALARM + " to set " + ((allowWhileIdle) ? "exact, allow-while-idle" : "alarm-clock") + " alarms."; + "exact alarms."; if (mConstants.CRASH_NON_CLOCK_APPS) { throw new SecurityException(errorMessage); } else { Slog.wtf(TAG, errorMessage); idleOptions = mOptsWithoutFgs.toBundle(); lowQuota = allowWhileIdle; } } // If the app is on the full system power allow-list (not except-idle), or we're // in a soft failure mode, we still allow the alarms. // We give temporary allowlist to allow-while-idle alarms but without FGS // capability. Note that apps that are in the power allow-list do not need it. idleOptions = allowWhileIdle ? mOptsWithoutFgs.toBundle() : null; lowerQuota = allowWhileIdle; } if (lowQuota) { if (lowerQuota) { flags &= ~FLAG_ALLOW_WHILE_IDLE; flags |= FLAG_ALLOW_WHILE_IDLE_COMPAT; } Loading Loading @@ -2998,13 +3005,10 @@ public class AlarmManagerService extends SystemService { /** * Called when an app loses {@link Manifest.permission#SCHEDULE_EXACT_ALARM} to remove alarms * that the app is no longer eligible to use. * TODO (b/179541791): Revisit and write tests once UX is final. * TODO (b/179541791): Add revocation history to dumpsys. */ void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName) { if (UserHandle.isCore(uid) || uid == mSystemUiUid) { return; } if (isExemptFromPermission(uid)) { if (isExemptFromExactAlarmPermission(uid)) { return; } if (!CompatChanges.isChangeEnabled( Loading @@ -3015,7 +3019,7 @@ public class AlarmManagerService extends SystemService { final Predicate<Alarm> whichAlarms = a -> (a.uid == uid && a.packageName.equals(packageName) && ((a.flags & FLAG_ALLOW_WHILE_IDLE) != 0 || a.alarmClock != null)); && a.windowLength == AlarmManager.WINDOW_EXACT); final ArrayList<Alarm> removed = mAlarmStore.remove(whichAlarms); final boolean didRemove = !removed.isEmpty(); if (didRemove) { Loading Loading @@ -3873,6 +3877,7 @@ public class AlarmManagerService extends SystemService { return alarm.creatorUid; } @VisibleForTesting class AlarmHandler extends Handler { public static final int ALARM_EVENT = 1; Loading apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java +5 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,11 @@ public interface AlarmStore { */ void dumpProto(ProtoOutputStream pos, long nowElapsed); /** * @return a name for this alarm store that can be used for debugging and tests. */ String getName(); /** * A functional interface used to update the alarm. Used to describe the update in * {@link #updateAlarmDeliveries(AlarmDeliveryCalculator)} Loading apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java +9 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.StatLogger; import java.text.SimpleDateFormat; Loading @@ -40,6 +41,8 @@ import java.util.function.Predicate; * This keeps the alarms in batches, which are sorted on the start time of their delivery window. */ public class BatchingAlarmStore implements AlarmStore { @VisibleForTesting static final String TAG = BatchingAlarmStore.class.getSimpleName(); private final ArrayList<Batch> mAlarmBatches = new ArrayList<>(); private int mSize; Loading @@ -49,7 +52,7 @@ public class BatchingAlarmStore implements AlarmStore { int REBATCH_ALL_ALARMS = 0; } final StatLogger mStatLogger = new StatLogger("BatchingAlarmStore stats", new String[]{ final StatLogger mStatLogger = new StatLogger(TAG + " stats", new String[]{ "REBATCH_ALL_ALARMS", }); Loading Loading @@ -211,6 +214,11 @@ public class BatchingAlarmStore implements AlarmStore { } } @Override public String getName() { return TAG; } private void insertAndBatchAlarm(Alarm alarm) { final int whichBatch = ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) ? -1 : attemptCoalesce(alarm.getWhenElapsed(), alarm.getMaxWhenElapsed()); Loading apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java +9 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.StatLogger; import java.text.SimpleDateFormat; Loading @@ -38,6 +39,8 @@ import java.util.function.Predicate; * This keeps the alarms in a sorted list, and only batches them at the time of delivery. */ public class LazyAlarmStore implements AlarmStore { @VisibleForTesting static final String TAG = LazyAlarmStore.class.getSimpleName(); private final ArrayList<Alarm> mAlarms = new ArrayList<>(); private Runnable mOnAlarmClockRemoved; Loading @@ -47,7 +50,7 @@ public class LazyAlarmStore implements AlarmStore { int GET_NEXT_WAKEUP_DELIVERY_TIME = 1; } final StatLogger mStatLogger = new StatLogger("LazyAlarmStore stats", new String[]{ final StatLogger mStatLogger = new StatLogger(TAG + " stats", new String[]{ "GET_NEXT_DELIVERY_TIME", "GET_NEXT_WAKEUP_DELIVERY_TIME", }); Loading Loading @@ -214,4 +217,9 @@ public class LazyAlarmStore implements AlarmStore { a.dumpDebug(pos, AlarmManagerServiceDumpProto.PENDING_ALARMS, nowElapsed); } } @Override public String getName() { return TAG; } } Loading
apex/jobscheduler/framework/java/android/app/AlarmManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,11 @@ public class AlarmManager { * scheduled as exact. Applications are strongly discouraged from using exact * alarms unnecessarily as they reduce the OS's ability to minimize battery use. * * <p> * Starting with {@link Build.VERSION_CODES#S}, apps require the * {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this * API. * * @param type type of alarm. * @param triggerAtMillis time in milliseconds that the alarm should go * off, using the appropriate clock (depending on the alarm type). Loading @@ -558,6 +563,7 @@ public class AlarmManager { * @see #RTC * @see #RTC_WAKEUP */ @RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true) public void setExact(@AlarmType int type, long triggerAtMillis, PendingIntent operation) { setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, operation, null, null, null, null, null); Loading @@ -571,7 +577,13 @@ public class AlarmManager { * The OnAlarmListener's {@link OnAlarmListener#onAlarm() onAlarm()} method will be * invoked via the specified target Handler, or on the application's main looper * if {@code null} is passed as the {@code targetHandler} parameter. * * <p> * Starting with {@link Build.VERSION_CODES#S}, apps require the * {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this * API. */ @RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true) public void setExact(@AlarmType int type, long triggerAtMillis, String tag, OnAlarmListener listener, Handler targetHandler) { setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, null, listener, tag, Loading
apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +43 −38 Original line number Diff line number Diff line Loading @@ -388,6 +388,8 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting static final String KEY_MAX_INTERVAL = "max_interval"; @VisibleForTesting static final String KEY_MIN_WINDOW = "min_window"; @VisibleForTesting static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION = "allow_while_idle_whitelist_duration"; @VisibleForTesting Loading Loading @@ -428,11 +430,13 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting static final String KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW = "allow_while_idle_compat_window"; private static final String KEY_CRASH_NON_CLOCK_APPS = "crash_non_clock_apps"; @VisibleForTesting static final String KEY_CRASH_NON_CLOCK_APPS = "crash_non_clock_apps"; private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; private static final long DEFAULT_MAX_INTERVAL = 365 * INTERVAL_DAY; private static final long DEFAULT_MIN_WINDOW = 10_000; private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10 * 1000; private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000; private static final int DEFAULT_MAX_ALARMS_PER_UID = 500; Loading Loading @@ -475,6 +479,9 @@ public class AlarmManagerService extends SystemService { // Maximum alarm recurrence interval public long MAX_INTERVAL = DEFAULT_MAX_INTERVAL; // Minimum window size for inexact alarms public long MIN_WINDOW = DEFAULT_MIN_WINDOW; // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE. public long ALLOW_WHILE_IDLE_WHITELIST_DURATION = DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION; Loading Loading @@ -575,6 +582,9 @@ public class AlarmManagerService extends SystemService { ALLOW_WHILE_IDLE_QUOTA = 1; } break; case KEY_MIN_WINDOW: MIN_WINDOW = properties.getLong(KEY_MIN_WINDOW, DEFAULT_MIN_WINDOW); break; case KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA: ALLOW_WHILE_IDLE_COMPAT_QUOTA = properties.getInt( KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, Loading Loading @@ -738,6 +748,11 @@ public class AlarmManagerService extends SystemService { TimeUtils.formatDuration(MAX_INTERVAL, pw); pw.println(); pw.print(KEY_MIN_WINDOW); pw.print("="); TimeUtils.formatDuration(MIN_WINDOW, pw); pw.println(); pw.print(KEY_LISTENER_TIMEOUT); pw.print("="); TimeUtils.formatDuration(LISTENER_TIMEOUT, pw); Loading Loading @@ -1642,6 +1657,7 @@ public class AlarmManagerService extends SystemService { // Fix this window in place, so that as time approaches we don't collapse it. windowLength = maxElapsed - triggerElapsed; } else { windowLength = Math.max(windowLength, mConstants.MIN_WINDOW); maxElapsed = triggerElapsed + windowLength; } synchronized (mLock) { Loading Loading @@ -1981,8 +1997,10 @@ public class AlarmManagerService extends SystemService { * Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact, * allow-while-idle alarms. */ boolean isExemptFromPermission(int uid) { return (UserHandle.isSameApp(mSystemUiUid, uid) || mLocalDeviceIdleController == null boolean isExemptFromExactAlarmPermission(int uid) { return (UserHandle.isSameApp(mSystemUiUid, uid) || UserHandle.isCore(uid) || mLocalDeviceIdleController == null || mLocalDeviceIdleController.isAppOnWhitelist(UserHandle.getAppId(uid))); } Loading @@ -2002,54 +2020,43 @@ public class AlarmManagerService extends SystemService { mAppOps.checkPackage(callingUid, callingPackage); final boolean allowWhileIdle = (flags & FLAG_ALLOW_WHILE_IDLE) != 0; final boolean exact = (windowLength == AlarmManager.WINDOW_EXACT); Bundle idleOptions = null; if (alarmClock != null || allowWhileIdle) { // make sure the caller is allowed to use the requested kind of alarm, and also // decide what broadcast options to use. // decide what quota and broadcast options to use. Bundle idleOptions = null; if (exact || allowWhileIdle) { final boolean needsPermission; boolean lowQuota; boolean lowerQuota; if (CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, callingPackage, UserHandle.getUserHandleForUid(callingUid))) { if (windowLength != AlarmManager.WINDOW_EXACT) { needsPermission = false; lowQuota = true; idleOptions = isExemptFromPermission(callingUid) ? mOptsWithFgs.toBundle() : mOptsWithoutFgs.toBundle(); } else if (alarmClock != null) { needsPermission = true; lowQuota = false; idleOptions = mOptsWithFgs.toBundle(); } else { needsPermission = true; lowQuota = false; idleOptions = mOptsWithFgs.toBundle(); } needsPermission = exact; lowerQuota = !exact; idleOptions = exact ? mOptsWithFgs.toBundle() : mOptsWithoutFgs.toBundle(); } else { needsPermission = false; lowQuota = allowWhileIdle; lowerQuota = allowWhileIdle; idleOptions = allowWhileIdle ? mOptsWithFgs.toBundle() : null; } if (needsPermission && !canScheduleExactAlarms()) { if (alarmClock == null && isExemptFromPermission(callingUid)) { // If the app is on the full system allow-list (not except-idle), we still // allow the alarms, but with a lower quota to keep pre-S compatibility. lowQuota = true; } else { if (alarmClock != null || !isExemptFromExactAlarmPermission(callingUid)) { final String errorMessage = "Caller " + callingPackage + " needs to hold " + Manifest.permission.SCHEDULE_EXACT_ALARM + " to set " + ((allowWhileIdle) ? "exact, allow-while-idle" : "alarm-clock") + " alarms."; + "exact alarms."; if (mConstants.CRASH_NON_CLOCK_APPS) { throw new SecurityException(errorMessage); } else { Slog.wtf(TAG, errorMessage); idleOptions = mOptsWithoutFgs.toBundle(); lowQuota = allowWhileIdle; } } // If the app is on the full system power allow-list (not except-idle), or we're // in a soft failure mode, we still allow the alarms. // We give temporary allowlist to allow-while-idle alarms but without FGS // capability. Note that apps that are in the power allow-list do not need it. idleOptions = allowWhileIdle ? mOptsWithoutFgs.toBundle() : null; lowerQuota = allowWhileIdle; } if (lowQuota) { if (lowerQuota) { flags &= ~FLAG_ALLOW_WHILE_IDLE; flags |= FLAG_ALLOW_WHILE_IDLE_COMPAT; } Loading Loading @@ -2998,13 +3005,10 @@ public class AlarmManagerService extends SystemService { /** * Called when an app loses {@link Manifest.permission#SCHEDULE_EXACT_ALARM} to remove alarms * that the app is no longer eligible to use. * TODO (b/179541791): Revisit and write tests once UX is final. * TODO (b/179541791): Add revocation history to dumpsys. */ void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName) { if (UserHandle.isCore(uid) || uid == mSystemUiUid) { return; } if (isExemptFromPermission(uid)) { if (isExemptFromExactAlarmPermission(uid)) { return; } if (!CompatChanges.isChangeEnabled( Loading @@ -3015,7 +3019,7 @@ public class AlarmManagerService extends SystemService { final Predicate<Alarm> whichAlarms = a -> (a.uid == uid && a.packageName.equals(packageName) && ((a.flags & FLAG_ALLOW_WHILE_IDLE) != 0 || a.alarmClock != null)); && a.windowLength == AlarmManager.WINDOW_EXACT); final ArrayList<Alarm> removed = mAlarmStore.remove(whichAlarms); final boolean didRemove = !removed.isEmpty(); if (didRemove) { Loading Loading @@ -3873,6 +3877,7 @@ public class AlarmManagerService extends SystemService { return alarm.creatorUid; } @VisibleForTesting class AlarmHandler extends Handler { public static final int ALARM_EVENT = 1; Loading
apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java +5 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,11 @@ public interface AlarmStore { */ void dumpProto(ProtoOutputStream pos, long nowElapsed); /** * @return a name for this alarm store that can be used for debugging and tests. */ String getName(); /** * A functional interface used to update the alarm. Used to describe the update in * {@link #updateAlarmDeliveries(AlarmDeliveryCalculator)} Loading
apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java +9 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.StatLogger; import java.text.SimpleDateFormat; Loading @@ -40,6 +41,8 @@ import java.util.function.Predicate; * This keeps the alarms in batches, which are sorted on the start time of their delivery window. */ public class BatchingAlarmStore implements AlarmStore { @VisibleForTesting static final String TAG = BatchingAlarmStore.class.getSimpleName(); private final ArrayList<Batch> mAlarmBatches = new ArrayList<>(); private int mSize; Loading @@ -49,7 +52,7 @@ public class BatchingAlarmStore implements AlarmStore { int REBATCH_ALL_ALARMS = 0; } final StatLogger mStatLogger = new StatLogger("BatchingAlarmStore stats", new String[]{ final StatLogger mStatLogger = new StatLogger(TAG + " stats", new String[]{ "REBATCH_ALL_ALARMS", }); Loading Loading @@ -211,6 +214,11 @@ public class BatchingAlarmStore implements AlarmStore { } } @Override public String getName() { return TAG; } private void insertAndBatchAlarm(Alarm alarm) { final int whichBatch = ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) ? -1 : attemptCoalesce(alarm.getWhenElapsed(), alarm.getMaxWhenElapsed()); Loading
apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java +9 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.StatLogger; import java.text.SimpleDateFormat; Loading @@ -38,6 +39,8 @@ import java.util.function.Predicate; * This keeps the alarms in a sorted list, and only batches them at the time of delivery. */ public class LazyAlarmStore implements AlarmStore { @VisibleForTesting static final String TAG = LazyAlarmStore.class.getSimpleName(); private final ArrayList<Alarm> mAlarms = new ArrayList<>(); private Runnable mOnAlarmClockRemoved; Loading @@ -47,7 +50,7 @@ public class LazyAlarmStore implements AlarmStore { int GET_NEXT_WAKEUP_DELIVERY_TIME = 1; } final StatLogger mStatLogger = new StatLogger("LazyAlarmStore stats", new String[]{ final StatLogger mStatLogger = new StatLogger(TAG + " stats", new String[]{ "GET_NEXT_DELIVERY_TIME", "GET_NEXT_WAKEUP_DELIVERY_TIME", }); Loading Loading @@ -214,4 +217,9 @@ public class LazyAlarmStore implements AlarmStore { a.dumpDebug(pos, AlarmManagerServiceDumpProto.PENDING_ALARMS, nowElapsed); } } @Override public String getName() { return TAG; } }