diff options
author | 2024-12-13 11:28:07 -0800 | |
---|---|---|
committer | 2024-12-13 11:28:07 -0800 | |
commit | 960649d6c51168a5ff0bfa66849e93abb6eace4f (patch) | |
tree | 858299cb0f37e3db5e9aaaf526d6913bed4cdd0a /apex | |
parent | 7c4ce2fb711aa1bfa9afa648f6adbe72c4fb95c4 (diff) | |
parent | e38ab1a9611dcf6bf519b0077170d896e4784504 (diff) |
Merge "JobScheduler: Enable abandoned job overrides" into main
Diffstat (limited to 'apex')
4 files changed, 50 insertions, 16 deletions
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java index b6f0c04b8c16..7fef4e502c97 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java @@ -23,6 +23,10 @@ import android.annotation.Nullable; import android.annotation.TestApi; import android.app.ActivityManager; import android.app.usage.UsageStatsManager; +import android.compat.Compatibility; +import android.compat.annotation.ChangeId; +import android.compat.annotation.Disabled; +import android.compat.annotation.Overridable; import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.pm.PackageManager; @@ -349,6 +353,16 @@ public class JobParameters implements Parcelable { private JobCleanupCallback mJobCleanupCallback; @Nullable private Cleaner.Cleanable mCleanable; + /** + * Override handling of abandoned jobs in the system. Overriding this change + * will prevent the system to handle abandoned jobs and report it as a new + * stop reason STOP_REASON_TIMEOUT_ABANDONED. + * @hide + */ + @ChangeId + @Disabled + @Overridable + public static final long OVERRIDE_HANDLE_ABANDONED_JOBS = 372529068L; /** @hide */ public JobParameters(IBinder callback, String namespace, int jobId, PersistableBundle extras, @@ -677,6 +691,10 @@ public class JobParameters implements Parcelable { * @hide */ public void enableCleaner() { + if (!Flags.handleAbandonedJobs() + || Compatibility.isChangeEnabled(OVERRIDE_HANDLE_ABANDONED_JOBS)) { + return; + } // JobParameters objects are passed by reference in local Binder // transactions for clients running as SYSTEM. The life cycle of the // JobParameters objects are no longer controlled by the client. @@ -695,6 +713,10 @@ public class JobParameters implements Parcelable { * @hide */ public void disableCleaner() { + if (!Flags.handleAbandonedJobs() + || Compatibility.isChangeEnabled(OVERRIDE_HANDLE_ABANDONED_JOBS)) { + return; + } if (mJobCleanupCallback != null) { mJobCleanupCallback.disableCleaner(); if (mCleanable != null) { diff --git a/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java b/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java index 69b83cc02b54..d460dcc65473 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java @@ -165,11 +165,9 @@ public abstract class JobServiceEngine { case MSG_EXECUTE_JOB: { final JobParameters params = (JobParameters) msg.obj; try { - if (Flags.handleAbandonedJobs()) { - params.enableCleaner(); - } + params.enableCleaner(); boolean workOngoing = JobServiceEngine.this.onStartJob(params); - if (Flags.handleAbandonedJobs() && !workOngoing) { + if (!workOngoing) { params.disableCleaner(); } ackStartMessage(params, workOngoing); @@ -196,9 +194,7 @@ public abstract class JobServiceEngine { IJobCallback callback = params.getCallback(); if (callback != null) { try { - if (Flags.handleAbandonedJobs()) { - params.disableCleaner(); - } + params.disableCleaner(); callback.jobFinished(params.getJobId(), needsReschedule); } catch (RemoteException e) { Log.e(TAG, "Error reporting job finish to system: binder has gone" + 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 0b884057ea19..4335cae65a3c 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -16,6 +16,7 @@ package com.android.server.job; +import static android.app.job.JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; @@ -1986,8 +1987,8 @@ public class JobSchedulerService extends com.android.server.SystemService jobStatus.getNumAbandonedFailures(), /* 0 is reserved for UNKNOWN_POLICY */ jobStatus.getJob().getBackoffPolicy() + 1, - shouldUseAggressiveBackoff(jobStatus.getNumAbandonedFailures())); - + shouldUseAggressiveBackoff( + jobStatus.getNumAbandonedFailures(), jobStatus.getSourceUid())); // If the job is immediately ready to run, then we can just immediately // put it in the pending list and try to schedule it. This is especially @@ -2432,7 +2433,8 @@ public class JobSchedulerService extends com.android.server.SystemService cancelled.getNumAbandonedFailures(), /* 0 is reserved for UNKNOWN_POLICY */ cancelled.getJob().getBackoffPolicy() + 1, - shouldUseAggressiveBackoff(cancelled.getNumAbandonedFailures())); + shouldUseAggressiveBackoff( + cancelled.getNumAbandonedFailures(), cancelled.getSourceUid())); } // If this is a replacement, bring in the new version of the job if (incomingJob != null) { @@ -3024,6 +3026,7 @@ public class JobSchedulerService extends com.android.server.SystemService int numFailures = failureToReschedule.getNumFailures(); int numAbandonedFailures = failureToReschedule.getNumAbandonedFailures(); int numSystemStops = failureToReschedule.getNumSystemStops(); + final int uid = failureToReschedule.getSourceUid(); // 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 // or the user stopped the job somehow. @@ -3033,6 +3036,7 @@ public class JobSchedulerService extends com.android.server.SystemService || stopReason == JobParameters.STOP_REASON_USER) { numFailures++; } else if (android.app.job.Flags.handleAbandonedJobs() + && !CompatChanges.isChangeEnabled(OVERRIDE_HANDLE_ABANDONED_JOBS, uid) && internalStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED) { numAbandonedFailures++; numFailures++; @@ -3041,7 +3045,7 @@ public class JobSchedulerService extends com.android.server.SystemService } int backoffPolicy = job.getBackoffPolicy(); - if (shouldUseAggressiveBackoff(numAbandonedFailures)) { + if (shouldUseAggressiveBackoff(numAbandonedFailures, uid)) { backoffPolicy = JobInfo.BACKOFF_POLICY_EXPONENTIAL; } @@ -3112,8 +3116,9 @@ public class JobSchedulerService extends com.android.server.SystemService * @return {@code true} if the given number of abandoned failures indicates that JobScheduler * should use an aggressive backoff policy. */ - public boolean shouldUseAggressiveBackoff(int numAbandonedFailures) { + public boolean shouldUseAggressiveBackoff(int numAbandonedFailures, int uid) { return android.app.job.Flags.handleAbandonedJobs() + && !CompatChanges.isChangeEnabled(OVERRIDE_HANDLE_ABANDONED_JOBS, uid) && numAbandonedFailures > mConstants.ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF; } @@ -3223,7 +3228,9 @@ 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()) { + if (android.app.job.Flags.handleAbandonedJobs() + && !CompatChanges.isChangeEnabled( + OVERRIDE_HANDLE_ABANDONED_JOBS, jobStatus.getSourceUid())) { jobTimedOut |= (debugStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED); } @@ -3309,6 +3316,8 @@ public class JobSchedulerService extends com.android.server.SystemService final JobStatus rescheduledJob = needsReschedule ? getRescheduleJobForFailureLocked(jobStatus, stopReason, debugStopReason) : null; final boolean isStopReasonAbandoned = android.app.job.Flags.handleAbandonedJobs() + && !CompatChanges.isChangeEnabled( + OVERRIDE_HANDLE_ABANDONED_JOBS, jobStatus.getSourceUid()) && (debugStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED); if (rescheduledJob != null && !rescheduledJob.shouldTreatAsUserInitiatedJob() diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java index 2b401c8ff6b1..ebfda527001d 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java @@ -16,6 +16,8 @@ package com.android.server.job; +import static android.app.job.JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS; + import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_NONE; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import static com.android.server.job.JobSchedulerService.safelyScaleBytesToKBForHistogram; @@ -550,7 +552,8 @@ public final class JobServiceContext implements ServiceConnection { job.getNumAbandonedFailures(), /* 0 is reserved for UNKNOWN_POLICY */ job.getJob().getBackoffPolicy() + 1, - mService.shouldUseAggressiveBackoff(job.getNumAbandonedFailures())); + mService.shouldUseAggressiveBackoff( + job.getNumAbandonedFailures(), job.getSourceUid())); sEnqueuedJwiAtJobStart.logSampleWithUid(job.getUid(), job.getWorkCount()); final String sourcePackage = job.getSourcePackageName(); if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) { @@ -1461,7 +1464,10 @@ public final class JobServiceContext implements ServiceConnection { final StringBuilder debugStopReason = new StringBuilder("client timed out"); if (android.app.job.Flags.handleAbandonedJobs() - && executing != null && executing.isAbandoned()) { + && executing != null + && !CompatChanges.isChangeEnabled( + OVERRIDE_HANDLE_ABANDONED_JOBS, executing.getSourceUid()) + && executing.isAbandoned()) { final String abandonedMessage = " and maybe abandoned"; stopReason = JobParameters.STOP_REASON_TIMEOUT_ABANDONED; internalStopReason = JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED; @@ -1689,7 +1695,8 @@ public final class JobServiceContext implements ServiceConnection { completedJob.getNumAbandonedFailures(), /* 0 is reserved for UNKNOWN_POLICY */ completedJob.getJob().getBackoffPolicy() + 1, - mService.shouldUseAggressiveBackoff(completedJob.getNumAbandonedFailures())); + mService.shouldUseAggressiveBackoff( + completedJob.getNumAbandonedFailures(), completedJob.getSourceUid())); if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) { Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_SYSTEM_SERVER, JobSchedulerService.TRACE_TRACK_NAME, getId()); |