Loading apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java +50 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,30 @@ class JobConcurrencyManager { return mRunningJobs.contains(job); } /** * Return {@code true} if the specified job has been executing for longer than the minimum * execution guarantee. */ @GuardedBy("mLock") boolean isJobLongRunningLocked(@NonNull JobStatus job) { if (!mRunningJobs.contains(job)) { return false; } for (int i = mActiveServices.size() - 1; i >= 0; --i) { final JobServiceContext jsc = mActiveServices.get(i); final JobStatus jobStatus = jsc.getRunningJobLocked(); if (jobStatus == job) { return !jsc.isWithinExecutionGuaranteeTime(); } } Slog.wtf(TAG, "Couldn't find long running job on a context"); mRunningJobs.remove(job); return false; } /** * Returns true if a job that is "similar" to the provided job is currently running. * "Similar" in this context means any job that the {@link JobStore} would consider equivalent Loading Loading @@ -989,6 +1013,26 @@ class JobConcurrencyManager { } } /** * Stops any jobs that have run for more than their minimum execution guarantee and are * restricted by the given {@link JobRestriction}. */ @GuardedBy("mLock") void maybeStopLongRunningJobsLocked(@NonNull JobRestriction restriction) { for (int i = mActiveServices.size() - 1; i >= 0; --i) { final JobServiceContext jsc = mActiveServices.get(i); final JobStatus jobStatus = jsc.getRunningJobLocked(); if (jobStatus != null && !jsc.isWithinExecutionGuaranteeTime() && restriction.isJobRestricted(jobStatus)) { jsc.cancelExecutingJobLocked(restriction.getReason(), restriction.getInternalReason(), JobParameters.getInternalReasonCodeDescription( restriction.getInternalReason())); } } } @GuardedBy("mLock") void stopNonReadyActiveJobsLocked() { for (int i = 0; i < mActiveServices.size(); i++) { Loading Loading @@ -1349,6 +1393,12 @@ class JobConcurrencyManager { if (mPowerManager.isDeviceIdleMode()) { return "deep doze"; } final JobRestriction jobRestriction; if ((jobRestriction = mService.checkIfRestricted(js)) != null) { return "restriction:" + JobParameters.getInternalReasonCodeDescription( jobRestriction.getInternalReason()); } // Update config in case memory usage has changed significantly. updateCounterConfigLocked(); Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +17 −0 Original line number Diff line number Diff line Loading @@ -1772,6 +1772,12 @@ public class JobSchedulerService extends com.android.server.SystemService return mConcurrencyManager.isJobRunningLocked(job); } /** @see JobConcurrencyManager#isJobLongRunningLocked(JobStatus) */ @GuardedBy("mLock") public boolean isLongRunningLocked(JobStatus job) { return mConcurrencyManager.isJobLongRunningLocked(job); } private void noteJobPending(JobStatus job) { mJobPackageTracker.notePending(job); } Loading Loading @@ -2049,6 +2055,17 @@ public class JobSchedulerService extends com.android.server.SystemService } } @Override public void onRestrictionStateChanged(@NonNull JobRestriction restriction, boolean stopLongRunningJobs) { mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget(); if (stopLongRunningJobs) { synchronized (mLock) { mConcurrencyManager.maybeStopLongRunningJobsLocked(restriction); } } } @Override public void onRunJobNow(JobStatus jobStatus) { if (jobStatus == null) { Loading apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +2 −2 Original line number Diff line number Diff line Loading @@ -736,10 +736,10 @@ public final class JobServiceContext implements ServiceConnection { @GuardedBy("mLock") private void doCancelLocked(@JobParameters.StopReason int stopReasonCode, int internalStopReasonCode, @Nullable String debugReason) { if (mVerb == VERB_FINISHED) { if (mVerb == VERB_FINISHED || mVerb == VERB_STOPPING) { if (DEBUG) { Slog.d(TAG, "Trying to process cancel for torn-down context, ignoring."); "Too late to process cancel for context (verb=" + mVerb + "), ignoring."); } return; } Loading apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java +11 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.util.ArraySet; import com.android.server.job.controllers.JobStatus; import com.android.server.job.restrictions.JobRestriction; import java.util.List; Loading @@ -36,6 +37,16 @@ public interface StateChangedListener { */ void onControllerStateChanged(@Nullable ArraySet<JobStatus> changedJobs); /** * Called by a {@link com.android.server.job.restrictions.JobRestriction} to notify the * JobScheduler that it should check on the state of all jobs. * * @param stopLongRunningJobs Whether to stop any jobs that have run for more than their minimum * execution guarantee and are restricted by the changed restriction */ void onRestrictionStateChanged(@NonNull JobRestriction restriction, boolean stopLongRunningJobs); /** * Called by the controller to notify the JobManager that regardless of the state of the task, * it must be run immediately. Loading apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java +10 −6 Original line number Diff line number Diff line Loading @@ -73,9 +73,10 @@ public class ThermalStatusRestriction extends JobRestriction { // bucket (thus resulting in us beginning to enforce the tightest // restrictions). || (mThermalStatus < UPPER_THRESHOLD && status > UPPER_THRESHOLD); final boolean increased = mThermalStatus < status; mThermalStatus = status; if (significantChange) { mService.onControllerStateChanged(null); mService.onRestrictionStateChanged(ThermalStatusRestriction.this, increased); } } }); Loading @@ -89,16 +90,19 @@ public class ThermalStatusRestriction extends JobRestriction { final int priority = job.getEffectivePriority(); if (mThermalStatus >= HIGHER_PRIORITY_THRESHOLD) { // For moderate throttling, only let expedited jobs and high priority regular jobs that // are already running run. // haven't been running for long run. return !job.shouldTreatAsExpeditedJob() && !(priority == JobInfo.PRIORITY_HIGH && mService.isCurrentlyRunningLocked(job)); && mService.isCurrentlyRunningLocked(job) && !mService.isLongRunningLocked(job)); } if (mThermalStatus >= LOW_PRIORITY_THRESHOLD) { // For light throttling, throttle all min priority jobs and all low priority jobs that // aren't already running. return (priority == JobInfo.PRIORITY_LOW && !mService.isCurrentlyRunningLocked(job)) || priority == JobInfo.PRIORITY_MIN; // aren't already running or have been running for long enough. return priority == JobInfo.PRIORITY_MIN || (priority == JobInfo.PRIORITY_LOW && (!mService.isCurrentlyRunningLocked(job) || mService.isLongRunningLocked(job))); } return false; } Loading Loading
apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java +50 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,30 @@ class JobConcurrencyManager { return mRunningJobs.contains(job); } /** * Return {@code true} if the specified job has been executing for longer than the minimum * execution guarantee. */ @GuardedBy("mLock") boolean isJobLongRunningLocked(@NonNull JobStatus job) { if (!mRunningJobs.contains(job)) { return false; } for (int i = mActiveServices.size() - 1; i >= 0; --i) { final JobServiceContext jsc = mActiveServices.get(i); final JobStatus jobStatus = jsc.getRunningJobLocked(); if (jobStatus == job) { return !jsc.isWithinExecutionGuaranteeTime(); } } Slog.wtf(TAG, "Couldn't find long running job on a context"); mRunningJobs.remove(job); return false; } /** * Returns true if a job that is "similar" to the provided job is currently running. * "Similar" in this context means any job that the {@link JobStore} would consider equivalent Loading Loading @@ -989,6 +1013,26 @@ class JobConcurrencyManager { } } /** * Stops any jobs that have run for more than their minimum execution guarantee and are * restricted by the given {@link JobRestriction}. */ @GuardedBy("mLock") void maybeStopLongRunningJobsLocked(@NonNull JobRestriction restriction) { for (int i = mActiveServices.size() - 1; i >= 0; --i) { final JobServiceContext jsc = mActiveServices.get(i); final JobStatus jobStatus = jsc.getRunningJobLocked(); if (jobStatus != null && !jsc.isWithinExecutionGuaranteeTime() && restriction.isJobRestricted(jobStatus)) { jsc.cancelExecutingJobLocked(restriction.getReason(), restriction.getInternalReason(), JobParameters.getInternalReasonCodeDescription( restriction.getInternalReason())); } } } @GuardedBy("mLock") void stopNonReadyActiveJobsLocked() { for (int i = 0; i < mActiveServices.size(); i++) { Loading Loading @@ -1349,6 +1393,12 @@ class JobConcurrencyManager { if (mPowerManager.isDeviceIdleMode()) { return "deep doze"; } final JobRestriction jobRestriction; if ((jobRestriction = mService.checkIfRestricted(js)) != null) { return "restriction:" + JobParameters.getInternalReasonCodeDescription( jobRestriction.getInternalReason()); } // Update config in case memory usage has changed significantly. updateCounterConfigLocked(); Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +17 −0 Original line number Diff line number Diff line Loading @@ -1772,6 +1772,12 @@ public class JobSchedulerService extends com.android.server.SystemService return mConcurrencyManager.isJobRunningLocked(job); } /** @see JobConcurrencyManager#isJobLongRunningLocked(JobStatus) */ @GuardedBy("mLock") public boolean isLongRunningLocked(JobStatus job) { return mConcurrencyManager.isJobLongRunningLocked(job); } private void noteJobPending(JobStatus job) { mJobPackageTracker.notePending(job); } Loading Loading @@ -2049,6 +2055,17 @@ public class JobSchedulerService extends com.android.server.SystemService } } @Override public void onRestrictionStateChanged(@NonNull JobRestriction restriction, boolean stopLongRunningJobs) { mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget(); if (stopLongRunningJobs) { synchronized (mLock) { mConcurrencyManager.maybeStopLongRunningJobsLocked(restriction); } } } @Override public void onRunJobNow(JobStatus jobStatus) { if (jobStatus == null) { Loading
apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +2 −2 Original line number Diff line number Diff line Loading @@ -736,10 +736,10 @@ public final class JobServiceContext implements ServiceConnection { @GuardedBy("mLock") private void doCancelLocked(@JobParameters.StopReason int stopReasonCode, int internalStopReasonCode, @Nullable String debugReason) { if (mVerb == VERB_FINISHED) { if (mVerb == VERB_FINISHED || mVerb == VERB_STOPPING) { if (DEBUG) { Slog.d(TAG, "Trying to process cancel for torn-down context, ignoring."); "Too late to process cancel for context (verb=" + mVerb + "), ignoring."); } return; } Loading
apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java +11 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.util.ArraySet; import com.android.server.job.controllers.JobStatus; import com.android.server.job.restrictions.JobRestriction; import java.util.List; Loading @@ -36,6 +37,16 @@ public interface StateChangedListener { */ void onControllerStateChanged(@Nullable ArraySet<JobStatus> changedJobs); /** * Called by a {@link com.android.server.job.restrictions.JobRestriction} to notify the * JobScheduler that it should check on the state of all jobs. * * @param stopLongRunningJobs Whether to stop any jobs that have run for more than their minimum * execution guarantee and are restricted by the changed restriction */ void onRestrictionStateChanged(@NonNull JobRestriction restriction, boolean stopLongRunningJobs); /** * Called by the controller to notify the JobManager that regardless of the state of the task, * it must be run immediately. Loading
apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java +10 −6 Original line number Diff line number Diff line Loading @@ -73,9 +73,10 @@ public class ThermalStatusRestriction extends JobRestriction { // bucket (thus resulting in us beginning to enforce the tightest // restrictions). || (mThermalStatus < UPPER_THRESHOLD && status > UPPER_THRESHOLD); final boolean increased = mThermalStatus < status; mThermalStatus = status; if (significantChange) { mService.onControllerStateChanged(null); mService.onRestrictionStateChanged(ThermalStatusRestriction.this, increased); } } }); Loading @@ -89,16 +90,19 @@ public class ThermalStatusRestriction extends JobRestriction { final int priority = job.getEffectivePriority(); if (mThermalStatus >= HIGHER_PRIORITY_THRESHOLD) { // For moderate throttling, only let expedited jobs and high priority regular jobs that // are already running run. // haven't been running for long run. return !job.shouldTreatAsExpeditedJob() && !(priority == JobInfo.PRIORITY_HIGH && mService.isCurrentlyRunningLocked(job)); && mService.isCurrentlyRunningLocked(job) && !mService.isLongRunningLocked(job)); } if (mThermalStatus >= LOW_PRIORITY_THRESHOLD) { // For light throttling, throttle all min priority jobs and all low priority jobs that // aren't already running. return (priority == JobInfo.PRIORITY_LOW && !mService.isCurrentlyRunningLocked(job)) || priority == JobInfo.PRIORITY_MIN; // aren't already running or have been running for long enough. return priority == JobInfo.PRIORITY_MIN || (priority == JobInfo.PRIORITY_LOW && (!mService.isCurrentlyRunningLocked(job) || mService.isLongRunningLocked(job))); } return false; } Loading