Loading core/java/android/app/job/JobInfo.java +15 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,14 @@ public class JobInfo implements Parcelable { */ public static final int FLAG_IS_PREFETCH = 1 << 2; /** * This job needs to be exempted from the app standby throttling. Only the system (UID 1000) * can set it. Jobs with a time constrant must not have it. * * @hide */ public static final int FLAG_EXEMPT_FROM_APP_STANDBY = 1 << 3; /** * @hide */ Loading Loading @@ -355,6 +363,13 @@ public class JobInfo implements Parcelable { return flags; } /** @hide */ public boolean isExemptedFromAppStandby() { return ((flags & FLAG_EXEMPT_FROM_APP_STANDBY) != 0) && !hasEarlyConstraint() && !hasLateConstraint(); } /** * Whether this job requires that the device be charging (or be a non-battery-powered * device connected to permanent power, such as Android TV devices). Loading services/core/java/com/android/server/job/JobSchedulerService.java +22 −13 Original line number Diff line number Diff line Loading @@ -1814,7 +1814,9 @@ public final class JobSchedulerService extends com.android.server.SystemService // If the app is in a non-active standby bucket, make sure we've waited // an appropriate amount of time since the last invocation. During device- // wide parole, standby bucketing is ignored. if (!mInParole) { // // But if a job has FLAG_EXEMPT_FROM_APP_STANDBY, don't check it. if (!mInParole && !job.getJob().isExemptedFromAppStandby()) { final int bucket = job.getStandbyBucket(); if (mHeartbeat < mNextBucketHeartbeat[bucket]) { // Only skip this job if it's still waiting for the end of its (initial) nominal Loading Loading @@ -2339,6 +2341,22 @@ public final class JobSchedulerService extends com.android.server.SystemService return canPersist; } private void validateJobFlags(JobInfo job, int callingUid) { if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); } if ((job.getFlags() & JobInfo.FLAG_EXEMPT_FROM_APP_STANDBY) != 0) { if (callingUid != Process.SYSTEM_UID) { throw new SecurityException("Job has invalid flags"); } if (job.hasLateConstraint() || job.hasEarlyConstraint()) { Slog.wtf(TAG, "Jobs with time-constraints mustn't have" +" FLAG_EXEMPT_FROM_APP_STANDBY. Job=" + job); } } } // IJobScheduler implementation @Override public int schedule(JobInfo job) throws RemoteException { Loading @@ -2357,10 +2375,7 @@ public final class JobSchedulerService extends com.android.server.SystemService } } if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); } validateJobFlags(job, uid); long ident = Binder.clearCallingIdentity(); try { Loading Loading @@ -2388,10 +2403,7 @@ public final class JobSchedulerService extends com.android.server.SystemService throw new NullPointerException("work is null"); } if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); } validateJobFlags(job, uid); long ident = Binder.clearCallingIdentity(); try { Loading Loading @@ -2422,10 +2434,7 @@ public final class JobSchedulerService extends com.android.server.SystemService + " not permitted to schedule jobs for other apps"); } if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); } validateJobFlags(job, callerUid); long ident = Binder.clearCallingIdentity(); try { Loading Loading
core/java/android/app/job/JobInfo.java +15 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,14 @@ public class JobInfo implements Parcelable { */ public static final int FLAG_IS_PREFETCH = 1 << 2; /** * This job needs to be exempted from the app standby throttling. Only the system (UID 1000) * can set it. Jobs with a time constrant must not have it. * * @hide */ public static final int FLAG_EXEMPT_FROM_APP_STANDBY = 1 << 3; /** * @hide */ Loading Loading @@ -355,6 +363,13 @@ public class JobInfo implements Parcelable { return flags; } /** @hide */ public boolean isExemptedFromAppStandby() { return ((flags & FLAG_EXEMPT_FROM_APP_STANDBY) != 0) && !hasEarlyConstraint() && !hasLateConstraint(); } /** * Whether this job requires that the device be charging (or be a non-battery-powered * device connected to permanent power, such as Android TV devices). Loading
services/core/java/com/android/server/job/JobSchedulerService.java +22 −13 Original line number Diff line number Diff line Loading @@ -1814,7 +1814,9 @@ public final class JobSchedulerService extends com.android.server.SystemService // If the app is in a non-active standby bucket, make sure we've waited // an appropriate amount of time since the last invocation. During device- // wide parole, standby bucketing is ignored. if (!mInParole) { // // But if a job has FLAG_EXEMPT_FROM_APP_STANDBY, don't check it. if (!mInParole && !job.getJob().isExemptedFromAppStandby()) { final int bucket = job.getStandbyBucket(); if (mHeartbeat < mNextBucketHeartbeat[bucket]) { // Only skip this job if it's still waiting for the end of its (initial) nominal Loading Loading @@ -2339,6 +2341,22 @@ public final class JobSchedulerService extends com.android.server.SystemService return canPersist; } private void validateJobFlags(JobInfo job, int callingUid) { if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); } if ((job.getFlags() & JobInfo.FLAG_EXEMPT_FROM_APP_STANDBY) != 0) { if (callingUid != Process.SYSTEM_UID) { throw new SecurityException("Job has invalid flags"); } if (job.hasLateConstraint() || job.hasEarlyConstraint()) { Slog.wtf(TAG, "Jobs with time-constraints mustn't have" +" FLAG_EXEMPT_FROM_APP_STANDBY. Job=" + job); } } } // IJobScheduler implementation @Override public int schedule(JobInfo job) throws RemoteException { Loading @@ -2357,10 +2375,7 @@ public final class JobSchedulerService extends com.android.server.SystemService } } if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); } validateJobFlags(job, uid); long ident = Binder.clearCallingIdentity(); try { Loading Loading @@ -2388,10 +2403,7 @@ public final class JobSchedulerService extends com.android.server.SystemService throw new NullPointerException("work is null"); } if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); } validateJobFlags(job, uid); long ident = Binder.clearCallingIdentity(); try { Loading Loading @@ -2422,10 +2434,7 @@ public final class JobSchedulerService extends com.android.server.SystemService + " not permitted to schedule jobs for other apps"); } if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); } validateJobFlags(job, callerUid); long ident = Binder.clearCallingIdentity(); try { Loading