diff options
6 files changed, 200 insertions, 52 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index 963307b110cf..a5a08fb9997c 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -573,6 +573,7 @@ public class JobSchedulerService extends com.android.server.SystemService case Constants.KEY_MIN_LINEAR_BACKOFF_TIME_MS: case Constants.KEY_MIN_EXP_BACKOFF_TIME_MS: case Constants.KEY_SYSTEM_STOP_TO_FAILURE_RATIO: + case Constants.KEY_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF: mConstants.updateBackoffConstantsLocked(); break; case Constants.KEY_CONN_CONGESTION_DELAY_FRAC: @@ -679,6 +680,8 @@ public class JobSchedulerService extends com.android.server.SystemService private static final String KEY_MIN_EXP_BACKOFF_TIME_MS = "min_exp_backoff_time_ms"; private static final String KEY_SYSTEM_STOP_TO_FAILURE_RATIO = "system_stop_to_failure_ratio"; + private static final String KEY_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF = + "abandoned_job_timeouts_before_aggressive_backoff"; private static final String KEY_CONN_CONGESTION_DELAY_FRAC = "conn_congestion_delay_frac"; private static final String KEY_CONN_PREFETCH_RELAX_FRAC = "conn_prefetch_relax_frac"; private static final String KEY_CONN_USE_CELL_SIGNAL_STRENGTH = @@ -750,6 +753,7 @@ public class JobSchedulerService extends com.android.server.SystemService private static final long DEFAULT_MIN_LINEAR_BACKOFF_TIME_MS = JobInfo.MIN_BACKOFF_MILLIS; private static final long DEFAULT_MIN_EXP_BACKOFF_TIME_MS = JobInfo.MIN_BACKOFF_MILLIS; private static final int DEFAULT_SYSTEM_STOP_TO_FAILURE_RATIO = 3; + private static final int DEFAULT_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF = 3; private static final float DEFAULT_CONN_CONGESTION_DELAY_FRAC = 0.5f; private static final float DEFAULT_CONN_PREFETCH_RELAX_FRAC = 0.5f; private static final boolean DEFAULT_CONN_USE_CELL_SIGNAL_STRENGTH = true; @@ -845,7 +849,12 @@ public class JobSchedulerService extends com.android.server.SystemService * incremental failure in the backoff policy calculation. */ int SYSTEM_STOP_TO_FAILURE_RATIO = DEFAULT_SYSTEM_STOP_TO_FAILURE_RATIO; - + /** + * Number of consecutive timeouts by abandoned jobs before we change to aggressive backoff + * policy. + */ + int ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF = + DEFAULT_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF; /** * The fraction of a job's running window that must pass before we * consider running it when the network is congested. @@ -1078,6 +1087,10 @@ public class JobSchedulerService extends com.android.server.SystemService SYSTEM_STOP_TO_FAILURE_RATIO = DeviceConfig.getInt(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_SYSTEM_STOP_TO_FAILURE_RATIO, DEFAULT_SYSTEM_STOP_TO_FAILURE_RATIO); + ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF = DeviceConfig.getInt( + DeviceConfig.NAMESPACE_JOB_SCHEDULER, + KEY_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF, + DEFAULT_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF); } // TODO(141645789): move into ConnectivityController.CcConfig @@ -1287,6 +1300,8 @@ public class JobSchedulerService extends com.android.server.SystemService pw.print(KEY_MIN_LINEAR_BACKOFF_TIME_MS, MIN_LINEAR_BACKOFF_TIME_MS).println(); pw.print(KEY_MIN_EXP_BACKOFF_TIME_MS, MIN_EXP_BACKOFF_TIME_MS).println(); pw.print(KEY_SYSTEM_STOP_TO_FAILURE_RATIO, SYSTEM_STOP_TO_FAILURE_RATIO).println(); + pw.print(KEY_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF, + ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF).println(); pw.print(KEY_CONN_CONGESTION_DELAY_FRAC, CONN_CONGESTION_DELAY_FRAC).println(); pw.print(KEY_CONN_PREFETCH_RELAX_FRAC, CONN_PREFETCH_RELAX_FRAC).println(); pw.print(KEY_CONN_USE_CELL_SIGNAL_STRENGTH, CONN_USE_CELL_SIGNAL_STRENGTH).println(); @@ -2997,6 +3012,7 @@ public class JobSchedulerService extends com.android.server.SystemService final long initialBackoffMillis = job.getInitialBackoffMillis(); int numFailures = failureToReschedule.getNumFailures(); + int numAbandonedFailures = failureToReschedule.getNumAbandonedFailures(); int numSystemStops = failureToReschedule.getNumSystemStops(); // We should back off slowly if JobScheduler keeps stopping the job, // but back off immediately if the issue appeared to be the app's fault @@ -3006,9 +3022,19 @@ public class JobSchedulerService extends com.android.server.SystemService || internalStopReason == JobParameters.INTERNAL_STOP_REASON_ANR || stopReason == JobParameters.STOP_REASON_USER) { numFailures++; + } else if (android.app.job.Flags.handleAbandonedJobs() + && internalStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED) { + numAbandonedFailures++; + numFailures++; } else { numSystemStops++; } + + int backoffPolicy = job.getBackoffPolicy(); + if (shouldUseAggressiveBackoff(numAbandonedFailures)) { + backoffPolicy = JobInfo.BACKOFF_POLICY_EXPONENTIAL; + } + final int backoffAttempts = numFailures + numSystemStops / mConstants.SYSTEM_STOP_TO_FAILURE_RATIO; final long earliestRuntimeMs; @@ -3017,7 +3043,7 @@ public class JobSchedulerService extends com.android.server.SystemService earliestRuntimeMs = JobStatus.NO_EARLIEST_RUNTIME; } else { long delayMillis; - switch (job.getBackoffPolicy()) { + switch (backoffPolicy) { case JobInfo.BACKOFF_POLICY_LINEAR: { long backoff = initialBackoffMillis; if (backoff < mConstants.MIN_LINEAR_BACKOFF_TIME_MS) { @@ -3046,7 +3072,7 @@ public class JobSchedulerService extends com.android.server.SystemService } JobStatus newJob = new JobStatus(failureToReschedule, earliestRuntimeMs, - JobStatus.NO_LATEST_RUNTIME, numFailures, numSystemStops, + JobStatus.NO_LATEST_RUNTIME, numFailures, numAbandonedFailures, numSystemStops, failureToReschedule.getLastSuccessfulRunTime(), sSystemClock.millis(), failureToReschedule.getCumulativeExecutionTimeMs()); if (stopReason == JobParameters.STOP_REASON_USER) { @@ -3069,6 +3095,20 @@ public class JobSchedulerService extends com.android.server.SystemService } /** + * Returns {@code true} if the given number of abandoned failures indicates that JobScheduler + * should use an aggressive backoff policy. + * + * @param numAbandonedFailures The number of abandoned failures. + * @return {@code true} if the given number of abandoned failures indicates that JobScheduler + * should use an aggressive backoff policy. + */ + public boolean shouldUseAggressiveBackoff(int numAbandonedFailures) { + return android.app.job.Flags.handleAbandonedJobs() + && numAbandonedFailures + > mConstants.ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF; + } + + /** * Maximum time buffer in which JobScheduler will try to optimize periodic job scheduling. This * does not cause a job's period to be larger than requested (eg: if the requested period is * shorter than this buffer). This is used to put a limit on when JobScheduler will intervene @@ -3147,6 +3187,7 @@ public class JobSchedulerService extends com.android.server.SystemService return new JobStatus(periodicToReschedule, elapsedNow + period - flex, elapsedNow + period, 0 /* numFailures */, 0 /* numSystemStops */, + 0 /* numAbandonedFailures */, sSystemClock.millis() /* lastSuccessfulRunTime */, periodicToReschedule.getLastFailedRunTime(), 0 /* Reset cumulativeExecutionTime because of successful execution */); @@ -3163,6 +3204,7 @@ public class JobSchedulerService extends com.android.server.SystemService return new JobStatus(periodicToReschedule, newEarliestRunTimeElapsed, newLatestRuntimeElapsed, 0 /* numFailures */, 0 /* numSystemStops */, + 0 /* numAbandonedFailures */, sSystemClock.millis() /* lastSuccessfulRunTime */, periodicToReschedule.getLastFailedRunTime(), 0 /* Reset cumulativeExecutionTime because of successful execution */); @@ -3171,6 +3213,10 @@ public class JobSchedulerService extends com.android.server.SystemService @VisibleForTesting void maybeProcessBuggyJob(@NonNull JobStatus jobStatus, int debugStopReason) { boolean jobTimedOut = debugStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT; + if (android.app.job.Flags.handleAbandonedJobs()) { + jobTimedOut |= (debugStopReason + == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED); + } // If madeActive = 0, the job never actually started. if (!jobTimedOut && jobStatus.madeActive > 0) { final long executionDurationMs = sUptimeMillisClock.millis() - jobStatus.madeActive; @@ -3252,9 +3298,12 @@ public class JobSchedulerService extends com.android.server.SystemService // we stop it. final JobStatus rescheduledJob = needsReschedule ? getRescheduleJobForFailureLocked(jobStatus, stopReason, debugStopReason) : null; + final boolean isStopReasonAbandoned = android.app.job.Flags.handleAbandonedJobs() + && (debugStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED); if (rescheduledJob != null && !rescheduledJob.shouldTreatAsUserInitiatedJob() && (debugStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT + || isStopReasonAbandoned || debugStopReason == JobParameters.INTERNAL_STOP_REASON_PREEMPT)) { rescheduledJob.disallowRunInBatterySaverAndDoze(); } diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java index d8934d8f83b8..dfb36818c818 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java @@ -269,7 +269,9 @@ public final class JobStore { convertRtcBoundsToElapsed(utcTimes, elapsedNow); JobStatus newJob = new JobStatus(job, elapsedRuntimes.first, elapsedRuntimes.second, - 0, 0, job.getLastSuccessfulRunTime(), job.getLastFailedRunTime(), + 0 /* numFailures */, 0 /* numAbandonedFailures */, + 0 /* numSystemStops */, job.getLastSuccessfulRunTime(), + job.getLastFailedRunTime(), job.getCumulativeExecutionTimeMs()); newJob.prepareLocked(); toAdd.add(newJob); 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 a3eaefd5f057..5a33aa0ab7eb 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 @@ -316,6 +316,12 @@ public final class JobStatus { private final int numFailures; /** + * How many times this job has stopped due to {@link + * JobParameters#STOP_REASON_TIMEOUT_ABANDONED}. + */ + private final int mNumAbandonedFailures; + + /** * The number of times JobScheduler has forced this job to stop due to reasons mostly outside * of the app's control. */ @@ -605,6 +611,8 @@ public final class JobStatus { * @param tag A string associated with the job for debugging/logging purposes. * @param numFailures Count of how many times this job has requested a reschedule because * its work was not yet finished. + * @param mNumAbandonedFailures Count of how many times this job has requested a reschedule + * because it was abandoned. * @param numSystemStops Count of how many times JobScheduler has forced this job to stop due to * factors mostly out of the app's control. * @param earliestRunTimeElapsedMillis Milestone: earliest point in time at which the job @@ -617,7 +625,7 @@ public final class JobStatus { */ private JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, int standbyBucket, @Nullable String namespace, String tag, - int numFailures, int numSystemStops, + int numFailures, int mNumAbandonedFailures, int numSystemStops, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis, long lastSuccessfulRunTime, long lastFailedRunTime, long cumulativeExecutionTimeMs, int internalFlags, @@ -677,6 +685,7 @@ public final class JobStatus { this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis; this.mOriginalLatestRunTimeElapsedMillis = latestRunTimeElapsedMillis; this.numFailures = numFailures; + this.mNumAbandonedFailures = mNumAbandonedFailures; mNumSystemStops = numSystemStops; int requiredConstraints = job.getConstraintFlags(); @@ -750,7 +759,8 @@ public final class JobStatus { this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(), jobStatus.getStandbyBucket(), jobStatus.getNamespace(), - jobStatus.getSourceTag(), jobStatus.getNumFailures(), jobStatus.getNumSystemStops(), + jobStatus.getSourceTag(), jobStatus.getNumFailures(), + jobStatus.getNumAbandonedFailures(), jobStatus.getNumSystemStops(), jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed(), jobStatus.getLastSuccessfulRunTime(), jobStatus.getLastFailedRunTime(), jobStatus.getCumulativeExecutionTimeMs(), @@ -787,6 +797,7 @@ public final class JobStatus { this(job, callingUid, sourcePkgName, sourceUserId, standbyBucket, namespace, sourceTag, /* numFailures */ 0, /* numSystemStops */ 0, + /* mNumAbandonedFailures */ 0, earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis, lastSuccessfulRunTime, lastFailedRunTime, cumulativeExecutionTimeMs, innerFlags, dynamicConstraints); @@ -806,13 +817,15 @@ public final class JobStatus { /** Create a new job to be rescheduled with the provided parameters. */ public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis, - long newLatestRuntimeElapsedMillis, int numFailures, int numSystemStops, + long newLatestRuntimeElapsedMillis, int numFailures, + int mNumAbandonedFailures, int numSystemStops, long lastSuccessfulRunTime, long lastFailedRunTime, long cumulativeExecutionTimeMs) { this(rescheduling.job, rescheduling.getUid(), rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(), rescheduling.getStandbyBucket(), rescheduling.getNamespace(), - rescheduling.getSourceTag(), numFailures, numSystemStops, + rescheduling.getSourceTag(), numFailures, + mNumAbandonedFailures, numSystemStops, newEarliestRuntimeElapsedMillis, newLatestRuntimeElapsedMillis, lastSuccessfulRunTime, lastFailedRunTime, cumulativeExecutionTimeMs, @@ -851,7 +864,8 @@ public final class JobStatus { int standbyBucket = JobSchedulerService.standbyBucketForPackage(jobPackage, sourceUserId, elapsedNow); return new JobStatus(job, callingUid, sourcePkg, sourceUserId, - standbyBucket, namespace, tag, /* numFailures */ 0, /* numSystemStops */ 0, + standbyBucket, namespace, tag, /* numFailures */ 0, + /* mNumAbandonedFailures */ 0, /* numSystemStops */ 0, earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis, 0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */, /* cumulativeExecutionTime */ 0, @@ -1146,6 +1160,13 @@ public final class JobStatus { } /** + * Returns the number of times the job stopped previously for STOP_REASON_TIMEOUT_ABANDONED. + */ + public int getNumAbandonedFailures() { + return mNumAbandonedFailures; + } + + /** * Returns the number of times the system stopped a previous execution of this job for reasons * that were likely outside the app's control. */ diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java index dd7ce21e3628..c831475577d8 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java @@ -16,6 +16,7 @@ package com.android.server.job; +import static android.app.job.Flags.FLAG_HANDLE_ABANDONED_JOBS; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; @@ -82,6 +83,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.WorkSource; import android.os.WorkSource.WorkChain; +import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; @@ -1056,6 +1058,75 @@ public class JobSchedulerServiceTest { /** * Confirm that * {@link JobSchedulerService#getRescheduleJobForFailureLocked(JobStatus, int, int)} + * returns a job with the correct delay for abandoned jobs. + */ + @Test + @EnableFlags(FLAG_HANDLE_ABANDONED_JOBS) + public void testGetRescheduleJobForFailure_abandonedJob() { + final long nowElapsed = sElapsedRealtimeClock.millis(); + final long initialBackoffMs = MINUTE_IN_MILLIS; + mService.mConstants.SYSTEM_STOP_TO_FAILURE_RATIO = 3; + + JobStatus originalJob = createJobStatus("testGetRescheduleJobForFailure", + createJobInfo() + .setBackoffCriteria(initialBackoffMs, JobInfo.BACKOFF_POLICY_LINEAR)); + assertEquals(JobStatus.NO_EARLIEST_RUNTIME, originalJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_LATEST_RUNTIME, originalJob.getLatestRunTimeElapsed()); + + // failure = 1, systemStop = 0, abandoned = 1 + JobStatus rescheduledJob = mService.getRescheduleJobForFailureLocked(originalJob, + JobParameters.STOP_REASON_DEVICE_STATE, + JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED); + assertEquals(nowElapsed + initialBackoffMs, rescheduledJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed()); + + // failure = 2, systemstop = 0, abandoned = 2 + rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob, + JobParameters.STOP_REASON_DEVICE_STATE, + JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED); + assertEquals(nowElapsed + (2 * initialBackoffMs), rescheduledJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed()); + + // failure = 3, systemstop = 0, abandoned = 3 + rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob, + JobParameters.STOP_REASON_DEVICE_STATE, + JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED); + assertEquals(nowElapsed + (3 * initialBackoffMs), rescheduledJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed()); + + // failure = 4, systemstop = 0, abandoned = 4 + rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob, + JobParameters.STOP_REASON_DEVICE_STATE, + JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED); + assertEquals( + nowElapsed + ((long) Math.scalb((float) initialBackoffMs, 3)), + rescheduledJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed()); + + // failure = 4, systemstop = 1, abandoned = 4 + rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob, + JobParameters.STOP_REASON_DEVICE_STATE, + JobParameters.INTERNAL_STOP_REASON_DEVICE_THERMAL); + assertEquals( + nowElapsed + ((long) Math.scalb((float) initialBackoffMs, 3)), + rescheduledJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed()); + + // failure = 4, systemStop = 4 / SYSTEM_STOP_TO_FAILURE_RATIO, abandoned = 4 + for (int i = 0; i < mService.mConstants.SYSTEM_STOP_TO_FAILURE_RATIO; ++i) { + rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob, + JobParameters.STOP_REASON_SYSTEM_PROCESSING, + JobParameters.INTERNAL_STOP_REASON_RTC_UPDATED); + } + assertEquals( + nowElapsed + ((long) Math.scalb((float) initialBackoffMs, 4)), + rescheduledJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed()); + } + + /** + * Confirm that + * {@link JobSchedulerService#getRescheduleJobForFailureLocked(JobStatus, int, int)} * returns a job that is correctly marked as demoted by the user. */ @Test 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 c6a6865f1cf1..c64973a67589 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 @@ -706,14 +706,14 @@ public class FlexibilityControllerTest { // "True" start is nowElapsed + HOUR_IN_MILLIS nowElapsed + HOUR_IN_MILLIS + adjustmentMs, nowElapsed + 2 * HOUR_IN_MILLIS, - 0 /* numFailures */, 0 /* numSystemStops */, + 0 /* numFailures */, 0 /* numAbandonedFailures */, 0 /* numSystemStops */, JobSchedulerService.sSystemClock.millis() /* lastSuccessfulRunTime */, 0, 0); jsFlex = new JobStatus(jsFlex, // "True" start is nowElapsed + 2 * HOUR_IN_MILLIS - 20 * MINUTE_IN_MILLIS nowElapsed + 2 * HOUR_IN_MILLIS - 20 * MINUTE_IN_MILLIS + adjustmentMs, nowElapsed + 2 * HOUR_IN_MILLIS, - 0 /* numFailures */, 0 /* numSystemStops */, + 0 /* numFailures */, 0 /* numAbandonedFailures */, 0 /* numSystemStops */, JobSchedulerService.sSystemClock.millis() /* lastSuccessfulRunTime */, 0, 0); @@ -726,13 +726,13 @@ public class FlexibilityControllerTest { jsBasic = new JobStatus(jsBasic, nowElapsed + 30 * MINUTE_IN_MILLIS, NO_LATEST_RUNTIME, - 1 /* numFailures */, 1 /* numSystemStops */, + 1 /* numFailures */, 0 /* numAbandonedFailures */, 1 /* numSystemStops */, JobSchedulerService.sSystemClock.millis() /* lastSuccessfulRunTime */, 0, 0); jsFlex = new JobStatus(jsFlex, nowElapsed + 30 * MINUTE_IN_MILLIS, NO_LATEST_RUNTIME, - 1 /* numFailures */, 1 /* numSystemStops */, + 1 /* numFailures */, 0 /* numAbandonedFailures */, 1 /* numSystemStops */, JobSchedulerService.sSystemClock.millis() /* lastSuccessfulRunTime */, 0, 0); @@ -847,21 +847,24 @@ public class FlexibilityControllerTest { JobInfo.Builder jb = createJob(0).setOverrideDeadline(HOUR_IN_MILLIS); JobStatus js = createJobStatus("time", jb); js = new JobStatus( - js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 2, /* numSystemStops */ 0, + js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 2, + 0 /* numAbandonedFailures */, /* numSystemStops */ 0, 0, FROZEN_TIME, FROZEN_TIME); assertEquals(mFcConfig.RESCHEDULED_JOB_DEADLINE_MS, mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, 0)); js = new JobStatus( - js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 2, /* numSystemStops */ 1, + js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 2, + 0 /* numAbandonedFailures */, /* numSystemStops */ 1, 0, FROZEN_TIME, FROZEN_TIME); assertEquals(2 * mFcConfig.RESCHEDULED_JOB_DEADLINE_MS, mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, 0)); js = new JobStatus( - js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 0, /* numSystemStops */ 10, + js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 0, + 0 /* numAbandonedFailures */, /* numSystemStops */ 10, 0, FROZEN_TIME, FROZEN_TIME); assertEquals(mFcConfig.MAX_RESCHEDULED_DEADLINE_MS, mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, 0)); @@ -1092,11 +1095,13 @@ public class FlexibilityControllerTest { JobInfo.Builder jb = createJob(0); JobStatus js = createJobStatus("time", jb); js = new JobStatus( - js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 1, /* numSystemStops */ 0, + js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 1, + /* numAbandonedFailures */ 0, /* numSystemStops */ 0, 0, FROZEN_TIME, FROZEN_TIME); assertFalse(js.hasFlexibilityConstraint()); js = new JobStatus( - js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 0, /* numSystemStops */ 1, + js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 0, + /* numAbandonedFailures */ 0, /* numSystemStops */ 1, 0, FROZEN_TIME, FROZEN_TIME); assertFalse(js.hasFlexibilityConstraint()); } diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java index 2d0f4b69e2fe..86101cf591e7 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java @@ -459,35 +459,35 @@ public class JobStatusTest { int numFailures = 1; int numSystemStops = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority()); // 2+ failures, priority should be lowered as much as possible. numFailures = 2; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority()); numFailures = 5; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority()); numFailures = 8; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority()); // System stops shouldn't factor in the downgrade. numSystemStops = 10; numFailures = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority()); // Less than 2 failures, but job is downgraded. numFailures = 1; numSystemStops = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER); assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority()); } @@ -505,44 +505,44 @@ public class JobStatusTest { int numFailures = 1; int numSystemStops = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority()); // Failures in [2,4), priority should be lowered slightly. numFailures = 2; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_DEFAULT, job.getEffectivePriority()); numFailures = 3; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_DEFAULT, job.getEffectivePriority()); // Failures in [4,6), priority should be lowered more. numFailures = 4; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority()); numFailures = 5; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority()); // 6+ failures, priority should be lowered as much as possible. numFailures = 6; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority()); numFailures = 12; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority()); // System stops shouldn't factor in the downgrade. numSystemStops = 10; numFailures = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority()); } @@ -563,32 +563,32 @@ public class JobStatusTest { int numFailures = 1; int numSystemStops = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority()); numFailures = 4; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority()); numFailures = 5; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority()); // 6+ failures, priority should be lowered as much as possible. numFailures = 6; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority()); numFailures = 12; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority()); // System stops shouldn't factor in the downgrade. numSystemStops = 10; numFailures = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority()); } @@ -606,28 +606,28 @@ public class JobStatusTest { int numFailures = 1; int numSystemStops = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority()); // 2+ failures, priority shouldn't be affected while job is still a UI job numFailures = 2; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority()); numFailures = 5; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority()); numFailures = 8; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority()); // System stops shouldn't factor in the downgrade. numSystemStops = 10; numFailures = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority()); // Job can no long run as user-initiated. Downgrades should be effective. @@ -641,28 +641,28 @@ public class JobStatusTest { numFailures = 1; numSystemStops = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority()); // 2+ failures, priority should start getting lower numFailures = 2; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_DEFAULT, job.getEffectivePriority()); numFailures = 5; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority()); numFailures = 8; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority()); // System stops shouldn't factor in the downgrade. numSystemStops = 10; numFailures = 0; job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures, - numSystemStops, 0, 0, 0); + 0, numSystemStops, 0, 0, 0); assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority()); } @@ -772,14 +772,14 @@ public class JobStatusTest { assertTrue(job.shouldTreatAsUserInitiatedJob()); JobStatus rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, - 0, 0, 0, 0, 0); + 0, 0, 0, 0, 0, 0); assertTrue(rescheduledJob.shouldTreatAsUserInitiatedJob()); job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER); assertFalse(job.shouldTreatAsUserInitiatedJob()); rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, - 0, 0, 0, 0, 0); + 0, 0, 0, 0, 0, 0); assertFalse(rescheduledJob.shouldTreatAsUserInitiatedJob()); rescheduledJob.removeInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER); @@ -797,14 +797,14 @@ public class JobStatusTest { assertTrue(job.shouldTreatAsUserInitiatedJob()); JobStatus rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, - 0, 0, 0, 0, 0); + 0, 0, 0, 0, 0, 0); assertTrue(rescheduledJob.shouldTreatAsUserInitiatedJob()); job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ); assertFalse(job.shouldTreatAsUserInitiatedJob()); rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, - 0, 0, 0, 0, 0); + 0, 0, 0, 0, 0, 0); assertFalse(rescheduledJob.shouldTreatAsUserInitiatedJob()); rescheduledJob.removeInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ); |