Loading apex/jobscheduler/framework/java/android/app/job/JobParameters.java +5 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ import java.lang.annotation.RetentionPolicy; */ public class JobParameters implements Parcelable { /** @hide */ public static final int INTERNAL_STOP_REASON_UNKNOWN = -1; /** @hide */ public static final int INTERNAL_STOP_REASON_CANCELED = JobProtoEnums.INTERNAL_STOP_REASON_CANCELLED; // 0. Loading Loading @@ -106,6 +109,7 @@ public class JobParameters implements Parcelable { * @hide */ public static final int[] JOB_STOP_REASON_CODES = { INTERNAL_STOP_REASON_UNKNOWN, INTERNAL_STOP_REASON_CANCELED, INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED, INTERNAL_STOP_REASON_PREEMPT, Loading Loading @@ -269,7 +273,7 @@ public class JobParameters implements Parcelable { private final Network network; private int mStopReason = STOP_REASON_UNDEFINED; private int mInternalStopReason; // Default value is REASON_CANCELED private int mInternalStopReason = INTERNAL_STOP_REASON_UNKNOWN; private String debugStopReason; // Human readable stop reason for debugging. /** @hide */ Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +81 −9 Original line number Diff line number Diff line Loading @@ -227,6 +227,7 @@ public class JobSchedulerService extends com.android.server.SystemService static final int MSG_UID_GONE = 5; static final int MSG_UID_ACTIVE = 6; static final int MSG_UID_IDLE = 7; static final int MSG_CHECK_CHANGED_JOB_LIST = 8; /** * Track Services that have currently active or pending jobs. The index is provided by Loading Loading @@ -326,6 +327,10 @@ public class JobSchedulerService extends com.android.server.SystemService /** Cached mapping of UIDs (for all users) to a list of packages in the UID. */ private final SparseSetArray<String> mUidToPackageCache = new SparseSetArray<>(); /** List of jobs whose controller state has changed since the last time we evaluated the job. */ @GuardedBy("mLock") private final ArraySet<JobStatus> mChangedJobList = new ArraySet<>(); /** * Named indices into standby bucket arrays, for clarity in referring to * specific buckets' bookkeeping. Loading Loading @@ -1718,10 +1723,13 @@ public class JobSchedulerService extends com.android.server.SystemService return mConcurrencyManager.isJobRunningLocked(job); } private void noteJobPending(JobStatus job) { mJobPackageTracker.notePending(job); } void noteJobsPending(List<JobStatus> jobs) { for (int i = jobs.size() - 1; i >= 0; i--) { JobStatus job = jobs.get(i); mJobPackageTracker.notePending(job); noteJobPending(jobs.get(i)); } } Loading Loading @@ -1971,13 +1979,19 @@ public class JobSchedulerService extends com.android.server.SystemService // StateChangedListener implementations. /** * Posts a message to the {@link com.android.server.job.JobSchedulerService.JobHandler} that * some controller's state has changed, so as to run through the list of jobs and start/stop * any that are eligible. * Posts a message to the {@link com.android.server.job.JobSchedulerService.JobHandler} to run * through a list of jobs and start/stop any whose status has changed. */ @Override public void onControllerStateChanged() { public void onControllerStateChanged(@Nullable ArraySet<JobStatus> changedJobs) { if (changedJobs == null) { mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget(); } else if (changedJobs.size() > 0) { synchronized (mLock) { mChangedJobList.addAll(changedJobs); } mHandler.obtainMessage(MSG_CHECK_CHANGED_JOB_LIST).sendToTarget(); } } @Override Loading Loading @@ -2009,6 +2023,7 @@ public class JobSchedulerService extends com.android.server.SystemService mJobPackageTracker.notePending(js); addOrderedItem(mPendingJobs, js, mPendingJobComparator); } mChangedJobList.remove(js); } else { Slog.e(TAG, "Given null job to check individually"); } Loading @@ -2017,7 +2032,6 @@ public class JobSchedulerService extends com.android.server.SystemService if (DEBUG) { Slog.d(TAG, "MSG_CHECK_JOB"); } removeMessages(MSG_CHECK_JOB); if (mReportedActive) { // if jobs are currently being run, queue all ready jobs for execution. queueReadyJobsForExecutionLocked(); Loading @@ -2032,6 +2046,12 @@ public class JobSchedulerService extends com.android.server.SystemService } queueReadyJobsForExecutionLocked(); break; case MSG_CHECK_CHANGED_JOB_LIST: if (DEBUG) { Slog.d(TAG, "MSG_CHECK_CHANGED_JOB_LIST"); } checkChangedJobListLocked(); break; case MSG_STOP_JOB: cancelJobImplLocked((JobStatus) message.obj, null, message.arg1, JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED, Loading Loading @@ -2158,6 +2178,11 @@ public class JobSchedulerService extends com.android.server.SystemService // MSG_CHECK_JOB is a weaker form of _GREEDY. Since we're checking and queueing all ready // jobs, we don't need to keep any MSG_CHECK_JOB messages in the queue. mHandler.removeMessages(MSG_CHECK_JOB); // MSG_CHECK_CHANGED_JOB_LIST is a weaker form of _GREEDY. Since we're checking and queueing // all ready jobs, we don't need to keep any MSG_CHECK_CHANGED_JOB_LIST messages in the // queue. mHandler.removeMessages(MSG_CHECK_CHANGED_JOB_LIST); mChangedJobList.clear(); if (DEBUG) { Slog.d(TAG, "queuing all ready jobs for execution:"); } Loading Loading @@ -2220,7 +2245,6 @@ public class JobSchedulerService extends com.android.server.SystemService reset(); } // Functor method invoked for each job via JobStore.forEachJob() @Override public void accept(JobStatus job) { final boolean isRunning = isCurrentlyRunningLocked(job); Loading Loading @@ -2272,6 +2296,37 @@ public class JobSchedulerService extends com.android.server.SystemService runnableJobs.add(job); } } else { if (isRunning) { final int internalStopReason; final String debugReason; if (!job.isReady()) { if (job.getEffectiveStandbyBucket() == RESTRICTED_INDEX && job.getStopReason() == JobParameters.STOP_REASON_APP_STANDBY) { internalStopReason = JobParameters.INTERNAL_STOP_REASON_RESTRICTED_BUCKET; debugReason = "cancelled due to restricted bucket"; } else { internalStopReason = JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED; debugReason = "cancelled due to unsatisfied constraints"; } } else { final JobRestriction restriction = checkIfRestricted(job); if (restriction != null) { internalStopReason = restriction.getInternalReason(); debugReason = "restricted due to " + JobParameters.getInternalReasonCodeDescription( internalStopReason); } else { internalStopReason = JobParameters.INTERNAL_STOP_REASON_UNKNOWN; debugReason = "couldn't figure out why the job should stop running"; } } stopJobOnServiceContextLocked(job, job.getStopReason(), internalStopReason, debugReason); } else if (mPendingJobs.remove(job)) { noteJobNonPending(job); } evaluateControllerStatesLocked(job); } } Loading Loading @@ -2312,6 +2367,11 @@ public class JobSchedulerService extends com.android.server.SystemService @GuardedBy("mLock") private void maybeQueueReadyJobsForExecutionLocked() { mHandler.removeMessages(MSG_CHECK_JOB); // This method will evaluate all jobs, so we don't need to keep any messages for a suubset // of jobs in the queue. mHandler.removeMessages(MSG_CHECK_CHANGED_JOB_LIST); mChangedJobList.clear(); if (DEBUG) Slog.d(TAG, "Maybe queuing ready jobs..."); noteJobsNonpending(mPendingJobs); Loading @@ -2321,6 +2381,18 @@ public class JobSchedulerService extends com.android.server.SystemService mMaybeQueueFunctor.postProcessLocked(); } @GuardedBy("mLock") private void checkChangedJobListLocked() { mHandler.removeMessages(MSG_CHECK_CHANGED_JOB_LIST); if (DEBUG) { Slog.d(TAG, "Check changed jobs..."); } mChangedJobList.forEach(mMaybeQueueFunctor); mMaybeQueueFunctor.postProcessLocked(); mChangedJobList.clear(); } /** Returns true if both the calling and source users for the job are started. */ @GuardedBy("mLock") public boolean areUsersStartedLocked(final JobStatus job) { Loading apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java +5 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.server.job; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArraySet; import com.android.server.job.controllers.JobStatus; Loading @@ -29,10 +31,10 @@ import java.util.List; */ public interface StateChangedListener { /** * Called by the controller to notify the JobManager that it should check on the state of a * task. * Called by the controller to notify the JobScheduler that it should check on the state of a * set of jobs. If {@code changedJobs} is null, then all registered jobs will be evaluated. */ public void onControllerStateChanged(); void onControllerStateChanged(@Nullable ArraySet<JobStatus> changedJobs); /** * Called by the controller to notify the JobManager that regardless of the state of the task, Loading apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +6 −5 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.os.SystemClock; import android.os.UserHandle; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; Loading Loading @@ -191,8 +192,8 @@ public final class BackgroundJobsController extends StateController { )); } if (mUpdateJobFunctor.mChanged) { mStateChangedListener.onControllerStateChanged(); if (mUpdateJobFunctor.mChangedJobs.size() > 0) { mStateChangedListener.onControllerStateChanged(mUpdateJobFunctor.mChangedJobs); } } Loading Loading @@ -222,7 +223,7 @@ public final class BackgroundJobsController extends StateController { private final class UpdateJobFunctor implements Consumer<JobStatus> { int mActiveState; boolean mChanged = false; final ArraySet<JobStatus> mChangedJobs = new ArraySet<>(); int mTotalCount = 0; int mCheckedCount = 0; long mUpdateTimeElapsed = 0; Loading @@ -230,7 +231,7 @@ public final class BackgroundJobsController extends StateController { void prepare(int newActiveState) { mActiveState = newActiveState; mUpdateTimeElapsed = sElapsedRealtimeClock.millis(); mChanged = false; mChangedJobs.clear(); mTotalCount = 0; mCheckedCount = 0; } Loading @@ -240,7 +241,7 @@ public final class BackgroundJobsController extends StateController { mTotalCount++; mCheckedCount++; if (updateSingleJobRestrictionLocked(jobStatus, mUpdateTimeElapsed, mActiveState)) { mChanged = true; mChangedJobs.add(jobStatus); } } } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +1 −1 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ public final class BatteryController extends RestrictingController { } else if (reportChange) { // Otherwise, just let the job scheduler know the state has changed and take care of it // as it thinks is best. mStateChangedListener.onControllerStateChanged(); mStateChangedListener.onControllerStateChanged(mTrackedTasks); } } Loading Loading
apex/jobscheduler/framework/java/android/app/job/JobParameters.java +5 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ import java.lang.annotation.RetentionPolicy; */ public class JobParameters implements Parcelable { /** @hide */ public static final int INTERNAL_STOP_REASON_UNKNOWN = -1; /** @hide */ public static final int INTERNAL_STOP_REASON_CANCELED = JobProtoEnums.INTERNAL_STOP_REASON_CANCELLED; // 0. Loading Loading @@ -106,6 +109,7 @@ public class JobParameters implements Parcelable { * @hide */ public static final int[] JOB_STOP_REASON_CODES = { INTERNAL_STOP_REASON_UNKNOWN, INTERNAL_STOP_REASON_CANCELED, INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED, INTERNAL_STOP_REASON_PREEMPT, Loading Loading @@ -269,7 +273,7 @@ public class JobParameters implements Parcelable { private final Network network; private int mStopReason = STOP_REASON_UNDEFINED; private int mInternalStopReason; // Default value is REASON_CANCELED private int mInternalStopReason = INTERNAL_STOP_REASON_UNKNOWN; private String debugStopReason; // Human readable stop reason for debugging. /** @hide */ Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +81 −9 Original line number Diff line number Diff line Loading @@ -227,6 +227,7 @@ public class JobSchedulerService extends com.android.server.SystemService static final int MSG_UID_GONE = 5; static final int MSG_UID_ACTIVE = 6; static final int MSG_UID_IDLE = 7; static final int MSG_CHECK_CHANGED_JOB_LIST = 8; /** * Track Services that have currently active or pending jobs. The index is provided by Loading Loading @@ -326,6 +327,10 @@ public class JobSchedulerService extends com.android.server.SystemService /** Cached mapping of UIDs (for all users) to a list of packages in the UID. */ private final SparseSetArray<String> mUidToPackageCache = new SparseSetArray<>(); /** List of jobs whose controller state has changed since the last time we evaluated the job. */ @GuardedBy("mLock") private final ArraySet<JobStatus> mChangedJobList = new ArraySet<>(); /** * Named indices into standby bucket arrays, for clarity in referring to * specific buckets' bookkeeping. Loading Loading @@ -1718,10 +1723,13 @@ public class JobSchedulerService extends com.android.server.SystemService return mConcurrencyManager.isJobRunningLocked(job); } private void noteJobPending(JobStatus job) { mJobPackageTracker.notePending(job); } void noteJobsPending(List<JobStatus> jobs) { for (int i = jobs.size() - 1; i >= 0; i--) { JobStatus job = jobs.get(i); mJobPackageTracker.notePending(job); noteJobPending(jobs.get(i)); } } Loading Loading @@ -1971,13 +1979,19 @@ public class JobSchedulerService extends com.android.server.SystemService // StateChangedListener implementations. /** * Posts a message to the {@link com.android.server.job.JobSchedulerService.JobHandler} that * some controller's state has changed, so as to run through the list of jobs and start/stop * any that are eligible. * Posts a message to the {@link com.android.server.job.JobSchedulerService.JobHandler} to run * through a list of jobs and start/stop any whose status has changed. */ @Override public void onControllerStateChanged() { public void onControllerStateChanged(@Nullable ArraySet<JobStatus> changedJobs) { if (changedJobs == null) { mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget(); } else if (changedJobs.size() > 0) { synchronized (mLock) { mChangedJobList.addAll(changedJobs); } mHandler.obtainMessage(MSG_CHECK_CHANGED_JOB_LIST).sendToTarget(); } } @Override Loading Loading @@ -2009,6 +2023,7 @@ public class JobSchedulerService extends com.android.server.SystemService mJobPackageTracker.notePending(js); addOrderedItem(mPendingJobs, js, mPendingJobComparator); } mChangedJobList.remove(js); } else { Slog.e(TAG, "Given null job to check individually"); } Loading @@ -2017,7 +2032,6 @@ public class JobSchedulerService extends com.android.server.SystemService if (DEBUG) { Slog.d(TAG, "MSG_CHECK_JOB"); } removeMessages(MSG_CHECK_JOB); if (mReportedActive) { // if jobs are currently being run, queue all ready jobs for execution. queueReadyJobsForExecutionLocked(); Loading @@ -2032,6 +2046,12 @@ public class JobSchedulerService extends com.android.server.SystemService } queueReadyJobsForExecutionLocked(); break; case MSG_CHECK_CHANGED_JOB_LIST: if (DEBUG) { Slog.d(TAG, "MSG_CHECK_CHANGED_JOB_LIST"); } checkChangedJobListLocked(); break; case MSG_STOP_JOB: cancelJobImplLocked((JobStatus) message.obj, null, message.arg1, JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED, Loading Loading @@ -2158,6 +2178,11 @@ public class JobSchedulerService extends com.android.server.SystemService // MSG_CHECK_JOB is a weaker form of _GREEDY. Since we're checking and queueing all ready // jobs, we don't need to keep any MSG_CHECK_JOB messages in the queue. mHandler.removeMessages(MSG_CHECK_JOB); // MSG_CHECK_CHANGED_JOB_LIST is a weaker form of _GREEDY. Since we're checking and queueing // all ready jobs, we don't need to keep any MSG_CHECK_CHANGED_JOB_LIST messages in the // queue. mHandler.removeMessages(MSG_CHECK_CHANGED_JOB_LIST); mChangedJobList.clear(); if (DEBUG) { Slog.d(TAG, "queuing all ready jobs for execution:"); } Loading Loading @@ -2220,7 +2245,6 @@ public class JobSchedulerService extends com.android.server.SystemService reset(); } // Functor method invoked for each job via JobStore.forEachJob() @Override public void accept(JobStatus job) { final boolean isRunning = isCurrentlyRunningLocked(job); Loading Loading @@ -2272,6 +2296,37 @@ public class JobSchedulerService extends com.android.server.SystemService runnableJobs.add(job); } } else { if (isRunning) { final int internalStopReason; final String debugReason; if (!job.isReady()) { if (job.getEffectiveStandbyBucket() == RESTRICTED_INDEX && job.getStopReason() == JobParameters.STOP_REASON_APP_STANDBY) { internalStopReason = JobParameters.INTERNAL_STOP_REASON_RESTRICTED_BUCKET; debugReason = "cancelled due to restricted bucket"; } else { internalStopReason = JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED; debugReason = "cancelled due to unsatisfied constraints"; } } else { final JobRestriction restriction = checkIfRestricted(job); if (restriction != null) { internalStopReason = restriction.getInternalReason(); debugReason = "restricted due to " + JobParameters.getInternalReasonCodeDescription( internalStopReason); } else { internalStopReason = JobParameters.INTERNAL_STOP_REASON_UNKNOWN; debugReason = "couldn't figure out why the job should stop running"; } } stopJobOnServiceContextLocked(job, job.getStopReason(), internalStopReason, debugReason); } else if (mPendingJobs.remove(job)) { noteJobNonPending(job); } evaluateControllerStatesLocked(job); } } Loading Loading @@ -2312,6 +2367,11 @@ public class JobSchedulerService extends com.android.server.SystemService @GuardedBy("mLock") private void maybeQueueReadyJobsForExecutionLocked() { mHandler.removeMessages(MSG_CHECK_JOB); // This method will evaluate all jobs, so we don't need to keep any messages for a suubset // of jobs in the queue. mHandler.removeMessages(MSG_CHECK_CHANGED_JOB_LIST); mChangedJobList.clear(); if (DEBUG) Slog.d(TAG, "Maybe queuing ready jobs..."); noteJobsNonpending(mPendingJobs); Loading @@ -2321,6 +2381,18 @@ public class JobSchedulerService extends com.android.server.SystemService mMaybeQueueFunctor.postProcessLocked(); } @GuardedBy("mLock") private void checkChangedJobListLocked() { mHandler.removeMessages(MSG_CHECK_CHANGED_JOB_LIST); if (DEBUG) { Slog.d(TAG, "Check changed jobs..."); } mChangedJobList.forEach(mMaybeQueueFunctor); mMaybeQueueFunctor.postProcessLocked(); mChangedJobList.clear(); } /** Returns true if both the calling and source users for the job are started. */ @GuardedBy("mLock") public boolean areUsersStartedLocked(final JobStatus job) { Loading
apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java +5 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.server.job; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArraySet; import com.android.server.job.controllers.JobStatus; Loading @@ -29,10 +31,10 @@ import java.util.List; */ public interface StateChangedListener { /** * Called by the controller to notify the JobManager that it should check on the state of a * task. * Called by the controller to notify the JobScheduler that it should check on the state of a * set of jobs. If {@code changedJobs} is null, then all registered jobs will be evaluated. */ public void onControllerStateChanged(); void onControllerStateChanged(@Nullable ArraySet<JobStatus> changedJobs); /** * Called by the controller to notify the JobManager that regardless of the state of the task, Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +6 −5 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.os.SystemClock; import android.os.UserHandle; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; Loading Loading @@ -191,8 +192,8 @@ public final class BackgroundJobsController extends StateController { )); } if (mUpdateJobFunctor.mChanged) { mStateChangedListener.onControllerStateChanged(); if (mUpdateJobFunctor.mChangedJobs.size() > 0) { mStateChangedListener.onControllerStateChanged(mUpdateJobFunctor.mChangedJobs); } } Loading Loading @@ -222,7 +223,7 @@ public final class BackgroundJobsController extends StateController { private final class UpdateJobFunctor implements Consumer<JobStatus> { int mActiveState; boolean mChanged = false; final ArraySet<JobStatus> mChangedJobs = new ArraySet<>(); int mTotalCount = 0; int mCheckedCount = 0; long mUpdateTimeElapsed = 0; Loading @@ -230,7 +231,7 @@ public final class BackgroundJobsController extends StateController { void prepare(int newActiveState) { mActiveState = newActiveState; mUpdateTimeElapsed = sElapsedRealtimeClock.millis(); mChanged = false; mChangedJobs.clear(); mTotalCount = 0; mCheckedCount = 0; } Loading @@ -240,7 +241,7 @@ public final class BackgroundJobsController extends StateController { mTotalCount++; mCheckedCount++; if (updateSingleJobRestrictionLocked(jobStatus, mUpdateTimeElapsed, mActiveState)) { mChanged = true; mChangedJobs.add(jobStatus); } } } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +1 −1 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ public final class BatteryController extends RestrictingController { } else if (reportChange) { // Otherwise, just let the job scheduler know the state has changed and take care of it // as it thinks is best. mStateChangedListener.onControllerStateChanged(); mStateChangedListener.onControllerStateChanged(mTrackedTasks); } } Loading