summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Suprabh Shukla <suprabh@google.com> 2020-12-21 12:44:47 -0800
committer Suprabh Shukla <suprabh@google.com> 2021-01-11 12:23:38 -0800
commit17f6e2007fd1e455dd52e4ff7fa50db84f848540 (patch)
tree99be06e48627abd5723c798f28675f6dc3373239
parent5ff940635092bf4bb4675eb770c462a79b2114bd (diff)
Adding Battery saver policy to alarms
Adding a separate policy to control whether alarms are eligible to go off or not. This decouples battery saver and user applied background restriction (a.k.a. forced-app-standby) logic, which have diverged due to a lot of special exceptions in battery saver policy. This should make it easier to maintain both in the future. A side effect of this separation of logic is that any alarms that were due before battery saver was turned on but were held back due to user FAS will be delivered when the user turns off FAS, even when battery saver is on. This also has the benefit of deferring the relevant alarms before setting the kernel timer so no redundant wakeups are incurred. Also fixed a bug where adding an app to the power exemption list was not unblocking restricted alarms for that app. Test: atest CtsAlarmManagerTestCases atest FrameworksMockingServicesTests:com.android.server.alarm atest FrameworksMockingServicesTests:AppStateTrackerTest Bug: 158795479 Bug: 170279979 Change-Id: Ic05e06c2576113a82d4f39ee61b86af63c23ac02
-rw-r--r--apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java95
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java10
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java183
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java477
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java130
5 files changed, 657 insertions, 238 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index 4dc9cf850893..cc3e9c33fe42 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -274,11 +274,8 @@ public class AppStateTrackerImpl implements AppStateTracker {
int uid, @NonNull String packageName) {
updateJobsForUidPackage(uid, packageName, sender.isUidActive(uid));
- if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
+ if (!sender.areAlarmsRestricted(uid, packageName)) {
unblockAlarmsForUidPackage(uid, packageName);
- } else if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ true)) {
- // we need to deliver the allow-while-idle alarms for this uid, package
- unblockAllUnrestrictedAlarms();
}
if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) {
@@ -302,6 +299,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
final boolean isActive = sender.isUidActive(uid);
updateJobsForUid(uid, isActive);
+ updateAlarmsForUid(uid);
if (isActive) {
unblockAlarmsForUid(uid);
@@ -313,7 +311,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
*/
private void onPowerSaveUnexempted(AppStateTrackerImpl sender) {
updateAllJobs();
- unblockAllUnrestrictedAlarms();
+ updateAllAlarms();
}
/**
@@ -322,6 +320,8 @@ public class AppStateTrackerImpl implements AppStateTracker {
*/
private void onPowerSaveExemptionListChanged(AppStateTrackerImpl sender) {
updateAllJobs();
+ updateAllAlarms();
+ unblockAllUnrestrictedAlarms();
}
/**
@@ -344,7 +344,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
private void onExemptedBucketChanged(AppStateTrackerImpl sender) {
// This doesn't happen very often, so just re-evaluate all jobs / alarms.
updateAllJobs();
- unblockAllUnrestrictedAlarms();
+ updateAllAlarms();
}
/**
@@ -352,10 +352,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
*/
private void onForceAllAppsStandbyChanged(AppStateTrackerImpl sender) {
updateAllJobs();
-
- if (!sender.isForceAllAppsStandbyEnabled()) {
- unblockAllUnrestrictedAlarms();
- }
+ updateAllAlarms();
}
/**
@@ -387,6 +384,19 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
/**
+ * Called when all alarms need to be re-evaluated for eligibility based on
+ * {@link #areAlarmsRestrictedByBatterySaver}.
+ */
+ public void updateAllAlarms() {
+ }
+
+ /**
+ * Called when the given uid state changes to active / idle.
+ */
+ public void updateAlarmsForUid(int uid) {
+ }
+
+ /**
* Called when the job restrictions for multiple UIDs might have changed, so the alarm
* manager should re-evaluate all restrictions for all blocked jobs.
*/
@@ -918,7 +928,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
// Feature flag for forced app standby changed.
final boolean unblockAlarms;
synchronized (mLock) {
- unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
+ unblockAlarms = !mForcedAppStandbyEnabled;
}
for (Listener l : cloneListeners()) {
l.updateAllJobs();
@@ -1109,53 +1119,64 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
/**
- * @return whether alarms should be restricted for a UID package-name.
- */
- public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
- boolean isExemptOnBatterySaver) {
- return isRestricted(uid, packageName, /*useTempExemptionListToo=*/ false,
- isExemptOnBatterySaver);
- }
-
- /**
- * @return whether jobs should be restricted for a UID package-name.
+ * @return whether alarms should be restricted for a UID package-name, due to explicit
+ * user-forced app standby. Use {{@link #areAlarmsRestrictedByBatterySaver} to check for
+ * restrictions induced by battery saver.
*/
- public boolean areJobsRestricted(int uid, @NonNull String packageName,
- boolean hasForegroundExemption) {
- return isRestricted(uid, packageName, /*useTempExemptionListToo=*/ true,
- hasForegroundExemption);
+ public boolean areAlarmsRestricted(int uid, @NonNull String packageName) {
+ if (isUidActive(uid)) {
+ return false;
+ }
+ synchronized (mLock) {
+ final int appId = UserHandle.getAppId(uid);
+ if (ArrayUtils.contains(mPowerExemptAllAppIds, appId)) {
+ return false;
+ }
+ return (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName));
+ }
}
/**
- * @return whether foreground services should be suppressed in the background
- * due to forced app standby for the given app
+ * @return whether alarms should be restricted when due to battery saver.
*/
- public boolean areForegroundServicesRestricted(int uid, @NonNull String packageName) {
+ public boolean areAlarmsRestrictedByBatterySaver(int uid, @NonNull String packageName) {
+ if (isUidActive(uid)) {
+ return false;
+ }
synchronized (mLock) {
- return isRunAnyRestrictedLocked(uid, packageName);
+ final int appId = UserHandle.getAppId(uid);
+ if (ArrayUtils.contains(mPowerExemptAllAppIds, appId)) {
+ return false;
+ }
+ final int userId = UserHandle.getUserId(uid);
+ if (mAppStandbyInternal.isAppIdleEnabled() && !mAppStandbyInternal.isInParole()
+ && mExemptedBucketPackages.contains(userId, packageName)) {
+ return false;
+ }
+ return mForceAllAppsStandby;
}
}
+
/**
- * @return whether force-app-standby is effective for a UID package-name.
+ * @return whether jobs should be restricted for a UID package-name. This could be due to
+ * battery saver or user-forced app standby
*/
- private boolean isRestricted(int uid, @NonNull String packageName,
- boolean useTempExemptionListToo, boolean exemptOnBatterySaver) {
+ public boolean areJobsRestricted(int uid, @NonNull String packageName,
+ boolean hasForegroundExemption) {
if (isUidActive(uid)) {
return false;
}
synchronized (mLock) {
final int appId = UserHandle.getAppId(uid);
- if (ArrayUtils.contains(mPowerExemptAllAppIds, appId)) {
- return false;
- }
- if (useTempExemptionListToo && ArrayUtils.contains(mTempExemptAppIds, appId)) {
+ if (ArrayUtils.contains(mPowerExemptAllAppIds, appId)
+ || ArrayUtils.contains(mTempExemptAppIds, appId)) {
return false;
}
if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
return true;
}
- if (exemptOnBatterySaver) {
+ if (hasForegroundExemption) {
return false;
}
final int userId = UserHandle.getUserId(uid);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
index a8c0f0ec3e00..657c368d0aee 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
@@ -42,7 +42,7 @@ import java.util.Date;
*/
class Alarm {
@VisibleForTesting
- public static final int NUM_POLICIES = 3;
+ public static final int NUM_POLICIES = 4;
/**
* Index used to store the time the alarm was requested to expire. To be used with
* {@link #setPolicyElapsed(int, long)}.
@@ -59,6 +59,12 @@ class Alarm {
*/
public static final int DEVICE_IDLE_POLICY_INDEX = 2;
+ /**
+ * Index used to store the earliest time the alarm can expire based on battery saver policy.
+ * To be used with {@link #setPolicyElapsed(int, long)}.
+ */
+ public static final int BATTERY_SAVER_POLICY_INDEX = 3;
+
public final int type;
/**
* The original trigger time supplied by the caller. This can be in the elapsed or rtc time base
@@ -223,6 +229,8 @@ class Alarm {
return "app_standby";
case DEVICE_IDLE_POLICY_INDEX:
return "device_idle";
+ case BATTERY_SAVER_POLICY_INDEX:
+ return "battery_saver";
default:
return "--unknown--";
}
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 7842d487dfb2..aa46cfdc5c8a 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -28,6 +28,7 @@ import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.os.UserHandle.USER_SYSTEM;
import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX;
+import static com.android.server.alarm.Alarm.BATTERY_SAVER_POLICY_INDEX;
import static com.android.server.alarm.Alarm.DEVICE_IDLE_POLICY_INDEX;
import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX;
@@ -156,6 +157,7 @@ public class AlarmManagerService extends SystemService {
static final int TICK_HISTORY_DEPTH = 10;
static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
+ static final long INDEFINITE_DELAY = 365 * MILLIS_IN_DAY;
// Indices into the KEYS_APP_STANDBY_QUOTAS array.
static final int ACTIVE_INDEX = 0;
@@ -964,8 +966,7 @@ public class AlarmManagerService extends SystemService {
* Check all alarms in {@link #mPendingBackgroundAlarms} and send the ones that are not
* restricted.
*
- * This is only called when the global "force all apps-standby" flag changes or when the
- * power save whitelist changes, so it's okay to be slow.
+ * This is only called when the power save whitelist changes, so it's okay to be slow.
*/
void sendAllUnrestrictedPendingBackgroundAlarmsLocked() {
final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>();
@@ -984,7 +985,6 @@ public class AlarmManagerService extends SystemService {
Predicate<Alarm> isBackgroundRestricted) {
for (int uidIndex = pendingAlarms.size() - 1; uidIndex >= 0; uidIndex--) {
- final int uid = pendingAlarms.keyAt(uidIndex);
final ArrayList<Alarm> alarmsForUid = pendingAlarms.valueAt(uidIndex);
for (int alarmIndex = alarmsForUid.size() - 1; alarmIndex >= 0; alarmIndex--) {
@@ -1620,6 +1620,44 @@ public class AlarmManagerService extends SystemService {
}
/**
+ * Adjusts the delivery time of the alarm based on battery saver rules.
+ *
+ * @param alarm The alarm to adjust
+ * @return {@code true} if the alarm delivery time was updated.
+ */
+ private boolean adjustDeliveryTimeBasedOnBatterySaver(Alarm alarm) {
+ final long nowElapsed = mInjector.getElapsedRealtime();
+ if (isExemptFromBatterySaver(alarm)) {
+ return false;
+ }
+
+ if (!(mAppStateTracker != null && mAppStateTracker.areAlarmsRestrictedByBatterySaver(
+ alarm.creatorUid, alarm.sourcePackage))) {
+ return alarm.setPolicyElapsed(BATTERY_SAVER_POLICY_INDEX, nowElapsed);
+ }
+
+ final long batterSaverPolicyElapsed;
+ if ((alarm.flags & (AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED)) != 0) {
+ // Unrestricted.
+ batterSaverPolicyElapsed = nowElapsed;
+ } else if ((alarm.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) {
+ // Allowed but limited.
+ final long minDelay;
+ if (mUseAllowWhileIdleShortTime.get(alarm.creatorUid)) {
+ minDelay = mConstants.ALLOW_WHILE_IDLE_SHORT_TIME;
+ } else {
+ minDelay = mConstants.ALLOW_WHILE_IDLE_LONG_TIME;
+ }
+ final long lastDispatch = mLastAllowWhileIdleDispatch.get(alarm.creatorUid, 0);
+ batterSaverPolicyElapsed = (lastDispatch == 0) ? nowElapsed : lastDispatch + minDelay;
+ } else {
+ // Not allowed.
+ batterSaverPolicyElapsed = nowElapsed + INDEFINITE_DELAY;
+ }
+ return alarm.setPolicyElapsed(BATTERY_SAVER_POLICY_INDEX, batterSaverPolicyElapsed);
+ }
+
+ /**
* Adjusts the delivery time of the alarm based on device_idle (doze) rules.
*
* @param alarm The alarm to adjust
@@ -1756,6 +1794,7 @@ public class AlarmManagerService extends SystemService {
if (a.alarmClock != null) {
mNextAlarmClockMayChange = true;
}
+ adjustDeliveryTimeBasedOnBatterySaver(a);
adjustDeliveryTimeBasedOnBucketLocked(a);
mAlarmStore.add(a);
rescheduleKernelAlarmsLocked();
@@ -2230,14 +2269,6 @@ public class AlarmManagerService extends SystemService {
pw.print(": ");
final long lastTime = mLastAllowWhileIdleDispatch.valueAt(i);
TimeUtils.formatDuration(lastTime, nowELAPSED, pw);
-
- final long minInterval = getWhileIdleMinIntervalLocked(uid);
- pw.print(" Next allowed:");
- TimeUtils.formatDuration(lastTime + minInterval, nowELAPSED, pw);
- pw.print(" (");
- TimeUtils.formatDuration(minInterval, 0, pw);
- pw.print(")");
-
pw.println();
}
pw.decreaseIndent();
@@ -2511,8 +2542,6 @@ public class AlarmManagerService extends SystemService {
proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.UID, uid);
proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.TIME_MS,
lastTime);
- proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.NEXT_ALLOWED_MS,
- lastTime + getWhileIdleMinIntervalLocked(uid));
proto.end(token);
}
@@ -3119,30 +3148,36 @@ public class AlarmManagerService extends SystemService {
}
}
+ private boolean isExemptFromBatterySaver(Alarm alarm) {
+ if (alarm.alarmClock != null) {
+ return true;
+ }
+ if ((alarm.operation != null)
+ && (alarm.operation.isActivity() || alarm.operation.isForegroundService())) {
+ return true;
+ }
+ if (UserHandle.isCore(alarm.creatorUid)) {
+ return true;
+ }
+ return false;
+ }
+
private boolean isBackgroundRestricted(Alarm alarm) {
- boolean exemptOnBatterySaver = (alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0;
if (alarm.alarmClock != null) {
// Don't defer alarm clocks
return false;
}
- if (alarm.operation != null) {
- if (alarm.operation.isActivity()) {
- // Don't defer starting actual UI
- return false;
- }
- if (alarm.operation.isForegroundService()) {
- // FG service alarms are nearly as important; consult AST policy
- exemptOnBatterySaver = true;
- }
+ if (alarm.operation != null && alarm.operation.isActivity()) {
+ // Don't defer starting actual UI
+ return false;
}
final String sourcePackage = alarm.sourcePackage;
final int sourceUid = alarm.creatorUid;
if (UserHandle.isCore(sourceUid)) {
return false;
}
- return (mAppStateTracker != null) &&
- mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage,
- exemptOnBatterySaver);
+ return (mAppStateTracker != null) && mAppStateTracker.areAlarmsRestricted(sourceUid,
+ sourcePackage);
}
private static native long init();
@@ -3153,46 +3188,10 @@ public class AlarmManagerService extends SystemService {
private static native int setKernelTimezone(long nativeData, int minuteswest);
private static native long getNextAlarm(long nativeData, int type);
- private long getWhileIdleMinIntervalLocked(int uid) {
- final boolean ebs = (mAppStateTracker != null)
- && mAppStateTracker.isForceAllAppsStandbyEnabled();
-
- if (!ebs || mUseAllowWhileIdleShortTime.get(uid)) {
- // if the last allow-while-idle went off while uid was fg, or the uid
- // recently came into fg, don't block the alarm for long.
- return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME;
- }
- return mConstants.ALLOW_WHILE_IDLE_LONG_TIME;
- }
-
boolean triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED) {
boolean hasWakeup = false;
final ArrayList<Alarm> pendingAlarms = mAlarmStore.removePendingAlarms(nowELAPSED);
for (final Alarm alarm : pendingAlarms) {
- if ((alarm.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) {
- // If this is an ALLOW_WHILE_IDLE alarm, we constrain how frequently the app can
- // schedule such alarms. The first such alarm from an app is always delivered.
- final long lastTime = mLastAllowWhileIdleDispatch.get(alarm.creatorUid, -1);
- final long minTime = lastTime + getWhileIdleMinIntervalLocked(alarm.creatorUid);
- if (lastTime >= 0 && nowELAPSED < minTime) {
- // Whoops, it hasn't been long enough since the last ALLOW_WHILE_IDLE
- // alarm went off for this app. Reschedule the alarm to be in the
- // correct time period.
- alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, minTime);
- if (RECORD_DEVICE_IDLE_ALARMS) {
- IdleDispatchEntry ent = new IdleDispatchEntry();
- ent.uid = alarm.uid;
- ent.pkg = alarm.operation.getCreatorPackage();
- ent.tag = alarm.operation.getTag("");
- ent.op = "RESCHEDULE";
- ent.elapsedRealtime = nowELAPSED;
- ent.argRealtime = lastTime;
- mAllowWhileIdleDispatches.add(ent);
- }
- setImplLocked(alarm);
- continue;
- }
- }
if (isBackgroundRestricted(alarm)) {
// Alarms with FLAG_WAKE_FROM_IDLE or mPendingIdleUntil alarm are not deferred
if (DEBUG_BG_LIMIT) {
@@ -3924,8 +3923,41 @@ public class AlarmManagerService extends SystemService {
}
private final Listener mForceAppStandbyListener = new Listener() {
+
+ @Override
+ public void updateAllAlarms() {
+ // Called when:
+ // 1. Power exemption list changes,
+ // 2. Battery saver state is toggled,
+ // 3. Any package is moved into or out of the EXEMPTED bucket.
+ synchronized (mLock) {
+ if (mAlarmStore.updateAlarmDeliveries(
+ a -> adjustDeliveryTimeBasedOnBatterySaver(a))) {
+ rescheduleKernelAlarmsLocked();
+ }
+ }
+ }
+
+ @Override
+ public void updateAlarmsForUid(int uid) {
+ // Called when the given uid's state switches b/w active and idle.
+ synchronized (mLock) {
+ if (mAlarmStore.updateAlarmDeliveries(a -> {
+ if (a.creatorUid != uid) {
+ return false;
+ }
+ return adjustDeliveryTimeBasedOnBatterySaver(a);
+ })) {
+ rescheduleKernelAlarmsLocked();
+ }
+ }
+ }
+
@Override
public void unblockAllUnrestrictedAlarms() {
+ // Called when:
+ // 1. Power exemption list changes,
+ // 2. User FAS feature is disabled.
synchronized (mLock) {
sendAllUnrestrictedPendingBackgroundAlarmsLocked();
}
@@ -3934,12 +3966,14 @@ public class AlarmManagerService extends SystemService {
@Override
public void unblockAlarmsForUid(int uid) {
synchronized (mLock) {
+ // Called when the given uid becomes active.
sendPendingBackgroundAlarmsLocked(uid, null);
}
}
@Override
public void unblockAlarmsForUidPackage(int uid, String packageName) {
+ // Called when user turns off FAS for this (uid, package).
synchronized (mLock) {
sendPendingBackgroundAlarmsLocked(uid, packageName);
}
@@ -3950,9 +3984,14 @@ public class AlarmManagerService extends SystemService {
synchronized (mLock) {
if (foreground) {
mUseAllowWhileIdleShortTime.put(uid, true);
-
- // Note we don't have to drain the pending while-idle alarms here, because
- // this event should coincide with unblockAlarmsForUid().
+ if (mAlarmStore.updateAlarmDeliveries(a -> {
+ if (a.creatorUid != uid || (a.flags & FLAG_ALLOW_WHILE_IDLE) == 0) {
+ return false;
+ }
+ return adjustDeliveryTimeBasedOnBatterySaver(a);
+ })) {
+ rescheduleKernelAlarmsLocked();
+ }
}
}
}
@@ -4236,18 +4275,20 @@ public class AlarmManagerService extends SystemService {
if (allowWhileIdle) {
// Record the last time this uid handled an ALLOW_WHILE_IDLE alarm.
mLastAllowWhileIdleDispatch.put(alarm.creatorUid, nowELAPSED);
- mAlarmStore.updateAlarmDeliveries(a -> {
- if (a.creatorUid != alarm.creatorUid) {
- return false;
- }
- return adjustDeliveryTimeBasedOnDeviceIdle(a);
- });
if ((mAppStateTracker == null)
|| mAppStateTracker.isUidInForeground(alarm.creatorUid)) {
mUseAllowWhileIdleShortTime.put(alarm.creatorUid, true);
} else {
mUseAllowWhileIdleShortTime.put(alarm.creatorUid, false);
}
+ mAlarmStore.updateAlarmDeliveries(a -> {
+ if (a.creatorUid != alarm.creatorUid
+ || (a.flags & FLAG_ALLOW_WHILE_IDLE) == 0) {
+ return false;
+ }
+ return adjustDeliveryTimeBasedOnDeviceIdle(a)
+ | adjustDeliveryTimeBasedOnBatterySaver(a);
+ });
if (RECORD_DEVICE_IDLE_ALARMS) {
IdleDispatchEntry ent = new IdleDispatchEntry();
ent.uid = alarm.uid;
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 3220dff553d3..a691a8d44e48 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -313,29 +313,30 @@ public class AppStateTrackerTest {
}
}
- private static final int NONE = 0;
- private static final int ALARMS_ONLY = 1 << 0;
- private static final int JOBS_ONLY = 1 << 1;
- private static final int JOBS_AND_ALARMS = ALARMS_ONLY | JOBS_ONLY;
-
- private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName,
- int restrictionTypes, boolean exemptFromBatterySaver) {
- assertEquals(((restrictionTypes & JOBS_ONLY) != 0),
- instance.areJobsRestricted(uid, packageName, exemptFromBatterySaver));
- assertEquals(((restrictionTypes & ALARMS_ONLY) != 0),
- instance.areAlarmsRestricted(uid, packageName, exemptFromBatterySaver));
+ private void areJobsRestricted(AppStateTrackerTestable instance, int[] uids, String[] packages,
+ boolean[] restricted, boolean exemption) {
+ assertTrue(uids.length == packages.length && uids.length == restricted.length);
+ for (int i = 0; i < uids.length; i++) {
+ assertEquals(restricted[i],
+ instance.areJobsRestricted(uids[i], packages[i], exemption));
+ }
}
- private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName,
- int restrictionTypes) {
- areRestricted(instance, uid, packageName, restrictionTypes,
- /*exemptFromBatterySaver=*/ false);
+ private void areAlarmsRestrictedByFAS(AppStateTrackerTestable instance, int[] uids,
+ String[] packages, boolean[] restricted) {
+ assertTrue(uids.length == packages.length && uids.length == restricted.length);
+ for (int i = 0; i < uids.length; i++) {
+ assertEquals(restricted[i], instance.areAlarmsRestricted(uids[i], packages[i]));
+ }
}
- private void areRestrictedWithExemption(AppStateTrackerTestable instance,
- int uid, String packageName, int restrictionTypes) {
- areRestricted(instance, uid, packageName, restrictionTypes,
- /*exemptFromBatterySaver=*/ true);
+ private void areAlarmsRestrictedByBatterySaver(AppStateTrackerTestable instance, int[] uids,
+ String[] packages, boolean[] restricted) {
+ assertTrue(uids.length == packages.length && uids.length == restricted.length);
+ for (int i = 0; i < uids.length; i++) {
+ assertEquals(restricted[i],
+ instance.areAlarmsRestrictedByBatterySaver(uids[i], packages[i]));
+ }
}
@Test
@@ -344,30 +345,42 @@ public class AppStateTrackerTest {
callStart(instance);
assertFalse(instance.isForceAllAppsStandbyEnabled());
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, NONE);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
-
- areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
- areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
- areRestrictedWithExemption(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false},
+ true);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false});
mPowerSaveMode = true;
mPowerSaveObserver.accept(getPowerSaveState());
assertTrue(instance.isForceAllAppsStandbyEnabled());
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
-
- areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
- areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
- areRestrictedWithExemption(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false},
+ true);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, false});
// Toggle the foreground state.
- mPowerSaveMode = true;
- mPowerSaveObserver.accept(getPowerSaveState());
assertFalse(instance.isUidActive(UID_1));
assertFalse(instance.isUidActive(UID_2));
@@ -376,34 +389,65 @@ public class AppStateTrackerTest {
mIUidObserver.onUidActive(UID_1);
waitUntilMainHandlerDrain();
waitUntilMainHandlerDrain();
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, true, true, false},
+ false);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, true, true, false});
+
assertTrue(instance.isUidActive(UID_1));
assertFalse(instance.isUidActive(UID_2));
mIUidObserver.onUidGone(UID_1, /*disable=*/ false);
waitUntilMainHandlerDrain();
waitUntilMainHandlerDrain();
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, false},
+ false);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, false});
+
assertFalse(instance.isUidActive(UID_1));
assertFalse(instance.isUidActive(UID_2));
mIUidObserver.onUidActive(UID_1);
waitUntilMainHandlerDrain();
waitUntilMainHandlerDrain();
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, true, true, false},
+ false);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, true, true, false});
mIUidObserver.onUidIdle(UID_1, /*disable=*/ false);
waitUntilMainHandlerDrain();
waitUntilMainHandlerDrain();
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, false},
+ false);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, false});
+
assertFalse(instance.isUidActive(UID_1));
assertFalse(instance.isUidActive(UID_2));
@@ -416,11 +460,19 @@ public class AppStateTrackerTest {
assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, NONE);
- areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, false},
+ false);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, false});
+ areAlarmsRestrictedByFAS(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, false});
setAppOps(UID_1, PACKAGE_1, true);
setAppOps(UID_10_2, PACKAGE_2, true);
@@ -429,24 +481,72 @@ public class AppStateTrackerTest {
assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, NONE);
- areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, false, false, true, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, false, false, true, false},
+ true);
+
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, false});
+ areAlarmsRestrictedByFAS(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, false, false, true, false});
// Toggle power saver, should still be the same.
mPowerSaveMode = true;
mPowerSaveObserver.accept(getPowerSaveState());
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, true, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, false, false, true, false},
+ true);
+
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, true, false});
+ areAlarmsRestrictedByFAS(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, false, false, true, false});
+
mPowerSaveMode = false;
mPowerSaveObserver.accept(getPowerSaveState());
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, NONE);
- areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, false, false, true, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, false, false, true, false},
+ true);
+
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, false});
+ areAlarmsRestrictedByFAS(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, false, false, true, false});
// Clear the app ops and update the exemption list.
setAppOps(UID_1, PACKAGE_1, false);
@@ -455,24 +555,41 @@ public class AppStateTrackerTest {
mPowerSaveMode = true;
mPowerSaveObserver.accept(getPowerSaveState());
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, true, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, false},
+ true);
+
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, true, false});
+ areAlarmsRestrictedByFAS(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, false});
instance.setPowerSaveExemptionListAppIds(new int[] {UID_1}, new int[] {},
new int[] {UID_2});
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY);
- areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY);
- areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, UID_3, UID_10_3, Process.SYSTEM_UID},
+ new String[]{PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_3, PACKAGE_3,
+ PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, true, true, false},
+ false);
+
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, UID_3, UID_10_3, Process.SYSTEM_UID},
+ new String[]{PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_3, PACKAGE_3,
+ PACKAGE_SYSTEM},
+ new boolean[] {false, false, true, true, true, true, false});
// Again, make sure toggling the global state doesn't change it.
mPowerSaveMode = false;
@@ -481,13 +598,18 @@ public class AppStateTrackerTest {
mPowerSaveMode = true;
mPowerSaveObserver.accept(getPowerSaveState());
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY);
- areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY);
- areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, UID_3, UID_10_3, Process.SYSTEM_UID},
+ new String[]{PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_3, PACKAGE_3,
+ PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false, true, true, false},
+ false);
+
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_10_1, UID_2, UID_10_2, UID_3, UID_10_3, Process.SYSTEM_UID},
+ new String[]{PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_3, PACKAGE_3,
+ PACKAGE_SYSTEM},
+ new boolean[] {false, false, true, true, true, true, false});
assertTrue(instance.isUidPowerSaveExempt(UID_1));
assertTrue(instance.isUidPowerSaveExempt(UID_10_1));
@@ -646,52 +768,98 @@ public class AppStateTrackerTest {
}
@Test
- public void testExempt() throws Exception {
+ public void testExemptedBucket() throws Exception {
final AppStateTrackerTestable instance = newInstance();
callStart(instance);
assertFalse(instance.isForceAllAppsStandbyEnabled());
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, NONE);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false},
+ false);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false});
mPowerSaveMode = true;
mPowerSaveObserver.accept(getPowerSaveState());
assertTrue(instance.isForceAllAppsStandbyEnabled());
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {false, false, false, false},
+ true);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
+ new boolean[] {true, true, true, false});
// Exempt package 2 on user-10.
mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
-
- areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
- areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
- areRestrictedWithExemption(instance, UID_10_2, PACKAGE_2, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {true, true, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {false, false, false},
+ true);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {true, true, false});
// Exempt package 1 on user-0.
mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {false, true, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {false, false, false},
+ true);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {false, true, false});
// Unexempt package 2 on user-10.
mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
UsageStatsManager.STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE);
- areRestricted(instance, UID_1, PACKAGE_1, NONE);
- areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
- areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {false, true, true},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {false, false, false},
+ true);
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {false, true, true});
// Check force-app-standby.
// EXEMPT doesn't exempt from force-app-standby.
@@ -703,13 +871,28 @@ public class AppStateTrackerTest {
mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 0, false,
UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
+ // All 3 packages (u0:p1, u0:p2, u10:p2) are now in the exempted bucket.
setAppOps(UID_1, PACKAGE_1, true);
- areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestricted(instance, UID_2, PACKAGE_2, NONE);
-
- areRestrictedWithExemption(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
- areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {true, false, false},
+ false);
+ areJobsRestricted(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {true, false, false},
+ true);
+
+ areAlarmsRestrictedByBatterySaver(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {false, false, false});
+ areAlarmsRestrictedByFAS(instance,
+ new int[] {UID_1, UID_2, UID_10_2},
+ new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
+ new boolean[] {true, false, false});
}
@Test
@@ -809,6 +992,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -823,7 +1008,9 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
- verify(l, times(1)).unblockAllUnrestrictedAlarms();
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
+ verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
@@ -853,6 +1040,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -865,6 +1054,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(1)).unblockAlarmsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
@@ -876,15 +1067,16 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- // Unrestrict while battery saver is on. Shouldn't fire.
+ // Test overlap with battery saver
mPowerSaveMode = true;
mPowerSaveObserver.accept(getPowerSaveState());
- // Note toggling appops while BS is on will suppress unblockAlarmsForUidPackage().
setAppOps(UID_10_2, PACKAGE_2, true);
waitUntilMainHandlerDrain();
@@ -892,6 +1084,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -906,7 +1100,9 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
- verify(l, times(1)).unblockAllUnrestrictedAlarms();
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
+ verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
@@ -922,7 +1118,9 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
- verify(l, times(0)).unblockAllUnrestrictedAlarms();
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
+ verify(l, times(1)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
@@ -934,7 +1132,9 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
- verify(l, times(1)).unblockAllUnrestrictedAlarms();
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
+ verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
@@ -948,6 +1148,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -961,12 +1163,14 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- // Do the same thing with battery saver on. (Currently same callbacks are called.)
+ // Do the same thing with battery saver on.
mPowerSaveMode = true;
mPowerSaveObserver.accept(getPowerSaveState());
@@ -975,6 +1179,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -989,7 +1195,9 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
- verify(l, times(0)).unblockAllUnrestrictedAlarms();
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
+ verify(l, times(1)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
@@ -1001,7 +1209,9 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
- verify(l, times(1)).unblockAllUnrestrictedAlarms();
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
+ verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
@@ -1015,6 +1225,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -1028,6 +1240,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(anyInt());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -1037,9 +1251,8 @@ public class AppStateTrackerTest {
// -------------------------------------------------------------------------
// Tests with proc state changes.
- // With battery save.
- mPowerSaveMode = true;
- mPowerSaveObserver.accept(getPowerSaveState());
+ // With battery saver.
+ // Battery saver is already on.
mIUidObserver.onUidActive(UID_10_1);
@@ -1049,6 +1262,8 @@ public class AppStateTrackerTest {
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -1062,6 +1277,8 @@ public class AppStateTrackerTest {
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -1075,6 +1292,8 @@ public class AppStateTrackerTest {
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -1088,12 +1307,14 @@ public class AppStateTrackerTest {
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- // Without battery save.
+ // Without battery saver.
mPowerSaveMode = false;
mPowerSaveObserver.accept(getPowerSaveState());
@@ -1102,7 +1323,9 @@ public class AppStateTrackerTest {
verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
- verify(l, times(1)).unblockAllUnrestrictedAlarms();
+ verify(l, times(1)).updateAllAlarms();
+ verify(l, times(0)).updateAlarmsForUid(eq(UID_10_1));
+ verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
@@ -1115,6 +1338,8 @@ public class AppStateTrackerTest {
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -1128,6 +1353,8 @@ public class AppStateTrackerTest {
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -1141,6 +1368,8 @@ public class AppStateTrackerTest {
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
@@ -1154,6 +1383,8 @@ public class AppStateTrackerTest {
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+ verify(l, times(0)).updateAllAlarms();
+ verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
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 8edac4f8ce58..7a970a1c3d46 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -52,6 +52,7 @@ import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENE
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
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.INDEFINITE_DELAY;
import static com.android.server.alarm.AlarmManagerService.IS_WAKEUP_MASK;
import static com.android.server.alarm.AlarmManagerService.TIME_CHANGED_MASK;
import static com.android.server.alarm.AlarmManagerService.WORKING_INDEX;
@@ -71,6 +72,7 @@ import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.never;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -817,14 +819,14 @@ public class AlarmManagerServiceTest {
}
@Test
- public void testAlarmRestrictedInBatterySaver() throws Exception {
+ public void testAlarmRestrictedByFAS() throws Exception {
final ArgumentCaptor<AppStateTrackerImpl.Listener> listenerArgumentCaptor =
ArgumentCaptor.forClass(AppStateTrackerImpl.Listener.class);
verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture());
final PendingIntent alarmPi = getNewMockPendingIntent();
- when(mAppStateTracker.areAlarmsRestricted(TEST_CALLING_UID, TEST_CALLING_PACKAGE,
- false)).thenReturn(true);
+ when(mAppStateTracker.areAlarmsRestricted(TEST_CALLING_UID,
+ TEST_CALLING_PACKAGE)).thenReturn(true);
setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 2, alarmPi);
assertEquals(mNowElapsedTest + 2, mTestTimer.getElapsed());
@@ -1301,7 +1303,6 @@ public class AlarmManagerServiceTest {
final long awiDelayForTest = 23;
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_LONG_TIME, awiDelayForTest);
- setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_SHORT_TIME, 0);
setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 1000,
getNewMockPendingIntent());
@@ -1336,7 +1337,7 @@ public class AlarmManagerServiceTest {
}
@Test
- public void allowWhileIdleUnrestricted() throws Exception {
+ public void allowWhileIdleUnrestrictedInIdle() throws Exception {
doReturn(0).when(mService).fuzzForDuration(anyLong());
final long awiDelayForTest = 127;
@@ -1361,7 +1362,7 @@ public class AlarmManagerServiceTest {
}
@Test
- public void deviceIdleThrottling() throws Exception {
+ public void deviceIdleDeferralOnSet() throws Exception {
doReturn(0).when(mService).fuzzForDuration(anyLong());
final long deviceIdleUntil = mNowElapsedTest + 1234;
@@ -1386,6 +1387,123 @@ public class AlarmManagerServiceTest {
}
@Test
+ public void deviceIdleStateChanges() throws Exception {
+ doReturn(0).when(mService).fuzzForDuration(anyLong());
+
+ final int numAlarms = 10;
+ final PendingIntent[] pis = new PendingIntent[numAlarms];
+ for (int i = 0; i < numAlarms; i++) {
+ setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + i + 1,
+ pis[i] = getNewMockPendingIntent());
+ assertEquals(mNowElapsedTest + 1, mTestTimer.getElapsed());
+ }
+
+ final PendingIntent idleUntil = getNewMockPendingIntent();
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 1234, idleUntil);
+
+ assertEquals(mNowElapsedTest + 1234, mTestTimer.getElapsed());
+
+ mNowElapsedTest += 5;
+ mTestTimer.expire();
+ // Nothing should happen.
+ verify(pis[0], never()).send(eq(mMockContext), eq(0), any(Intent.class), any(),
+ any(Handler.class), isNull(), any());
+
+ mService.removeLocked(idleUntil, null);
+ mTestTimer.expire();
+ // Now, the first 5 alarms (upto i = 4) should expire.
+ for (int i = 0; i < 5; i++) {
+ verify(pis[i]).send(eq(mMockContext), eq(0), any(Intent.class), any(),
+ any(Handler.class), isNull(), any());
+ }
+ // Rest should be restored, so the timer should reflect the next alarm.
+ assertEquals(mNowElapsedTest + 1, mTestTimer.getElapsed());
+ }
+
+ @Test
+ public void batterySaverThrottling() {
+ final ArgumentCaptor<AppStateTrackerImpl.Listener> listenerArgumentCaptor =
+ ArgumentCaptor.forClass(AppStateTrackerImpl.Listener.class);
+ verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture());
+ final AppStateTrackerImpl.Listener listener = listenerArgumentCaptor.getValue();
+
+ final PendingIntent alarmPi = getNewMockPendingIntent();
+ when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
+ TEST_CALLING_PACKAGE)).thenReturn(true);
+ setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 7, alarmPi);
+ assertEquals(mNowElapsedTest + INDEFINITE_DELAY, mTestTimer.getElapsed());
+
+ when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
+ TEST_CALLING_PACKAGE)).thenReturn(false);
+ listener.updateAllAlarms();
+ assertEquals(mNowElapsedTest + 7, mTestTimer.getElapsed());
+
+ when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
+ TEST_CALLING_PACKAGE)).thenReturn(true);
+ listener.updateAlarmsForUid(TEST_CALLING_UID);
+ assertEquals(mNowElapsedTest + INDEFINITE_DELAY, mTestTimer.getElapsed());
+ }
+
+ @Test
+ public void allowWhileIdleAlarmsInBatterySaver() throws Exception {
+ final ArgumentCaptor<AppStateTrackerImpl.Listener> listenerArgumentCaptor =
+ ArgumentCaptor.forClass(AppStateTrackerImpl.Listener.class);
+ verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture());
+ final AppStateTrackerImpl.Listener listener = listenerArgumentCaptor.getValue();
+
+ final long longDelay = 23;
+ final long shortDelay = 7;
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_LONG_TIME, longDelay);
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_SHORT_TIME, shortDelay);
+
+ when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
+ TEST_CALLING_PACKAGE)).thenReturn(true);
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 1,
+ getNewMockPendingIntent(), false);
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 2,
+ getNewMockPendingIntent(), false);
+
+ assertEquals(mNowElapsedTest + 1, mTestTimer.getElapsed());
+
+ mNowElapsedTest += 1;
+ mTestTimer.expire();
+
+ assertEquals(mNowElapsedTest + longDelay, mTestTimer.getElapsed());
+ listener.onUidForeground(TEST_CALLING_UID, true);
+ // The next alarm should be deferred by shortDelay.
+ assertEquals(mNowElapsedTest + shortDelay, mTestTimer.getElapsed());
+
+ mNowElapsedTest = mTestTimer.getElapsed();
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 1,
+ getNewMockPendingIntent(), false);
+
+ when(mAppStateTracker.isUidInForeground(TEST_CALLING_UID)).thenReturn(true);
+ mTestTimer.expire();
+ // The next alarm should be deferred by shortDelay again.
+ assertEquals(mNowElapsedTest + shortDelay, mTestTimer.getElapsed());
+
+ mNowElapsedTest = mTestTimer.getElapsed();
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 1,
+ getNewMockPendingIntent(), true);
+ when(mAppStateTracker.isUidInForeground(TEST_CALLING_UID)).thenReturn(false);
+ mTestTimer.expire();
+ final long lastAwiDispatch = mNowElapsedTest;
+ // Unrestricted, so should not be changed.
+ assertEquals(mNowElapsedTest + 1, mTestTimer.getElapsed());
+
+ mNowElapsedTest = mTestTimer.getElapsed();
+ // AWI_unrestricted should not affect normal AWI bookkeeping.
+ // The next alarm is after the short delay but before the long delay.
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, lastAwiDispatch + shortDelay + 1,
+ getNewMockPendingIntent(), false);
+ mTestTimer.expire();
+ assertEquals(lastAwiDispatch + longDelay, mTestTimer.getElapsed());
+
+ listener.onUidForeground(TEST_CALLING_UID, true);
+ assertEquals(lastAwiDispatch + shortDelay + 1, mTestTimer.getElapsed());
+ }
+
+ @Test
public void dispatchOrder() throws Exception {
doReturn(0).when(mService).fuzzForDuration(anyLong());