diff options
| author | 2017-06-20 23:46:27 +0000 | |
|---|---|---|
| committer | 2017-06-20 23:46:31 +0000 | |
| commit | 820a5063b4dcbd5036e5a82f46cdb6b10c80dec1 (patch) | |
| tree | f6569c3f241ea10c29a418f250ce4e936c60e023 | |
| parent | 13cfb46e41a18b011233ed8fbc259942ca19b067 (diff) | |
| parent | ab8a67fa78fc8e03ae8eb73d633d3e5e70867f02 (diff) | |
Merge "Update jobscheduler dumpsys" into oc-dr1-dev
5 files changed, 87 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/job/JobPackageTracker.java b/services/core/java/com/android/server/job/JobPackageTracker.java index 8ad1beace643..ba922959213c 100644 --- a/services/core/java/com/android/server/job/JobPackageTracker.java +++ b/services/core/java/com/android/server/job/JobPackageTracker.java @@ -39,19 +39,23 @@ public final class JobPackageTracker { public static final int EVENT_NULL = 0; public static final int EVENT_START_JOB = 1; public static final int EVENT_STOP_JOB = 2; + public static final int EVENT_START_PERIODIC_JOB = 3; + public static final int EVENT_STOP_PERIODIC_JOB = 4; private final RingBufferIndices mEventIndices = new RingBufferIndices(EVENT_BUFFER_SIZE); private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE]; private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE]; private final int[] mEventUids = new int[EVENT_BUFFER_SIZE]; private final String[] mEventTags = new String[EVENT_BUFFER_SIZE]; + private final int[] mEventJobIds = new int[EVENT_BUFFER_SIZE]; - public void addEvent(int cmd, int uid, String tag) { + public void addEvent(int cmd, int uid, String tag, int jobId) { int index = mEventIndices.add(); mEventCmds[index] = cmd; mEventTimes[index] = SystemClock.elapsedRealtime(); mEventUids[index] = uid; mEventTags[index] = tag; + mEventJobIds[index] = jobId; } DataSet mCurDataSet = new DataSet(); @@ -365,7 +369,8 @@ public final class JobPackageTracker { } else { mCurDataSet.incActive(job.getSourceUid(), job.getSourcePackageName(), now); } - addEvent(EVENT_START_JOB, job.getSourceUid(), job.getBatteryName()); + addEvent(job.getJob().isPeriodic() ? EVENT_START_PERIODIC_JOB : EVENT_START_JOB, + job.getSourceUid(), job.getBatteryName(), job.getJobId()); } public void noteInactive(JobStatus job) { @@ -376,7 +381,8 @@ public final class JobPackageTracker { mCurDataSet.decActive(job.getSourceUid(), job.getSourcePackageName(), now); } rebatchIfNeeded(now); - addEvent(EVENT_STOP_JOB, job.getSourceUid(), job.getBatteryName()); + addEvent(job.getJob().isPeriodic() ? EVENT_STOP_JOB : EVENT_STOP_PERIODIC_JOB, + job.getSourceUid(), job.getBatteryName(), job.getJobId()); } public void noteConcurrency(int totalActive, int fgActive) { @@ -448,16 +454,20 @@ public final class JobPackageTracker { } final String label; switch (mEventCmds[index]) { - case EVENT_START_JOB: label = "START"; break; - case EVENT_STOP_JOB: label = " STOP"; break; - default: label = " ??"; break; + case EVENT_START_JOB: label = " START"; break; + case EVENT_STOP_JOB: label = " STOP"; break; + case EVENT_START_PERIODIC_JOB: label = "START-P"; break; + case EVENT_STOP_PERIODIC_JOB: label = " STOP-P"; break; + default: label = " ??"; break; } pw.print(prefix); TimeUtils.formatDuration(mEventTimes[index]-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); pw.print(" "); pw.print(label); - pw.print(": "); + pw.print(": #"); UserHandle.formatUid(pw, uid); + pw.print("/"); + pw.print(mEventJobIds[index]); pw.print(" "); pw.println(mEventTags[index]); } diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index b8fe88439c2d..98c65fd487ca 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -1122,7 +1122,8 @@ public final class JobSchedulerService extends com.android.server.SystemService delayMillis = Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS); JobStatus newJob = new JobStatus(failureToReschedule, elapsedNowMillis + delayMillis, - JobStatus.NO_LATEST_RUNTIME, backoffAttempts); + JobStatus.NO_LATEST_RUNTIME, backoffAttempts, + failureToReschedule.getLastSuccessfulRunTime(), System.currentTimeMillis()); for (int ic=0; ic<mControllers.size(); ic++) { StateController controller = mControllers.get(ic); controller.rescheduleForFailureLocked(newJob, failureToReschedule); @@ -1160,7 +1161,9 @@ public final class JobSchedulerService extends com.android.server.SystemService newEarliestRunTimeElapsed/1000 + ", " + newLatestRuntimeElapsed/1000 + "]s"); } return new JobStatus(periodicToReschedule, newEarliestRunTimeElapsed, - newLatestRuntimeElapsed, 0 /* backoffAttempt */); + newLatestRuntimeElapsed, 0 /* backoffAttempt */, + System.currentTimeMillis() /* lastSuccessfulRunTime */, + periodicToReschedule.getLastFailedRunTime()); } // JobCompletedListener implementations. diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java index f0cd8a8569e0..84810bebf1f1 100644 --- a/services/core/java/com/android/server/job/JobStore.java +++ b/services/core/java/com/android/server/job/JobStore.java @@ -345,6 +345,11 @@ public final class JobStore { out.attribute(null, "uid", Integer.toString(jobStatus.getUid())); out.attribute(null, "priority", String.valueOf(jobStatus.getPriority())); out.attribute(null, "flags", String.valueOf(jobStatus.getFlags())); + + out.attribute(null, "lastSuccessfulRunTime", + String.valueOf(jobStatus.getLastSuccessfulRunTime())); + out.attribute(null, "lastFailedRunTime", + String.valueOf(jobStatus.getLastFailedRunTime())); } private void writeBundleToXml(PersistableBundle extras, XmlSerializer out) @@ -555,6 +560,8 @@ public final class JobStore { IOException { JobInfo.Builder jobBuilder; int uid, sourceUserId; + long lastSuccessfulRunTime; + long lastFailedRunTime; // Read out job identifier attributes and priority. try { @@ -572,6 +579,12 @@ public final class JobStore { } val = parser.getAttributeValue(null, "sourceUserId"); sourceUserId = val == null ? -1 : Integer.parseInt(val); + + val = parser.getAttributeValue(null, "lastSuccessfulRunTime"); + lastSuccessfulRunTime = val == null ? 0 : Long.parseLong(val); + + val = parser.getAttributeValue(null, "lastFailedRunTime"); + lastFailedRunTime = val == null ? 0 : Long.parseLong(val); } catch (NumberFormatException e) { Slog.e(TAG, "Error parsing job's required fields, skipping"); return null; @@ -708,7 +721,8 @@ public final class JobStore { // And now we're done JobStatus js = new JobStatus( jobBuilder.build(), uid, sourcePackageName, sourceUserId, sourceTag, - elapsedRuntimes.first, elapsedRuntimes.second); + elapsedRuntimes.first, elapsedRuntimes.second, + lastSuccessfulRunTime, lastFailedRunTime); return js; } diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java index 446b0d67ce95..9658da7a5de0 100644 --- a/services/core/java/com/android/server/job/controllers/JobStatus.java +++ b/services/core/java/com/android/server/job/controllers/JobStatus.java @@ -26,6 +26,7 @@ import android.net.Uri; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; +import android.text.format.Time; import android.util.ArraySet; import android.util.Slog; import android.util.TimeUtils; @@ -184,6 +185,17 @@ public final class JobStatus { public long madeActive; /** + * Last time a job finished successfully for a periodic job, in the currentTimeMillis time, + * for dumpsys. + */ + private long mLastSuccessfulRunTime; + + /** + * Last time a job finished unsuccessfully, in the currentTimeMillis time, for dumpsys. + */ + private long mLastFailedRunTime; + + /** * For use only by ContentObserverController: state it is maintaining about content URIs * being observed. */ @@ -196,7 +208,7 @@ public final class JobStatus { private JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, String tag, int numFailures, long earliestRunTimeElapsedMillis, - long latestRunTimeElapsedMillis) { + long latestRunTimeElapsedMillis, long lastSuccessfulRunTime, long lastFailedRunTime) { this.job = job; this.callingUid = callingUid; @@ -263,6 +275,9 @@ public final class JobStatus { requiredConstraints |= CONSTRAINT_CONTENT_TRIGGER; } this.requiredConstraints = requiredConstraints; + + mLastSuccessfulRunTime = lastSuccessfulRunTime; + mLastFailedRunTime = lastFailedRunTime; } /** Copy constructor. */ @@ -270,7 +285,8 @@ public final class JobStatus { this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(), jobStatus.getSourceTag(), jobStatus.getNumFailures(), - jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed()); + jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed(), + jobStatus.getLastSuccessfulRunTime(), jobStatus.getLastFailedRunTime()); } /** @@ -281,18 +297,22 @@ public final class JobStatus { * We consider a freshly loaded job to no longer be in back-off. */ public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, - String sourceTag, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { + String sourceTag, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis, + long lastSuccessfulRunTime, long lastFailedRunTime) { this(job, callingUid, sourcePackageName, sourceUserId, sourceTag, 0, - earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis); + earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis, + lastSuccessfulRunTime, lastFailedRunTime); } /** Create a new job to be rescheduled with the provided parameters. */ public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis, - long newLatestRuntimeElapsedMillis, int backoffAttempt) { + long newLatestRuntimeElapsedMillis, int backoffAttempt, + long lastSuccessfulRunTime, long lastFailedRunTime) { this(rescheduling.job, rescheduling.getUid(), rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(), rescheduling.getSourceTag(), backoffAttempt, newEarliestRuntimeElapsedMillis, - newLatestRuntimeElapsedMillis); + newLatestRuntimeElapsedMillis, + lastSuccessfulRunTime, lastFailedRunTime); } /** @@ -316,7 +336,8 @@ public final class JobStatus { elapsedNow + job.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME; } return new JobStatus(job, callingUid, sourcePackageName, sourceUserId, tag, 0, - earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis); + earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis, + 0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */); } public void enqueueWorkLocked(IActivityManager am, JobWorkItem work) { @@ -669,6 +690,14 @@ public final class JobStatus { trackingControllers |= which; } + public long getLastSuccessfulRunTime() { + return mLastSuccessfulRunTime; + } + + public long getLastFailedRunTime() { + return mLastFailedRunTime; + } + public boolean shouldDump(int filterUid) { return filterUid == -1 || UserHandle.getAppId(getUid()) == filterUid || UserHandle.getAppId(getSourceUid()) == filterUid; @@ -1041,5 +1070,17 @@ public final class JobStatus { if (numFailures != 0) { pw.print(prefix); pw.print("Num failures: "); pw.println(numFailures); } + final Time t = new Time(); + final String format = "%Y-%m-%d %H:%M:%S"; + if (mLastSuccessfulRunTime != 0) { + pw.print(prefix); pw.print("Last successful run: "); + t.set(mLastSuccessfulRunTime); + pw.println(t.format(format)); + } + if (mLastFailedRunTime != 0) { + pw.print(prefix); pw.print("Last failed run: "); + t.set(mLastFailedRunTime); + pw.println(t.format(format)); + } } } diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java index 33e1a1652b22..689c8f7e6e01 100644 --- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java @@ -206,7 +206,8 @@ public class JobStoreTest extends AndroidTestCase { invalidLateRuntimeElapsedMillis - TWO_HOURS; // Early is (late - period). final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage", 0 /* sourceUserId */, "someTag", - invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis); + invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis, + 0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */); mTaskStoreUnderTest.add(js); Thread.sleep(IO_WAIT); |