Merge "Add a way to disable non-wakeup alarm deferral."

This commit is contained in:
TreeHugger Robot
2022-09-16 18:06:04 +00:00
committed by Android (Google) Code Review
4 changed files with 53 additions and 3 deletions

View File

@@ -676,6 +676,9 @@ public class AlarmManagerService extends SystemService {
private static final String KEY_TIME_TICK_ALLOWED_WHILE_IDLE =
"time_tick_allowed_while_idle";
private static final String KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF =
"delay_nonwakeup_alarms_while_screen_off";
@VisibleForTesting
static final String KEY_ALLOW_WHILE_IDLE_QUOTA = "allow_while_idle_quota";
@@ -743,6 +746,8 @@ public class AlarmManagerService extends SystemService {
private static final int DEFAULT_TEMPORARY_QUOTA_BUMP = 0;
private static final boolean DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = true;
// Minimum futurity of a new alarm
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
@@ -835,6 +840,9 @@ public class AlarmManagerService extends SystemService {
*/
public int TEMPORARY_QUOTA_BUMP = DEFAULT_TEMPORARY_QUOTA_BUMP;
public boolean DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF =
DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF;
private long mLastAllowWhileIdleWhitelistDuration = -1;
private int mVersion = 0;
@@ -1011,6 +1019,11 @@ public class AlarmManagerService extends SystemService {
TEMPORARY_QUOTA_BUMP = properties.getInt(KEY_TEMPORARY_QUOTA_BUMP,
DEFAULT_TEMPORARY_QUOTA_BUMP);
break;
case KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF:
DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = properties.getBoolean(
KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF,
DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);
break;
default:
if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
// The quotas need to be updated in order, so we can't just rely
@@ -1249,6 +1262,10 @@ public class AlarmManagerService extends SystemService {
pw.print(KEY_TEMPORARY_QUOTA_BUMP, TEMPORARY_QUOTA_BUMP);
pw.println();
pw.print(KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF,
DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);
pw.println();
pw.decreaseIndent();
}
@@ -4360,7 +4377,11 @@ public class AlarmManagerService extends SystemService {
}
}
@GuardedBy("mLock")
boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) {
if (!mConstants.DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF) {
return false;
}
if (mInteractive) {
return false;
}

View File

@@ -644,7 +644,7 @@ public final class FlexibilityController extends StateController {
static final String KEY_FALLBACK_FLEXIBILITY_DEADLINE =
FC_CONFIG_PREFIX + "fallback_flexibility_deadline_ms";
static final String KEY_MIN_TIME_BETWEEN_FLEXIBILITY_ALARMS_MS =
FC_CONFIG_PREFIX + "min_alarm_time_flexibility_ms";
FC_CONFIG_PREFIX + "min_time_between_flexibility_alarms_ms";
static final String KEY_PERCENTS_TO_DROP_NUM_FLEXIBLE_CONSTRAINTS =
FC_CONFIG_PREFIX + "percents_to_drop_num_flexible_constraints";
static final String KEY_MAX_RESCHEDULED_DEADLINE_MS =

View File

@@ -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;
@@ -52,6 +53,11 @@ public abstract class AlarmQueue<K> implements AlarmManager.OnAlarmListener {
private static final boolean DEBUG = false;
private static final long NOT_SCHEDULED = -1;
/**
* The threshold used to consider a new trigger time to be significantly different from the
* currently used trigger time.
*/
private static final long SIGNIFICANT_TRIGGER_TIME_CHANGE_THRESHOLD_MS = MINUTE_IN_MILLIS;
/**
* Internal priority queue for each key's alarm, ordered by the time the alarm should go off.
@@ -59,7 +65,7 @@ public abstract class AlarmQueue<K> implements AlarmManager.OnAlarmListener {
*/
private static class AlarmPriorityQueue<Q> extends PriorityQueue<Pair<Q, Long>> {
AlarmPriorityQueue() {
super(1, (o1, o2) -> (int) (o1.second - o2.second));
super(1, Comparator.comparingLong(o -> o.second));
}
/**
@@ -306,8 +312,10 @@ public abstract class AlarmQueue<K> implements AlarmManager.OnAlarmListener {
// earlier but not significantly so, then we essentially delay the check for some
// apps by up to a minute.
// 3. The alarm is after the current alarm.
final long timeShiftThresholdMs =
Math.min(SIGNIFICANT_TRIGGER_TIME_CHANGE_THRESHOLD_MS, mMinTimeBetweenAlarmsMs);
if (mTriggerTimeElapsed == NOT_SCHEDULED
|| nextTriggerTimeElapsed < mTriggerTimeElapsed - MINUTE_IN_MILLIS
|| nextTriggerTimeElapsed < mTriggerTimeElapsed - timeShiftThresholdMs
|| mTriggerTimeElapsed < nextTriggerTimeElapsed) {
if (DEBUG) {
Slog.d(TAG, "Scheduling alarm at " + nextTriggerTimeElapsed

View File

@@ -155,6 +155,27 @@ public class AlarmQueueTest {
anyInt(), eq(nowElapsed + HOUR_IN_MILLIS), eq(ALARM_TAG), any(), any());
}
@Test
public void testAddingLargeAlarmTimes() {
final AlarmQueue<String> 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.