summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommy Webb <tommy@calyxinstitute.org>2023-03-13 16:16:58 -0400
committeralk3pInjection <webmaster@raspii.tech>2023-04-20 00:08:54 +0800
commit31cbe9d5d2e39d55b46e5856eaa8a8f7a9c36919 (patch)
tree6b0eb9667af386007503a5d048a54b1d983392d0
parent6280c835c16fad823e80f7b069af97b939601ffc (diff)
JobScheduler: Respect allow-in-power-save perm
Apps like Messaging may be allowlisted to be unaffected by doze mode using the allow-in-power-save permission, but prior to this change, their jobs are still restricted from running when the device is idle, leading to delayed processing. On the other hand, jobs scheduled by packages that are user-exempted via the "Unrestricted" app battery usage option do not experience such delays. This change causes system- exempted packages to be treated the same as user-exempted packages. Issue: calyxos#1525 Bug: 223643513 Test: CtsJobSchedulerTestCases Change-Id: I6d95b3940e536e93aae4b2b48706069e964bdb99
-rw-r--r--apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java27
-rw-r--r--apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java29
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java8
-rw-r--r--core/proto/android/server/appstatetracker.proto5
6 files changed, 69 insertions, 4 deletions
diff --git a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
index caf7e7f4a4ed..7ec603de40fd 100644
--- a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
@@ -73,6 +73,8 @@ public interface DeviceIdleInternal {
boolean isAppOnWhitelist(int appid);
+ int[] getPowerSaveWhitelistSystemAppIds();
+
int[] getPowerSaveWhitelistUserAppIds();
int[] getPowerSaveTempWhitelistAppIds();
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index fab5b5fd6933..606f0df0dfda 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -109,6 +109,12 @@ public class AppStateTrackerImpl implements AppStateTracker {
final SparseBooleanArray mActiveUids = new SparseBooleanArray();
/**
+ * System exemption list in the device idle controller.
+ */
+ @GuardedBy("mLock")
+ private int[] mPowerExemptSystemAppIds = new int[0];
+
+ /**
* System except-idle + user exemption list in the device idle controller.
*/
@GuardedBy("mLock")
@@ -1075,6 +1081,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
* Called by device idle controller to update the power save exemption lists.
*/
public void setPowerSaveExemptionListAppIds(
+ int[] powerSaveExemptionListSystemAppIdArray,
int[] powerSaveExemptionListExceptIdleAppIdArray,
int[] powerSaveExemptionListUserAppIdArray,
int[] tempExemptionListAppIdArray) {
@@ -1082,6 +1089,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
final int[] previousExemptionList = mPowerExemptAllAppIds;
final int[] previousTempExemptionList = mTempExemptAppIds;
+ mPowerExemptSystemAppIds = powerSaveExemptionListSystemAppIdArray;
mPowerExemptAllAppIds = powerSaveExemptionListExceptIdleAppIdArray;
mTempExemptAppIds = tempExemptionListAppIdArray;
mPowerExemptUserAppIds = powerSaveExemptionListUserAppIdArray;
@@ -1302,6 +1310,18 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
/**
+ * @return whether or not a UID is in either the user defined power-save exemption list or the
+ system full exemption list (not including except-idle)
+ */
+ public boolean isUidPowerSaveIdleExempt(int uid) {
+ final int appId = UserHandle.getAppId(uid);
+ synchronized (mLock) {
+ return ArrayUtils.contains(mPowerExemptUserAppIds, appId)
+ || ArrayUtils.contains(mPowerExemptSystemAppIds, appId);
+ }
+ }
+
+ /**
* @return whether a UID is in the temp power-save exemption list or not.
*
* Note clients normally shouldn't need to access it. It's only for dumpsys.
@@ -1338,6 +1358,9 @@ public class AppStateTrackerImpl implements AppStateTracker {
pw.print("Active uids: ");
dumpUids(pw, mActiveUids);
+ pw.print("System exemption list appids: ");
+ pw.println(Arrays.toString(mPowerExemptSystemAppIds));
+
pw.print("Except-idle + user exemption list appids: ");
pw.println(Arrays.toString(mPowerExemptAllAppIds));
@@ -1415,6 +1438,10 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
}
+ for (int appId : mPowerExemptSystemAppIds) {
+ proto.write(AppStateTrackerProto.POWER_SAVE_SYSTEM_EXEMPT_APP_IDS, appId);
+ }
+
for (int appId : mPowerExemptAllAppIds) {
proto.write(AppStateTrackerProto.POWER_SAVE_EXEMPT_APP_IDS, appId);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 40d1b4c9b267..40a51bd3470a 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -563,6 +563,12 @@ public class DeviceIdleController extends SystemService
private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
/**
+ * Current system app IDs that are in the complete power save white list. This array can
+ * be shared with others because it will not be modified once set.
+ */
+ private int[] mPowerSaveWhitelistSystemAppIdArray = new int[0];
+
+ /**
* App IDs that have been white-listed to opt out of power save restrictions, except
* for device idle modes.
*/
@@ -2089,6 +2095,11 @@ public class DeviceIdleController extends SystemService
return DeviceIdleController.this.isAppOnWhitelistInternal(appid);
}
+ @Override
+ public int[] getPowerSaveWhitelistSystemAppIds() {
+ return DeviceIdleController.this.getPowerSaveSystemWhitelistAppIds();
+ }
+
/**
* Returns the array of app ids whitelisted by user. Take care not to
* modify this, as it is a reference to the original copy. But the reference
@@ -2271,6 +2282,12 @@ public class DeviceIdleController extends SystemService
}
}
+ int[] getPowerSaveSystemWhitelistAppIds() {
+ synchronized (this) {
+ return mPowerSaveWhitelistSystemAppIdArray;
+ }
+ }
+
int[] getPowerSaveWhitelistUserAppIds() {
synchronized (this) {
return mPowerSaveWhitelistUserAppIdArray;
@@ -2281,6 +2298,16 @@ public class DeviceIdleController extends SystemService
return new File(Environment.getDataDirectory(), "system");
}
+ /** Returns the keys of a SparseBooleanArray, paying no attention to its values. */
+ private static int[] keysToIntArray(final SparseBooleanArray sparseArray) {
+ final int size = sparseArray.size();
+ final int[] array = new int[size];
+ for (int i = 0; i < size; i++) {
+ array[i] = sparseArray.keyAt(i);
+ }
+ return array;
+ }
+
@Override
public void onStart() {
final PackageManager pm = getContext().getPackageManager();
@@ -2317,6 +2344,7 @@ public class DeviceIdleController extends SystemService
} catch (PackageManager.NameNotFoundException e) {
}
}
+ mPowerSaveWhitelistSystemAppIdArray = keysToIntArray(mPowerSaveWhitelistSystemAppIds);
mConstants = mInjector.getConstants(this);
@@ -4222,6 +4250,7 @@ public class DeviceIdleController extends SystemService
private void passWhiteListsToForceAppStandbyTrackerLocked() {
mAppStateTracker.setPowerSaveExemptionListAppIds(
+ mPowerSaveWhitelistSystemAppIdArray,
mPowerSaveWhitelistExceptIdleAppIdArray,
mPowerSaveWhitelistUserAppIdArray,
mTempWhitelistAppIdArray);
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 37ce0d29d0e1..a65e86d888de 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -2861,7 +2861,7 @@ public class AlarmManagerService extends SystemService {
} else if (workSource == null && (UserHandle.isCore(callingUid)
|| UserHandle.isSameApp(callingUid, mSystemUiUid)
|| ((mAppStateTracker != null)
- && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) {
+ && mAppStateTracker.isUidPowerSaveIdleExempt(callingUid)))) {
flags |= FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
flags &= ~(FLAG_ALLOW_WHILE_IDLE | FLAG_PRIORITIZE);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
index abbe177c5d49..01f0b30cc48a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -74,6 +74,7 @@ public final class DeviceIdleJobsController extends StateController {
* True when in device idle mode, so we don't want to schedule any jobs.
*/
private boolean mDeviceIdleMode;
+ private int[] mPowerSaveWhitelistSystemAppIds;
private int[] mDeviceIdleWhitelistAppIds;
private int[] mPowerSaveTempWhitelistAppIds;
@@ -133,6 +134,8 @@ public final class DeviceIdleJobsController extends StateController {
mLocalDeviceIdleController =
LocalServices.getService(DeviceIdleInternal.class);
mDeviceIdleWhitelistAppIds = mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
+ mPowerSaveWhitelistSystemAppIds =
+ mLocalDeviceIdleController.getPowerSaveWhitelistSystemAppIds();
mPowerSaveTempWhitelistAppIds =
mLocalDeviceIdleController.getPowerSaveTempWhitelistAppIds();
mDeviceIdleUpdateFunctor = new DeviceIdleUpdateFunctor();
@@ -196,8 +199,9 @@ public final class DeviceIdleJobsController extends StateController {
* Checks if the given job's scheduling app id exists in the device idle user whitelist.
*/
boolean isWhitelistedLocked(JobStatus job) {
- return Arrays.binarySearch(mDeviceIdleWhitelistAppIds,
- UserHandle.getAppId(job.getSourceUid())) >= 0;
+ final int appId = UserHandle.getAppId(job.getSourceUid());
+ return Arrays.binarySearch(mDeviceIdleWhitelistAppIds, appId) >= 0
+ || Arrays.binarySearch(mPowerSaveWhitelistSystemAppIds, appId) >= 0;
}
/**
diff --git a/core/proto/android/server/appstatetracker.proto b/core/proto/android/server/appstatetracker.proto
index f5583d4f476f..0d0fb097d963 100644
--- a/core/proto/android/server/appstatetracker.proto
+++ b/core/proto/android/server/appstatetracker.proto
@@ -25,7 +25,7 @@ option java_multiple_files = true;
// Dump from com.android.server.AppStateTracker.
//
-// Next ID: 14
+// Next ID: 15
message AppStateTrackerProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -41,6 +41,9 @@ message AppStateTrackerProto {
// UIDs currently in the foreground.
repeated int32 foreground_uids = 11;
+ // App ids that are in power-save system exemption list.
+ repeated int32 power_save_system_exempt_app_ids = 14;
+
// App ids that are in power-save exemption list.
repeated int32 power_save_exempt_app_ids = 3;