Merge changes Ia8c656a0,I01f98255 into sc-dev
* changes: Change device-idle alarm fuzzing Hold wakeup alarms for as long as possible
This commit is contained in:
committed by
Android (Google) Code Review
commit
a94c55f2f4
@@ -151,10 +151,10 @@ import java.util.Comparator;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -251,7 +251,6 @@ public class AlarmManagerService extends SystemService {
|
|||||||
Intent mTimeTickIntent;
|
Intent mTimeTickIntent;
|
||||||
IAlarmListener mTimeTickTrigger;
|
IAlarmListener mTimeTickTrigger;
|
||||||
PendingIntent mDateChangeSender;
|
PendingIntent mDateChangeSender;
|
||||||
Random mRandom;
|
|
||||||
boolean mInteractive = true;
|
boolean mInteractive = true;
|
||||||
long mNonInteractiveStartTime;
|
long mNonInteractiveStartTime;
|
||||||
long mNonInteractiveTime;
|
long mNonInteractiveTime;
|
||||||
@@ -516,6 +515,10 @@ public class AlarmManagerService extends SystemService {
|
|||||||
static final String KEY_PRIORITY_ALARM_DELAY = "priority_alarm_delay";
|
static final String KEY_PRIORITY_ALARM_DELAY = "priority_alarm_delay";
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String KEY_EXACT_ALARM_DENY_LIST = "exact_alarm_deny_list";
|
static final String KEY_EXACT_ALARM_DENY_LIST = "exact_alarm_deny_list";
|
||||||
|
@VisibleForTesting
|
||||||
|
static final String KEY_MIN_DEVICE_IDLE_FUZZ = "min_device_idle_fuzz";
|
||||||
|
@VisibleForTesting
|
||||||
|
static final String KEY_MAX_DEVICE_IDLE_FUZZ = "max_device_idle_fuzz";
|
||||||
|
|
||||||
private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
|
private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
|
||||||
private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
|
private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
|
||||||
@@ -556,6 +559,9 @@ public class AlarmManagerService extends SystemService {
|
|||||||
|
|
||||||
private static final long DEFAULT_PRIORITY_ALARM_DELAY = 9 * 60_000;
|
private static final long DEFAULT_PRIORITY_ALARM_DELAY = 9 * 60_000;
|
||||||
|
|
||||||
|
private static final long DEFAULT_MIN_DEVICE_IDLE_FUZZ = 2 * 60_000;
|
||||||
|
private static final long DEFAULT_MAX_DEVICE_IDLE_FUZZ = 15 * 60_000;
|
||||||
|
|
||||||
// Minimum futurity of a new alarm
|
// Minimum futurity of a new alarm
|
||||||
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
|
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
|
||||||
|
|
||||||
@@ -618,10 +624,23 @@ public class AlarmManagerService extends SystemService {
|
|||||||
public long PRIORITY_ALARM_DELAY = DEFAULT_PRIORITY_ALARM_DELAY;
|
public long PRIORITY_ALARM_DELAY = DEFAULT_PRIORITY_ALARM_DELAY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of apps that won't get SCHEDULE_EXACT_ALARM when the app-op mode for
|
* Read-only set of apps that won't get SCHEDULE_EXACT_ALARM when the app-op mode for
|
||||||
* OP_SCHEDULE_EXACT_ALARM is MODE_DEFAULT.
|
* OP_SCHEDULE_EXACT_ALARM is MODE_DEFAULT. Since this is read-only and volatile, this can
|
||||||
|
* be accessed without synchronizing on {@link #mLock}.
|
||||||
*/
|
*/
|
||||||
public Set<String> EXACT_ALARM_DENY_LIST = Collections.emptySet();
|
public volatile Set<String> EXACT_ALARM_DENY_LIST = Collections.emptySet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum time interval that an IDLE_UNTIL will be pulled earlier to a subsequent
|
||||||
|
* WAKE_FROM_IDLE alarm.
|
||||||
|
*/
|
||||||
|
public long MIN_DEVICE_IDLE_FUZZ = DEFAULT_MIN_DEVICE_IDLE_FUZZ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum time interval that an IDLE_UNTIL will be pulled earlier to a subsequent
|
||||||
|
* WAKE_FROM_IDLE alarm.
|
||||||
|
*/
|
||||||
|
public long MAX_DEVICE_IDLE_FUZZ = DEFAULT_MAX_DEVICE_IDLE_FUZZ;
|
||||||
|
|
||||||
private long mLastAllowWhileIdleWhitelistDuration = -1;
|
private long mLastAllowWhileIdleWhitelistDuration = -1;
|
||||||
private int mVersion = 0;
|
private int mVersion = 0;
|
||||||
@@ -660,6 +679,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
@Override
|
@Override
|
||||||
public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
|
public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
|
||||||
boolean standbyQuotaUpdated = false;
|
boolean standbyQuotaUpdated = false;
|
||||||
|
boolean deviceIdleFuzzBoundariesUpdated = false;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mVersion++;
|
mVersion++;
|
||||||
for (String name : properties.getKeyset()) {
|
for (String name : properties.getKeyset()) {
|
||||||
@@ -787,6 +807,13 @@ public class AlarmManagerService extends SystemService {
|
|||||||
updateExactAlarmDenyList(values);
|
updateExactAlarmDenyList(values);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case KEY_MIN_DEVICE_IDLE_FUZZ:
|
||||||
|
case KEY_MAX_DEVICE_IDLE_FUZZ:
|
||||||
|
if (!deviceIdleFuzzBoundariesUpdated) {
|
||||||
|
updateDeviceIdleFuzzBoundaries();
|
||||||
|
deviceIdleFuzzBoundariesUpdated = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
|
if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
|
||||||
// The quotas need to be updated in order, so we can't just rely
|
// The quotas need to be updated in order, so we can't just rely
|
||||||
@@ -824,6 +851,24 @@ public class AlarmManagerService extends SystemService {
|
|||||||
mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
|
mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateDeviceIdleFuzzBoundaries() {
|
||||||
|
final DeviceConfig.Properties properties = DeviceConfig.getProperties(
|
||||||
|
DeviceConfig.NAMESPACE_ALARM_MANAGER,
|
||||||
|
KEY_MIN_DEVICE_IDLE_FUZZ, KEY_MAX_DEVICE_IDLE_FUZZ);
|
||||||
|
|
||||||
|
MIN_DEVICE_IDLE_FUZZ = properties.getLong(KEY_MIN_DEVICE_IDLE_FUZZ,
|
||||||
|
DEFAULT_MIN_DEVICE_IDLE_FUZZ);
|
||||||
|
MAX_DEVICE_IDLE_FUZZ = properties.getLong(KEY_MAX_DEVICE_IDLE_FUZZ,
|
||||||
|
DEFAULT_MAX_DEVICE_IDLE_FUZZ);
|
||||||
|
|
||||||
|
if (MAX_DEVICE_IDLE_FUZZ < MIN_DEVICE_IDLE_FUZZ) {
|
||||||
|
Slog.w(TAG, "max_device_idle_fuzz cannot be smaller than"
|
||||||
|
+ " min_device_idle_fuzz! Increasing to "
|
||||||
|
+ MIN_DEVICE_IDLE_FUZZ);
|
||||||
|
MAX_DEVICE_IDLE_FUZZ = MIN_DEVICE_IDLE_FUZZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateStandbyQuotasLocked() {
|
private void updateStandbyQuotasLocked() {
|
||||||
// The bucket quotas need to be read as an atomic unit but the properties passed to
|
// The bucket quotas need to be read as an atomic unit but the properties passed to
|
||||||
// onPropertiesChanged may only have one key populated at a time.
|
// onPropertiesChanged may only have one key populated at a time.
|
||||||
@@ -1133,12 +1178,8 @@ public class AlarmManagerService extends SystemService {
|
|||||||
if (mNextWakeFromIdle != null && isRtc(mNextWakeFromIdle.type)) {
|
if (mNextWakeFromIdle != null && isRtc(mNextWakeFromIdle.type)) {
|
||||||
// The next wake from idle got updated due to the rtc time change, so we need
|
// The next wake from idle got updated due to the rtc time change, so we need
|
||||||
// to update the time we have to come out of idle too.
|
// to update the time we have to come out of idle too.
|
||||||
final boolean idleUntilUpdated = mAlarmStore.updateAlarmDeliveries(a -> {
|
final boolean idleUntilUpdated = mAlarmStore.updateAlarmDeliveries(
|
||||||
if (a != mPendingIdleUntil) {
|
a -> (a == mPendingIdleUntil) && adjustIdleUntilTime(a));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return adjustIdleUntilTime(a);
|
|
||||||
});
|
|
||||||
if (idleUntilUpdated) {
|
if (idleUntilUpdated) {
|
||||||
mAlarmStore.updateAlarmDeliveries(
|
mAlarmStore.updateAlarmDeliveries(
|
||||||
alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm));
|
alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm));
|
||||||
@@ -1911,23 +1952,30 @@ public class AlarmManagerService extends SystemService {
|
|||||||
if ((alarm.flags & AlarmManager.FLAG_IDLE_UNTIL) == 0) {
|
if ((alarm.flags & AlarmManager.FLAG_IDLE_UNTIL) == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
restoreRequestedTime(alarm);
|
final boolean changedBeforeFuzz = restoreRequestedTime(alarm);
|
||||||
long triggerBeforeFuzz = alarm.getRequestedElapsed();
|
if (mNextWakeFromIdle == null) {
|
||||||
if (mNextWakeFromIdle != null && triggerBeforeFuzz > mNextWakeFromIdle.getWhenElapsed()) {
|
// No need to change anything in the absence of a wake-from-idle request.
|
||||||
triggerBeforeFuzz = mNextWakeFromIdle.getWhenElapsed();
|
return changedBeforeFuzz;
|
||||||
}
|
}
|
||||||
// Add fuzz to make the alarm go off some time before the actual desired time.
|
final long upcomingWakeFromIdle = mNextWakeFromIdle.getWhenElapsed();
|
||||||
final int fuzz = fuzzForDuration(alarm.getWhenElapsed() - mInjector.getElapsedRealtime());
|
// Add fuzz to make the alarm go off some time before the next upcoming wake-from-idle, as
|
||||||
final int delta;
|
// these alarms are usually wall-clock aligned.
|
||||||
if (fuzz > 0) {
|
if (alarm.getWhenElapsed() < (upcomingWakeFromIdle - mConstants.MIN_DEVICE_IDLE_FUZZ)) {
|
||||||
if (mRandom == null) {
|
// No need to fuzz as this is already earlier than the coming wake-from-idle.
|
||||||
mRandom = new Random();
|
return changedBeforeFuzz;
|
||||||
}
|
}
|
||||||
delta = mRandom.nextInt(fuzz);
|
final long nowElapsed = mInjector.getElapsedRealtime();
|
||||||
|
final long futurity = upcomingWakeFromIdle - nowElapsed;
|
||||||
|
|
||||||
|
if (futurity <= mConstants.MIN_DEVICE_IDLE_FUZZ) {
|
||||||
|
// No point in fuzzing as the minimum fuzz will take the time in the past.
|
||||||
|
alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, nowElapsed);
|
||||||
} else {
|
} else {
|
||||||
delta = 0;
|
final ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||||
|
final long upperBoundExcl = Math.min(mConstants.MAX_DEVICE_IDLE_FUZZ, futurity) + 1;
|
||||||
|
final long fuzz = random.nextLong(mConstants.MIN_DEVICE_IDLE_FUZZ, upperBoundExcl);
|
||||||
|
alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, upcomingWakeFromIdle - fuzz);
|
||||||
}
|
}
|
||||||
alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, triggerBeforeFuzz - delta);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2130,12 +2178,8 @@ public class AlarmManagerService extends SystemService {
|
|||||||
// If this wake from idle is earlier than whatever was previously scheduled,
|
// If this wake from idle is earlier than whatever was previously scheduled,
|
||||||
// and we are currently idling, then the idle-until time needs to be updated.
|
// and we are currently idling, then the idle-until time needs to be updated.
|
||||||
if (mPendingIdleUntil != null) {
|
if (mPendingIdleUntil != null) {
|
||||||
final boolean updated = mAlarmStore.updateAlarmDeliveries(alarm -> {
|
final boolean updated = mAlarmStore.updateAlarmDeliveries(
|
||||||
if (alarm != mPendingIdleUntil) {
|
alarm -> (alarm == mPendingIdleUntil) && adjustIdleUntilTime(alarm));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return adjustIdleUntilTime(alarm);
|
|
||||||
});
|
|
||||||
if (updated) {
|
if (updated) {
|
||||||
// idle-until got updated, so also update all alarms not allowed while idle.
|
// idle-until got updated, so also update all alarms not allowed while idle.
|
||||||
mAlarmStore.updateAlarmDeliveries(
|
mAlarmStore.updateAlarmDeliveries(
|
||||||
@@ -3675,20 +3719,6 @@ public class AlarmManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int fuzzForDuration(long duration) {
|
|
||||||
if (duration < 15 * 60 * 1000) {
|
|
||||||
// If the duration until the time is less than 15 minutes, the maximum fuzz
|
|
||||||
// is the duration.
|
|
||||||
return (int) duration;
|
|
||||||
} else if (duration < 90 * 60 * 1000) {
|
|
||||||
// If duration is less than 1 1/2 hours, the maximum fuzz is 15 minutes,
|
|
||||||
return 15 * 60 * 1000;
|
|
||||||
} else {
|
|
||||||
// Otherwise, we will fuzz by at most half an hour.
|
|
||||||
return 30 * 60 * 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) {
|
boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) {
|
||||||
if (mInteractive) {
|
if (mInteractive) {
|
||||||
return false;
|
return false;
|
||||||
@@ -4698,8 +4728,10 @@ public class AlarmManagerService extends SystemService {
|
|||||||
if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) {
|
if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (doze && adjustDeliveryTimeBasedOnDeviceIdle(a))
|
final boolean dozeAdjusted = doze && adjustDeliveryTimeBasedOnDeviceIdle(a);
|
||||||
|| (batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a));
|
final boolean batterySaverAdjusted =
|
||||||
|
batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a);
|
||||||
|
return dozeAdjusted || batterySaverAdjusted;
|
||||||
});
|
});
|
||||||
} else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
|
} else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
|
||||||
mLastPriorityAlarmDispatch.put(alarm.creatorUid, nowELAPSED);
|
mLastPriorityAlarmDispatch.put(alarm.creatorUid, nowELAPSED);
|
||||||
@@ -4708,8 +4740,10 @@ public class AlarmManagerService extends SystemService {
|
|||||||
|| (alarm.flags & FLAG_PRIORITIZE) == 0) {
|
|| (alarm.flags & FLAG_PRIORITIZE) == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (doze && adjustDeliveryTimeBasedOnDeviceIdle(a))
|
final boolean dozeAdjusted = doze && adjustDeliveryTimeBasedOnDeviceIdle(a);
|
||||||
|| (batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a));
|
final boolean batterySaverAdjusted =
|
||||||
|
batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a);
|
||||||
|
return dozeAdjusted || batterySaverAdjusted;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (RECORD_DEVICE_IDLE_ALARMS) {
|
if (RECORD_DEVICE_IDLE_ALARMS) {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import java.util.function.Predicate;
|
|||||||
public class LazyAlarmStore implements AlarmStore {
|
public class LazyAlarmStore implements AlarmStore {
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String TAG = LazyAlarmStore.class.getSimpleName();
|
static final String TAG = LazyAlarmStore.class.getSimpleName();
|
||||||
|
private static final long ALARM_DEADLINE_SLOP = 500;
|
||||||
|
|
||||||
private final ArrayList<Alarm> mAlarms = new ArrayList<>();
|
private final ArrayList<Alarm> mAlarms = new ArrayList<>();
|
||||||
private Runnable mOnAlarmClockRemoved;
|
private Runnable mOnAlarmClockRemoved;
|
||||||
@@ -75,7 +76,7 @@ public class LazyAlarmStore implements AlarmStore {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAlarms.addAll(alarms);
|
mAlarms.addAll(alarms);
|
||||||
Collections.sort(alarms, sDecreasingTimeOrder);
|
Collections.sort(mAlarms, sDecreasingTimeOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -163,25 +164,47 @@ public class LazyAlarmStore implements AlarmStore {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayList<Alarm> removePendingAlarms(long nowElapsed) {
|
public ArrayList<Alarm> removePendingAlarms(long nowElapsed) {
|
||||||
final ArrayList<Alarm> pending = new ArrayList<>();
|
final ArrayList<Alarm> pending = new ArrayList<>();
|
||||||
final ArrayList<Alarm> standAlones = new ArrayList<>();
|
|
||||||
|
// Only send wake-up alarms if this is the absolutely latest time we can evaluate
|
||||||
|
// for at least one wakeup alarm. This prevents sending other non-wakeup alarms when the
|
||||||
|
// screen is off but the CPU is awake for some reason.
|
||||||
|
boolean sendWakeups = false;
|
||||||
|
|
||||||
|
// If any alarm with FLAG_STANDALONE is present, we cannot send any alarms without that flag
|
||||||
|
// in the present batch.
|
||||||
|
boolean standalonesOnly = false;
|
||||||
|
|
||||||
for (int i = mAlarms.size() - 1; i >= 0; i--) {
|
for (int i = mAlarms.size() - 1; i >= 0; i--) {
|
||||||
final Alarm alarm = mAlarms.get(i);
|
final Alarm alarm = mAlarms.get(i);
|
||||||
if (alarm.getWhenElapsed() > nowElapsed) {
|
if (alarm.getWhenElapsed() > nowElapsed) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
mAlarms.remove(i);
|
||||||
pending.add(alarm);
|
pending.add(alarm);
|
||||||
|
if (alarm.wakeup && alarm.getMaxWhenElapsed() <= nowElapsed + ALARM_DEADLINE_SLOP) {
|
||||||
|
// Using some slop as it is better to send the wakeup alarm now, rather than
|
||||||
|
// waking up again a short time later, just to send it.
|
||||||
|
sendWakeups = true;
|
||||||
|
}
|
||||||
if ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) {
|
if ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) {
|
||||||
standAlones.add(alarm);
|
standalonesOnly = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!standAlones.isEmpty()) {
|
final ArrayList<Alarm> toSend = new ArrayList<>();
|
||||||
// If there are deliverable standalone alarms, others must not go out yet.
|
for (int i = pending.size() - 1; i >= 0; i--) {
|
||||||
mAlarms.removeAll(standAlones);
|
final Alarm pendingAlarm = pending.get(i);
|
||||||
return standAlones;
|
if (!sendWakeups && pendingAlarm.wakeup) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (standalonesOnly && (pendingAlarm.flags & AlarmManager.FLAG_STANDALONE) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pending.remove(i);
|
||||||
|
toSend.add(pendingAlarm);
|
||||||
}
|
}
|
||||||
mAlarms.removeAll(pending);
|
// Perhaps some alarms could not be sent right now. Adding them back for later.
|
||||||
return pending;
|
addAll(pending);
|
||||||
|
return toSend;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ import static com.android.server.alarm.AlarmManagerService.Constants.KEY_CRASH_N
|
|||||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_EXACT_ALARM_DENY_LIST;
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_EXACT_ALARM_DENY_LIST;
|
||||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LAZY_BATCHING;
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LAZY_BATCHING;
|
||||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
|
||||||
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_DEVICE_IDLE_FUZZ;
|
||||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
|
||||||
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_DEVICE_IDLE_FUZZ;
|
||||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_FUTURITY;
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_FUTURITY;
|
||||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_INTERVAL;
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_INTERVAL;
|
||||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_WINDOW;
|
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_WINDOW;
|
||||||
@@ -654,6 +656,8 @@ public class AlarmManagerServiceTest {
|
|||||||
setDeviceConfigLong(KEY_LISTENER_TIMEOUT, 45);
|
setDeviceConfigLong(KEY_LISTENER_TIMEOUT, 45);
|
||||||
setDeviceConfigLong(KEY_MIN_WINDOW, 50);
|
setDeviceConfigLong(KEY_MIN_WINDOW, 50);
|
||||||
setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, 55);
|
setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, 55);
|
||||||
|
setDeviceConfigLong(KEY_MIN_DEVICE_IDLE_FUZZ, 60);
|
||||||
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 65);
|
||||||
assertEquals(5, mService.mConstants.MIN_FUTURITY);
|
assertEquals(5, mService.mConstants.MIN_FUTURITY);
|
||||||
assertEquals(10, mService.mConstants.MIN_INTERVAL);
|
assertEquals(10, mService.mConstants.MIN_INTERVAL);
|
||||||
assertEquals(15, mService.mConstants.MAX_INTERVAL);
|
assertEquals(15, mService.mConstants.MAX_INTERVAL);
|
||||||
@@ -665,6 +669,8 @@ public class AlarmManagerServiceTest {
|
|||||||
assertEquals(45, mService.mConstants.LISTENER_TIMEOUT);
|
assertEquals(45, mService.mConstants.LISTENER_TIMEOUT);
|
||||||
assertEquals(50, mService.mConstants.MIN_WINDOW);
|
assertEquals(50, mService.mConstants.MIN_WINDOW);
|
||||||
assertEquals(55, mService.mConstants.PRIORITY_ALARM_DELAY);
|
assertEquals(55, mService.mConstants.PRIORITY_ALARM_DELAY);
|
||||||
|
assertEquals(60, mService.mConstants.MIN_DEVICE_IDLE_FUZZ);
|
||||||
|
assertEquals(65, mService.mConstants.MAX_DEVICE_IDLE_FUZZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -736,6 +742,20 @@ public class AlarmManagerServiceTest {
|
|||||||
mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW);
|
mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deviceIdleFuzzRangeNonNegative() {
|
||||||
|
final long newMinFuzz = mService.mConstants.MAX_DEVICE_IDLE_FUZZ + 1542;
|
||||||
|
final long newMaxFuzz = mService.mConstants.MIN_DEVICE_IDLE_FUZZ - 131;
|
||||||
|
|
||||||
|
setDeviceConfigLong(KEY_MIN_DEVICE_IDLE_FUZZ, newMinFuzz);
|
||||||
|
assertTrue("Negative device-idle fuzz range", mService.mConstants.MAX_DEVICE_IDLE_FUZZ
|
||||||
|
>= mService.mConstants.MIN_DEVICE_IDLE_FUZZ);
|
||||||
|
|
||||||
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, newMaxFuzz);
|
||||||
|
assertTrue("Negative device-idle fuzz range", mService.mConstants.MAX_DEVICE_IDLE_FUZZ
|
||||||
|
>= mService.mConstants.MIN_DEVICE_IDLE_FUZZ);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMinFuturity() {
|
public void testMinFuturity() {
|
||||||
setDeviceConfigLong(KEY_MIN_FUTURITY, 10L);
|
setDeviceConfigLong(KEY_MIN_FUTURITY, 10L);
|
||||||
@@ -1431,7 +1451,7 @@ public class AlarmManagerServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void singleIdleUntil() {
|
public void singleIdleUntil() {
|
||||||
doReturn(0).when(mService).fuzzForDuration(anyLong());
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
|
||||||
|
|
||||||
final PendingIntent idleUntilPi6 = getNewMockPendingIntent();
|
final PendingIntent idleUntilPi6 = getNewMockPendingIntent();
|
||||||
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, idleUntilPi6);
|
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, idleUntilPi6);
|
||||||
@@ -1504,44 +1524,67 @@ public class AlarmManagerServiceTest {
|
|||||||
assertNull(mService.mNextWakeFromIdle);
|
assertNull(mService.mNextWakeFromIdle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void assertInRange(String message, long minIncl, long maxIncl, long val) {
|
||||||
|
assertTrue(message, val >= minIncl && val <= maxIncl);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void idleUntilBeforeWakeFromIdle() {
|
public void idleUntilFuzzedBeforeWakeFromIdle() {
|
||||||
doReturn(0).when(mService).fuzzForDuration(anyLong());
|
final long minFuzz = 6;
|
||||||
|
final long maxFuzz = 17;
|
||||||
|
setDeviceConfigLong(KEY_MIN_DEVICE_IDLE_FUZZ, minFuzz);
|
||||||
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, maxFuzz);
|
||||||
|
|
||||||
|
mNowElapsedTest = 119; // Arbitrary, just to ensure we are not testing on 0.
|
||||||
|
|
||||||
final PendingIntent idleUntilPi = getNewMockPendingIntent();
|
final PendingIntent idleUntilPi = getNewMockPendingIntent();
|
||||||
final long requestedIdleUntil = mNowElapsedTest + 10;
|
final long requestedIdleUntil = mNowElapsedTest + 12;
|
||||||
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, requestedIdleUntil, idleUntilPi);
|
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, requestedIdleUntil, idleUntilPi);
|
||||||
|
|
||||||
assertEquals(requestedIdleUntil, mService.mPendingIdleUntil.getWhenElapsed());
|
assertEquals(requestedIdleUntil, mService.mPendingIdleUntil.getWhenElapsed());
|
||||||
|
|
||||||
final PendingIntent wakeFromIdle5 = getNewMockPendingIntent();
|
final PendingIntent wakeFromIdle5 = getNewMockPendingIntent();
|
||||||
setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, wakeFromIdle5);
|
setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, wakeFromIdle5);
|
||||||
assertEquals(mNowElapsedTest + 5, mService.mPendingIdleUntil.getWhenElapsed());
|
// Anything before now, gets snapped to now. It is not necessary for it to fire
|
||||||
|
// immediately, just how it is implemented today for simplicity.
|
||||||
|
assertEquals(mNowElapsedTest, mService.mPendingIdleUntil.getWhenElapsed());
|
||||||
|
|
||||||
final PendingIntent wakeFromIdle8 = getNewMockPendingIntent();
|
final PendingIntent wakeFromIdle8 = getNewMockPendingIntent();
|
||||||
setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 8, wakeFromIdle8);
|
setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 8, wakeFromIdle8);
|
||||||
assertEquals(mNowElapsedTest + 5, mService.mPendingIdleUntil.getWhenElapsed());
|
// Next wake from idle is still the same.
|
||||||
|
assertEquals(mNowElapsedTest, mService.mPendingIdleUntil.getWhenElapsed());
|
||||||
|
|
||||||
final PendingIntent wakeFromIdle12 = getNewMockPendingIntent();
|
final PendingIntent wakeFromIdle19 = getNewMockPendingIntent();
|
||||||
setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 12, wakeFromIdle12);
|
setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 19, wakeFromIdle19);
|
||||||
assertEquals(mNowElapsedTest + 5, mService.mPendingIdleUntil.getWhenElapsed());
|
// Next wake from idle is still the same.
|
||||||
|
assertEquals(mNowElapsedTest, mService.mPendingIdleUntil.getWhenElapsed());
|
||||||
|
|
||||||
mService.removeLocked(wakeFromIdle5, null, REMOVE_REASON_UNDEFINED);
|
mService.removeLocked(wakeFromIdle5, null, REMOVE_REASON_UNDEFINED);
|
||||||
assertEquals(mNowElapsedTest + 8, mService.mPendingIdleUntil.getWhenElapsed());
|
// Next wake from idle is at now + 8.
|
||||||
|
long min = mNowElapsedTest;
|
||||||
|
long max = mNowElapsedTest + 8 - minFuzz;
|
||||||
|
assertInRange("Idle until alarm time not in expected range [" + min + ", " + max + "]",
|
||||||
|
min, max, mService.mPendingIdleUntil.getWhenElapsed());
|
||||||
|
|
||||||
mService.removeLocked(wakeFromIdle8, null, REMOVE_REASON_UNDEFINED);
|
mService.removeLocked(wakeFromIdle8, null, REMOVE_REASON_UNDEFINED);
|
||||||
|
// Next wake from idle is at now + 19, which is > minFuzz distance from
|
||||||
|
// the requested idle until time: now + 12.
|
||||||
assertEquals(requestedIdleUntil, mService.mPendingIdleUntil.getWhenElapsed());
|
assertEquals(requestedIdleUntil, mService.mPendingIdleUntil.getWhenElapsed());
|
||||||
|
|
||||||
mService.removeLocked(idleUntilPi, null, REMOVE_REASON_UNDEFINED);
|
mService.removeLocked(idleUntilPi, null, REMOVE_REASON_UNDEFINED);
|
||||||
assertNull(mService.mPendingIdleUntil);
|
assertNull(mService.mPendingIdleUntil);
|
||||||
|
|
||||||
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 15, idleUntilPi);
|
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 21, idleUntilPi);
|
||||||
assertEquals(mNowElapsedTest + 12, mService.mPendingIdleUntil.getWhenElapsed());
|
// Next wake from idle is at now + 19, which means this alarm should get pulled back.
|
||||||
|
min = mNowElapsedTest + 19 - maxFuzz;
|
||||||
|
max = mNowElapsedTest + 19 - minFuzz;
|
||||||
|
assertInRange("Idle until alarm time not in expected range [" + min + ", " + max + "]",
|
||||||
|
min, max, mService.mPendingIdleUntil.getWhenElapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void allowWhileIdleAlarmsWhileDeviceIdle() throws Exception {
|
public void allowWhileIdleAlarmsWhileDeviceIdle() throws Exception {
|
||||||
doReturn(0).when(mService).fuzzForDuration(anyLong());
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
|
||||||
|
|
||||||
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + mAllowWhileIdleWindow + 1000,
|
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + mAllowWhileIdleWindow + 1000,
|
||||||
getNewMockPendingIntent());
|
getNewMockPendingIntent());
|
||||||
@@ -1571,7 +1614,7 @@ public class AlarmManagerServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void allowWhileIdleUnrestricted() throws Exception {
|
public void allowWhileIdleUnrestricted() throws Exception {
|
||||||
doReturn(0).when(mService).fuzzForDuration(anyLong());
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
|
||||||
|
|
||||||
// Both battery saver and doze are on.
|
// Both battery saver and doze are on.
|
||||||
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 1000,
|
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 1000,
|
||||||
@@ -1597,7 +1640,7 @@ public class AlarmManagerServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deviceIdleDeferralOnSet() throws Exception {
|
public void deviceIdleDeferralOnSet() throws Exception {
|
||||||
doReturn(0).when(mService).fuzzForDuration(anyLong());
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
|
||||||
|
|
||||||
final long deviceIdleUntil = mNowElapsedTest + 1234;
|
final long deviceIdleUntil = mNowElapsedTest + 1234;
|
||||||
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, deviceIdleUntil, getNewMockPendingIntent());
|
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, deviceIdleUntil, getNewMockPendingIntent());
|
||||||
@@ -1622,7 +1665,7 @@ public class AlarmManagerServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deviceIdleStateChanges() throws Exception {
|
public void deviceIdleStateChanges() throws Exception {
|
||||||
doReturn(0).when(mService).fuzzForDuration(anyLong());
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
|
||||||
|
|
||||||
final int numAlarms = 10;
|
final int numAlarms = 10;
|
||||||
final PendingIntent[] pis = new PendingIntent[numAlarms];
|
final PendingIntent[] pis = new PendingIntent[numAlarms];
|
||||||
@@ -1740,7 +1783,7 @@ public class AlarmManagerServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void prioritizedAlarmsInDeviceIdle() throws Exception {
|
public void prioritizedAlarmsInDeviceIdle() throws Exception {
|
||||||
doReturn(0).when(mService).fuzzForDuration(anyLong());
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
|
||||||
|
|
||||||
final long minDelay = 5;
|
final long minDelay = 5;
|
||||||
setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, minDelay);
|
setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, minDelay);
|
||||||
@@ -1791,7 +1834,7 @@ public class AlarmManagerServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void dispatchOrder() throws Exception {
|
public void dispatchOrder() throws Exception {
|
||||||
doReturn(0).when(mService).fuzzForDuration(anyLong());
|
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
|
||||||
|
|
||||||
final long deviceIdleUntil = mNowElapsedTest + 1234;
|
final long deviceIdleUntil = mNowElapsedTest + 1234;
|
||||||
final PendingIntent idleUntilPi = getNewMockPendingIntent();
|
final PendingIntent idleUntilPi = getNewMockPendingIntent();
|
||||||
|
|||||||
Reference in New Issue
Block a user