Merge "API council requested tweaks to SubscriptionPlan." into pi-dev

This commit is contained in:
Jeff Sharkey
2018-04-09 23:20:43 +00:00
committed by Android (Google) Code Review
13 changed files with 111 additions and 68 deletions

View File

@@ -42405,7 +42405,7 @@ package android.telephony {
}
public final class SubscriptionPlan implements android.os.Parcelable {
method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
method public int describeContents();
method public int getDataLimitBehavior();
method public long getDataLimitBytes();
@@ -42427,9 +42427,7 @@ package android.telephony {
public static class SubscriptionPlan.Builder {
method public android.telephony.SubscriptionPlan build();
method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);

View File

@@ -5191,7 +5191,7 @@ package android.telephony {
}
public final class SubscriptionPlan implements android.os.Parcelable {
method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
method public int describeContents();
method public int getDataLimitBehavior();
method public long getDataLimitBytes();
@@ -5213,9 +5213,10 @@ package android.telephony {
public static class SubscriptionPlan.Builder {
method public android.telephony.SubscriptionPlan build();
method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);

View File

@@ -19,7 +19,7 @@ package android.net;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.BackupUtils;
import android.util.Pair;
import android.util.Range;
import android.util.RecurrenceRule;
import com.android.internal.util.Preconditions;
@@ -136,7 +136,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
return 0;
}
public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
public Iterator<Range<ZonedDateTime>> cycleIterator() {
return cycleRule.cycleIterator();
}

View File

@@ -31,6 +31,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.DebugUtils;
import android.util.Pair;
import android.util.Range;
import com.google.android.collect.Sets;
@@ -258,8 +259,21 @@ public class NetworkPolicyManager {
}
/** {@hide} */
@Deprecated
public static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(NetworkPolicy policy) {
return policy.cycleIterator();
final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
return new Iterator<Pair<ZonedDateTime, ZonedDateTime>>() {
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public Pair<ZonedDateTime, ZonedDateTime> next() {
final Range<ZonedDateTime> r = it.next();
return Pair.create(r.getLower(), r.getUpper());
}
};
}
/**

View File

@@ -158,7 +158,7 @@ public class RecurrenceRule implements Parcelable {
&& period.getDays() == 0;
}
public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
public Iterator<Range<ZonedDateTime>> cycleIterator() {
if (period != null) {
return new RecurringIterator();
} else {
@@ -166,7 +166,7 @@ public class RecurrenceRule implements Parcelable {
}
}
private class NonrecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
private class NonrecurringIterator implements Iterator<Range<ZonedDateTime>> {
boolean hasNext;
public NonrecurringIterator() {
@@ -179,13 +179,13 @@ public class RecurrenceRule implements Parcelable {
}
@Override
public Pair<ZonedDateTime, ZonedDateTime> next() {
public Range<ZonedDateTime> next() {
hasNext = false;
return new Pair<>(start, end);
return new Range<>(start, end);
}
}
private class RecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
private class RecurringIterator implements Iterator<Range<ZonedDateTime>> {
int i;
ZonedDateTime cycleStart;
ZonedDateTime cycleEnd;
@@ -231,12 +231,12 @@ public class RecurrenceRule implements Parcelable {
}
@Override
public Pair<ZonedDateTime, ZonedDateTime> next() {
public Range<ZonedDateTime> next() {
if (LOGD) Log.d(TAG, "Cycle " + i + " from " + cycleStart + " to " + cycleEnd);
Pair<ZonedDateTime, ZonedDateTime> p = new Pair<>(cycleStart, cycleEnd);
Range<ZonedDateTime> r = new Range<>(cycleStart, cycleEnd);
i--;
updateCycle();
return p;
return r;
}
}

View File

@@ -487,6 +487,7 @@
<protected-broadcast android:name="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" />
<protected-broadcast android:name="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED" />
<protected-broadcast android:name="android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION" />
<protected-broadcast android:name="android.telephony.action.SUBSCRIPTION_PLANS_CHANGED" />
<protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" />
<protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" />

View File

@@ -57,13 +57,13 @@ public class RecurrenceRuleTest extends TestCase {
assertTrue(r.isMonthly());
final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
assertTrue(it.hasNext());
assertEquals(Pair.create(
assertEquals(new Range<>(
ZonedDateTime.parse("2015-11-14T00:00:00.00Z"),
ZonedDateTime.parse("2015-12-14T00:00:00.00Z")), it.next());
assertTrue(it.hasNext());
assertEquals(Pair.create(
assertEquals(new Range<>(
ZonedDateTime.parse("2015-10-14T00:00:00.00Z"),
ZonedDateTime.parse("2015-11-14T00:00:00.00Z")), it.next());
}
@@ -77,13 +77,13 @@ public class RecurrenceRuleTest extends TestCase {
assertFalse(r.isMonthly());
final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
assertTrue(it.hasNext());
assertEquals(Pair.create(
assertEquals(new Range<>(
ZonedDateTime.parse("2010-11-17T00:11:00.00Z"),
ZonedDateTime.parse("2010-11-20T00:11:00.00Z")), it.next());
assertTrue(it.hasNext());
assertEquals(Pair.create(
assertEquals(new Range<>(
ZonedDateTime.parse("2010-11-14T00:11:00.00Z"),
ZonedDateTime.parse("2010-11-17T00:11:00.00Z")), it.next());
assertFalse(it.hasNext());
@@ -98,9 +98,9 @@ public class RecurrenceRuleTest extends TestCase {
assertFalse(r.isMonthly());
final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
assertTrue(it.hasNext());
assertEquals(Pair.create(
assertEquals(new Range<>(
ZonedDateTime.parse("2010-11-14T00:11:00.000Z"),
ZonedDateTime.parse("2010-11-20T00:11:00.000Z")), it.next());
assertFalse(it.hasNext());
@@ -112,7 +112,7 @@ public class RecurrenceRuleTest extends TestCase {
assertFalse(r.isMonthly());
final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
assertFalse(it.hasNext());
}
@@ -122,22 +122,22 @@ public class RecurrenceRuleTest extends TestCase {
ZonedDateTime.parse("2030-01-31T00:00:00.000Z"),
Period.ofMonths(1));
final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
ZonedDateTime lastStart = null;
int months = 0;
while (it.hasNext()) {
final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
final Range<ZonedDateTime> cycle = it.next();
// Make sure cycle has reasonable length
final long length = cycle.second.toEpochSecond() - cycle.first.toEpochSecond();
final long length = cycle.getUpper().toEpochSecond() - cycle.getLower().toEpochSecond();
assertTrue(cycle + " must be more than 4 weeks", length >= 2419200);
assertTrue(cycle + " must be less than 5 weeks", length <= 3024000);
// Make sure we have no gaps
if (lastStart != null) {
assertEquals(lastStart, cycle.second);
assertEquals(lastStart, cycle.getUpper());
}
lastStart = cycle.first;
lastStart = cycle.getLower();
months++;
}

View File

@@ -57,6 +57,7 @@ import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.DebugUtils;
import android.util.Pair;
import android.util.Range;
import android.util.Slog;
import com.android.internal.R;
@@ -266,9 +267,9 @@ public class MultipathPolicyTracker {
}
private long getRemainingDailyBudget(long limitBytes,
Pair<ZonedDateTime, ZonedDateTime> cycle) {
final long start = cycle.first.toInstant().toEpochMilli();
final long end = cycle.second.toInstant().toEpochMilli();
Range<ZonedDateTime> cycle) {
final long start = cycle.getLower().toInstant().toEpochMilli();
final long end = cycle.getUpper().toInstant().toEpochMilli();
final long totalBytes = getNetworkTotalBytes(start, end);
final long remainingBytes = totalBytes == -1 ? 0 : Math.max(0, limitBytes - totalBytes);
// 1 + ((end - now - 1) / millisInDay with integers is equivalent to:
@@ -389,7 +390,7 @@ public class MultipathPolicyTracker {
private static boolean hasActiveCycle(NetworkPolicy policy) {
return policy.hasCycle() && policy.lastLimitSnooze <
policy.cycleIterator().next().first.toInstant().toEpochMilli();
policy.cycleIterator().next().getLower().toInstant().toEpochMilli();
}
// Only ever updated on the handler thread. Accessed from other binder threads to retrieve

View File

@@ -195,6 +195,7 @@ import android.util.AtomicFile;
import android.util.DataUnit;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
import android.util.RecurrenceRule;
import android.util.Slog;
import android.util.SparseArray;
@@ -1777,11 +1778,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
quotaBytes = quotaUnlimited;
} else {
// Limited data; let's only use 10% of remaining budget
final Pair<ZonedDateTime, ZonedDateTime> cycle = plan.cycleIterator().next();
final long start = cycle.first.toInstant().toEpochMilli();
final long end = cycle.second.toInstant().toEpochMilli();
final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
final long start = cycle.getLower().toInstant().toEpochMilli();
final long end = cycle.getUpper().toInstant().toEpochMilli();
final Instant now = mClock.instant();
final long startOfDay = ZonedDateTime.ofInstant(now, cycle.first.getZone())
final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone())
.truncatedTo(ChronoUnit.DAYS)
.toInstant().toEpochMilli();
final long totalBytes = getTotalBytes(

View File

@@ -47,7 +47,7 @@ import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.IntArray;
import android.util.MathUtils;
import android.util.Pair;
import android.util.Range;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -266,11 +266,11 @@ public class NetworkStatsCollection implements FileRotator.Reader {
long collectEnd = end;
if (augmentEnd != SubscriptionPlan.TIME_UNKNOWN) {
final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = augmentPlan.cycleIterator();
final Iterator<Range<ZonedDateTime>> it = augmentPlan.cycleIterator();
while (it.hasNext()) {
final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
final long cycleStart = cycle.first.toInstant().toEpochMilli();
final long cycleEnd = cycle.second.toInstant().toEpochMilli();
final Range<ZonedDateTime> cycle = it.next();
final long cycleStart = cycle.getLower().toInstant().toEpochMilli();
final long cycleEnd = cycle.getUpper().toInstant().toEpochMilli();
if (cycleStart <= augmentEnd && augmentEnd < cycleEnd) {
augmentStart = cycleStart;
collectStart = Long.min(collectStart, augmentStart);

View File

@@ -121,7 +121,7 @@ import android.text.TextUtils;
import android.text.format.Time;
import android.util.DataUnit;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
import android.util.RecurrenceRule;
import com.android.internal.telephony.PhoneConstants;
@@ -821,11 +821,11 @@ public class NetworkPolicyManagerServiceTest {
private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
ZoneId.systemDefault());
final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = policy.cycleIterator();
final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
while (it.hasNext()) {
final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
if (cycle.first.toInstant().toEpochMilli() < currentTime) {
return cycle.first.toInstant().toEpochMilli();
final Range<ZonedDateTime> cycle = it.next();
if (cycle.getLower().toInstant().toEpochMilli() < currentTime) {
return cycle.getLower().toInstant().toEpochMilli();
}
}
throw new IllegalStateException(
@@ -835,7 +835,7 @@ public class NetworkPolicyManagerServiceTest {
private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
ZoneId.systemDefault());
return policy.cycleIterator().next().second.toInstant().toEpochMilli();
return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli();
}
@Test

View File

@@ -477,6 +477,9 @@ public class SubscriptionManager {
* <p>
* Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
* the user is interested in.
* <p>
* Receivers should protect themselves by checking that the sender holds the
* {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@SystemApi
@@ -1719,6 +1722,8 @@ public class SubscriptionManager {
* </ul>
*
* @param subId the subscriber this relationship applies to
* @throws SecurityException if the caller doesn't meet the requirements
* outlined above.
*/
@SystemApi
public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
@@ -1744,10 +1749,13 @@ public class SubscriptionManager {
* {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
* </ul>
*
* @param subId the subscriber this relationship applies to
* @param subId the subscriber this relationship applies to. An empty list
* may be sent to clear any existing plans.
* @param plans the list of plans. The first plan is always the primary and
* most important plan. Any additional plans are secondary and
* may not be displayed or used by decision making logic.
* @throws SecurityException if the caller doesn't meet the requirements
* outlined above.
*/
@SystemApi
public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
@@ -1788,6 +1796,8 @@ public class SubscriptionManager {
* be automatically cleared, or {@code 0} to leave in the
* requested state until explicitly cleared, or the next reboot,
* whichever happens first.
* @throws SecurityException if the caller doesn't meet the requirements
* outlined above.
*/
@SystemApi
public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
@@ -1822,6 +1832,8 @@ public class SubscriptionManager {
* be automatically cleared, or {@code 0} to leave in the
* requested state until explicitly cleared, or the next reboot,
* whichever happens first.
* @throws SecurityException if the caller doesn't meet the requirements
* outlined above.
*/
@SystemApi
public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,

View File

@@ -24,7 +24,7 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Pair;
import android.util.Range;
import android.util.RecurrenceRule;
import com.android.internal.util.Preconditions;
@@ -209,7 +209,7 @@ public final class SubscriptionPlan implements Parcelable {
* any recurrence rules. The iterator starts from the currently active cycle
* and walks backwards through time.
*/
public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
public Iterator<Range<ZonedDateTime>> cycleIterator() {
return cycleRule.cycleIterator();
}
@@ -227,6 +227,9 @@ public final class SubscriptionPlan implements Parcelable {
/**
* Start defining a {@link SubscriptionPlan} that covers a very specific
* window of time, and never automatically recurs.
*
* @param start The exact time at which the plan starts.
* @param end The exact time at which the plan ends.
*/
public static Builder createNonrecurring(ZonedDateTime start, ZonedDateTime end) {
if (!end.isAfter(start)) {
@@ -237,28 +240,40 @@ public final class SubscriptionPlan implements Parcelable {
}
/**
* Start defining a {@link SubscriptionPlan} that will recur
* automatically every month. It will always recur on the same day of a
* particular month. When a particular month ends before the defined
* recurrence day, the plan will recur on the last instant of that
* month.
* Start defining a {@link SubscriptionPlan} that starts at a specific
* time, and automatically recurs after each specific period of time,
* repeating indefinitely.
* <p>
* When the given period is set to exactly one month, the plan will
* always recur on the day of the month defined by
* {@link ZonedDateTime#getDayOfMonth()}. When a particular month ends
* before this day, the plan will recur on the last possible instant of
* that month.
*
* @param start The exact time at which the plan starts.
* @param period The period after which the plan automatically recurs.
*/
public static Builder createRecurring(ZonedDateTime start, Period period) {
return new Builder(start, null, period);
}
/** {@hide} */
@SystemApi
@Deprecated
public static Builder createRecurringMonthly(ZonedDateTime start) {
return new Builder(start, null, Period.ofMonths(1));
}
/**
* Start defining a {@link SubscriptionPlan} that will recur
* automatically every week.
*/
/** {@hide} */
@SystemApi
@Deprecated
public static Builder createRecurringWeekly(ZonedDateTime start) {
return new Builder(start, null, Period.ofDays(7));
}
/**
* Start defining a {@link SubscriptionPlan} that will recur
* automatically every day.
*/
/** {@hide} */
@SystemApi
@Deprecated
public static Builder createRecurringDaily(ZonedDateTime start) {
return new Builder(start, null, Period.ofDays(1));
}