From 9e653088c4ce19dd1cd8a056bfe782ea8c6f2655 Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Mon, 15 May 2023 21:24:59 +0000 Subject: [PATCH] Don't back off for first few system stops. System requested stops theoretically have no reason to trigger an immediate backoff because there's no indication the backoff will help improve success rate, so don't back off a job for the first few system stops. Bug: 282784507 Test: atest FrameworksMockingServicesTests:JobSchedulerServiceTest Change-Id: If30edd312e17a6baba05654075e7ed21ace6338b --- .../server/job/JobSchedulerService.java | 55 +++++++++++-------- .../server/job/JobSchedulerServiceTest.java | 4 +- 2 files changed, 35 insertions(+), 24 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 3f552b6906d07..ea7460dd2d71b 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -2600,34 +2600,43 @@ public class JobSchedulerService extends com.android.server.SystemService } else { numSystemStops++; } - final int backoffAttempts = Math.max(1, - numFailures + numSystemStops / mConstants.SYSTEM_STOP_TO_FAILURE_RATIO); - long delayMillis; + final int backoffAttempts = + numFailures + numSystemStops / mConstants.SYSTEM_STOP_TO_FAILURE_RATIO; + final long earliestRuntimeMs; - switch (job.getBackoffPolicy()) { - case JobInfo.BACKOFF_POLICY_LINEAR: { - long backoff = initialBackoffMillis; - if (backoff < mConstants.MIN_LINEAR_BACKOFF_TIME_MS) { - backoff = mConstants.MIN_LINEAR_BACKOFF_TIME_MS; + if (backoffAttempts == 0) { + earliestRuntimeMs = JobStatus.NO_EARLIEST_RUNTIME; + } else { + long delayMillis; + switch (job.getBackoffPolicy()) { + case JobInfo.BACKOFF_POLICY_LINEAR: { + long backoff = initialBackoffMillis; + if (backoff < mConstants.MIN_LINEAR_BACKOFF_TIME_MS) { + backoff = mConstants.MIN_LINEAR_BACKOFF_TIME_MS; + } + delayMillis = backoff * backoffAttempts; } - delayMillis = backoff * backoffAttempts; - } break; - default: - if (DEBUG) { - Slog.v(TAG, "Unrecognised back-off policy, defaulting to exponential."); + break; + default: + if (DEBUG) { + Slog.v(TAG, "Unrecognised back-off policy, defaulting to exponential."); + } + // Intentional fallthrough. + case JobInfo.BACKOFF_POLICY_EXPONENTIAL: { + long backoff = initialBackoffMillis; + if (backoff < mConstants.MIN_EXP_BACKOFF_TIME_MS) { + backoff = mConstants.MIN_EXP_BACKOFF_TIME_MS; + } + delayMillis = (long) Math.scalb(backoff, backoffAttempts - 1); } - case JobInfo.BACKOFF_POLICY_EXPONENTIAL: { - long backoff = initialBackoffMillis; - if (backoff < mConstants.MIN_EXP_BACKOFF_TIME_MS) { - backoff = mConstants.MIN_EXP_BACKOFF_TIME_MS; - } - delayMillis = (long) Math.scalb(backoff, backoffAttempts - 1); - } break; + break; + } + delayMillis = + Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS); + earliestRuntimeMs = elapsedNowMillis + delayMillis; } - delayMillis = - Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS); JobStatus newJob = new JobStatus(failureToReschedule, - elapsedNowMillis + delayMillis, + earliestRuntimeMs, JobStatus.NO_LATEST_RUNTIME, numFailures, numSystemStops, failureToReschedule.getLastSuccessfulRunTime(), sSystemClock.millis(), failureToReschedule.getCumulativeExecutionTimeMs()); 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 9cd22dd292a56..b19a13c30e895 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java @@ -402,13 +402,15 @@ public class JobSchedulerServiceTest { JobStatus rescheduledJob = mService.getRescheduleJobForFailureLocked(originalJob, JobParameters.STOP_REASON_DEVICE_STATE, JobParameters.INTERNAL_STOP_REASON_DEVICE_THERMAL); - assertEquals(nowElapsed + initialBackoffMs, rescheduledJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_EARLIEST_RUNTIME, rescheduledJob.getEarliestRunTime()); assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed()); // failure = 0, systemStop = 2 rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob, JobParameters.STOP_REASON_DEVICE_STATE, JobParameters.INTERNAL_STOP_REASON_PREEMPT); + assertEquals(JobStatus.NO_EARLIEST_RUNTIME, rescheduledJob.getEarliestRunTime()); + assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed()); // failure = 0, systemStop = 3 rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob, JobParameters.STOP_REASON_CONSTRAINT_CHARGING,