diff --git a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java index 0205430e707f1..1720534e1183c 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java @@ -285,6 +285,7 @@ public class JobParameters implements Parcelable { private final IBinder callback; private final boolean overrideDeadlineExpired; private final boolean mIsExpedited; + private final boolean mIsUserInitiated; private final Uri[] mTriggeredContentUris; private final String[] mTriggeredContentAuthorities; private final Network network; @@ -296,7 +297,8 @@ public class JobParameters implements Parcelable { /** @hide */ public JobParameters(IBinder callback, int jobId, PersistableBundle extras, Bundle transientExtras, ClipData clipData, int clipGrantFlags, - boolean overrideDeadlineExpired, boolean isExpedited, Uri[] triggeredContentUris, + boolean overrideDeadlineExpired, boolean isExpedited, + boolean isUserInitiated, Uri[] triggeredContentUris, String[] triggeredContentAuthorities, Network network) { this.jobId = jobId; this.extras = extras; @@ -306,6 +308,7 @@ public class JobParameters implements Parcelable { this.callback = callback; this.overrideDeadlineExpired = overrideDeadlineExpired; this.mIsExpedited = isExpedited; + this.mIsUserInitiated = isUserInitiated; this.mTriggeredContentUris = triggeredContentUris; this.mTriggeredContentAuthorities = triggeredContentAuthorities; this.network = network; @@ -391,6 +394,21 @@ public class JobParameters implements Parcelable { return mIsExpedited; } + /** + * @return Whether this job is running as a user-initiated job or not. A job is guaranteed to + * have all user-initiated job guarantees for the duration of the job execution if this returns + * {@code true}. This will return {@code false} if the job wasn't requested to run as a + * user-initiated job, or if it was requested to run as a user-initiated job but the app didn't + * meet any of the requirements at the time of execution, such as having the + * {@link android.Manifest.permission#RUN_LONG_JOBS} permission. + * + * @see JobInfo.Builder#setUserInitiated(boolean) + * @hide + */ + public boolean isUserInitiatedJob() { + return mIsUserInitiated; + } + /** * For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this * provides an easy way to tell whether the job is being executed due to the deadline @@ -535,6 +553,7 @@ public class JobParameters implements Parcelable { callback = in.readStrongBinder(); overrideDeadlineExpired = in.readInt() == 1; mIsExpedited = in.readBoolean(); + mIsUserInitiated = in.readBoolean(); mTriggeredContentUris = in.createTypedArray(Uri.CREATOR); mTriggeredContentAuthorities = in.createStringArray(); if (in.readInt() != 0) { @@ -575,6 +594,7 @@ public class JobParameters implements Parcelable { dest.writeStrongBinder(callback); dest.writeInt(overrideDeadlineExpired ? 1 : 0); dest.writeBoolean(mIsExpedited); + dest.writeBoolean(mIsUserInitiated); dest.writeTypedArray(mTriggeredContentUris, flags); dest.writeStringArray(mTriggeredContentAuthorities); if (network != null) { diff --git a/apex/jobscheduler/framework/java/android/app/job/JobService.java b/apex/jobscheduler/framework/java/android/app/job/JobService.java index 62799598cf6ac..898557dfb4f96 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobService.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobService.java @@ -400,9 +400,9 @@ public abstract class JobService extends Service { /** * Provide JobScheduler with a notification to post and tie to this job's lifecycle. - * This is required for all user-initiated jobs - * (scheduled via {link JobInfo.Builder#setUserInitiated(boolean)}) and optional for - * other jobs. If the app does not call this method for a required notification within + * This is only required for those user-initiated jobs which return {@code true} via + * {@link JobParameters#isUserInitiatedJob()}. + * If the app does not call this method for a required notification within * 10 seconds after {@link #onStartJob(JobParameters)} is called, * the system will trigger an ANR and stop this job. * 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 0dcfd24b263c9..dae2bb2fb571b 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java @@ -307,7 +307,8 @@ public final class JobServiceContext implements ServiceConnection { mParams = new JobParameters(mRunningCallback, job.getJobId(), ji.getExtras(), ji.getTransientExtras(), ji.getClipData(), ji.getClipGrantFlags(), isDeadlineExpired, job.shouldTreatAsExpeditedJob(), - triggeredUris, triggeredAuthorities, job.network); + job.shouldTreatAsUserInitiated(), triggeredUris, triggeredAuthorities, + job.network); mExecutionStartTimeElapsed = sElapsedRealtimeClock.millis(); mMinExecutionGuaranteeMillis = mService.getMinJobExecutionGuaranteeMs(job); mMaxExecutionTimeMillis = 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 251a4dac36850..2c6ada1058894 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 @@ -1351,8 +1351,9 @@ public final class JobStatus { * for any reason. */ public boolean shouldTreatAsUserInitiated() { - // TODO(248386641): implement - return false; + // TODO(248386641): update implementation to handle loss of privilege + // and also rename to `shouldTreatAsUserInitiatedJob` for consistency + return getJob().isUserInitiated(); } /**