Update jobscheduler dumpsys
- Show job IDs in the history. - Show "last successful/failed run time" for existing jobs. Bug 62052247 Test: Manual test with dumpsys jobscheduler Change-Id: Ic0cdab58e4c5b454a3df8300607e9c24c4b1f438
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -183,6 +184,17 @@ public final class JobStatus {
|
||||
public long madePending;
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user