diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java index 63781ae334d23..5ef6855151ccf 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java @@ -34,6 +34,7 @@ import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.JobSchedulerBackgroundThread; import com.android.server.LocalServices; import com.android.server.job.JobSchedulerService; @@ -100,6 +101,10 @@ public final class BatteryController extends RestrictingController { @Override @GuardedBy("mLock") public void prepareForExecutionLocked(JobStatus jobStatus) { + if (!jobStatus.hasPowerConstraint()) { + // Ignore all jobs the controller wouldn't be tracking. + return; + } if (DEBUG) { Slog.d(TAG, "Prepping for " + jobStatus.toShortString()); } @@ -259,6 +264,16 @@ public final class BatteryController extends RestrictingController { } } + @VisibleForTesting + ArraySet getTrackedJobs() { + return mTrackedTasks; + } + + @VisibleForTesting + ArraySet getTopStartedJobs() { + return mTopStartedJobs; + } + @Override public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate predicate) { diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java index 52d0494bd9f02..2f61908aa63d3 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java @@ -312,4 +312,71 @@ public class BatteryControllerTest { assertFalse(jobLateFg.isConstraintSatisfied(JobStatus.CONSTRAINT_CHARGING)); assertFalse(jobLateFgLow.isConstraintSatisfied(JobStatus.CONSTRAINT_CHARGING)); } + + @Test + public void testControllerOnlyTracksPowerJobs() { + JobStatus batteryJob = createJobStatus("testControllerOnlyTracksPowerJobs", + SOURCE_PACKAGE, mSourceUid, + createBaseJobInfoBuilder(1).setRequiresBatteryNotLow(true).build()); + JobStatus chargingJob = createJobStatus("testControllerOnlyTracksPowerJobs", + SOURCE_PACKAGE, mSourceUid, + createBaseJobInfoBuilder(2).setRequiresCharging(true).build()); + JobStatus bothPowerJob = createJobStatus("testControllerOnlyTracksPowerJobs", + SOURCE_PACKAGE, mSourceUid, + createBaseJobInfoBuilder(3) + .setRequiresCharging(true) + .setRequiresBatteryNotLow(true) + .build()); + JobStatus unrelatedJob = createJobStatus("testControllerOnlyTracksPowerJobs", + SOURCE_PACKAGE, mSourceUid, createBaseJobInfoBuilder(4).build()); + + // Follow the lifecycle of tracking + // Start tracking + trackJobs(batteryJob, chargingJob, bothPowerJob, unrelatedJob); + final ArraySet trackedJobs = mBatteryController.getTrackedJobs(); + final ArraySet topStartedJobs = mBatteryController.getTopStartedJobs(); + assertTrue(trackedJobs.contains(batteryJob)); + assertTrue(trackedJobs.contains(chargingJob)); + assertTrue(trackedJobs.contains(bothPowerJob)); + assertFalse(trackedJobs.contains(unrelatedJob)); + assertFalse(topStartedJobs.contains(batteryJob)); + assertFalse(topStartedJobs.contains(chargingJob)); + assertFalse(topStartedJobs.contains(bothPowerJob)); + assertFalse(topStartedJobs.contains(unrelatedJob)); + + // Procstate change shouldn't affect anything + setUidBias(mSourceUid, JobInfo.BIAS_TOP_APP); + assertTrue(trackedJobs.contains(batteryJob)); + assertTrue(trackedJobs.contains(chargingJob)); + assertTrue(trackedJobs.contains(bothPowerJob)); + assertFalse(trackedJobs.contains(unrelatedJob)); + assertFalse(topStartedJobs.contains(batteryJob)); + assertFalse(topStartedJobs.contains(chargingJob)); + assertFalse(topStartedJobs.contains(bothPowerJob)); + assertFalse(topStartedJobs.contains(unrelatedJob)); + + // Job starts running + mBatteryController.prepareForExecutionLocked(batteryJob); + mBatteryController.prepareForExecutionLocked(chargingJob); + mBatteryController.prepareForExecutionLocked(bothPowerJob); + mBatteryController.prepareForExecutionLocked(unrelatedJob); + assertTrue(topStartedJobs.contains(batteryJob)); + assertTrue(topStartedJobs.contains(chargingJob)); + assertTrue(topStartedJobs.contains(bothPowerJob)); + assertFalse(topStartedJobs.contains(unrelatedJob)); + + // Job cleanup + mBatteryController.maybeStopTrackingJobLocked(batteryJob, null, false); + mBatteryController.maybeStopTrackingJobLocked(chargingJob, null, false); + mBatteryController.maybeStopTrackingJobLocked(bothPowerJob, null, false); + mBatteryController.maybeStopTrackingJobLocked(unrelatedJob, null, false); + assertFalse(trackedJobs.contains(batteryJob)); + assertFalse(trackedJobs.contains(chargingJob)); + assertFalse(trackedJobs.contains(bothPowerJob)); + assertFalse(trackedJobs.contains(unrelatedJob)); + assertFalse(topStartedJobs.contains(batteryJob)); + assertFalse(topStartedJobs.contains(chargingJob)); + assertFalse(topStartedJobs.contains(bothPowerJob)); + assertFalse(topStartedJobs.contains(unrelatedJob)); + } }