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

Commit 04b45181 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by android-build-merger
Browse files

Merge "Fix issue #28477006: Add small event log to job scheduler" into nyc-dev am: 27c279d5

am: 68e9dba7

* commit '68e9dba7':
  Fix issue #28477006: Add small event log to job scheduler

Change-Id: If4aac5e2757555f0282ca047eba614dd4d1f05f0
parents 6271e43e 68e9dba7
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -309,8 +309,8 @@ public class DeviceIdleController extends SystemService
    private static final int EVENT_DEEP_IDLE = 4;
    private static final int EVENT_DEEP_MAINTENANCE = 5;

    private int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
    private long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
    private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
    private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE];

    private void addEvent(int cmd) {
        if (mEventCmds[0] != cmd) {
+1 −2
Original line number Diff line number Diff line
@@ -23,10 +23,9 @@ import com.android.server.job.controllers.JobStatus;
 * {@link com.android.server.job.JobSchedulerService}.
 */
public interface JobCompletedListener {

    /**
     * Callback for when a job is completed.
     * @param needsReschedule Whether the implementing class should reschedule this job.
     */
    public void onJobCompleted(JobStatus jobStatus, boolean needsReschedule);
    void onJobCompleted(JobStatus jobStatus, boolean needsReschedule);
}
+67 −5
Original line number Diff line number Diff line
@@ -33,6 +33,28 @@ public final class JobPackageTracker {
    // Number of historical data sets we keep.
    static final int NUM_HISTORY = 5;

    private static final int EVENT_BUFFER_SIZE = 50;

    public static final int EVENT_NULL = 0;
    public static final int EVENT_START_JOB = 1;
    public static final int EVENT_STOP_JOB = 2;

    private int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
    private long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
    private int[] mEventUids = new int[EVENT_BUFFER_SIZE];
    private String[] mEventTags = new String[EVENT_BUFFER_SIZE];

    public void addEvent(int cmd, int uid, String tag) {
        System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
        System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
        System.arraycopy(mEventUids, 0, mEventUids, 1, EVENT_BUFFER_SIZE - 1);
        System.arraycopy(mEventTags, 0, mEventTags, 1, EVENT_BUFFER_SIZE - 1);
        mEventCmds[0] = cmd;
        mEventTimes[0] = SystemClock.elapsedRealtime();
        mEventUids[0] = uid;
        mEventTags[0] = tag;
    }

    DataSet mCurDataSet = new DataSet();
    DataSet[] mLastDataSets = new DataSet[NUM_HISTORY];

@@ -240,7 +262,8 @@ public final class JobPackageTracker {
            }
        }

        void dump(PrintWriter pw, String header, String prefix, long now, long nowEllapsed) {
        void dump(PrintWriter pw, String header, String prefix, long now, long nowEllapsed,
                int filterUid) {
            final long period = getTotalTime(now);
            pw.print(prefix); pw.print(header); pw.print(" at ");
            pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", mStartClockTime).toString());
@@ -251,12 +274,16 @@ public final class JobPackageTracker {
            pw.println(":");
            final int NE = mEntries.size();
            for (int i = 0; i < NE; i++) {
                int uid = mEntries.keyAt(i);
                if (filterUid != -1 && filterUid != UserHandle.getAppId(uid)) {
                    continue;
                }
                ArrayMap<String, PackageEntry> uidMap = mEntries.valueAt(i);
                final int NP = uidMap.size();
                for (int j = 0; j < NP; j++) {
                    PackageEntry pe = uidMap.valueAt(j);
                    pw.print(prefix); pw.print("  ");
                    UserHandle.formatUid(pw, mEntries.keyAt(i));
                    UserHandle.formatUid(pw, uid);
                    pw.print(" / "); pw.print(uidMap.keyAt(j));
                    pw.print(":");
                    printDuration(pw, period, pe.getPendingTime(now), "pending");
@@ -309,6 +336,7 @@ public final class JobPackageTracker {
        } else {
            mCurDataSet.incActive(job.getSourceUid(), job.getSourcePackageName(), now);
        }
        addEvent(EVENT_START_JOB, job.getSourceUid(), job.getBatteryName());
    }

    public void noteInactive(JobStatus job) {
@@ -319,6 +347,7 @@ public final class JobPackageTracker {
            mCurDataSet.decActive(job.getSourceUid(), job.getSourcePackageName(), now);
        }
        rebatchIfNeeded(now);
        addEvent(EVENT_STOP_JOB, job.getSourceUid(), job.getBatteryName());
    }

    public float getLoadFactor(JobStatus job) {
@@ -339,7 +368,7 @@ public final class JobPackageTracker {
        return time / (float)period;
    }

    public void dump(PrintWriter pw, String prefix) {
    public void dump(PrintWriter pw, String prefix, int filterUid) {
        final long now = SystemClock.uptimeMillis();
        final long nowEllapsed = SystemClock.elapsedRealtime();
        final DataSet total;
@@ -352,10 +381,43 @@ public final class JobPackageTracker {
        mCurDataSet.addTo(total, now);
        for (int i = 1; i < mLastDataSets.length; i++) {
            if (mLastDataSets[i] != null) {
                mLastDataSets[i].dump(pw, "Historical stats", prefix, now, nowEllapsed);
                mLastDataSets[i].dump(pw, "Historical stats", prefix, now, nowEllapsed, filterUid);
                pw.println();
            }
        }
        total.dump(pw, "Current stats", prefix, now, nowEllapsed);
        total.dump(pw, "Current stats", prefix, now, nowEllapsed, filterUid);
    }

    public boolean dumpHistory(PrintWriter pw, String prefix, int filterUid) {
        if (mEventCmds[0] == EVENT_NULL) {
            return false;
        }
        pw.println("  Job history:");
        long now = SystemClock.elapsedRealtime();
        for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
            int uid = mEventUids[i];
            if (filterUid != -1 && filterUid != UserHandle.getAppId(filterUid)) {
                continue;
            }
            int cmd = mEventCmds[i];
            if (cmd == EVENT_NULL) {
                continue;
            }
            String label;
            switch (mEventCmds[i]) {
                case EVENT_START_JOB:           label = "START"; break;
                case EVENT_STOP_JOB:            label = " STOP"; break;
                default:                        label = "   ??"; break;
            }
            pw.print(prefix);
            TimeUtils.formatDuration(mEventTimes[i]-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
            pw.print(" ");
            pw.print(label);
            pw.print(": ");
            UserHandle.formatUid(pw, uid);
            pw.print(" ");
            pw.println(mEventTags[i]);
        }
        return true;
    }
}
+50 −15
Original line number Diff line number Diff line
@@ -1477,17 +1477,45 @@ public final class JobSchedulerService extends com.android.server.SystemService
        return s.toString();
    }

    static void dumpHelp(PrintWriter pw) {
        pw.println("Job Scheduler (jobscheduler) dump options:");
        pw.println("  [-h] [package] ...");
        pw.println("    -h: print this help");
        pw.println("  [package] is an optional package name to limit the output to.");
    }

    void dumpInternal(final PrintWriter pw, String[] args) {
        int filterUid = -1;
        if (!ArrayUtils.isEmpty(args)) {
            int opti = 0;
            while (opti < args.length) {
                String arg = args[opti];
                if ("-h".equals(arg)) {
                    dumpHelp(pw);
                    return;
                } else if ("-a".equals(arg)) {
                    // Ignore, we always dump all.
                } else if (arg.length() > 0 && arg.charAt(0) == '-') {
                    pw.println("Unknown option: " + arg);
                    return;
                } else {
                    break;
                }
                opti++;
            }
            if (opti < args.length) {
                String pkg = args[opti];
                try {
                filterUid = getContext().getPackageManager().getPackageUid(args[0],
                    filterUid = getContext().getPackageManager().getPackageUid(pkg,
                            PackageManager.MATCH_UNINSTALLED_PACKAGES);
                } catch (NameNotFoundException ignored) {
                    pw.println("Invalid package: " + pkg);
                    return;
                }
            }
        }

        final int filterUidFinal = filterUid;
        final int filterUidFinal = UserHandle.getAppId(filterUid);
        final long now = SystemClock.elapsedRealtime();
        synchronized (mLock) {
            pw.println("Started users: " + Arrays.toString(mStartedUsers));
@@ -1502,8 +1530,7 @@ public final class JobSchedulerService extends com.android.server.SystemService
                        pw.println(job.toShortString());

                        // Skip printing details if the caller requested a filter
                        if (filterUidFinal != -1 && job.getUid() != filterUidFinal
                                && job.getSourceUid() != filterUidFinal) {
                        if (!job.shouldDump(filterUidFinal)) {
                            return;
                        }

@@ -1526,17 +1553,23 @@ public final class JobSchedulerService extends com.android.server.SystemService
            }
            for (int i=0; i<mControllers.size(); i++) {
                pw.println();
                mControllers.get(i).dumpControllerStateLocked(pw);
                mControllers.get(i).dumpControllerStateLocked(pw, filterUidFinal);
            }
            pw.println();
            pw.println("Uid priority overrides:");
            for (int i=0; i< mUidPriorityOverride.size(); i++) {
                pw.print("  "); pw.print(UserHandle.formatUid(mUidPriorityOverride.keyAt(i)));
                int uid = mUidPriorityOverride.keyAt(i);
                if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
                    pw.print("  "); pw.print(UserHandle.formatUid(uid));
                    pw.print(": "); pw.println(mUidPriorityOverride.valueAt(i));
                }
            }
            pw.println();
            mJobPackageTracker.dump(pw, "");
            mJobPackageTracker.dump(pw, "", filterUidFinal);
            pw.println();
            if (mJobPackageTracker.dumpHistory(pw, "", filterUidFinal)) {
                pw.println();
            }
            pw.println("Pending queue:");
            for (int i=0; i<mPendingJobs.size(); i++) {
                JobStatus job = mPendingJobs.get(i);
@@ -1571,11 +1604,13 @@ public final class JobSchedulerService extends com.android.server.SystemService
                    }
                }
            }
            if (filterUid == -1) {
                pw.println();
                pw.print("mReadyToRock="); pw.println(mReadyToRock);
                pw.print("mReportedActive="); pw.println(mReportedActive);
                pw.print("mMaxActiveJobs="); pw.println(mMaxActiveJobs);
            }
        }
        pw.println();
    }
}
+5 −3
Original line number Diff line number Diff line
@@ -23,10 +23,8 @@ import android.util.Slog;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobStore;
import com.android.server.job.StateChangedListener;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * Controls when apps are considered idle and if jobs pertaining to those apps should
@@ -123,11 +121,15 @@ public class AppIdleController extends StateController {
    }

    @Override
    public void dumpControllerStateLocked(final PrintWriter pw) {
    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
        pw.println("AppIdle");
        pw.println("Parole On: " + mAppIdleParoleOn);
        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
            @Override public void process(JobStatus jobStatus) {
                // Skip printing details if the caller requested a filter
                if (!jobStatus.shouldDump(filterUid)) {
                    return;
                }
                pw.print("  ");
                pw.print(jobStatus.getSourcePackageName());
                pw.print(": runnable=");
Loading