Merge "Tweak SystemUpdatePolicy APIs" into pi-dev

This commit is contained in:
Rubin Xu
2018-04-06 12:54:24 +00:00
committed by Android (Google) Code Review
5 changed files with 209 additions and 134 deletions

View File

@@ -6749,6 +6749,12 @@ package android.app.admin {
field public static final android.os.Parcelable.Creator<android.app.admin.DnsEvent> CREATOR;
}
public class FreezePeriod {
ctor public FreezePeriod(java.time.MonthDay, java.time.MonthDay);
method public java.time.MonthDay getEnd();
method public java.time.MonthDay getStart();
}
public abstract class NetworkEvent implements android.os.Parcelable {
method public int describeContents();
method public long getId();
@@ -6819,16 +6825,16 @@ package android.app.admin {
field public static final int SECURITY_PATCH_STATE_UNKNOWN = 0; // 0x0
}
public class SystemUpdatePolicy implements android.os.Parcelable {
public final class SystemUpdatePolicy implements android.os.Parcelable {
method public static android.app.admin.SystemUpdatePolicy createAutomaticInstallPolicy();
method public static android.app.admin.SystemUpdatePolicy createPostponeInstallPolicy();
method public static android.app.admin.SystemUpdatePolicy createWindowedInstallPolicy(int, int);
method public int describeContents();
method public java.util.List<android.util.Pair<java.lang.Integer, java.lang.Integer>> getFreezePeriods();
method public java.util.List<android.app.admin.FreezePeriod> getFreezePeriods();
method public int getInstallWindowEnd();
method public int getInstallWindowStart();
method public int getPolicyType();
method public android.app.admin.SystemUpdatePolicy setFreezePeriods(java.util.List<android.util.Pair<java.lang.Integer, java.lang.Integer>>);
method public android.app.admin.SystemUpdatePolicy setFreezePeriods(java.util.List<android.app.admin.FreezePeriod>);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdatePolicy> CREATOR;
field public static final int TYPE_INSTALL_AUTOMATIC = 1; // 0x1
@@ -6841,11 +6847,12 @@ package android.app.admin {
method public int getErrorCode();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdatePolicy.ValidationFailedException> CREATOR;
field public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE = 5; // 0x5
field public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG = 4; // 0x4
field public static final int ERROR_DUPLICATE_OR_OVERLAP = 1; // 0x1
field public static final int ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE = 3; // 0x3
field public static final int ERROR_NEW_FREEZE_PERIOD_TOO_LONG = 2; // 0x2
field public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE = 6; // 0x6
field public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG = 5; // 0x5
field public static final int ERROR_DUPLICATE_OR_OVERLAP = 2; // 0x2
field public static final int ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE = 4; // 0x4
field public static final int ERROR_NEW_FREEZE_PERIOD_TOO_LONG = 3; // 0x3
field public static final int ERROR_UNKNOWN = 1; // 0x1
}
}

View File

@@ -452,7 +452,7 @@ package android.app.admin {
field public static final int STATE_USER_UNMANAGED = 0; // 0x0
}
public class SystemUpdatePolicy implements android.os.Parcelable {
public final class SystemUpdatePolicy implements android.os.Parcelable {
method public int describeContents();
method public android.app.admin.SystemUpdatePolicy.InstallationOption getInstallationOptionAt(long);
method public void writeToParcel(android.os.Parcel, int);

View File

@@ -20,49 +20,88 @@ import android.util.Log;
import android.util.Pair;
import java.time.LocalDate;
import java.time.MonthDay;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
* An interval representing one freeze period which repeats annually. We use the number of days
* since the start of (non-leap) year to define the start and end dates of an interval, both
* inclusive. If the end date is smaller than the start date, the interval is considered wrapped
* around the year-end. As far as an interval is concerned, February 29th should be treated as
* if it were February 28th: so an interval starting or ending on February 28th are not
* distinguishable from an interval on February 29th. When calulating interval length or
* distance between two dates, February 29th is also disregarded.
* A class that represents one freeze period which repeats <em>annually</em>. A freeze period has
* two {@link java.time#MonthDay} values that define the start and end dates of the period, both
* inclusive. If the end date is earlier than the start date, the period is considered wrapped
* around the year-end. As far as freeze period is concerned, leap year is disregarded and February
* 29th should be treated as if it were February 28th: so a freeze starting or ending on February
* 28th is identical to a freeze starting or ending on February 29th. When calulating the length of
* a freeze or the distance bewteen two freee periods, February 29th is also ignored.
*
* @see SystemUpdatePolicy#setFreezePeriods
* @hide
*/
public class FreezeInterval {
private static final String TAG = "FreezeInterval";
public class FreezePeriod {
private static final String TAG = "FreezePeriod";
private static final int DUMMY_YEAR = 2001;
static final int DAYS_IN_YEAR = 365; // 365 since DUMMY_YEAR is not a leap year
final int mStartDay; // [1,365]
final int mEndDay; // [1,365]
private final MonthDay mStart;
private final MonthDay mEnd;
FreezeInterval(int startDay, int endDay) {
if (startDay < 1 || startDay > 365 || endDay < 1 || endDay > 365) {
throw new RuntimeException("Bad dates for Interval: " + startDay + "," + endDay);
}
mStartDay = startDay;
mEndDay = endDay;
/*
* Start and end dates represented by number of days since the beginning of the year.
* They are internal representations of mStart and mEnd with normalized Leap year days
* (Feb 29 == Feb 28 == 59th day of year). All internal calclations are based on
* these two values so that leap year days are disregarded.
*/
private final int mStartDay; // [1, 365]
private final int mEndDay; // [1, 365]
/**
* Creates a freeze period by its start and end dates. If the end date is earlier than the start
* date, the freeze period is considered wrapping year-end.
*/
public FreezePeriod(MonthDay start, MonthDay end) {
mStart = start;
mStartDay = mStart.atYear(DUMMY_YEAR).getDayOfYear();
mEnd = end;
mEndDay = mEnd.atYear(DUMMY_YEAR).getDayOfYear();
}
/**
* Returns the start date (inclusive) of this freeze period.
*/
public MonthDay getStart() {
return mStart;
}
/**
* Returns the end date (inclusive) of this freeze period.
*/
public MonthDay getEnd() {
return mEnd;
}
/**
* @hide
*/
private FreezePeriod(int startDay, int endDay) {
mStartDay = startDay;
mStart = dayOfYearToMonthDay(startDay);
mEndDay = endDay;
mEnd = dayOfYearToMonthDay(endDay);
}
/** @hide */
int getLength() {
return getEffectiveEndDay() - mStartDay + 1;
}
/** @hide */
boolean isWrapped() {
return mEndDay < mStartDay;
}
/**
* Returns the effective end day, taking wrapping around year-end into consideration
* @hide
*/
int getEffectiveEndDay() {
if (!isWrapped()) {
@@ -72,6 +111,7 @@ public class FreezeInterval {
}
}
/** @hide */
boolean contains(LocalDate localDate) {
final int daysOfYear = dayOfYearDisregardLeapYear(localDate);
if (!isWrapped()) {
@@ -84,6 +124,7 @@ public class FreezeInterval {
}
}
/** @hide */
boolean after(LocalDate localDate) {
return mStartDay > dayOfYearDisregardLeapYear(localDate);
}
@@ -95,6 +136,7 @@ public class FreezeInterval {
* include now, the returned dates represents the next future interval.
* The result will always have the same month and dayOfMonth value as the non-instantiated
* interval itself.
* @hide
*/
Pair<LocalDate, LocalDate> toCurrentOrFutureRealDates(LocalDate now) {
final int nowDays = dayOfYearDisregardLeapYear(now);
@@ -138,14 +180,24 @@ public class FreezeInterval {
+ LocalDate.ofYearDay(DUMMY_YEAR, mEndDay).format(formatter);
}
// Treat the supplied date as in a non-leap year and return its day of year.
static int dayOfYearDisregardLeapYear(LocalDate date) {
/** @hide */
private static MonthDay dayOfYearToMonthDay(int dayOfYear) {
LocalDate date = LocalDate.ofYearDay(DUMMY_YEAR, dayOfYear);
return MonthDay.of(date.getMonth(), date.getDayOfMonth());
}
/**
* Treat the supplied date as in a non-leap year and return its day of year.
* @hide
*/
private static int dayOfYearDisregardLeapYear(LocalDate date) {
return date.withYear(DUMMY_YEAR).getDayOfYear();
}
/**
* Compute the number of days between first (inclusive) and second (exclusive),
* treating all years in between as non-leap.
* @hide
*/
public static int distanceWithoutLeapYear(LocalDate first, LocalDate second) {
return dayOfYearDisregardLeapYear(first) - dayOfYearDisregardLeapYear(second)
@@ -165,16 +217,16 @@ public class FreezeInterval {
* 3. At most one wrapped Interval remains, and it will be at the end of the list
* @hide
*/
protected static List<FreezeInterval> canonicalizeIntervals(List<FreezeInterval> intervals) {
static List<FreezePeriod> canonicalizePeriods(List<FreezePeriod> intervals) {
boolean[] taken = new boolean[DAYS_IN_YEAR];
// First convert the intervals into flat array
for (FreezeInterval interval : intervals) {
for (FreezePeriod interval : intervals) {
for (int i = interval.mStartDay; i <= interval.getEffectiveEndDay(); i++) {
taken[(i - 1) % DAYS_IN_YEAR] = true;
}
}
// Then reconstruct intervals from the array
List<FreezeInterval> result = new ArrayList<>();
List<FreezePeriod> result = new ArrayList<>();
int i = 0;
while (i < DAYS_IN_YEAR) {
if (!taken[i]) {
@@ -183,14 +235,14 @@ public class FreezeInterval {
}
final int intervalStart = i + 1;
while (i < DAYS_IN_YEAR && taken[i]) i++;
result.add(new FreezeInterval(intervalStart, i));
result.add(new FreezePeriod(intervalStart, i));
}
// Check if the last entry can be merged to the first entry to become one single
// wrapped interval
final int lastIndex = result.size() - 1;
if (lastIndex > 0 && result.get(lastIndex).mEndDay == DAYS_IN_YEAR
&& result.get(0).mStartDay == 1) {
FreezeInterval wrappedInterval = new FreezeInterval(result.get(lastIndex).mStartDay,
FreezePeriod wrappedInterval = new FreezePeriod(result.get(lastIndex).mStartDay,
result.get(0).mEndDay);
result.set(lastIndex, wrappedInterval);
result.remove(0);
@@ -207,18 +259,18 @@ public class FreezeInterval {
*
* @hide
*/
protected static void validatePeriods(List<FreezeInterval> periods) {
List<FreezeInterval> allPeriods = FreezeInterval.canonicalizeIntervals(periods);
static void validatePeriods(List<FreezePeriod> periods) {
List<FreezePeriod> allPeriods = FreezePeriod.canonicalizePeriods(periods);
if (allPeriods.size() != periods.size()) {
throw SystemUpdatePolicy.ValidationFailedException.duplicateOrOverlapPeriods();
}
for (int i = 0; i < allPeriods.size(); i++) {
FreezeInterval current = allPeriods.get(i);
FreezePeriod current = allPeriods.get(i);
if (current.getLength() > SystemUpdatePolicy.FREEZE_PERIOD_MAX_LENGTH) {
throw SystemUpdatePolicy.ValidationFailedException.freezePeriodTooLong("Freeze "
+ "period " + current + " is too long: " + current.getLength() + " days");
}
FreezeInterval previous = i > 0 ? allPeriods.get(i - 1)
FreezePeriod previous = i > 0 ? allPeriods.get(i - 1)
: allPeriods.get(allPeriods.size() - 1);
if (previous != current) {
final int separation;
@@ -247,7 +299,7 @@ public class FreezeInterval {
*
* @hide
*/
protected static void validateAgainstPreviousFreezePeriod(List<FreezeInterval> periods,
static void validateAgainstPreviousFreezePeriod(List<FreezePeriod> periods,
LocalDate prevPeriodStart, LocalDate prevPeriodEnd, LocalDate now) {
if (periods.size() == 0 || prevPeriodStart == null || prevPeriodEnd == null) {
return;
@@ -258,14 +310,14 @@ public class FreezeInterval {
// Clock was adjusted backwards. We can continue execution though, the separation
// and length validation below still works under this condition.
}
List<FreezeInterval> allPeriods = FreezeInterval.canonicalizeIntervals(periods);
List<FreezePeriod> allPeriods = FreezePeriod.canonicalizePeriods(periods);
// Given current time now, find the freeze period that's either current, or the one
// that's immediately afterwards. For the later case, it might be after the year-end,
// but this can only happen if there is only one freeze period.
FreezeInterval curOrNextFreezePeriod = allPeriods.get(0);
for (FreezeInterval interval : allPeriods) {
FreezePeriod curOrNextFreezePeriod = allPeriods.get(0);
for (FreezePeriod interval : allPeriods) {
if (interval.contains(now)
|| interval.mStartDay > FreezeInterval.dayOfYearDisregardLeapYear(now)) {
|| interval.mStartDay > FreezePeriod.dayOfYearDisregardLeapYear(now)) {
curOrNextFreezePeriod = interval;
break;
}
@@ -282,7 +334,7 @@ public class FreezeInterval {
// Now validate [prevPeriodStart, prevPeriodEnd] against curOrNextFreezeDates
final String periodsDescription = "Prev: " + prevPeriodStart + "," + prevPeriodEnd
+ "; cur: " + curOrNextFreezeDates.first + "," + curOrNextFreezeDates.second;
long separation = FreezeInterval.distanceWithoutLeapYear(curOrNextFreezeDates.first,
long separation = FreezePeriod.distanceWithoutLeapYear(curOrNextFreezeDates.first,
prevPeriodEnd) - 1;
if (separation > 0) {
// Two intervals do not overlap, check separation
@@ -292,7 +344,7 @@ public class FreezeInterval {
}
} else {
// Two intervals overlap, check combined length
long length = FreezeInterval.distanceWithoutLeapYear(curOrNextFreezeDates.second,
long length = FreezePeriod.distanceWithoutLeapYear(curOrNextFreezeDates.second,
prevPeriodStart) + 1;
if (length > SystemUpdatePolicy.FREEZE_PERIOD_MAX_LENGTH) {
throw ValidationFailedException.combinedPeriodTooLong("Combined freeze period "

View File

@@ -38,9 +38,11 @@ import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.MonthDay;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -51,7 +53,7 @@ import java.util.stream.Collectors;
* @see DevicePolicyManager#setSystemUpdatePolicy
* @see DevicePolicyManager#getSystemUpdatePolicy
*/
public class SystemUpdatePolicy implements Parcelable {
public final class SystemUpdatePolicy implements Parcelable {
private static final String TAG = "SystemUpdatePolicy";
/** @hide */
@@ -163,6 +165,7 @@ public class SystemUpdatePolicy implements Parcelable {
ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE,
ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG,
ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE,
ERROR_UNKNOWN,
})
@Retention(RetentionPolicy.SOURCE)
@interface ValidationFailureType {}
@@ -170,34 +173,39 @@ public class SystemUpdatePolicy implements Parcelable {
/** @hide */
public static final int ERROR_NONE = 0;
/**
* Validation failed with unknown error.
*/
public static final int ERROR_UNKNOWN = 1;
/**
* The freeze periods contains duplicates, periods that overlap with each
* other or periods whose start and end joins.
*/
public static final int ERROR_DUPLICATE_OR_OVERLAP = 1;
public static final int ERROR_DUPLICATE_OR_OVERLAP = 2;
/**
* There exists at least one freeze period whose length exceeds 90 days.
*/
public static final int ERROR_NEW_FREEZE_PERIOD_TOO_LONG = 2;
public static final int ERROR_NEW_FREEZE_PERIOD_TOO_LONG = 3;
/**
* There exists some freeze period which starts within 60 days of the preceding period's
* end time.
*/
public static final int ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE = 3;
public static final int ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE = 4;
/**
* The device has been in a freeze period and when combining with the new freeze period
* to be set, it will result in the total freeze period being longer than 90 days.
*/
public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG = 4;
public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG = 5;
/**
* The device has been in a freeze period and some new freeze period to be set is less
* than 60 days from the end of the last freeze period the device went through.
*/
public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE = 5;
public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE = 6;
@ValidationFailureType
private final int mErrorCode;
@@ -272,7 +280,7 @@ public class SystemUpdatePolicy implements Parcelable {
private int mMaintenanceWindowStart;
private int mMaintenanceWindowEnd;
private final ArrayList<FreezeInterval> mFreezePeriods;
private final ArrayList<FreezePeriod> mFreezePeriods;
private SystemUpdatePolicy() {
mPolicyType = TYPE_UNKNOWN;
@@ -444,12 +452,10 @@ public class SystemUpdatePolicy implements Parcelable {
* requirement set above
* @return this instance
*/
public SystemUpdatePolicy setFreezePeriods(List<Pair<Integer, Integer>> freezePeriods) {
List<FreezeInterval> newPeriods = freezePeriods.stream().map(
p -> new FreezeInterval(p.first, p.second)).collect(Collectors.toList());
FreezeInterval.validatePeriods(newPeriods);
public SystemUpdatePolicy setFreezePeriods(List<FreezePeriod> freezePeriods) {
FreezePeriod.validatePeriods(freezePeriods);
mFreezePeriods.clear();
mFreezePeriods.addAll(newPeriods);
mFreezePeriods.addAll(freezePeriods);
return this;
}
@@ -458,12 +464,8 @@ public class SystemUpdatePolicy implements Parcelable {
*
* @return the list of freeze periods, or an empty list if none was set.
*/
public List<Pair<Integer, Integer>> getFreezePeriods() {
List<Pair<Integer, Integer>> result = new ArrayList<>(mFreezePeriods.size());
for (FreezeInterval interval : mFreezePeriods) {
result.add(new Pair<>(interval.mStartDay, interval.mEndDay));
}
return result;
public List<FreezePeriod> getFreezePeriods() {
return Collections.unmodifiableList(mFreezePeriods);
}
/**
@@ -472,7 +474,7 @@ public class SystemUpdatePolicy implements Parcelable {
* @hide
*/
public Pair<LocalDate, LocalDate> getCurrentFreezePeriod(LocalDate now) {
for (FreezeInterval interval : mFreezePeriods) {
for (FreezePeriod interval : mFreezePeriods) {
if (interval.contains(now)) {
return interval.toCurrentOrFutureRealDates(now);
}
@@ -485,10 +487,10 @@ public class SystemUpdatePolicy implements Parcelable {
* is not within a freeze period.
*/
private long timeUntilNextFreezePeriod(long now) {
List<FreezeInterval> sortedPeriods = FreezeInterval.canonicalizeIntervals(mFreezePeriods);
List<FreezePeriod> sortedPeriods = FreezePeriod.canonicalizePeriods(mFreezePeriods);
LocalDate nowDate = millisToDate(now);
LocalDate nextFreezeStart = null;
for (FreezeInterval interval : sortedPeriods) {
for (FreezePeriod interval : sortedPeriods) {
if (interval.after(nowDate)) {
nextFreezeStart = interval.toCurrentOrFutureRealDates(nowDate).first;
break;
@@ -506,13 +508,13 @@ public class SystemUpdatePolicy implements Parcelable {
/** @hide */
public void validateFreezePeriods() {
FreezeInterval.validatePeriods(mFreezePeriods);
FreezePeriod.validatePeriods(mFreezePeriods);
}
/** @hide */
public void validateAgainstPreviousFreezePeriod(LocalDate prevPeriodStart,
LocalDate prevPeriodEnd, LocalDate now) {
FreezeInterval.validateAgainstPreviousFreezePeriod(mFreezePeriods, prevPeriodStart,
FreezePeriod.validateAgainstPreviousFreezePeriod(mFreezePeriods, prevPeriodStart,
prevPeriodEnd, now);
}
@@ -521,10 +523,10 @@ public class SystemUpdatePolicy implements Parcelable {
* updates and how long this action is valid for, given the current system update policy. Its
* action could be one of the following
* <ul>
* <li> {@code TYPE_INSTALL_AUTOMATIC} system updates should be installed immedately and without
* user intervention as soon as they become available.
* <li> {@code TYPE_POSTPONE} system updates should be postponed for a maximum of 30 days
* <li> {@code TYPE_PAUSE} system updates should be postponed indefinitely until further notice
* <li> {@link #TYPE_INSTALL_AUTOMATIC} system updates should be installed immedately and
* without user intervention as soon as they become available.
* <li> {@link #TYPE_POSTPONE} system updates should be postponed for a maximum of 30 days
* <li> {@link #TYPE_PAUSE} system updates should be postponed indefinitely until further notice
* </ul>
*
* The effective time measures how long this installation option is valid for from the queried
@@ -535,18 +537,38 @@ public class SystemUpdatePolicy implements Parcelable {
*/
@SystemApi
public static class InstallationOption {
/** @hide */
@IntDef(prefix = { "TYPE_" }, value = {
TYPE_INSTALL_AUTOMATIC,
TYPE_PAUSE,
TYPE_POSTPONE
})
@Retention(RetentionPolicy.SOURCE)
@interface InstallationOptionType {}
@InstallationOptionType
private final int mType;
private long mEffectiveTime;
InstallationOption(int type, long effectiveTime) {
InstallationOption(@InstallationOptionType int type, long effectiveTime) {
this.mType = type;
this.mEffectiveTime = effectiveTime;
}
public int getType() {
/**
* Returns the type of the current installation option, could be one of
* {@link #TYPE_INSTALL_AUTOMATIC}, {@link #TYPE_POSTPONE} and {@link #TYPE_PAUSE}.
* @return type of installation option.
*/
public @InstallationOptionType int getType() {
return mType;
}
/**
* Returns how long the current installation option in effective for, starting from the time
* of query.
* @return the effective time in milliseconds.
*/
public long getEffectiveTime() {
return mEffectiveTime;
}
@@ -667,9 +689,11 @@ public class SystemUpdatePolicy implements Parcelable {
int freezeCount = mFreezePeriods.size();
dest.writeInt(freezeCount);
for (int i = 0; i < freezeCount; i++) {
FreezeInterval interval = mFreezePeriods.get(i);
dest.writeInt(interval.mStartDay);
dest.writeInt(interval.mEndDay);
FreezePeriod interval = mFreezePeriods.get(i);
dest.writeInt(interval.getStart().getMonthValue());
dest.writeInt(interval.getStart().getDayOfMonth());
dest.writeInt(interval.getEnd().getMonthValue());
dest.writeInt(interval.getEnd().getDayOfMonth());
}
}
@@ -686,8 +710,9 @@ public class SystemUpdatePolicy implements Parcelable {
int freezeCount = source.readInt();
policy.mFreezePeriods.ensureCapacity(freezeCount);
for (int i = 0; i < freezeCount; i++) {
policy.mFreezePeriods.add(
new FreezeInterval(source.readInt(), source.readInt()));
MonthDay start = MonthDay.of(source.readInt(), source.readInt());
MonthDay end = MonthDay.of(source.readInt(), source.readInt());
policy.mFreezePeriods.add(new FreezePeriod(start, end));
}
return policy;
}
@@ -730,9 +755,9 @@ public class SystemUpdatePolicy implements Parcelable {
if (!parser.getName().equals(KEY_FREEZE_TAG)) {
continue;
}
policy.mFreezePeriods.add(new FreezeInterval(
Integer.parseInt(parser.getAttributeValue(null, KEY_FREEZE_START)),
Integer.parseInt(parser.getAttributeValue(null, KEY_FREEZE_END))));
policy.mFreezePeriods.add(new FreezePeriod(
MonthDay.parse(parser.getAttributeValue(null, KEY_FREEZE_START)),
MonthDay.parse(parser.getAttributeValue(null, KEY_FREEZE_END))));
}
return policy;
}
@@ -751,10 +776,10 @@ public class SystemUpdatePolicy implements Parcelable {
out.attribute(null, KEY_INSTALL_WINDOW_START, Integer.toString(mMaintenanceWindowStart));
out.attribute(null, KEY_INSTALL_WINDOW_END, Integer.toString(mMaintenanceWindowEnd));
for (int i = 0; i < mFreezePeriods.size(); i++) {
FreezeInterval interval = mFreezePeriods.get(i);
FreezePeriod interval = mFreezePeriods.get(i);
out.startTag(null, KEY_FREEZE_TAG);
out.attribute(null, KEY_FREEZE_START, Integer.toString(interval.mStartDay));
out.attribute(null, KEY_FREEZE_END, Integer.toString(interval.mEndDay));
out.attribute(null, KEY_FREEZE_START, interval.getStart().toString());
out.attribute(null, KEY_FREEZE_END, interval.getEnd().toString());
out.endTag(null, KEY_FREEZE_TAG);
}
}

View File

@@ -24,7 +24,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.app.admin.FreezeInterval;
import android.app.admin.FreezePeriod;
import android.app.admin.SystemUpdatePolicy;
import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
@@ -42,15 +42,15 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.MonthDay;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Unit tests for {@link android.app.admin.SystemUpdatePolicy}.
* Throughout this test, we use "MM-DD" format to denote dates without year.
@@ -224,36 +224,36 @@ public final class SystemUpdatePolicyTest {
@Test
public void testDistanceWithoutLeapYear() {
assertEquals(364, FreezeInterval.distanceWithoutLeapYear(
assertEquals(364, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2016, 12, 31), LocalDate.of(2016, 1, 1)));
assertEquals(365, FreezeInterval.distanceWithoutLeapYear(
assertEquals(365, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2017, 1, 1), LocalDate.of(2016, 1, 1)));
assertEquals(365, FreezeInterval.distanceWithoutLeapYear(
assertEquals(365, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2017, 2, 28), LocalDate.of(2016, 2, 29)));
assertEquals(-365, FreezeInterval.distanceWithoutLeapYear(
assertEquals(-365, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2016, 1, 1), LocalDate.of(2017, 1, 1)));
assertEquals(1, FreezeInterval.distanceWithoutLeapYear(
assertEquals(1, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 29)));
assertEquals(1, FreezeInterval.distanceWithoutLeapYear(
assertEquals(1, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 28)));
assertEquals(0, FreezeInterval.distanceWithoutLeapYear(
assertEquals(0, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2016, 2, 29), LocalDate.of(2016, 2, 28)));
assertEquals(0, FreezeInterval.distanceWithoutLeapYear(
assertEquals(0, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2016, 2, 28), LocalDate.of(2016, 2, 28)));
assertEquals(59, FreezeInterval.distanceWithoutLeapYear(
assertEquals(59, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2016, 3, 1), LocalDate.of(2016, 1, 1)));
assertEquals(59, FreezeInterval.distanceWithoutLeapYear(
assertEquals(59, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2017, 3, 1), LocalDate.of(2017, 1, 1)));
assertEquals(365 * 40, FreezeInterval.distanceWithoutLeapYear(
assertEquals(365 * 40, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2040, 1, 1), LocalDate.of(2000, 1, 1)));
assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear(
assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2019, 3, 1), LocalDate.of(2017, 3, 1)));
assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear(
assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2018, 3, 1), LocalDate.of(2016, 3, 1)));
assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear(
assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear(
LocalDate.of(2017, 3, 1), LocalDate.of(2015, 3, 1)));
}
@@ -386,10 +386,10 @@ public final class SystemUpdatePolicyTest {
// Two freeze periods
p = SystemUpdatePolicy.createAutomaticInstallPolicy();
setFreezePeriods(p, "05-01", "06-01", "11-01", "01-29");
// automatic policy for July, August, September and October
setFreezePeriods(p, "05-01", "06-01", "10-15", "01-10");
// automatic policy for July, August, September and October until 15th
assertInstallationOption(
SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(92),
SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(31 + 30 + 14),
millis_2018_08_01, p);
}
@@ -435,18 +435,18 @@ public final class SystemUpdatePolicyTest {
String... dates) throws Exception {
SystemUpdatePolicy p = SystemUpdatePolicy.createPostponeInstallPolicy();
setFreezePeriods(p, dates);
p.validateAgainstPreviousFreezePeriod(parseDate(prevStart), parseDate(prevEnd),
parseDate(now));
p.validateAgainstPreviousFreezePeriod(parseLocalDate(prevStart),
parseLocalDate(prevEnd), parseLocalDate(now));
}
// "MM-DD" format for date
private void setFreezePeriods(SystemUpdatePolicy policy, String... dates) throws Exception {
List<Pair<Integer, Integer>> periods = new ArrayList<>();
LocalDate lastDate = null;
List<FreezePeriod> periods = new ArrayList<>();
MonthDay lastDate = null;
for (String date : dates) {
LocalDate currentDate = parseDate(date);
MonthDay currentDate = parseMonthDay(date);
if (lastDate != null) {
periods.add(new Pair<>(lastDate.getDayOfYear(), currentDate.getDayOfYear()));
periods.add(new FreezePeriod(lastDate, currentDate));
lastDate = null;
} else {
lastDate = currentDate;
@@ -457,7 +457,7 @@ public final class SystemUpdatePolicyTest {
}
private void testSerialization(SystemUpdatePolicy policy,
List<Pair<Integer, Integer>> expectedPeriods) throws Exception {
List<FreezePeriod> expectedPeriods) throws Exception {
// Test parcel / unparcel
Parcel parcel = Parcel.obtain();
policy.writeToParcel(parcel, 0);
@@ -485,36 +485,27 @@ public final class SystemUpdatePolicyTest {
}
private void checkFreezePeriods(SystemUpdatePolicy policy,
List<Pair<Integer, Integer>> expectedPeriods) {
List<FreezePeriod> expectedPeriods) {
int i = 0;
for (Pair<Integer, Integer> period : policy.getFreezePeriods()) {
assertEquals(expectedPeriods.get(i).first, period.first);
assertEquals(expectedPeriods.get(i).second, period.second);
for (FreezePeriod period : policy.getFreezePeriods()) {
assertEquals(expectedPeriods.get(i).getStart(), period.getStart());
assertEquals(expectedPeriods.get(i).getEnd(), period.getEnd());
i++;
}
}
private LocalDate parseDate(String date) {
// Use leap year when parsing date string to handle "02-29", but force round down
// to Feb 28th by overriding the year to non-leap year.
final int year;
boolean monthDateOnly = false;
if (date.length() == 5) {
year = 2000;
monthDateOnly = true;
} else {
year = Integer.parseInt(date.substring(0, 4));
date = date.substring(5);
}
LocalDate result = LocalDate.of(year, Integer.parseInt(date.substring(0, 2)),
// MonthDay is of format MM-dd
private MonthDay parseMonthDay(String date) {
return MonthDay.of(Integer.parseInt(date.substring(0, 2)),
Integer.parseInt(date.substring(3, 5)));
if (monthDateOnly) {
return result.withYear(2001);
} else {
return result;
}
}
// LocalDat is of format YYYY-MM-dd
private LocalDate parseLocalDate(String date) {
return parseMonthDay(date.substring(5)).atYear(Integer.parseInt(date.substring(0, 4)));
}
private long toMillis(int year, int month, int day) {
return LocalDateTime.of(year, month, day, 0, 0, 0).atZone(ZoneId.systemDefault())
.toInstant().toEpochMilli();