Merge "Simplify some XML reading code."

This commit is contained in:
Kweku Adams
2022-11-28 16:16:00 +00:00
committed by Android (Google) Code Review

View File

@@ -412,6 +412,14 @@ public final class JobStore {
/** Version of the db schema. */
private static final int JOBS_FILE_VERSION = 1;
/**
* For legacy reasons, this tag is used to encapsulate the entire job list.
*/
private static final String XML_TAG_JOB_INFO = "job-info";
/**
* For legacy reasons, this tag represents a single {@link JobStatus} object.
*/
private static final String XML_TAG_JOB = "job";
/** Tag corresponds to constraints this job needs. */
private static final String XML_TAG_PARAMS_CONSTRAINTS = "constraints";
/** Tag corresponds to execution parameters. */
@@ -645,19 +653,19 @@ public final class JobStore {
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, "job-info");
out.startTag(null, XML_TAG_JOB_INFO);
out.attribute(null, "version", Integer.toString(JOBS_FILE_VERSION));
for (int i=0; i<jobList.size(); i++) {
JobStatus jobStatus = jobList.get(i);
if (DEBUG) {
Slog.d(TAG, "Saving job " + jobStatus.getJobId());
}
out.startTag(null, "job");
out.startTag(null, XML_TAG_JOB);
addAttributesToJobTag(out, jobStatus);
writeConstraintsToXml(out, jobStatus);
writeExecutionCriteriaToXml(out, jobStatus);
writeBundleToXml(jobStatus.getJob().getExtras(), out);
out.endTag(null, "job");
out.endTag(null, XML_TAG_JOB);
numJobs++;
if (jobStatus.getUid() == Process.SYSTEM_UID) {
@@ -667,7 +675,7 @@ public final class JobStore {
}
}
}
out.endTag(null, "job-info");
out.endTag(null, XML_TAG_JOB_INFO);
out.endDocument();
file.finishWrite(fos);
@@ -903,17 +911,17 @@ public final class JobStore {
return;
}
boolean needFileMigration = false;
long now = sElapsedRealtimeClock.millis();
long nowElapsed = sElapsedRealtimeClock.millis();
for (File file : files) {
final AtomicFile aFile = createJobFile(file);
try (FileInputStream fis = aFile.openRead()) {
synchronized (mLock) {
jobs = readJobMapImpl(fis, rtcGood);
jobs = readJobMapImpl(fis, rtcGood, nowElapsed);
if (jobs != null) {
for (int i = 0; i < jobs.size(); i++) {
JobStatus js = jobs.get(i);
js.prepareLocked();
js.enqueueTime = now;
js.enqueueTime = nowElapsed;
this.jobSet.add(js);
numJobs++;
@@ -959,7 +967,7 @@ public final class JobStore {
}
}
private List<JobStatus> readJobMapImpl(InputStream fis, boolean rtcIsGood)
private List<JobStatus> readJobMapImpl(InputStream fis, boolean rtcIsGood, long nowElapsed)
throws XmlPullParserException, IOException {
TypedXmlPullParser parser = Xml.resolvePullParser(fis);
@@ -977,28 +985,24 @@ public final class JobStore {
}
String tagName = parser.getName();
if ("job-info".equals(tagName)) {
if (XML_TAG_JOB_INFO.equals(tagName)) {
final List<JobStatus> jobs = new ArrayList<JobStatus>();
final int version;
final int version = parser.getAttributeInt(null, "version");
// Read in version info.
try {
version = Integer.parseInt(parser.getAttributeValue(null, "version"));
if (version > JOBS_FILE_VERSION || version < 0) {
Slog.d(TAG, "Invalid version number, aborting jobs file read.");
return null;
}
} catch (NumberFormatException e) {
Slog.e(TAG, "Invalid version number, aborting jobs file read.");
if (version > JOBS_FILE_VERSION || version < 0) {
Slog.d(TAG, "Invalid version number, aborting jobs file read.");
return null;
}
eventType = parser.next();
do {
// Read each <job/>
if (eventType == XmlPullParser.START_TAG) {
tagName = parser.getName();
// Start reading job.
if ("job".equals(tagName)) {
JobStatus persistedJob = restoreJobFromXml(rtcIsGood, parser, version);
if (XML_TAG_JOB.equals(tagName)) {
JobStatus persistedJob =
restoreJobFromXml(rtcIsGood, parser, version, nowElapsed);
if (persistedJob != null) {
if (DEBUG) {
Slog.d(TAG, "Read out " + persistedJob);
@@ -1022,7 +1026,7 @@ public final class JobStore {
* @return Newly instantiated job holding all the information we just read out of the xml tag.
*/
private JobStatus restoreJobFromXml(boolean rtcIsGood, TypedXmlPullParser parser,
int schemaVersion) throws XmlPullParserException, IOException {
int schemaVersion, long nowElapsed) throws XmlPullParserException, IOException {
JobInfo.Builder jobBuilder;
int uid, sourceUserId;
long lastSuccessfulRunTime;
@@ -1113,18 +1117,9 @@ public final class JobStore {
}
// Tuple of (earliest runtime, latest runtime) in UTC.
final Pair<Long, Long> rtcRuntimes;
try {
rtcRuntimes = buildRtcExecutionTimesFromXml(parser);
} catch (NumberFormatException e) {
if (DEBUG) {
Slog.d(TAG, "Error parsing execution time parameters, skipping.");
}
return null;
}
final Pair<Long, Long> rtcRuntimes = buildRtcExecutionTimesFromXml(parser);
final long elapsedNow = sElapsedRealtimeClock.millis();
Pair<Long, Long> elapsedRuntimes = convertRtcBoundsToElapsed(rtcRuntimes, elapsedNow);
Pair<Long, Long> elapsedRuntimes = convertRtcBoundsToElapsed(rtcRuntimes, nowElapsed);
if (XML_TAG_PERIODIC.equals(parser.getName())) {
try {
@@ -1137,8 +1132,8 @@ public final class JobStore {
// from now. This is the latest the periodic could be pushed out. This could
// happen if the periodic ran early (at flex time before period), and then the
// device rebooted.
if (elapsedRuntimes.second > elapsedNow + periodMillis + flexMillis) {
final long clampedLateRuntimeElapsed = elapsedNow + flexMillis
if (elapsedRuntimes.second > nowElapsed + periodMillis + flexMillis) {
final long clampedLateRuntimeElapsed = nowElapsed + flexMillis
+ periodMillis;
final long clampedEarlyRuntimeElapsed = clampedLateRuntimeElapsed
- flexMillis;
@@ -1163,11 +1158,11 @@ public final class JobStore {
} else if (XML_TAG_ONEOFF.equals(parser.getName())) {
try {
if (elapsedRuntimes.first != JobStatus.NO_EARLIEST_RUNTIME) {
jobBuilder.setMinimumLatency(elapsedRuntimes.first - elapsedNow);
jobBuilder.setMinimumLatency(elapsedRuntimes.first - nowElapsed);
}
if (elapsedRuntimes.second != JobStatus.NO_LATEST_RUNTIME) {
jobBuilder.setOverrideDeadline(
elapsedRuntimes.second - elapsedNow);
elapsedRuntimes.second - nowElapsed);
}
} catch (NumberFormatException e) {
Slog.d(TAG, "Error reading job execution criteria, skipping.");
@@ -1236,7 +1231,7 @@ public final class JobStore {
// And now we're done
final int appBucket = JobSchedulerService.standbyBucketForPackage(sourcePackageName,
sourceUserId, elapsedNow);
sourceUserId, nowElapsed);
JobStatus js = new JobStatus(
builtJob, uid, sourcePackageName, sourceUserId,
appBucket, sourceTag,
@@ -1246,9 +1241,10 @@ public final class JobStore {
return js;
}
private JobInfo.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException {
private JobInfo.Builder buildBuilderFromXml(TypedXmlPullParser parser)
throws XmlPullParserException {
// Pull out required fields from <job> attributes.
int jobId = Integer.parseInt(parser.getAttributeValue(null, "jobid"));
int jobId = parser.getAttributeInt(null, "jobid");
String packageName = parser.getAttributeValue(null, "package");
String className = parser.getAttributeValue(null, "class");
ComponentName cname = new ComponentName(packageName, className);
@@ -1405,20 +1401,13 @@ public final class JobStore {
* @return A Pair of timestamps in UTC wall-clock time. The first is the earliest
* time at which the job is to become runnable, and the second is the deadline at
* which it becomes overdue to execute.
* @throws NumberFormatException
*/
private Pair<Long, Long> buildRtcExecutionTimesFromXml(XmlPullParser parser)
throws NumberFormatException {
String val;
private Pair<Long, Long> buildRtcExecutionTimesFromXml(TypedXmlPullParser parser) {
// Pull out execution time data.
val = parser.getAttributeValue(null, "delay");
final long earliestRunTimeRtc = (val != null)
? Long.parseLong(val)
: JobStatus.NO_EARLIEST_RUNTIME;
val = parser.getAttributeValue(null, "deadline");
final long latestRunTimeRtc = (val != null)
? Long.parseLong(val)
: JobStatus.NO_LATEST_RUNTIME;
final long earliestRunTimeRtc =
parser.getAttributeLong(null, "delay", JobStatus.NO_EARLIEST_RUNTIME);
final long latestRunTimeRtc =
parser.getAttributeLong(null, "deadline", JobStatus.NO_LATEST_RUNTIME);
return Pair.create(earliestRunTimeRtc, latestRunTimeRtc);
}
}