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

Commit 9f920436 authored by Sanath Kumar's avatar Sanath Kumar Committed by Android (Google) Code Review
Browse files

Merge "Fix JobScheduler time constraint evaluation delays" into main

parents 57c0fc56 c327d1e6
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -127,3 +127,13 @@ flag {
    }
}

flag {
    name: "fix_deadline_delay_job_stall"
    namespace: "backstage_power"
    description: "Fix deadline and delay job stall due to a incorrect time check in TimeController"
    bug: "400440145"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+45 −5
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.expresslog.Counter;
import com.android.server.AppSchedulingModuleThread;
import com.android.server.job.Flags;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateControllerProto;

@@ -143,6 +144,26 @@ public final class TimeController extends StateController {
        }
    }

    /**
     * Check if the delay alarm has been delayed past the next scheduled time.
     * This can happen since we use a in-exact alarm for the delay.
     * Checking here avoids unnecessary delays in starting the job.
     */
    private boolean isDelayAlarmDelayed() {
        return Flags.fixDeadlineDelayJobStall()
            && sElapsedRealtimeClock.millis() >= mNextDelayExpiredElapsedMillis;
    }

    /**
     * Check if the deadline alarm has been delayed past the next scheduled time.
     * This can happen since we use a in-exact alarm for the deadline.
     * Checking here avoids unnecessary delays in starting the job.
     */
    private boolean isDeadlineAlarmDelayed() {
        return Flags.fixDeadlineDelayJobStall()
            && sElapsedRealtimeClock.millis() >= mNextJobExpiredElapsedMillis;
    }

    @Override
    public void evaluateStateLocked(JobStatus job) {
        final long nowElapsedMillis = sElapsedRealtimeClock.millis();
@@ -151,7 +172,8 @@ public final class TimeController extends StateController {
        // unnecessary processing of the timing delay.
        if (job.hasDeadlineConstraint()
                && !job.isConstraintSatisfied(JobStatus.CONSTRAINT_DEADLINE)
                && job.getLatestRunTimeElapsed() <= mNextJobExpiredElapsedMillis) {
                && (job.getLatestRunTimeElapsed() <= mNextJobExpiredElapsedMillis
                        || isDeadlineAlarmDelayed())) {
            if (evaluateDeadlineConstraint(job, nowElapsedMillis)) {
                if (job.isReady()) {
                    // If the job still isn't ready, there's no point trying to rush the
@@ -169,7 +191,8 @@ public final class TimeController extends StateController {
        }
        if (job.hasTimingDelayConstraint()
                && !job.isConstraintSatisfied(JobStatus.CONSTRAINT_TIMING_DELAY)
                && job.getEarliestRunTime() <= mNextDelayExpiredElapsedMillis) {
                && (job.getEarliestRunTime() <= mNextDelayExpiredElapsedMillis
                        || isDelayAlarmDelayed())) {
            // Since this is just the delay, we don't need to rush the Scheduler to run the job
            // immediately if the constraint is satisfied here.
            if (evaluateTimingDelayConstraint(job, nowElapsedMillis)) {
@@ -401,8 +424,16 @@ public final class TimeController extends StateController {
            if (DEBUG) {
                Slog.d(TAG, "Deadline-expired alarm fired");
            }

            if (Flags.fixDeadlineDelayJobStall()) {
                synchronized (mLock) {
                    mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
                    checkExpiredDeadlinesAndResetAlarm();
                }
            } else {
                checkExpiredDeadlinesAndResetAlarm();
            }
        }
    };

    private final OnAlarmListener mNextDelayExpiredListener = new OnAlarmListener() {
@@ -411,9 +442,18 @@ public final class TimeController extends StateController {
            if (DEBUG) {
                Slog.d(TAG, "Delay-expired alarm fired");
            }

            if (Flags.fixDeadlineDelayJobStall()) {
                synchronized (mLock) {
                    mLastFiredDelayExpiredElapsedMillis = sElapsedRealtimeClock.millis();
                    mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
                    checkExpiredDelaysAndResetAlarm();
                }
            } else {
                mLastFiredDelayExpiredElapsedMillis = sElapsedRealtimeClock.millis();
                checkExpiredDelaysAndResetAlarm();
            }
        }
    };

    @Override