Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f805b44 authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Allow system jobs to be exempted from app-standby"

parents 73a4d944 959acb52
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -255,6 +255,14 @@ public class JobInfo implements Parcelable {
     */
     */
    public static final int FLAG_IS_PREFETCH = 1 << 2;
    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
     * @hide
     */
     */
@@ -355,6 +363,13 @@ public class JobInfo implements Parcelable {
        return flags;
        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
     * 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).
     * device connected to permanent power, such as Android TV devices).
+22 −13
Original line number Original line Diff line number Diff line
@@ -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
        // 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-
        // an appropriate amount of time since the last invocation.  During device-
        // wide parole, standby bucketing is ignored.
        // 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();
            final int bucket = job.getStandbyBucket();
            if (mHeartbeat < mNextBucketHeartbeat[bucket]) {
            if (mHeartbeat < mNextBucketHeartbeat[bucket]) {
                // Only skip this job if it's still waiting for the end of its (initial) nominal
                // Only skip this job if it's still waiting for the end of its (initial) nominal
@@ -2339,6 +2341,22 @@ public final class JobSchedulerService extends com.android.server.SystemService
            return canPersist;
            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
        // IJobScheduler implementation
        @Override
        @Override
        public int schedule(JobInfo job) throws RemoteException {
        public int schedule(JobInfo job) throws RemoteException {
@@ -2357,10 +2375,7 @@ public final class JobSchedulerService extends com.android.server.SystemService
                }
                }
            }
            }


            if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
            validateJobFlags(job, uid);
                getContext().enforceCallingOrSelfPermission(
                        android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG);
            }


            long ident = Binder.clearCallingIdentity();
            long ident = Binder.clearCallingIdentity();
            try {
            try {
@@ -2388,10 +2403,7 @@ public final class JobSchedulerService extends com.android.server.SystemService
                throw new NullPointerException("work is null");
                throw new NullPointerException("work is null");
            }
            }


            if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
            validateJobFlags(job, uid);
                getContext().enforceCallingOrSelfPermission(
                        android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG);
            }


            long ident = Binder.clearCallingIdentity();
            long ident = Binder.clearCallingIdentity();
            try {
            try {
@@ -2422,10 +2434,7 @@ public final class JobSchedulerService extends com.android.server.SystemService
                        + " not permitted to schedule jobs for other apps");
                        + " not permitted to schedule jobs for other apps");
            }
            }


            if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
            validateJobFlags(job, callerUid);
                getContext().enforceCallingOrSelfPermission(
                        android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG);
            }


            long ident = Binder.clearCallingIdentity();
            long ident = Binder.clearCallingIdentity();
            try {
            try {