Loading PREUPLOAD.cfg +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp tests/ tools/ bpfmt = -d ktfmt = --kotlinlang-style --include-dirs=services/permission,packages/SystemUI,libs/WindowManager/Shell/src/com/android/wm/shell/freeform ktfmt = --kotlinlang-style --include-dirs=services/permission,packages/SystemUI,libs/WindowManager/Shell/src/com/android/wm/shell/freeform,libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education [Hook Scripts] checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT} Loading apex/jobscheduler/service/aconfig/app_idle.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -21,3 +21,10 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "adjust_default_bucket_elevation_params" namespace: "backstage_power" description: "Adjust the default bucket evaluation parameters" bug: "379909479" } apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +52 −3 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 = Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -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 Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -3068,6 +3094,20 @@ public class JobSchedulerService extends com.android.server.SystemService return newJob; } /** * 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 Loading Loading @@ -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 */); Loading @@ -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 */); Loading @@ -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; Loading Loading @@ -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(); } Loading apex/jobscheduler/service/java/com/android/server/job/JobStore.java +3 −1 Original line number Diff line number Diff line Loading @@ -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); Loading apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +26 −5 Original line number Diff line number Diff line Loading @@ -315,6 +315,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. Loading Loading @@ -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 Loading @@ -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, Loading Loading @@ -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(); Loading Loading @@ -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(), Loading Loading @@ -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); Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -1145,6 +1159,13 @@ public final class JobStatus { return numFailures; } /** * 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. Loading Loading
PREUPLOAD.cfg +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp tests/ tools/ bpfmt = -d ktfmt = --kotlinlang-style --include-dirs=services/permission,packages/SystemUI,libs/WindowManager/Shell/src/com/android/wm/shell/freeform ktfmt = --kotlinlang-style --include-dirs=services/permission,packages/SystemUI,libs/WindowManager/Shell/src/com/android/wm/shell/freeform,libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education [Hook Scripts] checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT} Loading
apex/jobscheduler/service/aconfig/app_idle.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -21,3 +21,10 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "adjust_default_bucket_elevation_params" namespace: "backstage_power" description: "Adjust the default bucket evaluation parameters" bug: "379909479" }
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +52 −3 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 = Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -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 Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -3068,6 +3094,20 @@ public class JobSchedulerService extends com.android.server.SystemService return newJob; } /** * 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 Loading Loading @@ -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 */); Loading @@ -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 */); Loading @@ -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; Loading Loading @@ -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(); } Loading
apex/jobscheduler/service/java/com/android/server/job/JobStore.java +3 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +26 −5 Original line number Diff line number Diff line Loading @@ -315,6 +315,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. Loading Loading @@ -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 Loading @@ -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, Loading Loading @@ -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(); Loading Loading @@ -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(), Loading Loading @@ -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); Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -1145,6 +1159,13 @@ public final class JobStatus { return numFailures; } /** * 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. Loading