
- 18.1: Fix exempted background tasks when dozing (GrapheneOS) - 20.0: pick a fix for some colors after qpr2 - 20.0: fix the missing notification backdrop Signed-off-by: Tad <tad@spotco.us>
130 lines
7.1 KiB
Diff
130 lines
7.1 KiB
Diff
From 4f12bdfdda5cd0d538790c05ee784e5fb5e1e2fb Mon Sep 17 00:00:00 2001
|
|
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
|
|
Date: Thu, 7 Jul 2022 09:28:40 +0300
|
|
Subject: [PATCH] DeviceIdleJobsController: don't ignore whitelisted system
|
|
apps
|
|
|
|
Only user app IDs were written to `mDeviceIdleWhitelistAppIds`, both initially and when
|
|
`PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED` broadcast was received. All other places that
|
|
listen to that broadcast retrieve both user and system app IDs.
|
|
|
|
The only place where `mDeviceIdleWhitelistAppIds` array is checked is in `isWhitelistedLocked()`,
|
|
which is called only by `updateTaskStateLocked()` to check whether the app is on the device idle whitelist.
|
|
|
|
It's not clear why DeviceIdleJobsController ignores system apps.
|
|
File level comment doesn't mention the distinction between system and user apps:
|
|
"When device is dozing, set constraint for all jobs, except whitelisted apps, as not satisfied."
|
|
Comment for isWhitelistedLocked() does, however:
|
|
"Checks if the given job's scheduling app id exists in the device idle user whitelist."
|
|
However, that method is called for both system and user apps, and returns false for system apps
|
|
because only whitelist of user apps is checked. This leads to long delays for jobs that were
|
|
submitted by whitelisted system apps when device is in the Doze mode. No such delays happen with
|
|
whitelisted user apps.
|
|
|
|
Other places use a different naming for array of app IDs that includes only user apps,
|
|
eg `mDeviceIdleWhitelistUserAppIds`, not `mDeviceIdleWhitelistAppIds`.
|
|
|
|
I've looked through the Git history of DeviceIdleJobsController and JobSchedulerService, but didn't
|
|
find a reason for this behavior. Perhaps, system apps were exempted from device idle JobScheduler
|
|
restricitions in some other place previously, or this was a bug from the start.
|
|
|
|
Tested on an emulator with the Messaging app, which uses JobScheduler
|
|
during processing of incoming SMS:
|
|
1. Check that Messaging app is on system deviceidle whitelist:
|
|
```
|
|
$ dumpsys deviceidle whitelist | grep com.android.messaging
|
|
system-excidle,com.android.messaging,10090
|
|
system,com.android.messaging,10090
|
|
```
|
|
2. Simulate sending an SMS: it appears immediately
|
|
3. Simulate Doze mode: `$ dumpsys deviceidle force-idle`
|
|
4. Simulate sending an SMS again. Message doesn't appear, even if the Messaging app is open
|
|
5. Exit Doze mode: `$ dumpsys deviceidle unforce`. All pending messages appear immediately
|
|
6. Add Messaging app to the user whitelist:
|
|
```
|
|
$ dumpsys deviceidle whitelist +com.android.messaging
|
|
$ dumpsys deviceidle whitelist | grep com.android.messaging
|
|
system-excidle,com.android.messaging,10090
|
|
system,com.android.messaging,10090
|
|
user,com.android.messaging,10090
|
|
```
|
|
7. Simulate Doze mode again: `$ dumpsys deviceidle force-idle`
|
|
8. Simulate sending an SMS, note that it appears immediately this time
|
|
|
|
Also made a test system app to make sure that this issue isn't caused by low targetSdk of the
|
|
Messaging app (it targets SDK 24). Same issue with targetSdk 32 app.
|
|
|
|
In both cases, applying this patch fixes the issue.
|
|
---
|
|
.../java/com/android/server/DeviceIdleInternal.java | 2 +-
|
|
.../java/com/android/server/DeviceIdleController.java | 6 +++---
|
|
.../server/job/controllers/DeviceIdleJobsController.java | 6 +++---
|
|
3 files changed, 7 insertions(+), 7 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..1b1d2252dae1 100644
|
|
--- a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
|
|
+++ b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
|
|
@@ -73,7 +73,7 @@ void addPowerSaveTempWhitelistAppDirect(int uid, long duration,
|
|
|
|
boolean isAppOnWhitelist(int appid);
|
|
|
|
- int[] getPowerSaveWhitelistUserAppIds();
|
|
+ int[] getPowerSaveWhitelistAppIds();
|
|
|
|
int[] getPowerSaveTempWhitelistAppIds();
|
|
|
|
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
|
|
index 84d05c8b4144..61f0ad028caf 100644
|
|
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
|
|
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
|
|
@@ -2096,14 +2096,14 @@ public boolean isAppOnWhitelist(int appid) {
|
|
}
|
|
|
|
/**
|
|
- * Returns the array of app ids whitelisted by user. Take care not to
|
|
+ * Returns the array of whitelisted app ids. Take care not to
|
|
* modify this, as it is a reference to the original copy. But the reference
|
|
* can change when the list changes, so it needs to be re-acquired when
|
|
* {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent.
|
|
*/
|
|
@Override
|
|
- public int[] getPowerSaveWhitelistUserAppIds() {
|
|
- return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds();
|
|
+ public int[] getPowerSaveWhitelistAppIds() {
|
|
+ return DeviceIdleController.this.getAppIdWhitelistInternal();
|
|
}
|
|
|
|
@Override
|
|
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 79ef321eaf07..393726426afa 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
|
|
@@ -89,7 +89,7 @@ public void onReceive(Context context, Intent intent) {
|
|
case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED:
|
|
synchronized (mLock) {
|
|
mDeviceIdleWhitelistAppIds =
|
|
- mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
|
|
+ mLocalDeviceIdleController.getPowerSaveWhitelistAppIds();
|
|
if (DEBUG) {
|
|
Slog.d(TAG, "Got whitelist "
|
|
+ Arrays.toString(mDeviceIdleWhitelistAppIds));
|
|
@@ -131,7 +131,7 @@ public DeviceIdleJobsController(JobSchedulerService service) {
|
|
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
|
mLocalDeviceIdleController =
|
|
LocalServices.getService(DeviceIdleInternal.class);
|
|
- mDeviceIdleWhitelistAppIds = mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
|
|
+ mDeviceIdleWhitelistAppIds = mLocalDeviceIdleController.getPowerSaveWhitelistAppIds();
|
|
mPowerSaveTempWhitelistAppIds =
|
|
mLocalDeviceIdleController.getPowerSaveTempWhitelistAppIds();
|
|
mDeviceIdleUpdateFunctor = new DeviceIdleUpdateFunctor();
|
|
@@ -190,7 +190,7 @@ public void setUidActiveLocked(int uid, boolean active) {
|
|
}
|
|
|
|
/**
|
|
- * Checks if the given job's scheduling app id exists in the device idle user whitelist.
|
|
+ * Checks if the given job's scheduling app id exists in the device idle whitelist.
|
|
*/
|
|
boolean isWhitelistedLocked(JobStatus job) {
|
|
return Arrays.binarySearch(mDeviceIdleWhitelistAppIds,
|