summaryrefslogtreecommitdiff
path: root/apex
diff options
context:
space:
mode:
author Sanath Kumar <sanathku@google.com> 2024-12-13 11:28:07 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2024-12-13 11:28:07 -0800
commit960649d6c51168a5ff0bfa66849e93abb6eace4f (patch)
tree858299cb0f37e3db5e9aaaf526d6913bed4cdd0a /apex
parent7c4ce2fb711aa1bfa9afa648f6adbe72c4fb95c4 (diff)
parente38ab1a9611dcf6bf519b0077170d896e4784504 (diff)
Merge "JobScheduler: Enable abandoned job overrides" into main
Diffstat (limited to 'apex')
-rw-r--r--apex/jobscheduler/framework/java/android/app/job/JobParameters.java22
-rw-r--r--apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java10
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java21
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java13
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());