Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a78acfdd authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Exempting tempwhitelist apps from doze

Adding doze exemptions for apps on the tempwhitelist. Any app on the
temporary whitelist can schedule jobs that will be exempt from doze
restrictions as long as the app is in the whitelist.

Test: cts-tradefed run cts-dev -m JobScheduler -t \
android.jobscheduler.cts.TempWhitelistTest

Bug: 64071030

Change-Id: I3846565d927014e73fd1badd34a57226cc788ef3
parent fc17a92a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1336,6 +1336,10 @@ public class DeviceIdleController extends SystemService
        public int[] getPowerSaveWhitelistUserAppIds() {
            return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds();
        }

        public int[] getPowerSaveTempWhitelistAppIds() {
            return DeviceIdleController.this.getAppIdTempWhitelistInternal();
        }
    }

    public DeviceIdleController(Context context) {
+1 −0
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ public final class BackgroundJobsController extends StateController {

    @Override
    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
        pw.println("BackgroundJobsController");
        pw.print("Foreground uids: [");
        for (int i = 0; i < mForegroundUids.size(); i++) {
            if (mForegroundUids.valueAt(i)) pw.print(mForegroundUids.keyAt(i) + " ");
+61 −36
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.PowerManager;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Slog;

import com.android.internal.util.ArrayUtils;
@@ -55,6 +56,9 @@ public final class DeviceIdleJobsController extends StateController {
     */
    private boolean mDeviceIdleMode;
    private int[] mDeviceIdleWhitelistAppIds;
    private int[] mPowerSaveTempWhitelistAppIds;
    // These jobs were added when the app was in temp whitelist, these should be exempted from doze
    private final ArraySet<JobStatus> mTempWhitelistedJobs;

    final JobStore.JobStatusFunctor mUpdateFunctor = new JobStore.JobStatusFunctor() {
        @Override public void process(JobStatus jobStatus) {
@@ -79,15 +83,39 @@ public final class DeviceIdleJobsController extends StateController {
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED.equals(action)
                    || PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
                updateIdleMode(mPowerManager != null
                        ? (mPowerManager.isDeviceIdleMode()
                                || mPowerManager.isLightDeviceIdleMode())
                        : false);
            } else if (PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED.equals(action)) {
                updateWhitelist();
            switch (intent.getAction()) {
                case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
                case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
                    updateIdleMode(mPowerManager != null && (mPowerManager.isDeviceIdleMode()
                            || mPowerManager.isLightDeviceIdleMode()));
                    break;
                case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED:
                    synchronized (mLock) {
                        mDeviceIdleWhitelistAppIds =
                                mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
                        if (LOG_DEBUG) {
                            Slog.d(LOG_TAG, "Got whitelist "
                                    + Arrays.toString(mDeviceIdleWhitelistAppIds));
                        }
                    }
                    break;
                case PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED:
                    synchronized (mLock) {
                        mPowerSaveTempWhitelistAppIds =
                                mLocalDeviceIdleController.getPowerSaveTempWhitelistAppIds();
                        if (LOG_DEBUG) {
                            Slog.d(LOG_TAG, "Got temp whitelist "
                                    + Arrays.toString(mPowerSaveTempWhitelistAppIds));
                        }
                        boolean changed = false;
                        for (int i = 0; i < mTempWhitelistedJobs.size(); i ++) {
                            changed |= updateTaskStateLocked(mTempWhitelistedJobs.valueAt(i));
                        }
                        if (changed) {
                            mStateChangedListener.onControllerStateChanged();
                        }
                    }
                    break;
            }
        }
    };
@@ -101,20 +129,21 @@ public final class DeviceIdleJobsController extends StateController {
        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mLocalDeviceIdleController =
                LocalServices.getService(DeviceIdleController.LocalService.class);
        mDeviceIdleWhitelistAppIds = mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
        mPowerSaveTempWhitelistAppIds =
                mLocalDeviceIdleController.getPowerSaveTempWhitelistAppIds();
        mTempWhitelistedJobs = new ArraySet<>();
        final IntentFilter filter = new IntentFilter();
        filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
        filter.addAction(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
        filter.addAction(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
        filter.addAction(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
        mContext.registerReceiverAsUser(
                mBroadcastReceiver, UserHandle.ALL, filter, null, null);
    }

    void updateIdleMode(boolean enabled) {
        boolean changed = false;
        // Need the whitelist to be ready when going into idle
        if (mDeviceIdleWhitelistAppIds == null) {
            updateWhitelist();
        }
        synchronized (mLock) {
            if (mDeviceIdleMode != enabled) {
                changed = true;
@@ -130,46 +159,42 @@ public final class DeviceIdleJobsController extends StateController {
    }

    /**
     * Fetches the latest whitelist from the device idle controller.
     * Checks if the given job's scheduling app id exists in the device idle user whitelist.
     */
    void updateWhitelist() {
        synchronized (mLock) {
            if (mLocalDeviceIdleController != null) {
                mDeviceIdleWhitelistAppIds =
                        mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
                if (LOG_DEBUG) {
                    Slog.d(LOG_TAG, "Got whitelist " + Arrays.toString(mDeviceIdleWhitelistAppIds));
                }
            }
        }
    boolean isWhitelistedLocked(JobStatus job) {
        return ArrayUtils.contains(mDeviceIdleWhitelistAppIds,
                UserHandle.getAppId(job.getSourceUid()));
    }

    /**
     * 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 temp whitelist.
     */
    boolean isWhitelistedLocked(JobStatus job) {
        if (mDeviceIdleWhitelistAppIds != null
                && ArrayUtils.contains(mDeviceIdleWhitelistAppIds,
                        UserHandle.getAppId(job.getSourceUid()))) {
            return true;
        }
        return false;
    boolean isTempWhitelistedLocked(JobStatus job) {
        return ArrayUtils.contains(mPowerSaveTempWhitelistAppIds,
                UserHandle.getAppId(job.getSourceUid()));
    }

    private void updateTaskStateLocked(JobStatus task) {
        final boolean whitelisted = isWhitelistedLocked(task);
    private boolean updateTaskStateLocked(JobStatus task) {
        final boolean whitelisted = isWhitelistedLocked(task)
                || (mTempWhitelistedJobs.contains(task) && isTempWhitelistedLocked(task));
        final boolean enableTask = !mDeviceIdleMode || whitelisted;
        task.setDeviceNotDozingConstraintSatisfied(enableTask, whitelisted);
        return task.setDeviceNotDozingConstraintSatisfied(enableTask, whitelisted);
    }

    @Override
    public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
        if (isTempWhitelistedLocked(jobStatus)) {
            mTempWhitelistedJobs.add(jobStatus);
            jobStatus.setDeviceNotDozingConstraintSatisfied(true, true);
        } else {
            updateTaskStateLocked(jobStatus);
        }
    }

    @Override
    public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
            boolean forUpdate) {
        mTempWhitelistedJobs.remove(jobStatus);
    }

    @Override