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

Commit 6118fbfe authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Stop processing jobs whose state hasn't changed."

parents ca704f48 27971da7
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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.
@@ -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,
@@ -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 */
+81 −9
Original line number Diff line number Diff line
@@ -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
@@ -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.
@@ -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));
        }
    }

@@ -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
@@ -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");
                        }
@@ -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();
@@ -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,
@@ -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:");
        }
@@ -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);
@@ -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);
            }
        }
@@ -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);
@@ -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) {
+5 −3
Original line number Diff line number Diff line
@@ -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;

@@ -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,
+6 −5
Original line number Diff line number Diff line
@@ -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;
@@ -191,8 +192,8 @@ public final class BackgroundJobsController extends StateController {
            ));
        }

        if (mUpdateJobFunctor.mChanged) {
            mStateChangedListener.onControllerStateChanged();
        if (mUpdateJobFunctor.mChangedJobs.size() > 0) {
            mStateChangedListener.onControllerStateChanged(mUpdateJobFunctor.mChangedJobs);
        }
    }

@@ -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;
@@ -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;
        }
@@ -240,7 +241,7 @@ public final class BackgroundJobsController extends StateController {
            mTotalCount++;
            mCheckedCount++;
            if (updateSingleJobRestrictionLocked(jobStatus, mUpdateTimeElapsed, mActiveState)) {
                mChanged = true;
                mChangedJobs.add(jobStatus);
            }
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -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