diff options
3 files changed, 119 insertions, 80 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java index 6883d18cd937..aec464d0e820 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java @@ -241,6 +241,8 @@ public final class FlexibilityController extends StateController { private static final long MAX_TIME_WINDOW_MS = 24 * HOUR_IN_MILLIS; private final JobScoreBucket[] mScoreBuckets = new JobScoreBucket[NUM_SCORE_BUCKETS]; private int mScoreBucketIndex = 0; + private long mCachedScoreExpirationTimeElapsed; + private int mCachedScore; public void addScore(int add, long nowElapsed) { JobScoreBucket bucket = mScoreBuckets[mScoreBucketIndex]; @@ -248,10 +250,17 @@ public final class FlexibilityController extends StateController { bucket = new JobScoreBucket(); bucket.startTimeElapsed = nowElapsed; mScoreBuckets[mScoreBucketIndex] = bucket; + // Brand new bucket, there's nothing to remove from the score, + // so just update the expiration time if needed. + mCachedScoreExpirationTimeElapsed = Math.min(mCachedScoreExpirationTimeElapsed, + nowElapsed + MAX_TIME_WINDOW_MS); } else if (bucket.startTimeElapsed < nowElapsed - MAX_TIME_WINDOW_MS) { // The bucket is too old. bucket.reset(); bucket.startTimeElapsed = nowElapsed; + // Force a recalculation of the cached score instead of just updating the cached + // value and time in case there are multiple stale buckets. + mCachedScoreExpirationTimeElapsed = nowElapsed; } else if (bucket.startTimeElapsed < nowElapsed - MAX_TIME_WINDOW_MS / NUM_SCORE_BUCKETS) { // The current bucket's duration has completed. Move on to the next bucket. @@ -261,16 +270,26 @@ public final class FlexibilityController extends StateController { } bucket.score += add; + mCachedScore += add; } public int getScore(long nowElapsed) { + if (nowElapsed < mCachedScoreExpirationTimeElapsed) { + return mCachedScore; + } int score = 0; final long earliestElapsed = nowElapsed - MAX_TIME_WINDOW_MS; + long earliestValidBucketTimeElapsed = Long.MAX_VALUE; for (JobScoreBucket bucket : mScoreBuckets) { if (bucket != null && bucket.startTimeElapsed >= earliestElapsed) { score += bucket.score; + if (earliestValidBucketTimeElapsed > bucket.startTimeElapsed) { + earliestValidBucketTimeElapsed = bucket.startTimeElapsed; + } } } + mCachedScore = score; + mCachedScoreExpirationTimeElapsed = earliestValidBucketTimeElapsed + MAX_TIME_WINDOW_MS; return score; } @@ -378,10 +397,16 @@ public final class FlexibilityController extends StateController { @Override public void prepareForExecutionLocked(JobStatus jobStatus) { + if (jobStatus.lastEvaluatedBias == JobInfo.BIAS_TOP_APP) { + // Don't include jobs for the TOP app in the score calculation. + return; + } // Use the job's requested priority to determine its score since that is what the developer // selected and it will be stable across job runs. - final int score = mFallbackFlexibilityDeadlineScores - .get(jobStatus.getJob().getPriority(), jobStatus.getJob().getPriority() / 100); + final int priority = jobStatus.getJob().getPriority(); + final int score = mFallbackFlexibilityDeadlineScores.get(priority, + FcConfig.DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_SCORES + .get(priority, priority / 100)); JobScoreTracker jobScoreTracker = mJobScoreTrackers.get(jobStatus.getSourceUid(), jobStatus.getSourcePackageName()); if (jobScoreTracker == null) { @@ -394,6 +419,10 @@ public final class FlexibilityController extends StateController { @Override public void unprepareFromExecutionLocked(JobStatus jobStatus) { + if (jobStatus.lastEvaluatedBias == JobInfo.BIAS_TOP_APP) { + // Jobs for the TOP app are excluded from the score calculation. + return; + } // The job didn't actually start. Undo the score increase. JobScoreTracker jobScoreTracker = mJobScoreTrackers.get(jobStatus.getSourceUid(), jobStatus.getSourcePackageName()); @@ -401,8 +430,10 @@ public final class FlexibilityController extends StateController { Slog.e(TAG, "Unprepared a job that didn't result in a score change"); return; } - final int score = mFallbackFlexibilityDeadlineScores - .get(jobStatus.getJob().getPriority(), jobStatus.getJob().getPriority() / 100); + final int priority = jobStatus.getJob().getPriority(); + final int score = mFallbackFlexibilityDeadlineScores.get(priority, + FcConfig.DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_SCORES + .get(priority, priority / 100)); jobScoreTracker.addScore(-score, sElapsedRealtimeClock.millis()); } @@ -649,21 +680,24 @@ public final class FlexibilityController extends StateController { (long) Math.scalb(mRescheduledJobDeadline, js.getNumPreviousAttempts() - 2), mMaxRescheduledDeadline); } + + // Intentionally use the effective priority here. If a job's priority was effectively + // lowered, it will be less likely to run quickly given other policies in JobScheduler. + // Thus, there's no need to further delay the job based on flex policy. + final int jobPriority = js.getEffectivePriority(); + final int jobScore = + getScoreLocked(js.getSourceUid(), js.getSourcePackageName(), nowElapsed); + // Set an upper limit on the fallback deadline so that the delay doesn't become extreme. + final long fallbackDurationMs = Math.min(3 * mFallbackFlexibilityDeadlineMs, + mFallbackFlexibilityDeadlines.get(jobPriority, mFallbackFlexibilityDeadlineMs) + + mFallbackFlexibilityAdditionalScoreTimeFactors + .get(jobPriority, MINUTE_IN_MILLIS) * jobScore); + final long fallbackDeadlineMs = earliest + fallbackDurationMs; + if (js.getLatestRunTimeElapsed() == JobStatus.NO_LATEST_RUNTIME) { - // Intentionally use the effective priority here. If a job's priority was effectively - // lowered, it will be less likely to run quickly given other policies in JobScheduler. - // Thus, there's no need to further delay the job based on flex policy. - final int jobPriority = js.getEffectivePriority(); - final int jobScore = - getScoreLocked(js.getSourceUid(), js.getSourcePackageName(), nowElapsed); - // Set an upper limit on the fallback deadline so that the delay doesn't become extreme. - final long fallbackDeadlineMs = Math.min(3 * mFallbackFlexibilityDeadlineMs, - mFallbackFlexibilityDeadlines.get(jobPriority, mFallbackFlexibilityDeadlineMs) - + mFallbackFlexibilityAdditionalScoreTimeFactors - .get(jobPriority, MINUTE_IN_MILLIS) * jobScore); - return earliest + fallbackDeadlineMs; + return fallbackDeadlineMs; } - return js.getLatestRunTimeElapsed(); + return Math.max(fallbackDeadlineMs, js.getLatestRunTimeElapsed()); } @VisibleForTesting @@ -976,7 +1010,8 @@ public final class FlexibilityController extends StateController { // Something has gone horribly wrong. This has only occurred on incorrectly // configured tests, but add a check here for safety. Slog.wtf(TAG, "Got invalid latest when scheduling alarm." - + " Prefetch=" + js.getJob().isPrefetch()); + + " prefetch=" + js.getJob().isPrefetch() + + " periodic=" + js.getJob().isPeriodic()); // Since things have gone wrong, the safest and most reliable thing to do is // stop applying flex policy to the job. mFlexibilityTracker.setNumDroppedFlexibleConstraints(js, @@ -991,7 +1026,7 @@ public final class FlexibilityController extends StateController { if (DEBUG) { Slog.d(TAG, "scheduleDropNumConstraintsAlarm: " - + js.getSourcePackageName() + " " + js.getSourceUserId() + + js.toShortString() + " numApplied: " + js.getNumAppliedFlexibleConstraints() + " numRequired: " + js.getNumRequiredFlexibleConstraints() + " numSatisfied: " + Integer.bitCount( @@ -1199,11 +1234,11 @@ public final class FlexibilityController extends StateController { DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_ADDITIONAL_SCORE_TIME_FACTORS .put(PRIORITY_MAX, 0); DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_ADDITIONAL_SCORE_TIME_FACTORS - .put(PRIORITY_HIGH, 4 * MINUTE_IN_MILLIS); + .put(PRIORITY_HIGH, 3 * MINUTE_IN_MILLIS); DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_ADDITIONAL_SCORE_TIME_FACTORS - .put(PRIORITY_DEFAULT, 3 * MINUTE_IN_MILLIS); + .put(PRIORITY_DEFAULT, 2 * MINUTE_IN_MILLIS); DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_ADDITIONAL_SCORE_TIME_FACTORS - .put(PRIORITY_LOW, 2 * MINUTE_IN_MILLIS); + .put(PRIORITY_LOW, 1 * MINUTE_IN_MILLIS); DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_ADDITIONAL_SCORE_TIME_FACTORS .put(PRIORITY_MIN, 1 * MINUTE_IN_MILLIS); DEFAULT_PERCENTS_TO_DROP_FLEXIBLE_CONSTRAINTS @@ -1220,7 +1255,7 @@ public final class FlexibilityController extends StateController { private static final long DEFAULT_MIN_TIME_BETWEEN_FLEXIBILITY_ALARMS_MS = MINUTE_IN_MILLIS; private static final long DEFAULT_RESCHEDULED_JOB_DEADLINE_MS = HOUR_IN_MILLIS; - private static final long DEFAULT_MAX_RESCHEDULED_DEADLINE_MS = 5 * DAY_IN_MILLIS; + private static final long DEFAULT_MAX_RESCHEDULED_DEADLINE_MS = DAY_IN_MILLIS; @VisibleForTesting static final long DEFAULT_UNSEEN_CONSTRAINT_GRACE_PERIOD_MS = 3 * DAY_IN_MILLIS; diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index a3a686fdc5c8..a0b9c5fb7a60 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -16,8 +16,6 @@ package com.android.server.job.controllers; -import static android.text.format.DateUtils.HOUR_IN_MILLIS; - import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX; import static com.android.server.job.JobSchedulerService.EXEMPTED_INDEX; import static com.android.server.job.JobSchedulerService.NEVER_INDEX; @@ -430,9 +428,6 @@ public final class JobStatus { */ public static final int INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ = 1 << 2; - /** Minimum difference between start and end time to have flexible constraint */ - @VisibleForTesting - static final long MIN_WINDOW_FOR_FLEXIBILITY_MS = HOUR_IN_MILLIS; /** * Versatile, persistable flags for a job that's updated within the system server, * as opposed to {@link JobInfo#flags} that's set by callers. @@ -708,14 +703,10 @@ public final class JobStatus { final boolean lacksSomeFlexibleConstraints = ((~requiredConstraints) & SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS) != 0 || mCanApplyTransportAffinities; - final boolean satisfiesMinWindowException = - (latestRunTimeElapsedMillis - earliestRunTimeElapsedMillis) - >= MIN_WINDOW_FOR_FLEXIBILITY_MS; // The first time a job is rescheduled it will not be subject to flexible constraints. // Otherwise, every consecutive reschedule increases a jobs' flexibility deadline. if (!isRequestedExpeditedJob() && !job.isUserInitiated() - && satisfiesMinWindowException && (numFailures + numSystemStops) != 1 && lacksSomeFlexibleConstraints) { requiredConstraints |= CONSTRAINT_FLEXIBLE; diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java index 28471b37d2a0..6bcd778c234b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java @@ -49,7 +49,6 @@ import static com.android.server.job.controllers.JobStatus.CONSTRAINT_CONNECTIVI import static com.android.server.job.controllers.JobStatus.CONSTRAINT_CONTENT_TRIGGER; import static com.android.server.job.controllers.JobStatus.CONSTRAINT_FLEXIBLE; import static com.android.server.job.controllers.JobStatus.CONSTRAINT_IDLE; -import static com.android.server.job.controllers.JobStatus.MIN_WINDOW_FOR_FLEXIBILITY_MS; import static com.android.server.job.controllers.JobStatus.NO_LATEST_RUNTIME; import static org.junit.Assert.assertArrayEquals; @@ -410,10 +409,12 @@ public class FlexibilityControllerTest { @Test public void testOnConstantsUpdated_PercentsToDropConstraints() { + final long fallbackDuration = 12 * HOUR_IN_MILLIS; JobInfo.Builder jb = createJob(0) - .setOverrideDeadline(MIN_WINDOW_FOR_FLEXIBILITY_MS); + .setOverrideDeadline(HOUR_IN_MILLIS); JobStatus js = createJobStatus("testPercentsToDropConstraintsConfig", jb); - assertEquals(FROZEN_TIME + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 5, + // Even though the override deadline is 1 hour, the fallback duration is still used. + assertEquals(FROZEN_TIME + fallbackDuration / 10 * 5, mFlexibilityController.getNextConstraintDropTimeElapsedLocked(js)); setDeviceConfigString(KEY_PERCENTS_TO_DROP_FLEXIBLE_CONSTRAINTS, "500=1|2|3|4" @@ -441,13 +442,13 @@ public class FlexibilityControllerTest { mFlexibilityController.mFcConfig.PERCENTS_TO_DROP_FLEXIBLE_CONSTRAINTS .get(JobInfo.PRIORITY_MIN), new int[]{54, 55, 56, 57}); - assertEquals(FROZEN_TIME + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10, + assertEquals(FROZEN_TIME + fallbackDuration / 10, mFlexibilityController.getNextConstraintDropTimeElapsedLocked(js)); js.setNumDroppedFlexibleConstraints(1); - assertEquals(FROZEN_TIME + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 2, + assertEquals(FROZEN_TIME + fallbackDuration / 10 * 2, mFlexibilityController.getNextConstraintDropTimeElapsedLocked(js)); js.setNumDroppedFlexibleConstraints(2); - assertEquals(FROZEN_TIME + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 3, + assertEquals(FROZEN_TIME + fallbackDuration / 10 * 3, mFlexibilityController.getNextConstraintDropTimeElapsedLocked(js)); } @@ -504,37 +505,38 @@ public class FlexibilityControllerTest { @Test public void testGetNextConstraintDropTimeElapsedLocked() { + final long fallbackDuration = 50 * HOUR_IN_MILLIS; setDeviceConfigLong(KEY_FALLBACK_FLEXIBILITY_DEADLINE, 200 * HOUR_IN_MILLIS); setDeviceConfigString(KEY_FALLBACK_FLEXIBILITY_DEADLINES, "500=" + HOUR_IN_MILLIS + ",400=" + 25 * HOUR_IN_MILLIS - + ",300=" + 50 * HOUR_IN_MILLIS + + ",300=" + fallbackDuration + ",200=" + 100 * HOUR_IN_MILLIS + ",100=" + 200 * HOUR_IN_MILLIS); long nextTimeToDropNumConstraints; // no delay, deadline - JobInfo.Builder jb = createJob(0).setOverrideDeadline(MIN_WINDOW_FOR_FLEXIBILITY_MS); + JobInfo.Builder jb = createJob(0).setOverrideDeadline(HOUR_IN_MILLIS); JobStatus js = createJobStatus("time", jb); assertEquals(JobStatus.NO_EARLIEST_RUNTIME, js.getEarliestRunTime()); - assertEquals(MIN_WINDOW_FOR_FLEXIBILITY_MS + FROZEN_TIME, js.getLatestRunTimeElapsed()); + assertEquals(HOUR_IN_MILLIS + FROZEN_TIME, js.getLatestRunTimeElapsed()); assertEquals(FROZEN_TIME, js.enqueueTime); nextTimeToDropNumConstraints = mFlexibilityController .getNextConstraintDropTimeElapsedLocked(js); - assertEquals(FROZEN_TIME + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 5, + assertEquals(FROZEN_TIME + fallbackDuration / 10 * 5, nextTimeToDropNumConstraints); js.setNumDroppedFlexibleConstraints(1); nextTimeToDropNumConstraints = mFlexibilityController .getNextConstraintDropTimeElapsedLocked(js); - assertEquals(FROZEN_TIME + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 6, + assertEquals(FROZEN_TIME + fallbackDuration / 10 * 6, nextTimeToDropNumConstraints); js.setNumDroppedFlexibleConstraints(2); nextTimeToDropNumConstraints = mFlexibilityController .getNextConstraintDropTimeElapsedLocked(js); - assertEquals(FROZEN_TIME + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 7, + assertEquals(FROZEN_TIME + fallbackDuration / 10 * 7, nextTimeToDropNumConstraints); // delay, no deadline @@ -574,81 +576,83 @@ public class FlexibilityControllerTest { // delay, deadline jb = createJob(0) - .setOverrideDeadline(2 * MIN_WINDOW_FOR_FLEXIBILITY_MS) - .setMinimumLatency(MIN_WINDOW_FOR_FLEXIBILITY_MS); + .setOverrideDeadline(2 * HOUR_IN_MILLIS) + .setMinimumLatency(HOUR_IN_MILLIS); js = createJobStatus("time", jb); - final long windowStart = FROZEN_TIME + MIN_WINDOW_FOR_FLEXIBILITY_MS; + final long windowStart = FROZEN_TIME + HOUR_IN_MILLIS; nextTimeToDropNumConstraints = mFlexibilityController .getNextConstraintDropTimeElapsedLocked(js); - assertEquals(windowStart + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 5, + assertEquals(windowStart + fallbackDuration / 10 * 5, nextTimeToDropNumConstraints); js.setNumDroppedFlexibleConstraints(1); nextTimeToDropNumConstraints = mFlexibilityController .getNextConstraintDropTimeElapsedLocked(js); - assertEquals(windowStart + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 6, + assertEquals(windowStart + fallbackDuration / 10 * 6, nextTimeToDropNumConstraints); js.setNumDroppedFlexibleConstraints(2); nextTimeToDropNumConstraints = mFlexibilityController .getNextConstraintDropTimeElapsedLocked(js); - assertEquals(windowStart + MIN_WINDOW_FOR_FLEXIBILITY_MS / 10 * 7, + assertEquals(windowStart + fallbackDuration / 10 * 7, nextTimeToDropNumConstraints); } @Test public void testCurPercent() { + final long fallbackDuration = 10 * HOUR_IN_MILLIS; + setDeviceConfigString(KEY_FALLBACK_FLEXIBILITY_DEADLINES, "300=" + fallbackDuration); long deadline = 100 * MINUTE_IN_MILLIS; long nowElapsed = FROZEN_TIME; JobInfo.Builder jb = createJob(0).setOverrideDeadline(deadline); JobStatus js = createJobStatus("time", jb); assertEquals(FROZEN_TIME, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); - assertEquals(deadline + FROZEN_TIME, + assertEquals(FROZEN_TIME + fallbackDuration, mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, FROZEN_TIME)); - nowElapsed = FROZEN_TIME + 60 * MINUTE_IN_MILLIS; + nowElapsed = FROZEN_TIME + 6 * HOUR_IN_MILLIS; JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); - nowElapsed = FROZEN_TIME + 130 * MINUTE_IN_MILLIS; + nowElapsed = FROZEN_TIME + 13 * HOUR_IN_MILLIS; JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); - nowElapsed = FROZEN_TIME + 95 * MINUTE_IN_MILLIS; + nowElapsed = FROZEN_TIME + 9 * HOUR_IN_MILLIS; JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); - assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); + assertEquals(90, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); nowElapsed = FROZEN_TIME; JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); - long delay = MINUTE_IN_MILLIS; - deadline = 101 * MINUTE_IN_MILLIS; + long delay = HOUR_IN_MILLIS; + deadline = HOUR_IN_MILLIS + 100 * MINUTE_IN_MILLIS; jb = createJob(0).setOverrideDeadline(deadline).setMinimumLatency(delay); js = createJobStatus("time", jb); assertEquals(FROZEN_TIME + delay, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js)); - assertEquals(deadline + FROZEN_TIME, + assertEquals(FROZEN_TIME + delay + fallbackDuration, mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, FROZEN_TIME + delay)); - nowElapsed = FROZEN_TIME + delay + 60 * MINUTE_IN_MILLIS; + nowElapsed = FROZEN_TIME + delay + 6 * HOUR_IN_MILLIS; JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); - nowElapsed = FROZEN_TIME + 130 * MINUTE_IN_MILLIS; + nowElapsed = FROZEN_TIME + 13 * HOUR_IN_MILLIS; JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); - nowElapsed = FROZEN_TIME + delay + 95 * MINUTE_IN_MILLIS; + nowElapsed = FROZEN_TIME + delay + 9 * HOUR_IN_MILLIS; JobSchedulerService.sElapsedRealtimeClock = Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC); - assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); + assertEquals(90, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed)); } @Test @@ -786,26 +790,27 @@ public class FlexibilityControllerTest { // deadline JobInfo.Builder jb = createJob(0).setOverrideDeadline(HOUR_IN_MILLIS); JobStatus js = createJobStatus("time", jb); - assertEquals(HOUR_IN_MILLIS + FROZEN_TIME, - mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, 0)); + assertEquals(3 * HOUR_IN_MILLIS + js.enqueueTime, + mFlexibilityController + .getLifeCycleEndElapsedLocked(js, nowElapsed, js.enqueueTime)); // no deadline - assertEquals(FROZEN_TIME + 2 * HOUR_IN_MILLIS, + assertEquals(js.enqueueTime + 2 * HOUR_IN_MILLIS, mFlexibilityController.getLifeCycleEndElapsedLocked( createJobStatus("time", createJob(0).setPriority(JobInfo.PRIORITY_HIGH)), - nowElapsed, 100L)); - assertEquals(FROZEN_TIME + 3 * HOUR_IN_MILLIS, + nowElapsed, js.enqueueTime)); + assertEquals(js.enqueueTime + 3 * HOUR_IN_MILLIS, mFlexibilityController.getLifeCycleEndElapsedLocked( createJobStatus("time", createJob(0).setPriority(JobInfo.PRIORITY_DEFAULT)), - nowElapsed, 100L)); - assertEquals(FROZEN_TIME + 4 * HOUR_IN_MILLIS, + nowElapsed, js.enqueueTime)); + assertEquals(js.enqueueTime + 4 * HOUR_IN_MILLIS, mFlexibilityController.getLifeCycleEndElapsedLocked( createJobStatus("time", createJob(0).setPriority(JobInfo.PRIORITY_LOW)), - nowElapsed, 100L)); - assertEquals(FROZEN_TIME + 5 * HOUR_IN_MILLIS, + nowElapsed, js.enqueueTime)); + assertEquals(js.enqueueTime + 5 * HOUR_IN_MILLIS, mFlexibilityController.getLifeCycleEndElapsedLocked( createJobStatus("time", createJob(0).setPriority(JobInfo.PRIORITY_MIN)), - nowElapsed, 100L)); + nowElapsed, js.enqueueTime)); } @Test @@ -871,14 +876,16 @@ public class FlexibilityControllerTest { mFlexibilityController.prepareForExecutionLocked(jsLow); mFlexibilityController.prepareForExecutionLocked(jsMin); - // deadline - JobInfo.Builder jb = createJob(0).setOverrideDeadline(HOUR_IN_MILLIS); - JobStatus js = createJobStatus("testGetLifeCycleEndElapsedLocked_ScoreAddition", jb); - assertEquals(HOUR_IN_MILLIS + FROZEN_TIME, - mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, 0)); + final long longDeadlineMs = 14 * 24 * HOUR_IN_MILLIS; + JobInfo.Builder jbWithLongDeadline = createJob(0).setOverrideDeadline(longDeadlineMs); + JobStatus jsWithLongDeadline = createJobStatus( + "testGetLifeCycleEndElapsedLocked_ScoreAddition", jbWithLongDeadline); + JobInfo.Builder jbWithShortDeadline = + createJob(0).setOverrideDeadline(15 * MINUTE_IN_MILLIS); + JobStatus jsWithShortDeadline = createJobStatus( + "testGetLifeCycleEndElapsedLocked_ScoreAddition", jbWithShortDeadline); final long earliestMs = 123L; - // no deadline assertEquals(earliestMs + HOUR_IN_MILLIS + 5 * 15 * MINUTE_IN_MILLIS, mFlexibilityController.getLifeCycleEndElapsedLocked( createJobStatus("testGetLifeCycleEndElapsedLocked_ScoreAddition", @@ -894,6 +901,9 @@ public class FlexibilityControllerTest { createJobStatus("testGetLifeCycleEndElapsedLocked_ScoreAddition", createJob(0).setPriority(JobInfo.PRIORITY_DEFAULT)), nowElapsed, earliestMs)); + assertEquals(earliestMs + HOUR_IN_MILLIS + 3 * 15 * MINUTE_IN_MILLIS, + mFlexibilityController.getLifeCycleEndElapsedLocked( + jsWithShortDeadline, nowElapsed, earliestMs)); assertEquals(earliestMs + HOUR_IN_MILLIS + 2 * 15 * MINUTE_IN_MILLIS, mFlexibilityController.getLifeCycleEndElapsedLocked( createJobStatus("testGetLifeCycleEndElapsedLocked_ScoreAddition", @@ -904,6 +914,9 @@ public class FlexibilityControllerTest { createJobStatus("testGetLifeCycleEndElapsedLocked_ScoreAddition", createJob(0).setPriority(JobInfo.PRIORITY_MIN)), nowElapsed, earliestMs)); + assertEquals(jsWithLongDeadline.enqueueTime + longDeadlineMs, + mFlexibilityController.getLifeCycleEndElapsedLocked( + jsWithLongDeadline, nowElapsed, earliestMs)); } @Test @@ -1033,8 +1046,8 @@ public class FlexibilityControllerTest { JobInfo.Builder jb = createJob(0); jb.setMinimumLatency(1); jb.setOverrideDeadline(2); - JobStatus js = createJobStatus("Disable Flexible When Job Has Short Window", jb); - assertFalse(js.hasFlexibilityConstraint()); + JobStatus js = createJobStatus("testExceptions_ShortWindow", jb); + assertTrue(js.hasFlexibilityConstraint()); } @Test |