Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +17 −12 Original line number Original line Diff line number Diff line Loading @@ -746,7 +746,13 @@ public class JobSchedulerService extends com.android.server.SystemService final Constants mConstants; final Constants mConstants; final ConstantsObserver mConstantsObserver; final ConstantsObserver mConstantsObserver; static final Comparator<JobStatus> mEnqueueTimeComparator = (o1, o2) -> { private static final Comparator<JobStatus> sPendingJobComparator = (o1, o2) -> { // Jobs with an override state set (via adb) should be put first as tests/developers // expect the jobs to run immediately. if (o1.overrideState != o2.overrideState) { // Higher override state (OVERRIDE_FULL) should be before lower state (OVERRIDE_SOFT) return o2.overrideState - o1.overrideState; } if (o1.enqueueTime < o2.enqueueTime) { if (o1.enqueueTime < o2.enqueueTime) { return -1; return -1; } } Loading Loading @@ -1097,7 +1103,7 @@ public class JobSchedulerService extends com.android.server.SystemService // This is a new job, we can just immediately put it on the pending // This is a new job, we can just immediately put it on the pending // list and try to run it. // list and try to run it. mJobPackageTracker.notePending(jobStatus); mJobPackageTracker.notePending(jobStatus); addOrderedItem(mPendingJobs, jobStatus, mEnqueueTimeComparator); addOrderedItem(mPendingJobs, jobStatus, sPendingJobComparator); maybeRunPendingJobsLocked(); maybeRunPendingJobsLocked(); } else { } else { evaluateControllerStatesLocked(jobStatus); evaluateControllerStatesLocked(jobStatus); Loading Loading @@ -1858,7 +1864,7 @@ public class JobSchedulerService extends com.android.server.SystemService // state is such that all ready jobs should be run immediately. // state is such that all ready jobs should be run immediately. if (runNow != null && isReadyToBeExecutedLocked(runNow)) { if (runNow != null && isReadyToBeExecutedLocked(runNow)) { mJobPackageTracker.notePending(runNow); mJobPackageTracker.notePending(runNow); addOrderedItem(mPendingJobs, runNow, mEnqueueTimeComparator); addOrderedItem(mPendingJobs, runNow, sPendingJobComparator); } else { } else { queueReadyJobsForExecutionLocked(); queueReadyJobsForExecutionLocked(); } } Loading Loading @@ -2030,7 +2036,7 @@ public class JobSchedulerService extends com.android.server.SystemService noteJobsPending(newReadyJobs); noteJobsPending(newReadyJobs); mPendingJobs.addAll(newReadyJobs); mPendingJobs.addAll(newReadyJobs); if (mPendingJobs.size() > 1) { if (mPendingJobs.size() > 1) { mPendingJobs.sort(mEnqueueTimeComparator); mPendingJobs.sort(sPendingJobComparator); } } newReadyJobs.clear(); newReadyJobs.clear(); Loading Loading @@ -2107,7 +2113,7 @@ public class JobSchedulerService extends com.android.server.SystemService noteJobsPending(runnableJobs); noteJobsPending(runnableJobs); mPendingJobs.addAll(runnableJobs); mPendingJobs.addAll(runnableJobs); if (mPendingJobs.size() > 1) { if (mPendingJobs.size() > 1) { mPendingJobs.sort(mEnqueueTimeComparator); mPendingJobs.sort(sPendingJobComparator); } } } else { } else { if (DEBUG) { if (DEBUG) { Loading Loading @@ -2813,11 +2819,9 @@ public class JobSchedulerService extends com.android.server.SystemService } } // Shell command infrastructure: run the given job immediately // Shell command infrastructure: run the given job immediately int executeRunCommand(String pkgName, int userId, int jobId, boolean force) { int executeRunCommand(String pkgName, int userId, int jobId, boolean satisfied, boolean force) { if (DEBUG) { Slog.d(TAG, "executeRunCommand(): " + pkgName + "/" + userId Slog.v(TAG, "executeRunCommand(): " + pkgName + "/" + userId + " " + jobId + " s=" + satisfied + " f=" + force); + " " + jobId + " f=" + force); } try { try { final int uid = AppGlobals.getPackageManager().getPackageUid(pkgName, 0, final int uid = AppGlobals.getPackageManager().getPackageUid(pkgName, 0, Loading @@ -2832,7 +2836,8 @@ public class JobSchedulerService extends com.android.server.SystemService return JobSchedulerShellCommand.CMD_ERR_NO_JOB; return JobSchedulerShellCommand.CMD_ERR_NO_JOB; } } js.overrideState = (force) ? JobStatus.OVERRIDE_FULL : JobStatus.OVERRIDE_SOFT; js.overrideState = (force) ? JobStatus.OVERRIDE_FULL : (satisfied ? JobStatus.OVERRIDE_SORTING : JobStatus.OVERRIDE_SOFT); // Re-evaluate constraints after the override is set in case one of the overridden // Re-evaluate constraints after the override is set in case one of the overridden // constraints was preventing another constraint from thinking it needed to update. // constraints was preventing another constraint from thinking it needed to update. Loading @@ -2841,7 +2846,7 @@ public class JobSchedulerService extends com.android.server.SystemService } } if (!js.isConstraintsSatisfied()) { if (!js.isConstraintsSatisfied()) { js.overrideState = 0; js.overrideState = JobStatus.OVERRIDE_NONE; return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS; return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS; } } Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java +22 −4 Original line number Original line Diff line number Diff line Loading @@ -136,6 +136,7 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { checkPermission("force scheduled jobs"); checkPermission("force scheduled jobs"); boolean force = false; boolean force = false; boolean satisfied = false; int userId = UserHandle.USER_SYSTEM; int userId = UserHandle.USER_SYSTEM; String opt; String opt; Loading @@ -146,6 +147,11 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { force = true; force = true; break; break; case "-s": case "--satisfied": satisfied = true; break; case "-u": case "-u": case "--user": case "--user": userId = Integer.parseInt(getNextArgRequired()); userId = Integer.parseInt(getNextArgRequired()); Loading @@ -157,12 +163,17 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { } } } } if (force && satisfied) { pw.println("Cannot specify both --force and --satisfied"); return -1; } final String pkgName = getNextArgRequired(); final String pkgName = getNextArgRequired(); final int jobId = Integer.parseInt(getNextArgRequired()); final int jobId = Integer.parseInt(getNextArgRequired()); final long ident = Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); try { try { int ret = mInternal.executeRunCommand(pkgName, userId, jobId, force); int ret = mInternal.executeRunCommand(pkgName, userId, jobId, satisfied, force); if (printError(ret, pkgName, userId, jobId)) { if (printError(ret, pkgName, userId, jobId)) { return ret; return ret; } } Loading Loading @@ -424,11 +435,18 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { pw.println("Job scheduler (jobscheduler) commands:"); pw.println("Job scheduler (jobscheduler) commands:"); pw.println(" help"); pw.println(" help"); pw.println(" Print this help text."); pw.println(" Print this help text."); pw.println(" run [-f | --force] [-u | --user USER_ID] PACKAGE JOB_ID"); pw.println(" run [-f | --force] [-s | --satisfied] [-u | --user USER_ID] PACKAGE JOB_ID"); pw.println(" Trigger immediate execution of a specific scheduled job."); pw.println(" Trigger immediate execution of a specific scheduled job. For historical"); pw.println(" reasons, some constraints, such as battery, are ignored when this"); pw.println(" command is called. If you don't want any constraints to be ignored,"); pw.println(" include the -s flag."); pw.println(" Options:"); pw.println(" Options:"); pw.println(" -f or --force: run the job even if technical constraints such as"); pw.println(" -f or --force: run the job even if technical constraints such as"); pw.println(" connectivity are not currently met"); pw.println(" connectivity are not currently met. This is incompatible with -f "); pw.println(" and so an error will be reported if both are given."); pw.println(" -s or --satisfied: run the job only if all constraints are met."); pw.println(" This is incompatible with -f and so an error will be reported"); pw.println(" if both are given."); pw.println(" -u or --user: specify which user's job is to be run; the default is"); pw.println(" -u or --user: specify which user's job is to be run; the default is"); pw.println(" the primary or system user"); pw.println(" the primary or system user"); pw.println(" timeout [-u | --user USER_ID] [PACKAGE] [JOB_ID]"); pw.println(" timeout [-u | --user USER_ID] [PACKAGE] [JOB_ID]"); Loading apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +7 −3 Original line number Original line Diff line number Diff line Loading @@ -131,10 +131,14 @@ public final class JobStatus { // TODO(b/129954980) // TODO(b/129954980) private static final boolean STATS_LOG_ENABLED = false; private static final boolean STATS_LOG_ENABLED = false; // No override. public static final int OVERRIDE_NONE = 0; // Override to improve sorting order. Does not affect constraint evaluation. public static final int OVERRIDE_SORTING = 1; // Soft override: ignore constraints like time that don't affect API availability // Soft override: ignore constraints like time that don't affect API availability public static final int OVERRIDE_SOFT = 1; public static final int OVERRIDE_SOFT = 2; // Full override: ignore all constraints including API-affecting like connectivity // Full override: ignore all constraints including API-affecting like connectivity public static final int OVERRIDE_FULL = 2; public static final int OVERRIDE_FULL = 3; /** If not specified, trigger update delay is 10 seconds. */ /** If not specified, trigger update delay is 10 seconds. */ public static final long DEFAULT_TRIGGER_UPDATE_DELAY = 10*1000; public static final long DEFAULT_TRIGGER_UPDATE_DELAY = 10*1000; Loading Loading @@ -304,7 +308,7 @@ public final class JobStatus { public int nextPendingWorkId = 1; public int nextPendingWorkId = 1; // Used by shell commands // Used by shell commands public int overrideState = 0; public int overrideState = JobStatus.OVERRIDE_NONE; // When this job was enqueued, for ordering. (in elapsedRealtimeMillis) // When this job was enqueued, for ordering. (in elapsedRealtimeMillis) public long enqueueTime; public long enqueueTime; Loading Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +17 −12 Original line number Original line Diff line number Diff line Loading @@ -746,7 +746,13 @@ public class JobSchedulerService extends com.android.server.SystemService final Constants mConstants; final Constants mConstants; final ConstantsObserver mConstantsObserver; final ConstantsObserver mConstantsObserver; static final Comparator<JobStatus> mEnqueueTimeComparator = (o1, o2) -> { private static final Comparator<JobStatus> sPendingJobComparator = (o1, o2) -> { // Jobs with an override state set (via adb) should be put first as tests/developers // expect the jobs to run immediately. if (o1.overrideState != o2.overrideState) { // Higher override state (OVERRIDE_FULL) should be before lower state (OVERRIDE_SOFT) return o2.overrideState - o1.overrideState; } if (o1.enqueueTime < o2.enqueueTime) { if (o1.enqueueTime < o2.enqueueTime) { return -1; return -1; } } Loading Loading @@ -1097,7 +1103,7 @@ public class JobSchedulerService extends com.android.server.SystemService // This is a new job, we can just immediately put it on the pending // This is a new job, we can just immediately put it on the pending // list and try to run it. // list and try to run it. mJobPackageTracker.notePending(jobStatus); mJobPackageTracker.notePending(jobStatus); addOrderedItem(mPendingJobs, jobStatus, mEnqueueTimeComparator); addOrderedItem(mPendingJobs, jobStatus, sPendingJobComparator); maybeRunPendingJobsLocked(); maybeRunPendingJobsLocked(); } else { } else { evaluateControllerStatesLocked(jobStatus); evaluateControllerStatesLocked(jobStatus); Loading Loading @@ -1858,7 +1864,7 @@ public class JobSchedulerService extends com.android.server.SystemService // state is such that all ready jobs should be run immediately. // state is such that all ready jobs should be run immediately. if (runNow != null && isReadyToBeExecutedLocked(runNow)) { if (runNow != null && isReadyToBeExecutedLocked(runNow)) { mJobPackageTracker.notePending(runNow); mJobPackageTracker.notePending(runNow); addOrderedItem(mPendingJobs, runNow, mEnqueueTimeComparator); addOrderedItem(mPendingJobs, runNow, sPendingJobComparator); } else { } else { queueReadyJobsForExecutionLocked(); queueReadyJobsForExecutionLocked(); } } Loading Loading @@ -2030,7 +2036,7 @@ public class JobSchedulerService extends com.android.server.SystemService noteJobsPending(newReadyJobs); noteJobsPending(newReadyJobs); mPendingJobs.addAll(newReadyJobs); mPendingJobs.addAll(newReadyJobs); if (mPendingJobs.size() > 1) { if (mPendingJobs.size() > 1) { mPendingJobs.sort(mEnqueueTimeComparator); mPendingJobs.sort(sPendingJobComparator); } } newReadyJobs.clear(); newReadyJobs.clear(); Loading Loading @@ -2107,7 +2113,7 @@ public class JobSchedulerService extends com.android.server.SystemService noteJobsPending(runnableJobs); noteJobsPending(runnableJobs); mPendingJobs.addAll(runnableJobs); mPendingJobs.addAll(runnableJobs); if (mPendingJobs.size() > 1) { if (mPendingJobs.size() > 1) { mPendingJobs.sort(mEnqueueTimeComparator); mPendingJobs.sort(sPendingJobComparator); } } } else { } else { if (DEBUG) { if (DEBUG) { Loading Loading @@ -2813,11 +2819,9 @@ public class JobSchedulerService extends com.android.server.SystemService } } // Shell command infrastructure: run the given job immediately // Shell command infrastructure: run the given job immediately int executeRunCommand(String pkgName, int userId, int jobId, boolean force) { int executeRunCommand(String pkgName, int userId, int jobId, boolean satisfied, boolean force) { if (DEBUG) { Slog.d(TAG, "executeRunCommand(): " + pkgName + "/" + userId Slog.v(TAG, "executeRunCommand(): " + pkgName + "/" + userId + " " + jobId + " s=" + satisfied + " f=" + force); + " " + jobId + " f=" + force); } try { try { final int uid = AppGlobals.getPackageManager().getPackageUid(pkgName, 0, final int uid = AppGlobals.getPackageManager().getPackageUid(pkgName, 0, Loading @@ -2832,7 +2836,8 @@ public class JobSchedulerService extends com.android.server.SystemService return JobSchedulerShellCommand.CMD_ERR_NO_JOB; return JobSchedulerShellCommand.CMD_ERR_NO_JOB; } } js.overrideState = (force) ? JobStatus.OVERRIDE_FULL : JobStatus.OVERRIDE_SOFT; js.overrideState = (force) ? JobStatus.OVERRIDE_FULL : (satisfied ? JobStatus.OVERRIDE_SORTING : JobStatus.OVERRIDE_SOFT); // Re-evaluate constraints after the override is set in case one of the overridden // Re-evaluate constraints after the override is set in case one of the overridden // constraints was preventing another constraint from thinking it needed to update. // constraints was preventing another constraint from thinking it needed to update. Loading @@ -2841,7 +2846,7 @@ public class JobSchedulerService extends com.android.server.SystemService } } if (!js.isConstraintsSatisfied()) { if (!js.isConstraintsSatisfied()) { js.overrideState = 0; js.overrideState = JobStatus.OVERRIDE_NONE; return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS; return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS; } } Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java +22 −4 Original line number Original line Diff line number Diff line Loading @@ -136,6 +136,7 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { checkPermission("force scheduled jobs"); checkPermission("force scheduled jobs"); boolean force = false; boolean force = false; boolean satisfied = false; int userId = UserHandle.USER_SYSTEM; int userId = UserHandle.USER_SYSTEM; String opt; String opt; Loading @@ -146,6 +147,11 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { force = true; force = true; break; break; case "-s": case "--satisfied": satisfied = true; break; case "-u": case "-u": case "--user": case "--user": userId = Integer.parseInt(getNextArgRequired()); userId = Integer.parseInt(getNextArgRequired()); Loading @@ -157,12 +163,17 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { } } } } if (force && satisfied) { pw.println("Cannot specify both --force and --satisfied"); return -1; } final String pkgName = getNextArgRequired(); final String pkgName = getNextArgRequired(); final int jobId = Integer.parseInt(getNextArgRequired()); final int jobId = Integer.parseInt(getNextArgRequired()); final long ident = Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); try { try { int ret = mInternal.executeRunCommand(pkgName, userId, jobId, force); int ret = mInternal.executeRunCommand(pkgName, userId, jobId, satisfied, force); if (printError(ret, pkgName, userId, jobId)) { if (printError(ret, pkgName, userId, jobId)) { return ret; return ret; } } Loading Loading @@ -424,11 +435,18 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { pw.println("Job scheduler (jobscheduler) commands:"); pw.println("Job scheduler (jobscheduler) commands:"); pw.println(" help"); pw.println(" help"); pw.println(" Print this help text."); pw.println(" Print this help text."); pw.println(" run [-f | --force] [-u | --user USER_ID] PACKAGE JOB_ID"); pw.println(" run [-f | --force] [-s | --satisfied] [-u | --user USER_ID] PACKAGE JOB_ID"); pw.println(" Trigger immediate execution of a specific scheduled job."); pw.println(" Trigger immediate execution of a specific scheduled job. For historical"); pw.println(" reasons, some constraints, such as battery, are ignored when this"); pw.println(" command is called. If you don't want any constraints to be ignored,"); pw.println(" include the -s flag."); pw.println(" Options:"); pw.println(" Options:"); pw.println(" -f or --force: run the job even if technical constraints such as"); pw.println(" -f or --force: run the job even if technical constraints such as"); pw.println(" connectivity are not currently met"); pw.println(" connectivity are not currently met. This is incompatible with -f "); pw.println(" and so an error will be reported if both are given."); pw.println(" -s or --satisfied: run the job only if all constraints are met."); pw.println(" This is incompatible with -f and so an error will be reported"); pw.println(" if both are given."); pw.println(" -u or --user: specify which user's job is to be run; the default is"); pw.println(" -u or --user: specify which user's job is to be run; the default is"); pw.println(" the primary or system user"); pw.println(" the primary or system user"); pw.println(" timeout [-u | --user USER_ID] [PACKAGE] [JOB_ID]"); pw.println(" timeout [-u | --user USER_ID] [PACKAGE] [JOB_ID]"); Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +7 −3 Original line number Original line Diff line number Diff line Loading @@ -131,10 +131,14 @@ public final class JobStatus { // TODO(b/129954980) // TODO(b/129954980) private static final boolean STATS_LOG_ENABLED = false; private static final boolean STATS_LOG_ENABLED = false; // No override. public static final int OVERRIDE_NONE = 0; // Override to improve sorting order. Does not affect constraint evaluation. public static final int OVERRIDE_SORTING = 1; // Soft override: ignore constraints like time that don't affect API availability // Soft override: ignore constraints like time that don't affect API availability public static final int OVERRIDE_SOFT = 1; public static final int OVERRIDE_SOFT = 2; // Full override: ignore all constraints including API-affecting like connectivity // Full override: ignore all constraints including API-affecting like connectivity public static final int OVERRIDE_FULL = 2; public static final int OVERRIDE_FULL = 3; /** If not specified, trigger update delay is 10 seconds. */ /** If not specified, trigger update delay is 10 seconds. */ public static final long DEFAULT_TRIGGER_UPDATE_DELAY = 10*1000; public static final long DEFAULT_TRIGGER_UPDATE_DELAY = 10*1000; Loading Loading @@ -304,7 +308,7 @@ public final class JobStatus { public int nextPendingWorkId = 1; public int nextPendingWorkId = 1; // Used by shell commands // Used by shell commands public int overrideState = 0; public int overrideState = JobStatus.OVERRIDE_NONE; // When this job was enqueued, for ordering. (in elapsedRealtimeMillis) // When this job was enqueued, for ordering. (in elapsedRealtimeMillis) public long enqueueTime; public long enqueueTime; Loading