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

Commit be3fd775 authored by Kweku Adams's avatar Kweku Adams
Browse files

Dump most recently completed jobs.

Track the most recently completed jobs and log them in the dump to
aid in debugging.

Bug: 171305774
Test: visually inspect dump
Change-Id: Idb415b06ba1bb09eec82da58dcfe3f64845f829d
parent 1a0c0a51
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.net.Uri;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.LimitExceededException;
import android.os.Looper;
@@ -151,6 +152,9 @@ public class JobSchedulerService extends com.android.server.SystemService
    private static final boolean ENFORCE_MAX_JOBS = true;
    /** The maximum number of jobs that we allow an unprivileged app to schedule */
    private static final int MAX_JOBS_PER_APP = 100;
    /** The number of the most recently completed jobs to keep track of for debugging purposes. */
    private static final int NUM_COMPLETED_JOB_HISTORY =
            Build.IS_USERDEBUG || Build.IS_ENG ? 25 : 0;

    @VisibleForTesting
    public static Clock sSystemClock = Clock.systemUTC();
@@ -297,6 +301,10 @@ public class JobSchedulerService extends com.android.server.SystemService
     */
    boolean mReportedActive;

    private int mLastCompletedJobIndex = 0;
    private final JobStatus[] mLastCompletedJobs = new JobStatus[NUM_COMPLETED_JOB_HISTORY];
    private final long[] mLastCompletedJobTimeElapsed = new long[NUM_COMPLETED_JOB_HISTORY];

    /**
     * A mapping of which uids are currently in the foreground to their effective priority.
     */
@@ -1752,6 +1760,10 @@ public class JobSchedulerService extends com.android.server.SystemService
            Slog.d(TAG, "Completed " + jobStatus + ", reschedule=" + needsReschedule);
        }

        mLastCompletedJobs[mLastCompletedJobIndex] = jobStatus;
        mLastCompletedJobTimeElapsed[mLastCompletedJobIndex] = sElapsedRealtimeClock.millis();
        mLastCompletedJobIndex = (mLastCompletedJobIndex + 1) % NUM_COMPLETED_JOB_HISTORY;

        // Intentionally not checking expedited job quota here. An app can't find out if it's run
        // out of quota when it asks JS to reschedule an expedited job. Instead, the rescheduled
        // EJ will just be demoted to a regular job if the app has no EJ quota left.
@@ -3298,6 +3310,37 @@ public class JobSchedulerService extends com.android.server.SystemService
                }
            }
            pw.decreaseIndent();

            pw.println();
            boolean recentPrinted = false;
            pw.println("Recently completed jobs:");
            pw.increaseIndent();
            for (int r = 1; r <= NUM_COMPLETED_JOB_HISTORY; ++r) {
                // Print most recent first
                final int idx = (mLastCompletedJobIndex + NUM_COMPLETED_JOB_HISTORY - r)
                        % NUM_COMPLETED_JOB_HISTORY;
                final JobStatus job = mLastCompletedJobs[idx];
                if (job != null) {
                    if (!predicate.test(job)) {
                        continue;
                    }
                    recentPrinted = true;
                    TimeUtils.formatDuration(mLastCompletedJobTimeElapsed[idx], nowElapsed, pw);
                    pw.println();
                    // Double indent for readability
                    pw.increaseIndent();
                    pw.increaseIndent();
                    job.dump(pw, true, nowElapsed);
                    pw.decreaseIndent();
                    pw.decreaseIndent();
                }
            }
            if (!recentPrinted) {
                pw.println("None");
            }
            pw.decreaseIndent();
            pw.println();

            if (filterUid == -1) {
                pw.println();
                pw.print("mReadyToRock="); pw.println(mReadyToRock);