summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java132
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java79
2 files changed, 144 insertions, 67 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 0e362759ef4c..64686a1682f0 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -151,10 +151,10 @@ import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
-import java.util.Random;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeSet;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Predicate;
/**
@@ -251,7 +251,6 @@ public class AlarmManagerService extends SystemService {
Intent mTimeTickIntent;
IAlarmListener mTimeTickTrigger;
PendingIntent mDateChangeSender;
- Random mRandom;
boolean mInteractive = true;
long mNonInteractiveStartTime;
long mNonInteractiveTime;
@@ -516,6 +515,10 @@ public class AlarmManagerService extends SystemService {
static final String KEY_PRIORITY_ALARM_DELAY = "priority_alarm_delay";
@VisibleForTesting
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_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_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
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;
/**
- * Set of apps that won't get SCHEDULE_EXACT_ALARM when the app-op mode for
- * OP_SCHEDULE_EXACT_ALARM is MODE_DEFAULT.
+ * 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. Since this is read-only and volatile, this can
+ * be accessed without synchronizing on {@link #mLock}.
+ */
+ 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 Set<String> EXACT_ALARM_DENY_LIST = Collections.emptySet();
+ public long MAX_DEVICE_IDLE_FUZZ = DEFAULT_MAX_DEVICE_IDLE_FUZZ;
private long mLastAllowWhileIdleWhitelistDuration = -1;
private int mVersion = 0;
@@ -660,6 +679,7 @@ public class AlarmManagerService extends SystemService {
@Override
public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
boolean standbyQuotaUpdated = false;
+ boolean deviceIdleFuzzBoundariesUpdated = false;
synchronized (mLock) {
mVersion++;
for (String name : properties.getKeyset()) {
@@ -787,6 +807,13 @@ public class AlarmManagerService extends SystemService {
updateExactAlarmDenyList(values);
}
break;
+ case KEY_MIN_DEVICE_IDLE_FUZZ:
+ case KEY_MAX_DEVICE_IDLE_FUZZ:
+ if (!deviceIdleFuzzBoundariesUpdated) {
+ updateDeviceIdleFuzzBoundaries();
+ deviceIdleFuzzBoundariesUpdated = true;
+ }
+ break;
default:
if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
// 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);
}
+ 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() {
// 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.
@@ -1133,12 +1178,8 @@ public class AlarmManagerService extends SystemService {
if (mNextWakeFromIdle != null && isRtc(mNextWakeFromIdle.type)) {
// 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.
- final boolean idleUntilUpdated = mAlarmStore.updateAlarmDeliveries(a -> {
- if (a != mPendingIdleUntil) {
- return false;
- }
- return adjustIdleUntilTime(a);
- });
+ final boolean idleUntilUpdated = mAlarmStore.updateAlarmDeliveries(
+ a -> (a == mPendingIdleUntil) && adjustIdleUntilTime(a));
if (idleUntilUpdated) {
mAlarmStore.updateAlarmDeliveries(
alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm));
@@ -1911,23 +1952,30 @@ public class AlarmManagerService extends SystemService {
if ((alarm.flags & AlarmManager.FLAG_IDLE_UNTIL) == 0) {
return false;
}
- restoreRequestedTime(alarm);
- long triggerBeforeFuzz = alarm.getRequestedElapsed();
- if (mNextWakeFromIdle != null && triggerBeforeFuzz > mNextWakeFromIdle.getWhenElapsed()) {
- triggerBeforeFuzz = mNextWakeFromIdle.getWhenElapsed();
+ final boolean changedBeforeFuzz = restoreRequestedTime(alarm);
+ if (mNextWakeFromIdle == null) {
+ // No need to change anything in the absence of a wake-from-idle request.
+ return changedBeforeFuzz;
}
- // Add fuzz to make the alarm go off some time before the actual desired time.
- final int fuzz = fuzzForDuration(alarm.getWhenElapsed() - mInjector.getElapsedRealtime());
- final int delta;
- if (fuzz > 0) {
- if (mRandom == null) {
- mRandom = new Random();
- }
- delta = mRandom.nextInt(fuzz);
+ final long upcomingWakeFromIdle = mNextWakeFromIdle.getWhenElapsed();
+ // Add fuzz to make the alarm go off some time before the next upcoming wake-from-idle, as
+ // these alarms are usually wall-clock aligned.
+ if (alarm.getWhenElapsed() < (upcomingWakeFromIdle - mConstants.MIN_DEVICE_IDLE_FUZZ)) {
+ // No need to fuzz as this is already earlier than the coming wake-from-idle.
+ return changedBeforeFuzz;
+ }
+ 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 {
- 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;
}
@@ -2130,12 +2178,8 @@ public class AlarmManagerService extends SystemService {
// 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.
if (mPendingIdleUntil != null) {
- final boolean updated = mAlarmStore.updateAlarmDeliveries(alarm -> {
- if (alarm != mPendingIdleUntil) {
- return false;
- }
- return adjustIdleUntilTime(alarm);
- });
+ final boolean updated = mAlarmStore.updateAlarmDeliveries(
+ alarm -> (alarm == mPendingIdleUntil) && adjustIdleUntilTime(alarm));
if (updated) {
// idle-until got updated, so also update all alarms not allowed while idle.
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) {
if (mInteractive) {
return false;
@@ -4698,8 +4728,10 @@ public class AlarmManagerService extends SystemService {
if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) {
return false;
}
- return (doze && adjustDeliveryTimeBasedOnDeviceIdle(a))
- || (batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a));
+ final boolean dozeAdjusted = doze && adjustDeliveryTimeBasedOnDeviceIdle(a);
+ final boolean batterySaverAdjusted =
+ batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a);
+ return dozeAdjusted || batterySaverAdjusted;
});
} else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
mLastPriorityAlarmDispatch.put(alarm.creatorUid, nowELAPSED);
@@ -4708,8 +4740,10 @@ public class AlarmManagerService extends SystemService {
|| (alarm.flags & FLAG_PRIORITIZE) == 0) {
return false;
}
- return (doze && adjustDeliveryTimeBasedOnDeviceIdle(a))
- || (batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a));
+ final boolean dozeAdjusted = doze && adjustDeliveryTimeBasedOnDeviceIdle(a);
+ final boolean batterySaverAdjusted =
+ batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a);
+ return dozeAdjusted || batterySaverAdjusted;
});
}
if (RECORD_DEVICE_IDLE_ALARMS) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 64dad7f0feab..8382ff4cb506 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -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_LAZY_BATCHING;
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_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_INTERVAL;
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_MIN_WINDOW, 50);
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(10, mService.mConstants.MIN_INTERVAL);
assertEquals(15, mService.mConstants.MAX_INTERVAL);
@@ -665,6 +669,8 @@ public class AlarmManagerServiceTest {
assertEquals(45, mService.mConstants.LISTENER_TIMEOUT);
assertEquals(50, mService.mConstants.MIN_WINDOW);
assertEquals(55, mService.mConstants.PRIORITY_ALARM_DELAY);
+ assertEquals(60, mService.mConstants.MIN_DEVICE_IDLE_FUZZ);
+ assertEquals(65, mService.mConstants.MAX_DEVICE_IDLE_FUZZ);
}
@Test
@@ -737,6 +743,20 @@ public class AlarmManagerServiceTest {
}
@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
public void testMinFuturity() {
setDeviceConfigLong(KEY_MIN_FUTURITY, 10L);
assertEquals(10, mService.mConstants.MIN_FUTURITY);
@@ -1431,7 +1451,7 @@ public class AlarmManagerServiceTest {
@Test
public void singleIdleUntil() {
- doReturn(0).when(mService).fuzzForDuration(anyLong());
+ setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
final PendingIntent idleUntilPi6 = getNewMockPendingIntent();
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, idleUntilPi6);
@@ -1504,44 +1524,67 @@ public class AlarmManagerServiceTest {
assertNull(mService.mNextWakeFromIdle);
}
+ private static void assertInRange(String message, long minIncl, long maxIncl, long val) {
+ assertTrue(message, val >= minIncl && val <= maxIncl);
+ }
+
@Test
- public void idleUntilBeforeWakeFromIdle() {
- doReturn(0).when(mService).fuzzForDuration(anyLong());
+ public void idleUntilFuzzedBeforeWakeFromIdle() {
+ 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 long requestedIdleUntil = mNowElapsedTest + 10;
+ final long requestedIdleUntil = mNowElapsedTest + 12;
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, requestedIdleUntil, idleUntilPi);
assertEquals(requestedIdleUntil, mService.mPendingIdleUntil.getWhenElapsed());
final PendingIntent wakeFromIdle5 = getNewMockPendingIntent();
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();
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();
- setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 12, wakeFromIdle12);
- assertEquals(mNowElapsedTest + 5, mService.mPendingIdleUntil.getWhenElapsed());
+ final PendingIntent wakeFromIdle19 = getNewMockPendingIntent();
+ setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 19, wakeFromIdle19);
+ // Next wake from idle is still the same.
+ assertEquals(mNowElapsedTest, mService.mPendingIdleUntil.getWhenElapsed());
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);
+ // 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());
mService.removeLocked(idleUntilPi, null, REMOVE_REASON_UNDEFINED);
assertNull(mService.mPendingIdleUntil);
- setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 15, idleUntilPi);
- assertEquals(mNowElapsedTest + 12, mService.mPendingIdleUntil.getWhenElapsed());
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 21, idleUntilPi);
+ // 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
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,
getNewMockPendingIntent());
@@ -1571,7 +1614,7 @@ public class AlarmManagerServiceTest {
@Test
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.
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 1000,
@@ -1597,7 +1640,7 @@ public class AlarmManagerServiceTest {
@Test
public void deviceIdleDeferralOnSet() throws Exception {
- doReturn(0).when(mService).fuzzForDuration(anyLong());
+ setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
final long deviceIdleUntil = mNowElapsedTest + 1234;
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, deviceIdleUntil, getNewMockPendingIntent());
@@ -1622,7 +1665,7 @@ public class AlarmManagerServiceTest {
@Test
public void deviceIdleStateChanges() throws Exception {
- doReturn(0).when(mService).fuzzForDuration(anyLong());
+ setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
final int numAlarms = 10;
final PendingIntent[] pis = new PendingIntent[numAlarms];
@@ -1740,7 +1783,7 @@ public class AlarmManagerServiceTest {
@Test
public void prioritizedAlarmsInDeviceIdle() throws Exception {
- doReturn(0).when(mService).fuzzForDuration(anyLong());
+ setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
final long minDelay = 5;
setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, minDelay);
@@ -1791,7 +1834,7 @@ public class AlarmManagerServiceTest {
@Test
public void dispatchOrder() throws Exception {
- doReturn(0).when(mService).fuzzForDuration(anyLong());
+ setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
final long deviceIdleUntil = mNowElapsedTest + 1234;
final PendingIntent idleUntilPi = getNewMockPendingIntent();