Loading apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java +64 −20 Original line number Original line Diff line number Diff line Loading @@ -64,7 +64,7 @@ import java.util.List; * and which {@link JobServiceContext} to run each job on. * and which {@link JobServiceContext} to run each job on. */ */ class JobConcurrencyManager { class JobConcurrencyManager { private static final String TAG = JobSchedulerService.TAG; private static final String TAG = JobSchedulerService.TAG + ".Concurrency"; private static final boolean DEBUG = JobSchedulerService.DEBUG; private static final boolean DEBUG = JobSchedulerService.DEBUG; static final String CONFIG_KEY_PREFIX_CONCURRENCY = "concurrency_"; static final String CONFIG_KEY_PREFIX_CONCURRENCY = "concurrency_"; Loading Loading @@ -321,13 +321,14 @@ class JobConcurrencyManager { } } } } /** Return {@code true} if the state was updated. */ @GuardedBy("mLock") @GuardedBy("mLock") private void refreshSystemStateLocked() { private boolean refreshSystemStateLocked() { final long nowUptime = JobSchedulerService.sUptimeMillisClock.millis(); final long nowUptime = JobSchedulerService.sUptimeMillisClock.millis(); // Only refresh the information every so often. // Only refresh the information every so often. if (nowUptime < mNextSystemStateRefreshTime) { if (nowUptime < mNextSystemStateRefreshTime) { return; return false; } } final long start = mStatLogger.getTime(); final long start = mStatLogger.getTime(); Loading @@ -340,11 +341,14 @@ class JobConcurrencyManager { } } mStatLogger.logDurationStat(Stats.REFRESH_SYSTEM_STATE, start); mStatLogger.logDurationStat(Stats.REFRESH_SYSTEM_STATE, start); return true; } } @GuardedBy("mLock") @GuardedBy("mLock") private void updateCounterConfigLocked() { private void updateCounterConfigLocked() { refreshSystemStateLocked(); if (!refreshSystemStateLocked()) { return; } final WorkConfigLimitsPerMemoryTrimLevel workConfigs = mEffectiveInteractiveState final WorkConfigLimitsPerMemoryTrimLevel workConfigs = mEffectiveInteractiveState ? CONFIG_LIMITS_SCREEN_ON : CONFIG_LIMITS_SCREEN_OFF; ? CONFIG_LIMITS_SCREEN_ON : CONFIG_LIMITS_SCREEN_OFF; Loading Loading @@ -437,7 +441,8 @@ class JobConcurrencyManager { // (sharing the same Uid as nextPending) // (sharing the same Uid as nextPending) int minPriorityForPreemption = Integer.MAX_VALUE; int minPriorityForPreemption = Integer.MAX_VALUE; int selectedContextId = -1; int selectedContextId = -1; int workType = mWorkCountTracker.canJobStart(getJobWorkTypes(nextPending)); int allWorkTypes = getJobWorkTypes(nextPending); int workType = mWorkCountTracker.canJobStart(allWorkTypes); boolean startingJob = false; boolean startingJob = false; for (int j = 0; j < MAX_JOB_CONTEXTS_COUNT; j++) { for (int j = 0; j < MAX_JOB_CONTEXTS_COUNT; j++) { JobStatus job = contextIdToJobMap[j]; JobStatus job = contextIdToJobMap[j]; Loading Loading @@ -483,7 +488,7 @@ class JobConcurrencyManager { if (startingJob) { if (startingJob) { // Increase the counters when we're going to start a job. // Increase the counters when we're going to start a job. workTypeForContext[selectedContextId] = workType; workTypeForContext[selectedContextId] = workType; mWorkCountTracker.stageJob(workType); mWorkCountTracker.stageJob(workType, allWorkTypes); } } } } if (DEBUG) { if (DEBUG) { Loading Loading @@ -578,8 +583,10 @@ class JobConcurrencyManager { JobStatus highestPriorityJob = null; JobStatus highestPriorityJob = null; int highPriWorkType = workType; int highPriWorkType = workType; int highPriAllWorkTypes = workType; JobStatus backupJob = null; JobStatus backupJob = null; int backupWorkType = WORK_TYPE_NONE; int backupWorkType = WORK_TYPE_NONE; int backupAllWorkTypes = WORK_TYPE_NONE; for (int i = 0; i < pendingJobs.size(); i++) { for (int i = 0; i < pendingJobs.size(); i++) { final JobStatus nextPending = pendingJobs.get(i); final JobStatus nextPending = pendingJobs.get(i); Loading @@ -589,11 +596,12 @@ class JobConcurrencyManager { if (worker.getPreferredUid() != nextPending.getUid()) { if (worker.getPreferredUid() != nextPending.getUid()) { if (backupJob == null) { if (backupJob == null) { int workAsType = int allWorkTypes = getJobWorkTypes(nextPending); mWorkCountTracker.canJobStart(getJobWorkTypes(nextPending)); int workAsType = mWorkCountTracker.canJobStart(allWorkTypes); if (workAsType != WORK_TYPE_NONE) { if (workAsType != WORK_TYPE_NONE) { backupJob = nextPending; backupJob = nextPending; backupWorkType = workAsType; backupWorkType = workAsType; backupAllWorkTypes = allWorkTypes; } } } } continue; continue; Loading @@ -611,7 +619,8 @@ class JobConcurrencyManager { // reserved slots. We should just run the highest priority job we can find, // reserved slots. We should just run the highest priority job we can find, // though it would be ideal to use an available WorkType slot instead of // though it would be ideal to use an available WorkType slot instead of // overloading slots. // overloading slots. final int workAsType = mWorkCountTracker.canJobStart(getJobWorkTypes(nextPending)); highPriAllWorkTypes = getJobWorkTypes(nextPending); final int workAsType = mWorkCountTracker.canJobStart(highPriAllWorkTypes); if (workAsType == WORK_TYPE_NONE) { if (workAsType == WORK_TYPE_NONE) { // Just use the preempted job's work type since this new one is technically // Just use the preempted job's work type since this new one is technically // replacing it anyway. // replacing it anyway. Loading @@ -624,7 +633,7 @@ class JobConcurrencyManager { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Running job " + jobStatus + " as preemption"); Slog.d(TAG, "Running job " + jobStatus + " as preemption"); } } mWorkCountTracker.stageJob(highPriWorkType); mWorkCountTracker.stageJob(highPriWorkType, highPriAllWorkTypes); startJobLocked(worker, highestPriorityJob, highPriWorkType); startJobLocked(worker, highestPriorityJob, highPriWorkType); } else { } else { if (DEBUG) { if (DEBUG) { Loading @@ -635,7 +644,7 @@ class JobConcurrencyManager { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Running job " + jobStatus + " instead"); Slog.d(TAG, "Running job " + jobStatus + " instead"); } } mWorkCountTracker.stageJob(backupWorkType); mWorkCountTracker.stageJob(backupWorkType, backupAllWorkTypes); startJobLocked(worker, backupJob, backupWorkType); startJobLocked(worker, backupJob, backupWorkType); } } } } Loading @@ -647,6 +656,7 @@ class JobConcurrencyManager { // find. // find. JobStatus highestPriorityJob = null; JobStatus highestPriorityJob = null; int highPriWorkType = workType; int highPriWorkType = workType; int highPriAllWorkTypes = workType; for (int i = 0; i < pendingJobs.size(); i++) { for (int i = 0; i < pendingJobs.size(); i++) { final JobStatus nextPending = pendingJobs.get(i); final JobStatus nextPending = pendingJobs.get(i); Loading @@ -654,7 +664,8 @@ class JobConcurrencyManager { continue; continue; } } final int workAsType = mWorkCountTracker.canJobStart(getJobWorkTypes(nextPending)); final int allWorkTypes = getJobWorkTypes(nextPending); final int workAsType = mWorkCountTracker.canJobStart(allWorkTypes); if (workAsType == WORK_TYPE_NONE) { if (workAsType == WORK_TYPE_NONE) { continue; continue; } } Loading @@ -663,6 +674,7 @@ class JobConcurrencyManager { < nextPending.lastEvaluatedPriority) { < nextPending.lastEvaluatedPriority) { highestPriorityJob = nextPending; highestPriorityJob = nextPending; highPriWorkType = workAsType; highPriWorkType = workAsType; highPriAllWorkTypes = allWorkTypes; } } } } Loading @@ -672,7 +684,7 @@ class JobConcurrencyManager { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "About to run job: " + jobStatus); Slog.d(TAG, "About to run job: " + jobStatus); } } mWorkCountTracker.stageJob(highPriWorkType); mWorkCountTracker.stageJob(highPriWorkType, highPriAllWorkTypes); startJobLocked(worker, highestPriorityJob, highPriWorkType); startJobLocked(worker, highestPriorityJob, highPriWorkType); } } } } Loading Loading @@ -1102,26 +1114,58 @@ class JobConcurrencyManager { } } void incrementPendingJobCount(int workTypes) { void incrementPendingJobCount(int workTypes) { adjustPendingJobCount(workTypes, true); } void decrementPendingJobCount(int workTypes) { if (adjustPendingJobCount(workTypes, false) > 1) { // We don't need to adjust reservations if only one work type was modified // because that work type is the one we're using. // 0 is WORK_TYPE_NONE. int workType = 1; int rem = workTypes; while (rem > 0) { if ((rem & 1) != 0) { maybeAdjustReservations(workType); } rem = rem >>> 1; workType = workType << 1; } } } /** Returns the number of WorkTypes that were modified. */ private int adjustPendingJobCount(int workTypes, boolean add) { final int adj = add ? 1 : -1; int numAdj = 0; // We don't know which type we'll classify the job as when we run it yet, so make sure // We don't know which type we'll classify the job as when we run it yet, so make sure // we have space in all applicable slots. // we have space in all applicable slots. if ((workTypes & WORK_TYPE_TOP) == WORK_TYPE_TOP) { if ((workTypes & WORK_TYPE_TOP) == WORK_TYPE_TOP) { mNumPendingJobs.put(WORK_TYPE_TOP, mNumPendingJobs.get(WORK_TYPE_TOP) + 1); mNumPendingJobs.put(WORK_TYPE_TOP, mNumPendingJobs.get(WORK_TYPE_TOP) + adj); numAdj++; } } if ((workTypes & WORK_TYPE_EJ) == WORK_TYPE_EJ) { if ((workTypes & WORK_TYPE_EJ) == WORK_TYPE_EJ) { mNumPendingJobs.put(WORK_TYPE_EJ, mNumPendingJobs.get(WORK_TYPE_EJ) + 1); mNumPendingJobs.put(WORK_TYPE_EJ, mNumPendingJobs.get(WORK_TYPE_EJ) + adj); numAdj++; } } if ((workTypes & WORK_TYPE_BG) == WORK_TYPE_BG) { if ((workTypes & WORK_TYPE_BG) == WORK_TYPE_BG) { mNumPendingJobs.put(WORK_TYPE_BG, mNumPendingJobs.get(WORK_TYPE_BG) + 1); mNumPendingJobs.put(WORK_TYPE_BG, mNumPendingJobs.get(WORK_TYPE_BG) + adj); numAdj++; } } if ((workTypes & WORK_TYPE_BGUSER) == WORK_TYPE_BGUSER) { if ((workTypes & WORK_TYPE_BGUSER) == WORK_TYPE_BGUSER) { mNumPendingJobs.put(WORK_TYPE_BGUSER, mNumPendingJobs.get(WORK_TYPE_BGUSER) + 1); mNumPendingJobs.put(WORK_TYPE_BGUSER, mNumPendingJobs.get(WORK_TYPE_BGUSER) + adj); numAdj++; } } return numAdj; } } void stageJob(@WorkType int workType) { void stageJob(@WorkType int workType, int allWorkTypes) { final int newNumStartingJobs = mNumStartingJobs.get(workType) + 1; final int newNumStartingJobs = mNumStartingJobs.get(workType) + 1; mNumStartingJobs.put(workType, newNumStartingJobs); mNumStartingJobs.put(workType, newNumStartingJobs); mNumPendingJobs.put(workType, Math.max(0, mNumPendingJobs.get(workType) - 1)); decrementPendingJobCount(allWorkTypes); if (newNumStartingJobs + mNumRunningJobs.get(workType) if (newNumStartingJobs + mNumRunningJobs.get(workType) > mNumActuallyReservedSlots.get(workType)) { > mNumActuallyReservedSlots.get(workType)) { mNumUnspecializedRemaining--; mNumUnspecializedRemaining--; Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -3183,7 +3183,7 @@ public class JobSchedulerService extends com.android.server.SystemService TimeUtils.formatDuration(jsc.getTimeoutElapsed() - nowElapsed, pw); TimeUtils.formatDuration(jsc.getTimeoutElapsed() - nowElapsed, pw); pw.println(); pw.println(); job.dump(pw, " ", false, nowElapsed); job.dump(pw, " ", false, nowElapsed); int priority = evaluateJobPriorityLocked(jsc.getRunningJobLocked()); int priority = evaluateJobPriorityLocked(job); pw.print(" Evaluated priority: "); pw.print(" Evaluated priority: "); pw.println(JobInfo.getPriorityString(priority)); pw.println(JobInfo.getPriorityString(priority)); Loading Loading @@ -3349,7 +3349,7 @@ public class JobSchedulerService extends com.android.server.SystemService job.dump(proto, ActiveJob.RunningJob.DUMP, false, nowElapsed); job.dump(proto, ActiveJob.RunningJob.DUMP, false, nowElapsed); proto.write(ActiveJob.RunningJob.EVALUATED_PRIORITY, proto.write(ActiveJob.RunningJob.EVALUATED_PRIORITY, evaluateJobPriorityLocked(jsc.getRunningJobLocked())); evaluateJobPriorityLocked(job)); proto.write(ActiveJob.RunningJob.TIME_SINCE_MADE_ACTIVE_MS, proto.write(ActiveJob.RunningJob.TIME_SINCE_MADE_ACTIVE_MS, nowUptime - job.madeActive); nowUptime - job.madeActive); Loading apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_NONE; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.Nullable; import android.app.job.IJobCallback; import android.app.job.IJobCallback; import android.app.job.IJobService; import android.app.job.IJobService; import android.app.job.JobInfo; import android.app.job.JobInfo; Loading Loading @@ -326,6 +327,7 @@ public final class JobServiceContext implements ServiceConnection { /** /** * Used externally to query the running job. Will return null if there is no job running. * Used externally to query the running job. Will return null if there is no job running. */ */ @Nullable JobStatus getRunningJobLocked() { JobStatus getRunningJobLocked() { return mRunningJob; return mRunningJob; } } Loading services/tests/servicestests/src/com/android/server/job/WorkCountTrackerTest.java +320 −73 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java +64 −20 Original line number Original line Diff line number Diff line Loading @@ -64,7 +64,7 @@ import java.util.List; * and which {@link JobServiceContext} to run each job on. * and which {@link JobServiceContext} to run each job on. */ */ class JobConcurrencyManager { class JobConcurrencyManager { private static final String TAG = JobSchedulerService.TAG; private static final String TAG = JobSchedulerService.TAG + ".Concurrency"; private static final boolean DEBUG = JobSchedulerService.DEBUG; private static final boolean DEBUG = JobSchedulerService.DEBUG; static final String CONFIG_KEY_PREFIX_CONCURRENCY = "concurrency_"; static final String CONFIG_KEY_PREFIX_CONCURRENCY = "concurrency_"; Loading Loading @@ -321,13 +321,14 @@ class JobConcurrencyManager { } } } } /** Return {@code true} if the state was updated. */ @GuardedBy("mLock") @GuardedBy("mLock") private void refreshSystemStateLocked() { private boolean refreshSystemStateLocked() { final long nowUptime = JobSchedulerService.sUptimeMillisClock.millis(); final long nowUptime = JobSchedulerService.sUptimeMillisClock.millis(); // Only refresh the information every so often. // Only refresh the information every so often. if (nowUptime < mNextSystemStateRefreshTime) { if (nowUptime < mNextSystemStateRefreshTime) { return; return false; } } final long start = mStatLogger.getTime(); final long start = mStatLogger.getTime(); Loading @@ -340,11 +341,14 @@ class JobConcurrencyManager { } } mStatLogger.logDurationStat(Stats.REFRESH_SYSTEM_STATE, start); mStatLogger.logDurationStat(Stats.REFRESH_SYSTEM_STATE, start); return true; } } @GuardedBy("mLock") @GuardedBy("mLock") private void updateCounterConfigLocked() { private void updateCounterConfigLocked() { refreshSystemStateLocked(); if (!refreshSystemStateLocked()) { return; } final WorkConfigLimitsPerMemoryTrimLevel workConfigs = mEffectiveInteractiveState final WorkConfigLimitsPerMemoryTrimLevel workConfigs = mEffectiveInteractiveState ? CONFIG_LIMITS_SCREEN_ON : CONFIG_LIMITS_SCREEN_OFF; ? CONFIG_LIMITS_SCREEN_ON : CONFIG_LIMITS_SCREEN_OFF; Loading Loading @@ -437,7 +441,8 @@ class JobConcurrencyManager { // (sharing the same Uid as nextPending) // (sharing the same Uid as nextPending) int minPriorityForPreemption = Integer.MAX_VALUE; int minPriorityForPreemption = Integer.MAX_VALUE; int selectedContextId = -1; int selectedContextId = -1; int workType = mWorkCountTracker.canJobStart(getJobWorkTypes(nextPending)); int allWorkTypes = getJobWorkTypes(nextPending); int workType = mWorkCountTracker.canJobStart(allWorkTypes); boolean startingJob = false; boolean startingJob = false; for (int j = 0; j < MAX_JOB_CONTEXTS_COUNT; j++) { for (int j = 0; j < MAX_JOB_CONTEXTS_COUNT; j++) { JobStatus job = contextIdToJobMap[j]; JobStatus job = contextIdToJobMap[j]; Loading Loading @@ -483,7 +488,7 @@ class JobConcurrencyManager { if (startingJob) { if (startingJob) { // Increase the counters when we're going to start a job. // Increase the counters when we're going to start a job. workTypeForContext[selectedContextId] = workType; workTypeForContext[selectedContextId] = workType; mWorkCountTracker.stageJob(workType); mWorkCountTracker.stageJob(workType, allWorkTypes); } } } } if (DEBUG) { if (DEBUG) { Loading Loading @@ -578,8 +583,10 @@ class JobConcurrencyManager { JobStatus highestPriorityJob = null; JobStatus highestPriorityJob = null; int highPriWorkType = workType; int highPriWorkType = workType; int highPriAllWorkTypes = workType; JobStatus backupJob = null; JobStatus backupJob = null; int backupWorkType = WORK_TYPE_NONE; int backupWorkType = WORK_TYPE_NONE; int backupAllWorkTypes = WORK_TYPE_NONE; for (int i = 0; i < pendingJobs.size(); i++) { for (int i = 0; i < pendingJobs.size(); i++) { final JobStatus nextPending = pendingJobs.get(i); final JobStatus nextPending = pendingJobs.get(i); Loading @@ -589,11 +596,12 @@ class JobConcurrencyManager { if (worker.getPreferredUid() != nextPending.getUid()) { if (worker.getPreferredUid() != nextPending.getUid()) { if (backupJob == null) { if (backupJob == null) { int workAsType = int allWorkTypes = getJobWorkTypes(nextPending); mWorkCountTracker.canJobStart(getJobWorkTypes(nextPending)); int workAsType = mWorkCountTracker.canJobStart(allWorkTypes); if (workAsType != WORK_TYPE_NONE) { if (workAsType != WORK_TYPE_NONE) { backupJob = nextPending; backupJob = nextPending; backupWorkType = workAsType; backupWorkType = workAsType; backupAllWorkTypes = allWorkTypes; } } } } continue; continue; Loading @@ -611,7 +619,8 @@ class JobConcurrencyManager { // reserved slots. We should just run the highest priority job we can find, // reserved slots. We should just run the highest priority job we can find, // though it would be ideal to use an available WorkType slot instead of // though it would be ideal to use an available WorkType slot instead of // overloading slots. // overloading slots. final int workAsType = mWorkCountTracker.canJobStart(getJobWorkTypes(nextPending)); highPriAllWorkTypes = getJobWorkTypes(nextPending); final int workAsType = mWorkCountTracker.canJobStart(highPriAllWorkTypes); if (workAsType == WORK_TYPE_NONE) { if (workAsType == WORK_TYPE_NONE) { // Just use the preempted job's work type since this new one is technically // Just use the preempted job's work type since this new one is technically // replacing it anyway. // replacing it anyway. Loading @@ -624,7 +633,7 @@ class JobConcurrencyManager { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Running job " + jobStatus + " as preemption"); Slog.d(TAG, "Running job " + jobStatus + " as preemption"); } } mWorkCountTracker.stageJob(highPriWorkType); mWorkCountTracker.stageJob(highPriWorkType, highPriAllWorkTypes); startJobLocked(worker, highestPriorityJob, highPriWorkType); startJobLocked(worker, highestPriorityJob, highPriWorkType); } else { } else { if (DEBUG) { if (DEBUG) { Loading @@ -635,7 +644,7 @@ class JobConcurrencyManager { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Running job " + jobStatus + " instead"); Slog.d(TAG, "Running job " + jobStatus + " instead"); } } mWorkCountTracker.stageJob(backupWorkType); mWorkCountTracker.stageJob(backupWorkType, backupAllWorkTypes); startJobLocked(worker, backupJob, backupWorkType); startJobLocked(worker, backupJob, backupWorkType); } } } } Loading @@ -647,6 +656,7 @@ class JobConcurrencyManager { // find. // find. JobStatus highestPriorityJob = null; JobStatus highestPriorityJob = null; int highPriWorkType = workType; int highPriWorkType = workType; int highPriAllWorkTypes = workType; for (int i = 0; i < pendingJobs.size(); i++) { for (int i = 0; i < pendingJobs.size(); i++) { final JobStatus nextPending = pendingJobs.get(i); final JobStatus nextPending = pendingJobs.get(i); Loading @@ -654,7 +664,8 @@ class JobConcurrencyManager { continue; continue; } } final int workAsType = mWorkCountTracker.canJobStart(getJobWorkTypes(nextPending)); final int allWorkTypes = getJobWorkTypes(nextPending); final int workAsType = mWorkCountTracker.canJobStart(allWorkTypes); if (workAsType == WORK_TYPE_NONE) { if (workAsType == WORK_TYPE_NONE) { continue; continue; } } Loading @@ -663,6 +674,7 @@ class JobConcurrencyManager { < nextPending.lastEvaluatedPriority) { < nextPending.lastEvaluatedPriority) { highestPriorityJob = nextPending; highestPriorityJob = nextPending; highPriWorkType = workAsType; highPriWorkType = workAsType; highPriAllWorkTypes = allWorkTypes; } } } } Loading @@ -672,7 +684,7 @@ class JobConcurrencyManager { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "About to run job: " + jobStatus); Slog.d(TAG, "About to run job: " + jobStatus); } } mWorkCountTracker.stageJob(highPriWorkType); mWorkCountTracker.stageJob(highPriWorkType, highPriAllWorkTypes); startJobLocked(worker, highestPriorityJob, highPriWorkType); startJobLocked(worker, highestPriorityJob, highPriWorkType); } } } } Loading Loading @@ -1102,26 +1114,58 @@ class JobConcurrencyManager { } } void incrementPendingJobCount(int workTypes) { void incrementPendingJobCount(int workTypes) { adjustPendingJobCount(workTypes, true); } void decrementPendingJobCount(int workTypes) { if (adjustPendingJobCount(workTypes, false) > 1) { // We don't need to adjust reservations if only one work type was modified // because that work type is the one we're using. // 0 is WORK_TYPE_NONE. int workType = 1; int rem = workTypes; while (rem > 0) { if ((rem & 1) != 0) { maybeAdjustReservations(workType); } rem = rem >>> 1; workType = workType << 1; } } } /** Returns the number of WorkTypes that were modified. */ private int adjustPendingJobCount(int workTypes, boolean add) { final int adj = add ? 1 : -1; int numAdj = 0; // We don't know which type we'll classify the job as when we run it yet, so make sure // We don't know which type we'll classify the job as when we run it yet, so make sure // we have space in all applicable slots. // we have space in all applicable slots. if ((workTypes & WORK_TYPE_TOP) == WORK_TYPE_TOP) { if ((workTypes & WORK_TYPE_TOP) == WORK_TYPE_TOP) { mNumPendingJobs.put(WORK_TYPE_TOP, mNumPendingJobs.get(WORK_TYPE_TOP) + 1); mNumPendingJobs.put(WORK_TYPE_TOP, mNumPendingJobs.get(WORK_TYPE_TOP) + adj); numAdj++; } } if ((workTypes & WORK_TYPE_EJ) == WORK_TYPE_EJ) { if ((workTypes & WORK_TYPE_EJ) == WORK_TYPE_EJ) { mNumPendingJobs.put(WORK_TYPE_EJ, mNumPendingJobs.get(WORK_TYPE_EJ) + 1); mNumPendingJobs.put(WORK_TYPE_EJ, mNumPendingJobs.get(WORK_TYPE_EJ) + adj); numAdj++; } } if ((workTypes & WORK_TYPE_BG) == WORK_TYPE_BG) { if ((workTypes & WORK_TYPE_BG) == WORK_TYPE_BG) { mNumPendingJobs.put(WORK_TYPE_BG, mNumPendingJobs.get(WORK_TYPE_BG) + 1); mNumPendingJobs.put(WORK_TYPE_BG, mNumPendingJobs.get(WORK_TYPE_BG) + adj); numAdj++; } } if ((workTypes & WORK_TYPE_BGUSER) == WORK_TYPE_BGUSER) { if ((workTypes & WORK_TYPE_BGUSER) == WORK_TYPE_BGUSER) { mNumPendingJobs.put(WORK_TYPE_BGUSER, mNumPendingJobs.get(WORK_TYPE_BGUSER) + 1); mNumPendingJobs.put(WORK_TYPE_BGUSER, mNumPendingJobs.get(WORK_TYPE_BGUSER) + adj); numAdj++; } } return numAdj; } } void stageJob(@WorkType int workType) { void stageJob(@WorkType int workType, int allWorkTypes) { final int newNumStartingJobs = mNumStartingJobs.get(workType) + 1; final int newNumStartingJobs = mNumStartingJobs.get(workType) + 1; mNumStartingJobs.put(workType, newNumStartingJobs); mNumStartingJobs.put(workType, newNumStartingJobs); mNumPendingJobs.put(workType, Math.max(0, mNumPendingJobs.get(workType) - 1)); decrementPendingJobCount(allWorkTypes); if (newNumStartingJobs + mNumRunningJobs.get(workType) if (newNumStartingJobs + mNumRunningJobs.get(workType) > mNumActuallyReservedSlots.get(workType)) { > mNumActuallyReservedSlots.get(workType)) { mNumUnspecializedRemaining--; mNumUnspecializedRemaining--; Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -3183,7 +3183,7 @@ public class JobSchedulerService extends com.android.server.SystemService TimeUtils.formatDuration(jsc.getTimeoutElapsed() - nowElapsed, pw); TimeUtils.formatDuration(jsc.getTimeoutElapsed() - nowElapsed, pw); pw.println(); pw.println(); job.dump(pw, " ", false, nowElapsed); job.dump(pw, " ", false, nowElapsed); int priority = evaluateJobPriorityLocked(jsc.getRunningJobLocked()); int priority = evaluateJobPriorityLocked(job); pw.print(" Evaluated priority: "); pw.print(" Evaluated priority: "); pw.println(JobInfo.getPriorityString(priority)); pw.println(JobInfo.getPriorityString(priority)); Loading Loading @@ -3349,7 +3349,7 @@ public class JobSchedulerService extends com.android.server.SystemService job.dump(proto, ActiveJob.RunningJob.DUMP, false, nowElapsed); job.dump(proto, ActiveJob.RunningJob.DUMP, false, nowElapsed); proto.write(ActiveJob.RunningJob.EVALUATED_PRIORITY, proto.write(ActiveJob.RunningJob.EVALUATED_PRIORITY, evaluateJobPriorityLocked(jsc.getRunningJobLocked())); evaluateJobPriorityLocked(job)); proto.write(ActiveJob.RunningJob.TIME_SINCE_MADE_ACTIVE_MS, proto.write(ActiveJob.RunningJob.TIME_SINCE_MADE_ACTIVE_MS, nowUptime - job.madeActive); nowUptime - job.madeActive); Loading
apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_NONE; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.Nullable; import android.app.job.IJobCallback; import android.app.job.IJobCallback; import android.app.job.IJobService; import android.app.job.IJobService; import android.app.job.JobInfo; import android.app.job.JobInfo; Loading Loading @@ -326,6 +327,7 @@ public final class JobServiceContext implements ServiceConnection { /** /** * Used externally to query the running job. Will return null if there is no job running. * Used externally to query the running job. Will return null if there is no job running. */ */ @Nullable JobStatus getRunningJobLocked() { JobStatus getRunningJobLocked() { return mRunningJob; return mRunningJob; } } Loading
services/tests/servicestests/src/com/android/server/job/WorkCountTrackerTest.java +320 −73 File changed.Preview size limit exceeded, changes collapsed. Show changes