Loading apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +5 −4 Original line number Original line Diff line number Diff line Loading @@ -176,12 +176,13 @@ public final class BatteryController extends RestrictingController { Slog.d(TAG, "maybeReportNewChargingStateLocked: " Slog.d(TAG, "maybeReportNewChargingStateLocked: " + powerConnected + "/" + stablePower + "/" + batteryNotLow); + powerConnected + "/" + stablePower + "/" + batteryNotLow); } } final long nowElapsed = sElapsedRealtimeClock.millis(); mFlexibilityController.setConstraintSatisfied( mFlexibilityController.setConstraintSatisfied( JobStatus.CONSTRAINT_CHARGING, mService.isBatteryCharging()); JobStatus.CONSTRAINT_CHARGING, mService.isBatteryCharging(), nowElapsed); mFlexibilityController mFlexibilityController.setConstraintSatisfied( .setConstraintSatisfied(JobStatus.CONSTRAINT_BATTERY_NOT_LOW, batteryNotLow); JobStatus.CONSTRAINT_BATTERY_NOT_LOW, batteryNotLow, nowElapsed); final long nowElapsed = sElapsedRealtimeClock.millis(); for (int i = mTrackedTasks.size() - 1; i >= 0; i--) { for (int i = mTrackedTasks.size() - 1; i >= 0; i--) { final JobStatus ts = mTrackedTasks.valueAt(i); final JobStatus ts = mTrackedTasks.valueAt(i); if (ts.hasChargingConstraint()) { if (ts.hasChargingConstraint()) { Loading apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java +19 −22 Original line number Original line Diff line number Diff line Loading @@ -137,9 +137,9 @@ public final class FlexibilityController extends StateController { new PrefetchController.PrefetchChangedListener() { new PrefetchController.PrefetchChangedListener() { @Override @Override public void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, public void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, String pkgName, long prevEstimatedLaunchTime, long newEstimatedLaunchTime) { String pkgName, long prevEstimatedLaunchTime, long newEstimatedLaunchTime, long nowElapsed) { synchronized (mLock) { synchronized (mLock) { final long nowElapsed = sElapsedRealtimeClock.millis(); final long prefetchThreshold = final long prefetchThreshold = mPrefetchController.getLaunchTimeThresholdMs(); mPrefetchController.getLaunchTimeThresholdMs(); boolean jobWasInPrefetchWindow = prevEstimatedLaunchTime boolean jobWasInPrefetchWindow = prevEstimatedLaunchTime Loading @@ -158,8 +158,8 @@ public final class FlexibilityController extends StateController { if (!js.hasFlexibilityConstraint()) { if (!js.hasFlexibilityConstraint()) { continue; continue; } } mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed); } } } } } } Loading Loading @@ -191,7 +191,7 @@ public final class FlexibilityController extends StateController { js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY); js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY); final long nowElapsed = sElapsedRealtimeClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js)); js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js)); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed); } } } } Loading Loading @@ -239,7 +239,7 @@ public final class FlexibilityController extends StateController { * Changes flexibility constraint satisfaction for affected jobs. * Changes flexibility constraint satisfaction for affected jobs. */ */ @VisibleForTesting @VisibleForTesting void setConstraintSatisfied(int constraint, boolean state) { void setConstraintSatisfied(int constraint, boolean state, long nowElapsed) { synchronized (mLock) { synchronized (mLock) { final boolean old = (mSatisfiedFlexibleConstraints & constraint) != 0; final boolean old = (mSatisfiedFlexibleConstraints & constraint) != 0; if (old == state) { if (old == state) { Loading @@ -255,8 +255,6 @@ public final class FlexibilityController extends StateController { // The rest did not have a change in state and are still satisfied or unsatisfied. // The rest did not have a change in state and are still satisfied or unsatisfied. final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied); final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied); final long nowElapsed = sElapsedRealtimeClock.millis(); // In order to get the range of all potentially satisfied jobs, we start at the number // In order to get the range of all potentially satisfied jobs, we start at the number // of satisfied system-wide constraints and iterate to the max number of potentially // of satisfied system-wide constraints and iterate to the max number of potentially // satisfied constraints, determined by how many job-specific constraints exist. // satisfied constraints, determined by how many job-specific constraints exist. Loading Loading @@ -329,10 +327,9 @@ public final class FlexibilityController extends StateController { @VisibleForTesting @VisibleForTesting @GuardedBy("mLock") @GuardedBy("mLock") int getCurPercentOfLifecycleLocked(JobStatus js) { int getCurPercentOfLifecycleLocked(JobStatus js, long nowElapsed) { final long earliest = getLifeCycleBeginningElapsedLocked(js); final long earliest = getLifeCycleBeginningElapsedLocked(js); final long latest = getLifeCycleEndElapsedLocked(js, earliest); final long latest = getLifeCycleEndElapsedLocked(js, earliest); final long nowElapsed = sElapsedRealtimeClock.millis(); if (latest == NO_LIFECYCLE_END || earliest >= nowElapsed) { if (latest == NO_LIFECYCLE_END || earliest >= nowElapsed) { return 0; return 0; } } Loading Loading @@ -414,8 +411,8 @@ public final class FlexibilityController extends StateController { .getJobsByNumRequiredConstraints(j); .getJobsByNumRequiredConstraints(j); for (int i = 0; i < jobs.size(); i++) { for (int i = 0; i < jobs.size(); i++) { JobStatus js = jobs.valueAt(i); JobStatus js = jobs.valueAt(i); mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed); if (js.setFlexibilityConstraintSatisfied( if (js.setFlexibilityConstraintSatisfied( nowElapsed, isFlexibilitySatisfiedLocked(js))) { nowElapsed, isFlexibilitySatisfiedLocked(js))) { changedJobs.add(js); changedJobs.add(js); Loading Loading @@ -479,8 +476,8 @@ public final class FlexibilityController extends StateController { mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).remove(js); mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).remove(js); } } public void resetJobNumDroppedConstraints(JobStatus js) { public void resetJobNumDroppedConstraints(JobStatus js, long nowElapsed) { final int curPercent = getCurPercentOfLifecycleLocked(js); final int curPercent = getCurPercentOfLifecycleLocked(js, nowElapsed); int toDrop = 0; int toDrop = 0; final int jsMaxFlexibleConstraints = NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS final int jsMaxFlexibleConstraints = NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS + (js.getPreferUnmetered() ? 1 : 0); + (js.getPreferUnmetered() ? 1 : 0); Loading @@ -489,7 +486,8 @@ public final class FlexibilityController extends StateController { toDrop++; toDrop++; } } } } adjustJobsRequiredConstraints(js, js.getNumDroppedFlexibleConstraints() - toDrop); adjustJobsRequiredConstraints( js, js.getNumDroppedFlexibleConstraints() - toDrop, nowElapsed); } } /** Returns all tracked jobs. */ /** Returns all tracked jobs. */ Loading @@ -502,13 +500,12 @@ public final class FlexibilityController extends StateController { * Returns false if the job status's number of flexible constraints is now 0. * Returns false if the job status's number of flexible constraints is now 0. * Jobs with 0 required flexible constraints are removed from the tracker. * Jobs with 0 required flexible constraints are removed from the tracker. */ */ public boolean adjustJobsRequiredConstraints(JobStatus js, int n) { public boolean adjustJobsRequiredConstraints(JobStatus js, int n, long nowElapsed) { if (n == 0) { if (n == 0) { return false; return false; } } remove(js); remove(js); js.adjustNumRequiredFlexibleConstraints(n); js.adjustNumRequiredFlexibleConstraints(n); final long nowElapsed = sElapsedRealtimeClock.millis(); js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js)); js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js)); if (js.getNumRequiredFlexibleConstraints() <= 0) { if (js.getNumRequiredFlexibleConstraints() <= 0) { maybeStopTrackingJobLocked(js, null, false); maybeStopTrackingJobLocked(js, null, false); Loading Loading @@ -553,7 +550,7 @@ public final class FlexibilityController extends StateController { return js.getSourceUserId() == userId; return js.getSourceUserId() == userId; } } public void scheduleDropNumConstraintsAlarm(JobStatus js) { public void scheduleDropNumConstraintsAlarm(JobStatus js, long nowElapsed) { long nextTimeElapsed; long nextTimeElapsed; synchronized (mLock) { synchronized (mLock) { final long earliest = getLifeCycleBeginningElapsedLocked(js); final long earliest = getLifeCycleBeginningElapsedLocked(js); Loading @@ -567,7 +564,7 @@ public final class FlexibilityController extends StateController { if (latest - nextTimeElapsed < mDeadlineProximityLimitMs) { if (latest - nextTimeElapsed < mDeadlineProximityLimitMs) { mFlexibilityTracker.adjustJobsRequiredConstraints( mFlexibilityTracker.adjustJobsRequiredConstraints( js, -js.getNumRequiredFlexibleConstraints()); js, -js.getNumRequiredFlexibleConstraints(), nowElapsed); return; return; } } addAlarm(js, nextTimeElapsed); addAlarm(js, nextTimeElapsed); Loading @@ -578,21 +575,21 @@ public final class FlexibilityController extends StateController { protected void processExpiredAlarms(@NonNull ArraySet<JobStatus> expired) { protected void processExpiredAlarms(@NonNull ArraySet<JobStatus> expired) { synchronized (mLock) { synchronized (mLock) { ArraySet<JobStatus> changedJobs = new ArraySet<>(); ArraySet<JobStatus> changedJobs = new ArraySet<>(); final long nowElapsed = sElapsedRealtimeClock.millis(); for (int i = 0; i < expired.size(); i++) { for (int i = 0; i < expired.size(); i++) { JobStatus js = expired.valueAt(i); JobStatus js = expired.valueAt(i); boolean wasFlexibilitySatisfied = js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE); boolean wasFlexibilitySatisfied = js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE); final long earliest = getLifeCycleBeginningElapsedLocked(js); final long earliest = getLifeCycleBeginningElapsedLocked(js); final long latest = getLifeCycleEndElapsedLocked(js, earliest); final long latest = getLifeCycleEndElapsedLocked(js, earliest); final long nowElapsed = sElapsedRealtimeClock.millis(); if (latest - nowElapsed < mDeadlineProximityLimitMs) { if (latest - nowElapsed < mDeadlineProximityLimitMs) { mFlexibilityTracker.adjustJobsRequiredConstraints(js, mFlexibilityTracker.adjustJobsRequiredConstraints(js, -js.getNumRequiredFlexibleConstraints()); -js.getNumRequiredFlexibleConstraints(), nowElapsed); } else { } else { long nextTimeElapsed = long nextTimeElapsed = getNextConstraintDropTimeElapsedLocked(js, earliest, latest); getNextConstraintDropTimeElapsedLocked(js, earliest, latest); if (mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1) if (mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1, nowElapsed) && nextTimeElapsed != NO_LIFECYCLE_END) { && nextTimeElapsed != NO_LIFECYCLE_END) { mFlexibilityAlarmQueue.addAlarm(js, nextTimeElapsed); mFlexibilityAlarmQueue.addAlarm(js, nextTimeElapsed); } } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -95,9 +95,10 @@ public final class IdleController extends RestrictingController implements Idlen */ */ @Override @Override public void reportNewIdleState(boolean isIdle) { public void reportNewIdleState(boolean isIdle) { mFlexibilityController.setConstraintSatisfied(JobStatus.CONSTRAINT_IDLE, isIdle); synchronized (mLock) { synchronized (mLock) { final long nowElapsed = sElapsedRealtimeClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); mFlexibilityController.setConstraintSatisfied( JobStatus.CONSTRAINT_IDLE, isIdle, nowElapsed); for (int i = mTrackedTasks.size()-1; i >= 0; i--) { for (int i = mTrackedTasks.size()-1; i >= 0; i--) { mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle); mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle); } } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -105,7 +105,7 @@ public class PrefetchController extends StateController { public interface PrefetchChangedListener { public interface PrefetchChangedListener { /** Callback to inform listeners when estimated launch times change. */ /** Callback to inform listeners when estimated launch times change. */ void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, String pkgName, void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, String pkgName, long prevEstimatedLaunchTime, long newEstimatedLaunchTime); long prevEstimatedLaunchTime, long newEstimatedLaunchTime, long nowElapsed); } } @SuppressWarnings("FieldCanBeLocal") @SuppressWarnings("FieldCanBeLocal") Loading Loading @@ -308,8 +308,9 @@ public class PrefetchController extends StateController { final long nowElapsed = sElapsedRealtimeClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); updateThresholdAlarmLocked(userId, pkgName, now, nowElapsed); updateThresholdAlarmLocked(userId, pkgName, now, nowElapsed); for (int i = 0; i < mPrefetchChangedListeners.size(); i++) { for (int i = 0; i < mPrefetchChangedListeners.size(); i++) { mPrefetchChangedListeners.valueAt(i).onPrefetchCacheUpdated(jobs, mPrefetchChangedListeners.valueAt(i).onPrefetchCacheUpdated( userId, pkgName, prevEstimatedLaunchTime, newEstimatedLaunchTime); jobs, userId, pkgName, prevEstimatedLaunchTime, newEstimatedLaunchTime, nowElapsed); } } if (maybeUpdateConstraintForPkgLocked(now, nowElapsed, userId, pkgName)) { if (maybeUpdateConstraintForPkgLocked(now, nowElapsed, userId, pkgName)) { mStateChangedListener.onControllerStateChanged(jobs); mStateChangedListener.onControllerStateChanged(jobs); Loading services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java +63 −43 Original line number Original line Diff line number Diff line Loading @@ -209,7 +209,8 @@ public class FlexibilityControllerTest { public void testOnConstantsUpdated_DeadlineProximity() { public void testOnConstantsUpdated_DeadlineProximity() { JobStatus js = createJobStatus("testDeadlineProximityConfig", createJob(0)); JobStatus js = createJobStatus("testDeadlineProximityConfig", createJob(0)); setDeviceConfigLong(KEY_DEADLINE_PROXIMITY_LIMIT, Long.MAX_VALUE); setDeviceConfigLong(KEY_DEADLINE_PROXIMITY_LIMIT, Long.MAX_VALUE); mFlexibilityController.mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js); mFlexibilityController.mFlexibilityAlarmQueue .scheduleDropNumConstraintsAlarm(js, FROZEN_TIME); assertEquals(0, js.getNumRequiredFlexibleConstraints()); assertEquals(0, js.getNumRequiredFlexibleConstraints()); } } Loading Loading @@ -336,26 +337,31 @@ public class FlexibilityControllerTest { @Test @Test public void testCurPercent() { public void testCurPercent() { long deadline = 1000; long deadline = 1000; long nowElapsed; JobInfo.Builder jb = createJob(0).setOverrideDeadline(deadline); JobInfo.Builder jb = createJob(0).setOverrideDeadline(deadline); JobStatus js = createJobStatus("time", jb); JobStatus js = createJobStatus("time", jb); assertEquals(FROZEN_TIME, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); assertEquals(FROZEN_TIME, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); assertEquals(deadline + FROZEN_TIME, assertEquals(deadline + FROZEN_TIME, mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME)); mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME)); nowElapsed = 600 + FROZEN_TIME; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(600 + FROZEN_TIME), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = 1400; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(1400), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = 950 + FROZEN_TIME; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(950 + FROZEN_TIME), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = FROZEN_TIME; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(FROZEN_TIME), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); long delay = 100; long delay = 100; deadline = 1100; deadline = 1100; jb = createJob(0).setOverrideDeadline(deadline).setMinimumLatency(delay); jb = createJob(0).setOverrideDeadline(deadline).setMinimumLatency(delay); Loading @@ -366,18 +372,21 @@ public class FlexibilityControllerTest { assertEquals(deadline + FROZEN_TIME, assertEquals(deadline + FROZEN_TIME, mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME + delay)); mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME + delay)); nowElapsed = 600 + FROZEN_TIME + delay; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(600 + FROZEN_TIME + delay), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = 1400; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(1400), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = 950 + FROZEN_TIME + delay; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(950 + FROZEN_TIME + delay), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); } } @Test @Test Loading Loading @@ -491,19 +500,19 @@ public class FlexibilityControllerTest { assertEquals(3, trackedJobs.get(2).size()); assertEquals(3, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(0).size()); assertEquals(1, trackedJobs.get(1).size()); assertEquals(1, trackedJobs.get(1).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME); assertEquals(1, trackedJobs.get(0).size()); assertEquals(1, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(2, trackedJobs.get(2).size()); Loading @@ -515,24 +524,25 @@ public class FlexibilityControllerTest { assertEquals(1, trackedJobs.get(2).size()); assertEquals(1, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.resetJobNumDroppedConstraints(jobs[0]); flexTracker.resetJobNumDroppedConstraints(jobs[0], FROZEN_TIME); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.adjustJobsRequiredConstraints(jobs[0], -2); flexTracker.adjustJobsRequiredConstraints(jobs[0], -2, FROZEN_TIME); assertEquals(1, trackedJobs.get(0).size()); assertEquals(1, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(1, trackedJobs.get(2).size()); assertEquals(1, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); final long nowElapsed = ((DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_MS / 2) + HOUR_IN_MILLIS); JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli((DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_MS / 2) Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); + HOUR_IN_MILLIS), ZoneOffset.UTC); flexTracker.resetJobNumDroppedConstraints(jobs[0]); flexTracker.resetJobNumDroppedConstraints(jobs[0], nowElapsed); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(0).size()); assertEquals(1, trackedJobs.get(1).size()); assertEquals(1, trackedJobs.get(1).size()); assertEquals(1, trackedJobs.get(2).size()); assertEquals(1, trackedJobs.get(2).size()); Loading Loading @@ -615,13 +625,13 @@ public class FlexibilityControllerTest { @Test @Test public void testSetConstraintSatisfied_Constraints() { public void testSetConstraintSatisfied_Constraints() { mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME); assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, true); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, true, FROZEN_TIME); assertTrue(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); assertTrue(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME); assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); } } Loading Loading @@ -651,20 +661,21 @@ public class FlexibilityControllerTest { createJobStatus(String.valueOf(i), jb), null); createJobStatus(String.valueOf(i), jb), null); } } } } mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, false); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, false, FROZEN_TIME); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, false); mFlexibilityController.setConstraintSatisfied( CONSTRAINT_BATTERY_NOT_LOW, false, FROZEN_TIME); assertEquals(0, mFlexibilityController.mSatisfiedFlexibleConstraints); assertEquals(0, mFlexibilityController.mSatisfiedFlexibleConstraints); for (int i = 0; i < constraintCombinations.length; i++) { for (int i = 0; i < constraintCombinations.length; i++) { constraints = constraintCombinations[i]; constraints = constraintCombinations[i]; mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, (constraints & CONSTRAINT_CHARGING) != 0); (constraints & CONSTRAINT_CHARGING) != 0, FROZEN_TIME); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, (constraints & CONSTRAINT_IDLE) != 0); (constraints & CONSTRAINT_IDLE) != 0, FROZEN_TIME); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, (constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0); (constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0, FROZEN_TIME); assertEquals(constraints, mFlexibilityController.mSatisfiedFlexibleConstraints); assertEquals(constraints, mFlexibilityController.mSatisfiedFlexibleConstraints); synchronized (mFlexibilityController.mLock) { synchronized (mFlexibilityController.mLock) { Loading @@ -679,6 +690,7 @@ public class FlexibilityControllerTest { JobInfo.Builder jb = createJob(22).setOverrideDeadline(100L); JobInfo.Builder jb = createJob(22).setOverrideDeadline(100L); JobStatus js = createJobStatus("testResetJobNumDroppedConstraints", jb); JobStatus js = createJobStatus("testResetJobNumDroppedConstraints", jb); js.adjustNumRequiredFlexibleConstraints(3); js.adjustNumRequiredFlexibleConstraints(3); long nowElapsed; mFlexibilityController.mFlexibilityTracker.add(js); mFlexibilityController.mFlexibilityTracker.add(js); Loading @@ -687,45 +699,51 @@ public class FlexibilityControllerTest { assertEquals(1, mFlexibilityController assertEquals(1, mFlexibilityController .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size()); .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size()); nowElapsed = 155L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(155L), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1); mFlexibilityController.mFlexibilityTracker .adjustJobsRequiredConstraints(js, -1, nowElapsed); assertEquals(2, js.getNumRequiredFlexibleConstraints()); assertEquals(2, js.getNumRequiredFlexibleConstraints()); assertEquals(1, js.getNumDroppedFlexibleConstraints()); assertEquals(1, js.getNumDroppedFlexibleConstraints()); assertEquals(1, mFlexibilityController assertEquals(1, mFlexibilityController .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size()); .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size()); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); assertEquals(2, js.getNumRequiredFlexibleConstraints()); assertEquals(2, js.getNumRequiredFlexibleConstraints()); assertEquals(1, js.getNumDroppedFlexibleConstraints()); assertEquals(1, js.getNumDroppedFlexibleConstraints()); assertEquals(1, mFlexibilityController assertEquals(1, mFlexibilityController .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size()); .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size()); nowElapsed = 140L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(140L), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); assertEquals(3, js.getNumRequiredFlexibleConstraints()); assertEquals(3, js.getNumRequiredFlexibleConstraints()); assertEquals(0, js.getNumDroppedFlexibleConstraints()); assertEquals(0, js.getNumDroppedFlexibleConstraints()); assertEquals(1, mFlexibilityController assertEquals(1, mFlexibilityController .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size()); .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size()); nowElapsed = 175L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(175), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); assertEquals(0, js.getNumRequiredFlexibleConstraints()); assertEquals(0, js.getNumRequiredFlexibleConstraints()); assertEquals(3, js.getNumDroppedFlexibleConstraints()); assertEquals(3, js.getNumDroppedFlexibleConstraints()); nowElapsed = 165L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(165L), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); assertEquals(1, js.getNumRequiredFlexibleConstraints()); assertEquals(1, js.getNumRequiredFlexibleConstraints()); assertEquals(2, js.getNumDroppedFlexibleConstraints()); assertEquals(2, js.getNumDroppedFlexibleConstraints()); Loading @@ -745,12 +763,14 @@ public class FlexibilityControllerTest { mFlexibilityController.maybeStartTrackingJobLocked(js, null); mFlexibilityController.maybeStartTrackingJobLocked(js, null); final long nowElapsed = 150L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(150L), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mPrefetchChangedListener.onPrefetchCacheUpdated( mFlexibilityController.mPrefetchChangedListener.onPrefetchCacheUpdated( jobs, js.getUserId(), js.getSourcePackageName(), Long.MAX_VALUE, jobs, js.getUserId(), js.getSourcePackageName(), Long.MAX_VALUE, 1150L + mFlexibilityController.mConstants.PREFETCH_FORCE_BATCH_RELAX_THRESHOLD_MS); 1150L + mFlexibilityController.mConstants.PREFETCH_FORCE_BATCH_RELAX_THRESHOLD_MS, nowElapsed); assertEquals(150L, assertEquals(150L, (long) mFlexibilityController.mPrefetchLifeCycleStart (long) mFlexibilityController.mPrefetchLifeCycleStart Loading @@ -758,7 +778,7 @@ public class FlexibilityControllerTest { assertEquals(150L, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); assertEquals(150L, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); assertEquals(1150L, assertEquals(1150L, mFlexibilityController.getLifeCycleEndElapsedLocked(js, 150L)); mFlexibilityController.getLifeCycleEndElapsedLocked(js, 150L)); assertEquals(0, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(0, mFlexibilityController.getCurPercentOfLifecycleLocked(js, FROZEN_TIME)); assertEquals(650L, mFlexibilityController assertEquals(650L, mFlexibilityController .getNextConstraintDropTimeElapsedLocked(js)); .getNextConstraintDropTimeElapsedLocked(js)); assertEquals(3, js.getNumRequiredFlexibleConstraints()); assertEquals(3, js.getNumRequiredFlexibleConstraints()); Loading Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +5 −4 Original line number Original line Diff line number Diff line Loading @@ -176,12 +176,13 @@ public final class BatteryController extends RestrictingController { Slog.d(TAG, "maybeReportNewChargingStateLocked: " Slog.d(TAG, "maybeReportNewChargingStateLocked: " + powerConnected + "/" + stablePower + "/" + batteryNotLow); + powerConnected + "/" + stablePower + "/" + batteryNotLow); } } final long nowElapsed = sElapsedRealtimeClock.millis(); mFlexibilityController.setConstraintSatisfied( mFlexibilityController.setConstraintSatisfied( JobStatus.CONSTRAINT_CHARGING, mService.isBatteryCharging()); JobStatus.CONSTRAINT_CHARGING, mService.isBatteryCharging(), nowElapsed); mFlexibilityController mFlexibilityController.setConstraintSatisfied( .setConstraintSatisfied(JobStatus.CONSTRAINT_BATTERY_NOT_LOW, batteryNotLow); JobStatus.CONSTRAINT_BATTERY_NOT_LOW, batteryNotLow, nowElapsed); final long nowElapsed = sElapsedRealtimeClock.millis(); for (int i = mTrackedTasks.size() - 1; i >= 0; i--) { for (int i = mTrackedTasks.size() - 1; i >= 0; i--) { final JobStatus ts = mTrackedTasks.valueAt(i); final JobStatus ts = mTrackedTasks.valueAt(i); if (ts.hasChargingConstraint()) { if (ts.hasChargingConstraint()) { Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java +19 −22 Original line number Original line Diff line number Diff line Loading @@ -137,9 +137,9 @@ public final class FlexibilityController extends StateController { new PrefetchController.PrefetchChangedListener() { new PrefetchController.PrefetchChangedListener() { @Override @Override public void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, public void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, String pkgName, long prevEstimatedLaunchTime, long newEstimatedLaunchTime) { String pkgName, long prevEstimatedLaunchTime, long newEstimatedLaunchTime, long nowElapsed) { synchronized (mLock) { synchronized (mLock) { final long nowElapsed = sElapsedRealtimeClock.millis(); final long prefetchThreshold = final long prefetchThreshold = mPrefetchController.getLaunchTimeThresholdMs(); mPrefetchController.getLaunchTimeThresholdMs(); boolean jobWasInPrefetchWindow = prevEstimatedLaunchTime boolean jobWasInPrefetchWindow = prevEstimatedLaunchTime Loading @@ -158,8 +158,8 @@ public final class FlexibilityController extends StateController { if (!js.hasFlexibilityConstraint()) { if (!js.hasFlexibilityConstraint()) { continue; continue; } } mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed); } } } } } } Loading Loading @@ -191,7 +191,7 @@ public final class FlexibilityController extends StateController { js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY); js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY); final long nowElapsed = sElapsedRealtimeClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js)); js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js)); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed); } } } } Loading Loading @@ -239,7 +239,7 @@ public final class FlexibilityController extends StateController { * Changes flexibility constraint satisfaction for affected jobs. * Changes flexibility constraint satisfaction for affected jobs. */ */ @VisibleForTesting @VisibleForTesting void setConstraintSatisfied(int constraint, boolean state) { void setConstraintSatisfied(int constraint, boolean state, long nowElapsed) { synchronized (mLock) { synchronized (mLock) { final boolean old = (mSatisfiedFlexibleConstraints & constraint) != 0; final boolean old = (mSatisfiedFlexibleConstraints & constraint) != 0; if (old == state) { if (old == state) { Loading @@ -255,8 +255,6 @@ public final class FlexibilityController extends StateController { // The rest did not have a change in state and are still satisfied or unsatisfied. // The rest did not have a change in state and are still satisfied or unsatisfied. final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied); final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied); final long nowElapsed = sElapsedRealtimeClock.millis(); // In order to get the range of all potentially satisfied jobs, we start at the number // In order to get the range of all potentially satisfied jobs, we start at the number // of satisfied system-wide constraints and iterate to the max number of potentially // of satisfied system-wide constraints and iterate to the max number of potentially // satisfied constraints, determined by how many job-specific constraints exist. // satisfied constraints, determined by how many job-specific constraints exist. Loading Loading @@ -329,10 +327,9 @@ public final class FlexibilityController extends StateController { @VisibleForTesting @VisibleForTesting @GuardedBy("mLock") @GuardedBy("mLock") int getCurPercentOfLifecycleLocked(JobStatus js) { int getCurPercentOfLifecycleLocked(JobStatus js, long nowElapsed) { final long earliest = getLifeCycleBeginningElapsedLocked(js); final long earliest = getLifeCycleBeginningElapsedLocked(js); final long latest = getLifeCycleEndElapsedLocked(js, earliest); final long latest = getLifeCycleEndElapsedLocked(js, earliest); final long nowElapsed = sElapsedRealtimeClock.millis(); if (latest == NO_LIFECYCLE_END || earliest >= nowElapsed) { if (latest == NO_LIFECYCLE_END || earliest >= nowElapsed) { return 0; return 0; } } Loading Loading @@ -414,8 +411,8 @@ public final class FlexibilityController extends StateController { .getJobsByNumRequiredConstraints(j); .getJobsByNumRequiredConstraints(j); for (int i = 0; i < jobs.size(); i++) { for (int i = 0; i < jobs.size(); i++) { JobStatus js = jobs.valueAt(i); JobStatus js = jobs.valueAt(i); mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js); mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed); if (js.setFlexibilityConstraintSatisfied( if (js.setFlexibilityConstraintSatisfied( nowElapsed, isFlexibilitySatisfiedLocked(js))) { nowElapsed, isFlexibilitySatisfiedLocked(js))) { changedJobs.add(js); changedJobs.add(js); Loading Loading @@ -479,8 +476,8 @@ public final class FlexibilityController extends StateController { mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).remove(js); mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).remove(js); } } public void resetJobNumDroppedConstraints(JobStatus js) { public void resetJobNumDroppedConstraints(JobStatus js, long nowElapsed) { final int curPercent = getCurPercentOfLifecycleLocked(js); final int curPercent = getCurPercentOfLifecycleLocked(js, nowElapsed); int toDrop = 0; int toDrop = 0; final int jsMaxFlexibleConstraints = NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS final int jsMaxFlexibleConstraints = NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS + (js.getPreferUnmetered() ? 1 : 0); + (js.getPreferUnmetered() ? 1 : 0); Loading @@ -489,7 +486,8 @@ public final class FlexibilityController extends StateController { toDrop++; toDrop++; } } } } adjustJobsRequiredConstraints(js, js.getNumDroppedFlexibleConstraints() - toDrop); adjustJobsRequiredConstraints( js, js.getNumDroppedFlexibleConstraints() - toDrop, nowElapsed); } } /** Returns all tracked jobs. */ /** Returns all tracked jobs. */ Loading @@ -502,13 +500,12 @@ public final class FlexibilityController extends StateController { * Returns false if the job status's number of flexible constraints is now 0. * Returns false if the job status's number of flexible constraints is now 0. * Jobs with 0 required flexible constraints are removed from the tracker. * Jobs with 0 required flexible constraints are removed from the tracker. */ */ public boolean adjustJobsRequiredConstraints(JobStatus js, int n) { public boolean adjustJobsRequiredConstraints(JobStatus js, int n, long nowElapsed) { if (n == 0) { if (n == 0) { return false; return false; } } remove(js); remove(js); js.adjustNumRequiredFlexibleConstraints(n); js.adjustNumRequiredFlexibleConstraints(n); final long nowElapsed = sElapsedRealtimeClock.millis(); js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js)); js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js)); if (js.getNumRequiredFlexibleConstraints() <= 0) { if (js.getNumRequiredFlexibleConstraints() <= 0) { maybeStopTrackingJobLocked(js, null, false); maybeStopTrackingJobLocked(js, null, false); Loading Loading @@ -553,7 +550,7 @@ public final class FlexibilityController extends StateController { return js.getSourceUserId() == userId; return js.getSourceUserId() == userId; } } public void scheduleDropNumConstraintsAlarm(JobStatus js) { public void scheduleDropNumConstraintsAlarm(JobStatus js, long nowElapsed) { long nextTimeElapsed; long nextTimeElapsed; synchronized (mLock) { synchronized (mLock) { final long earliest = getLifeCycleBeginningElapsedLocked(js); final long earliest = getLifeCycleBeginningElapsedLocked(js); Loading @@ -567,7 +564,7 @@ public final class FlexibilityController extends StateController { if (latest - nextTimeElapsed < mDeadlineProximityLimitMs) { if (latest - nextTimeElapsed < mDeadlineProximityLimitMs) { mFlexibilityTracker.adjustJobsRequiredConstraints( mFlexibilityTracker.adjustJobsRequiredConstraints( js, -js.getNumRequiredFlexibleConstraints()); js, -js.getNumRequiredFlexibleConstraints(), nowElapsed); return; return; } } addAlarm(js, nextTimeElapsed); addAlarm(js, nextTimeElapsed); Loading @@ -578,21 +575,21 @@ public final class FlexibilityController extends StateController { protected void processExpiredAlarms(@NonNull ArraySet<JobStatus> expired) { protected void processExpiredAlarms(@NonNull ArraySet<JobStatus> expired) { synchronized (mLock) { synchronized (mLock) { ArraySet<JobStatus> changedJobs = new ArraySet<>(); ArraySet<JobStatus> changedJobs = new ArraySet<>(); final long nowElapsed = sElapsedRealtimeClock.millis(); for (int i = 0; i < expired.size(); i++) { for (int i = 0; i < expired.size(); i++) { JobStatus js = expired.valueAt(i); JobStatus js = expired.valueAt(i); boolean wasFlexibilitySatisfied = js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE); boolean wasFlexibilitySatisfied = js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE); final long earliest = getLifeCycleBeginningElapsedLocked(js); final long earliest = getLifeCycleBeginningElapsedLocked(js); final long latest = getLifeCycleEndElapsedLocked(js, earliest); final long latest = getLifeCycleEndElapsedLocked(js, earliest); final long nowElapsed = sElapsedRealtimeClock.millis(); if (latest - nowElapsed < mDeadlineProximityLimitMs) { if (latest - nowElapsed < mDeadlineProximityLimitMs) { mFlexibilityTracker.adjustJobsRequiredConstraints(js, mFlexibilityTracker.adjustJobsRequiredConstraints(js, -js.getNumRequiredFlexibleConstraints()); -js.getNumRequiredFlexibleConstraints(), nowElapsed); } else { } else { long nextTimeElapsed = long nextTimeElapsed = getNextConstraintDropTimeElapsedLocked(js, earliest, latest); getNextConstraintDropTimeElapsedLocked(js, earliest, latest); if (mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1) if (mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1, nowElapsed) && nextTimeElapsed != NO_LIFECYCLE_END) { && nextTimeElapsed != NO_LIFECYCLE_END) { mFlexibilityAlarmQueue.addAlarm(js, nextTimeElapsed); mFlexibilityAlarmQueue.addAlarm(js, nextTimeElapsed); } } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -95,9 +95,10 @@ public final class IdleController extends RestrictingController implements Idlen */ */ @Override @Override public void reportNewIdleState(boolean isIdle) { public void reportNewIdleState(boolean isIdle) { mFlexibilityController.setConstraintSatisfied(JobStatus.CONSTRAINT_IDLE, isIdle); synchronized (mLock) { synchronized (mLock) { final long nowElapsed = sElapsedRealtimeClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); mFlexibilityController.setConstraintSatisfied( JobStatus.CONSTRAINT_IDLE, isIdle, nowElapsed); for (int i = mTrackedTasks.size()-1; i >= 0; i--) { for (int i = mTrackedTasks.size()-1; i >= 0; i--) { mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle); mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle); } } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -105,7 +105,7 @@ public class PrefetchController extends StateController { public interface PrefetchChangedListener { public interface PrefetchChangedListener { /** Callback to inform listeners when estimated launch times change. */ /** Callback to inform listeners when estimated launch times change. */ void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, String pkgName, void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, String pkgName, long prevEstimatedLaunchTime, long newEstimatedLaunchTime); long prevEstimatedLaunchTime, long newEstimatedLaunchTime, long nowElapsed); } } @SuppressWarnings("FieldCanBeLocal") @SuppressWarnings("FieldCanBeLocal") Loading Loading @@ -308,8 +308,9 @@ public class PrefetchController extends StateController { final long nowElapsed = sElapsedRealtimeClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); updateThresholdAlarmLocked(userId, pkgName, now, nowElapsed); updateThresholdAlarmLocked(userId, pkgName, now, nowElapsed); for (int i = 0; i < mPrefetchChangedListeners.size(); i++) { for (int i = 0; i < mPrefetchChangedListeners.size(); i++) { mPrefetchChangedListeners.valueAt(i).onPrefetchCacheUpdated(jobs, mPrefetchChangedListeners.valueAt(i).onPrefetchCacheUpdated( userId, pkgName, prevEstimatedLaunchTime, newEstimatedLaunchTime); jobs, userId, pkgName, prevEstimatedLaunchTime, newEstimatedLaunchTime, nowElapsed); } } if (maybeUpdateConstraintForPkgLocked(now, nowElapsed, userId, pkgName)) { if (maybeUpdateConstraintForPkgLocked(now, nowElapsed, userId, pkgName)) { mStateChangedListener.onControllerStateChanged(jobs); mStateChangedListener.onControllerStateChanged(jobs); Loading
services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java +63 −43 Original line number Original line Diff line number Diff line Loading @@ -209,7 +209,8 @@ public class FlexibilityControllerTest { public void testOnConstantsUpdated_DeadlineProximity() { public void testOnConstantsUpdated_DeadlineProximity() { JobStatus js = createJobStatus("testDeadlineProximityConfig", createJob(0)); JobStatus js = createJobStatus("testDeadlineProximityConfig", createJob(0)); setDeviceConfigLong(KEY_DEADLINE_PROXIMITY_LIMIT, Long.MAX_VALUE); setDeviceConfigLong(KEY_DEADLINE_PROXIMITY_LIMIT, Long.MAX_VALUE); mFlexibilityController.mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js); mFlexibilityController.mFlexibilityAlarmQueue .scheduleDropNumConstraintsAlarm(js, FROZEN_TIME); assertEquals(0, js.getNumRequiredFlexibleConstraints()); assertEquals(0, js.getNumRequiredFlexibleConstraints()); } } Loading Loading @@ -336,26 +337,31 @@ public class FlexibilityControllerTest { @Test @Test public void testCurPercent() { public void testCurPercent() { long deadline = 1000; long deadline = 1000; long nowElapsed; JobInfo.Builder jb = createJob(0).setOverrideDeadline(deadline); JobInfo.Builder jb = createJob(0).setOverrideDeadline(deadline); JobStatus js = createJobStatus("time", jb); JobStatus js = createJobStatus("time", jb); assertEquals(FROZEN_TIME, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); assertEquals(FROZEN_TIME, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); assertEquals(deadline + FROZEN_TIME, assertEquals(deadline + FROZEN_TIME, mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME)); mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME)); nowElapsed = 600 + FROZEN_TIME; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(600 + FROZEN_TIME), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = 1400; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(1400), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = 950 + FROZEN_TIME; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(950 + FROZEN_TIME), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = FROZEN_TIME; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(FROZEN_TIME), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); long delay = 100; long delay = 100; deadline = 1100; deadline = 1100; jb = createJob(0).setOverrideDeadline(deadline).setMinimumLatency(delay); jb = createJob(0).setOverrideDeadline(deadline).setMinimumLatency(delay); Loading @@ -366,18 +372,21 @@ public class FlexibilityControllerTest { assertEquals(deadline + FROZEN_TIME, assertEquals(deadline + FROZEN_TIME, mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME + delay)); mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME + delay)); nowElapsed = 600 + FROZEN_TIME + delay; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(600 + FROZEN_TIME + delay), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = 1400; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(1400), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = 950 + FROZEN_TIME + delay; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(950 + FROZEN_TIME + delay), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); } } @Test @Test Loading Loading @@ -491,19 +500,19 @@ public class FlexibilityControllerTest { assertEquals(3, trackedJobs.get(2).size()); assertEquals(3, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(0).size()); assertEquals(1, trackedJobs.get(1).size()); assertEquals(1, trackedJobs.get(1).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME); assertEquals(1, trackedJobs.get(0).size()); assertEquals(1, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1); flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(2, trackedJobs.get(2).size()); Loading @@ -515,24 +524,25 @@ public class FlexibilityControllerTest { assertEquals(1, trackedJobs.get(2).size()); assertEquals(1, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.resetJobNumDroppedConstraints(jobs[0]); flexTracker.resetJobNumDroppedConstraints(jobs[0], FROZEN_TIME); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(2, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); flexTracker.adjustJobsRequiredConstraints(jobs[0], -2); flexTracker.adjustJobsRequiredConstraints(jobs[0], -2, FROZEN_TIME); assertEquals(1, trackedJobs.get(0).size()); assertEquals(1, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(0, trackedJobs.get(1).size()); assertEquals(1, trackedJobs.get(2).size()); assertEquals(1, trackedJobs.get(2).size()); assertEquals(0, trackedJobs.get(3).size()); assertEquals(0, trackedJobs.get(3).size()); final long nowElapsed = ((DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_MS / 2) + HOUR_IN_MILLIS); JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli((DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_MS / 2) Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); + HOUR_IN_MILLIS), ZoneOffset.UTC); flexTracker.resetJobNumDroppedConstraints(jobs[0]); flexTracker.resetJobNumDroppedConstraints(jobs[0], nowElapsed); assertEquals(0, trackedJobs.get(0).size()); assertEquals(0, trackedJobs.get(0).size()); assertEquals(1, trackedJobs.get(1).size()); assertEquals(1, trackedJobs.get(1).size()); assertEquals(1, trackedJobs.get(2).size()); assertEquals(1, trackedJobs.get(2).size()); Loading Loading @@ -615,13 +625,13 @@ public class FlexibilityControllerTest { @Test @Test public void testSetConstraintSatisfied_Constraints() { public void testSetConstraintSatisfied_Constraints() { mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME); assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, true); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, true, FROZEN_TIME); assertTrue(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); assertTrue(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME); assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE)); } } Loading Loading @@ -651,20 +661,21 @@ public class FlexibilityControllerTest { createJobStatus(String.valueOf(i), jb), null); createJobStatus(String.valueOf(i), jb), null); } } } } mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, false); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, false, FROZEN_TIME); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, false); mFlexibilityController.setConstraintSatisfied( CONSTRAINT_BATTERY_NOT_LOW, false, FROZEN_TIME); assertEquals(0, mFlexibilityController.mSatisfiedFlexibleConstraints); assertEquals(0, mFlexibilityController.mSatisfiedFlexibleConstraints); for (int i = 0; i < constraintCombinations.length; i++) { for (int i = 0; i < constraintCombinations.length; i++) { constraints = constraintCombinations[i]; constraints = constraintCombinations[i]; mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, (constraints & CONSTRAINT_CHARGING) != 0); (constraints & CONSTRAINT_CHARGING) != 0, FROZEN_TIME); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, (constraints & CONSTRAINT_IDLE) != 0); (constraints & CONSTRAINT_IDLE) != 0, FROZEN_TIME); mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, (constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0); (constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0, FROZEN_TIME); assertEquals(constraints, mFlexibilityController.mSatisfiedFlexibleConstraints); assertEquals(constraints, mFlexibilityController.mSatisfiedFlexibleConstraints); synchronized (mFlexibilityController.mLock) { synchronized (mFlexibilityController.mLock) { Loading @@ -679,6 +690,7 @@ public class FlexibilityControllerTest { JobInfo.Builder jb = createJob(22).setOverrideDeadline(100L); JobInfo.Builder jb = createJob(22).setOverrideDeadline(100L); JobStatus js = createJobStatus("testResetJobNumDroppedConstraints", jb); JobStatus js = createJobStatus("testResetJobNumDroppedConstraints", jb); js.adjustNumRequiredFlexibleConstraints(3); js.adjustNumRequiredFlexibleConstraints(3); long nowElapsed; mFlexibilityController.mFlexibilityTracker.add(js); mFlexibilityController.mFlexibilityTracker.add(js); Loading @@ -687,45 +699,51 @@ public class FlexibilityControllerTest { assertEquals(1, mFlexibilityController assertEquals(1, mFlexibilityController .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size()); .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size()); nowElapsed = 155L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(155L), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1); mFlexibilityController.mFlexibilityTracker .adjustJobsRequiredConstraints(js, -1, nowElapsed); assertEquals(2, js.getNumRequiredFlexibleConstraints()); assertEquals(2, js.getNumRequiredFlexibleConstraints()); assertEquals(1, js.getNumDroppedFlexibleConstraints()); assertEquals(1, js.getNumDroppedFlexibleConstraints()); assertEquals(1, mFlexibilityController assertEquals(1, mFlexibilityController .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size()); .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size()); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); assertEquals(2, js.getNumRequiredFlexibleConstraints()); assertEquals(2, js.getNumRequiredFlexibleConstraints()); assertEquals(1, js.getNumDroppedFlexibleConstraints()); assertEquals(1, js.getNumDroppedFlexibleConstraints()); assertEquals(1, mFlexibilityController assertEquals(1, mFlexibilityController .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size()); .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size()); nowElapsed = 140L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(140L), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); assertEquals(3, js.getNumRequiredFlexibleConstraints()); assertEquals(3, js.getNumRequiredFlexibleConstraints()); assertEquals(0, js.getNumDroppedFlexibleConstraints()); assertEquals(0, js.getNumDroppedFlexibleConstraints()); assertEquals(1, mFlexibilityController assertEquals(1, mFlexibilityController .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size()); .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size()); nowElapsed = 175L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(175), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); assertEquals(0, js.getNumRequiredFlexibleConstraints()); assertEquals(0, js.getNumRequiredFlexibleConstraints()); assertEquals(3, js.getNumDroppedFlexibleConstraints()); assertEquals(3, js.getNumDroppedFlexibleConstraints()); nowElapsed = 165L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(165L), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js); mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed); assertEquals(1, js.getNumRequiredFlexibleConstraints()); assertEquals(1, js.getNumRequiredFlexibleConstraints()); assertEquals(2, js.getNumDroppedFlexibleConstraints()); assertEquals(2, js.getNumDroppedFlexibleConstraints()); Loading @@ -745,12 +763,14 @@ public class FlexibilityControllerTest { mFlexibilityController.maybeStartTrackingJobLocked(js, null); mFlexibilityController.maybeStartTrackingJobLocked(js, null); final long nowElapsed = 150L; JobSchedulerService.sElapsedRealtimeClock = JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(150L), ZoneOffset.UTC); Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); mFlexibilityController.mPrefetchChangedListener.onPrefetchCacheUpdated( mFlexibilityController.mPrefetchChangedListener.onPrefetchCacheUpdated( jobs, js.getUserId(), js.getSourcePackageName(), Long.MAX_VALUE, jobs, js.getUserId(), js.getSourcePackageName(), Long.MAX_VALUE, 1150L + mFlexibilityController.mConstants.PREFETCH_FORCE_BATCH_RELAX_THRESHOLD_MS); 1150L + mFlexibilityController.mConstants.PREFETCH_FORCE_BATCH_RELAX_THRESHOLD_MS, nowElapsed); assertEquals(150L, assertEquals(150L, (long) mFlexibilityController.mPrefetchLifeCycleStart (long) mFlexibilityController.mPrefetchLifeCycleStart Loading @@ -758,7 +778,7 @@ public class FlexibilityControllerTest { assertEquals(150L, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); assertEquals(150L, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); assertEquals(1150L, assertEquals(1150L, mFlexibilityController.getLifeCycleEndElapsedLocked(js, 150L)); mFlexibilityController.getLifeCycleEndElapsedLocked(js, 150L)); assertEquals(0, mFlexibilityController.getCurPercentOfLifecycleLocked(js)); assertEquals(0, mFlexibilityController.getCurPercentOfLifecycleLocked(js, FROZEN_TIME)); assertEquals(650L, mFlexibilityController assertEquals(650L, mFlexibilityController .getNextConstraintDropTimeElapsedLocked(js)); .getNextConstraintDropTimeElapsedLocked(js)); assertEquals(3, js.getNumRequiredFlexibleConstraints()); assertEquals(3, js.getNumRequiredFlexibleConstraints()); Loading