153313d7e8153982f842910118371e1dc061248cdJeff Sharkey/* 253313d7e8153982f842910118371e1dc061248cdJeff Sharkey * Copyright (C) 2017 The Android Open Source Project 353313d7e8153982f842910118371e1dc061248cdJeff Sharkey * 453313d7e8153982f842910118371e1dc061248cdJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 553313d7e8153982f842910118371e1dc061248cdJeff Sharkey * you may not use this file except in compliance with the License. 653313d7e8153982f842910118371e1dc061248cdJeff Sharkey * You may obtain a copy of the License at 753313d7e8153982f842910118371e1dc061248cdJeff Sharkey * 853313d7e8153982f842910118371e1dc061248cdJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 953313d7e8153982f842910118371e1dc061248cdJeff Sharkey * 1053313d7e8153982f842910118371e1dc061248cdJeff Sharkey * Unless required by applicable law or agreed to in writing, software 1153313d7e8153982f842910118371e1dc061248cdJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 1253313d7e8153982f842910118371e1dc061248cdJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1353313d7e8153982f842910118371e1dc061248cdJeff Sharkey * See the License for the specific language governing permissions and 1453313d7e8153982f842910118371e1dc061248cdJeff Sharkey * limitations under the License. 1553313d7e8153982f842910118371e1dc061248cdJeff Sharkey */ 1653313d7e8153982f842910118371e1dc061248cdJeff Sharkey 1753313d7e8153982f842910118371e1dc061248cdJeff Sharkeypackage android.telephony; 1853313d7e8153982f842910118371e1dc061248cdJeff Sharkey 1953313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport android.annotation.BytesLong; 2053313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport android.annotation.CurrentTimeMillisLong; 2153313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport android.annotation.IntDef; 2217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport android.annotation.NonNull; 2353313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport android.annotation.Nullable; 24b7479988d248add39ba6ce1fe71dea6f810fd54fJeff Sharkeyimport android.annotation.SystemApi; 2553313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport android.os.Parcel; 2653313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport android.os.Parcelable; 270fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkeyimport android.util.Range; 2817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport android.util.RecurrenceRule; 2953313d7e8153982f842910118371e1dc061248cdJeff Sharkey 3017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport com.android.internal.util.Preconditions; 3153313d7e8153982f842910118371e1dc061248cdJeff Sharkey 3253313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport java.lang.annotation.Retention; 3353313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport java.lang.annotation.RetentionPolicy; 3417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.Period; 3553313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport java.time.ZonedDateTime; 3653313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport java.util.Iterator; 37003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkeyimport java.util.Objects; 3853313d7e8153982f842910118371e1dc061248cdJeff Sharkey 3917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey/** 4017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Description of a billing relationship plan between a carrier and a specific 4117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * subscriber. This information is used to present more useful UI to users, such 4217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * as explaining how much mobile data they have remaining, and what will happen 4317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * when they run out. 4417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 4517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List) 4617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @see SubscriptionManager#getSubscriptionPlans(int) 4717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 48b7479988d248add39ba6ce1fe71dea6f810fd54fJeff Sharkey@SystemApi 4953313d7e8153982f842910118371e1dc061248cdJeff Sharkeypublic final class SubscriptionPlan implements Parcelable { 5053313d7e8153982f842910118371e1dc061248cdJeff Sharkey /** {@hide} */ 5153313d7e8153982f842910118371e1dc061248cdJeff Sharkey @IntDef(prefix = "LIMIT_BEHAVIOR_", value = { 5253313d7e8153982f842910118371e1dc061248cdJeff Sharkey LIMIT_BEHAVIOR_UNKNOWN, 5353313d7e8153982f842910118371e1dc061248cdJeff Sharkey LIMIT_BEHAVIOR_DISABLED, 5453313d7e8153982f842910118371e1dc061248cdJeff Sharkey LIMIT_BEHAVIOR_BILLED, 5553313d7e8153982f842910118371e1dc061248cdJeff Sharkey LIMIT_BEHAVIOR_THROTTLED, 5653313d7e8153982f842910118371e1dc061248cdJeff Sharkey }) 5753313d7e8153982f842910118371e1dc061248cdJeff Sharkey @Retention(RetentionPolicy.SOURCE) 5853313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @interface LimitBehavior {} 5953313d7e8153982f842910118371e1dc061248cdJeff Sharkey 6017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** When a resource limit is hit, the behavior is unknown. */ 6153313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; 6217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** When a resource limit is hit, access is disabled. */ 6353313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static final int LIMIT_BEHAVIOR_DISABLED = 0; 6417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** When a resource limit is hit, the user is billed automatically. */ 6553313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static final int LIMIT_BEHAVIOR_BILLED = 1; 6617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** When a resource limit is hit, access is throttled to a slower rate. */ 6753313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static final int LIMIT_BEHAVIOR_THROTTLED = 2; 6853313d7e8153982f842910118371e1dc061248cdJeff Sharkey 6917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Value indicating a number of bytes is unknown. */ 7053313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static final long BYTES_UNKNOWN = -1; 7117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Value indicating a number of bytes is unlimited. */ 7217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public static final long BYTES_UNLIMITED = Long.MAX_VALUE; 7317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 7417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Value indicating a timestamp is unknown. */ 7553313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static final long TIME_UNKNOWN = -1; 7653313d7e8153982f842910118371e1dc061248cdJeff Sharkey 7717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey private final RecurrenceRule cycleRule; 7853313d7e8153982f842910118371e1dc061248cdJeff Sharkey private CharSequence title; 7953313d7e8153982f842910118371e1dc061248cdJeff Sharkey private CharSequence summary; 8053313d7e8153982f842910118371e1dc061248cdJeff Sharkey private long dataLimitBytes = BYTES_UNKNOWN; 8153313d7e8153982f842910118371e1dc061248cdJeff Sharkey private int dataLimitBehavior = LIMIT_BEHAVIOR_UNKNOWN; 8253313d7e8153982f842910118371e1dc061248cdJeff Sharkey private long dataUsageBytes = BYTES_UNKNOWN; 8353313d7e8153982f842910118371e1dc061248cdJeff Sharkey private long dataUsageTime = TIME_UNKNOWN; 8453313d7e8153982f842910118371e1dc061248cdJeff Sharkey 8517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey private SubscriptionPlan(RecurrenceRule cycleRule) { 8617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey this.cycleRule = Preconditions.checkNotNull(cycleRule); 8753313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 8853313d7e8153982f842910118371e1dc061248cdJeff Sharkey 8953313d7e8153982f842910118371e1dc061248cdJeff Sharkey private SubscriptionPlan(Parcel source) { 9017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey cycleRule = source.readParcelable(null); 9153313d7e8153982f842910118371e1dc061248cdJeff Sharkey title = source.readCharSequence(); 9253313d7e8153982f842910118371e1dc061248cdJeff Sharkey summary = source.readCharSequence(); 9353313d7e8153982f842910118371e1dc061248cdJeff Sharkey dataLimitBytes = source.readLong(); 9453313d7e8153982f842910118371e1dc061248cdJeff Sharkey dataLimitBehavior = source.readInt(); 9553313d7e8153982f842910118371e1dc061248cdJeff Sharkey dataUsageBytes = source.readLong(); 9653313d7e8153982f842910118371e1dc061248cdJeff Sharkey dataUsageTime = source.readLong(); 9753313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 9853313d7e8153982f842910118371e1dc061248cdJeff Sharkey 9953313d7e8153982f842910118371e1dc061248cdJeff Sharkey @Override 10053313d7e8153982f842910118371e1dc061248cdJeff Sharkey public int describeContents() { 10153313d7e8153982f842910118371e1dc061248cdJeff Sharkey return 0; 10253313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 10353313d7e8153982f842910118371e1dc061248cdJeff Sharkey 10453313d7e8153982f842910118371e1dc061248cdJeff Sharkey @Override 10553313d7e8153982f842910118371e1dc061248cdJeff Sharkey public void writeToParcel(Parcel dest, int flags) { 10617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey dest.writeParcelable(cycleRule, flags); 10753313d7e8153982f842910118371e1dc061248cdJeff Sharkey dest.writeCharSequence(title); 10853313d7e8153982f842910118371e1dc061248cdJeff Sharkey dest.writeCharSequence(summary); 10953313d7e8153982f842910118371e1dc061248cdJeff Sharkey dest.writeLong(dataLimitBytes); 11053313d7e8153982f842910118371e1dc061248cdJeff Sharkey dest.writeInt(dataLimitBehavior); 11153313d7e8153982f842910118371e1dc061248cdJeff Sharkey dest.writeLong(dataUsageBytes); 11253313d7e8153982f842910118371e1dc061248cdJeff Sharkey dest.writeLong(dataUsageTime); 11353313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 11453313d7e8153982f842910118371e1dc061248cdJeff Sharkey 11553313d7e8153982f842910118371e1dc061248cdJeff Sharkey @Override 11653313d7e8153982f842910118371e1dc061248cdJeff Sharkey public String toString() { 11717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new StringBuilder("SubscriptionPlan{") 11817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey .append("cycleRule=").append(cycleRule) 11953313d7e8153982f842910118371e1dc061248cdJeff Sharkey .append(" title=").append(title) 12053313d7e8153982f842910118371e1dc061248cdJeff Sharkey .append(" summary=").append(summary) 12153313d7e8153982f842910118371e1dc061248cdJeff Sharkey .append(" dataLimitBytes=").append(dataLimitBytes) 12253313d7e8153982f842910118371e1dc061248cdJeff Sharkey .append(" dataLimitBehavior=").append(dataLimitBehavior) 12353313d7e8153982f842910118371e1dc061248cdJeff Sharkey .append(" dataUsageBytes=").append(dataUsageBytes) 12453313d7e8153982f842910118371e1dc061248cdJeff Sharkey .append(" dataUsageTime=").append(dataUsageTime) 12517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey .append("}").toString(); 12653313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 12753313d7e8153982f842910118371e1dc061248cdJeff Sharkey 128003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey @Override 129003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey public int hashCode() { 130003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey return Objects.hash(cycleRule, title, summary, dataLimitBytes, dataLimitBehavior, 131003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey dataUsageBytes, dataUsageTime); 132003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey } 133003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey 134003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey @Override 135003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey public boolean equals(Object obj) { 136003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey if (obj instanceof SubscriptionPlan) { 137003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey final SubscriptionPlan other = (SubscriptionPlan) obj; 138003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey return Objects.equals(cycleRule, other.cycleRule) 139003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey && Objects.equals(title, other.title) 140003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey && Objects.equals(summary, other.summary) 141003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey && dataLimitBytes == other.dataLimitBytes 142003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey && dataLimitBehavior == other.dataLimitBehavior 143003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey && dataUsageBytes == other.dataUsageBytes 144003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey && dataUsageTime == other.dataUsageTime; 145003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey } 146003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey return false; 147003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey } 148003d3e61e6f6ed47e1d6301af302ce69557ba5faJeff Sharkey 14953313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static final Parcelable.Creator<SubscriptionPlan> CREATOR = new Parcelable.Creator<SubscriptionPlan>() { 15053313d7e8153982f842910118371e1dc061248cdJeff Sharkey @Override 15153313d7e8153982f842910118371e1dc061248cdJeff Sharkey public SubscriptionPlan createFromParcel(Parcel source) { 15253313d7e8153982f842910118371e1dc061248cdJeff Sharkey return new SubscriptionPlan(source); 15353313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 15453313d7e8153982f842910118371e1dc061248cdJeff Sharkey 15553313d7e8153982f842910118371e1dc061248cdJeff Sharkey @Override 15653313d7e8153982f842910118371e1dc061248cdJeff Sharkey public SubscriptionPlan[] newArray(int size) { 15753313d7e8153982f842910118371e1dc061248cdJeff Sharkey return new SubscriptionPlan[size]; 15853313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 15953313d7e8153982f842910118371e1dc061248cdJeff Sharkey }; 16053313d7e8153982f842910118371e1dc061248cdJeff Sharkey 16117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** {@hide} */ 16217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public @NonNull RecurrenceRule getCycleRule() { 16317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return cycleRule; 16453313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 16553313d7e8153982f842910118371e1dc061248cdJeff Sharkey 16617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Return the short title of this plan. */ 16753313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @Nullable CharSequence getTitle() { 16853313d7e8153982f842910118371e1dc061248cdJeff Sharkey return title; 16953313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 17053313d7e8153982f842910118371e1dc061248cdJeff Sharkey 17117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Return the short summary of this plan. */ 17253313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @Nullable CharSequence getSummary() { 17353313d7e8153982f842910118371e1dc061248cdJeff Sharkey return summary; 17453313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 17553313d7e8153982f842910118371e1dc061248cdJeff Sharkey 17617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 17717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return the usage threshold at which data access changes according to 17817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * {@link #getDataLimitBehavior()}. 17917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 18053313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @BytesLong long getDataLimitBytes() { 18153313d7e8153982f842910118371e1dc061248cdJeff Sharkey return dataLimitBytes; 18253313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 18353313d7e8153982f842910118371e1dc061248cdJeff Sharkey 18417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 18517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return the behavior of data access when usage reaches 18617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * {@link #getDataLimitBytes()}. 18717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 18853313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @LimitBehavior int getDataLimitBehavior() { 18953313d7e8153982f842910118371e1dc061248cdJeff Sharkey return dataLimitBehavior; 19053313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 19153313d7e8153982f842910118371e1dc061248cdJeff Sharkey 19217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 19317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return a snapshot of currently known mobile data usage at 19417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * {@link #getDataUsageTime()}. 19517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 19653313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @BytesLong long getDataUsageBytes() { 19753313d7e8153982f842910118371e1dc061248cdJeff Sharkey return dataUsageBytes; 19853313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 19953313d7e8153982f842910118371e1dc061248cdJeff Sharkey 20017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 20117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return the time at which {@link #getDataUsageBytes()} was valid. 20217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 20353313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @CurrentTimeMillisLong long getDataUsageTime() { 20453313d7e8153982f842910118371e1dc061248cdJeff Sharkey return dataUsageTime; 20553313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 20653313d7e8153982f842910118371e1dc061248cdJeff Sharkey 20753313d7e8153982f842910118371e1dc061248cdJeff Sharkey /** 20817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return an iterator that will return all valid data usage cycles based on 20917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * any recurrence rules. The iterator starts from the currently active cycle 21017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * and walks backwards through time. 21153313d7e8153982f842910118371e1dc061248cdJeff Sharkey */ 2120fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey public Iterator<Range<ZonedDateTime>> cycleIterator() { 21317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return cycleRule.cycleIterator(); 21453313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 21553313d7e8153982f842910118371e1dc061248cdJeff Sharkey 21617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 21717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Builder for a {@link SubscriptionPlan}. 21817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 21953313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static class Builder { 22053313d7e8153982f842910118371e1dc061248cdJeff Sharkey private final SubscriptionPlan plan; 22153313d7e8153982f842910118371e1dc061248cdJeff Sharkey 22217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** {@hide} */ 22317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public Builder(ZonedDateTime start, ZonedDateTime end, Period period) { 22417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey plan = new SubscriptionPlan(new RecurrenceRule(start, end, period)); 22553313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 22653313d7e8153982f842910118371e1dc061248cdJeff Sharkey 22717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 22817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Start defining a {@link SubscriptionPlan} that covers a very specific 22917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * window of time, and never automatically recurs. 2300fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * 2310fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * @param start The exact time at which the plan starts. 2320fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * @param end The exact time at which the plan ends. 23317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 23453313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static Builder createNonrecurring(ZonedDateTime start, ZonedDateTime end) { 23553313d7e8153982f842910118371e1dc061248cdJeff Sharkey if (!end.isAfter(start)) { 23653313d7e8153982f842910118371e1dc061248cdJeff Sharkey throw new IllegalArgumentException( 23753313d7e8153982f842910118371e1dc061248cdJeff Sharkey "End " + end + " isn't after start " + start); 23853313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 23917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new Builder(start, end, null); 24053313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 24153313d7e8153982f842910118371e1dc061248cdJeff Sharkey 24217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 2430fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * Start defining a {@link SubscriptionPlan} that starts at a specific 2440fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * time, and automatically recurs after each specific period of time, 2450fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * repeating indefinitely. 2460fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * <p> 2470fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * When the given period is set to exactly one month, the plan will 2480fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * always recur on the day of the month defined by 2490fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * {@link ZonedDateTime#getDayOfMonth()}. When a particular month ends 2500fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * before this day, the plan will recur on the last possible instant of 2510fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * that month. 2520fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * 2530fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * @param start The exact time at which the plan starts. 2540fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey * @param period The period after which the plan automatically recurs. 25517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 2560fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey public static Builder createRecurring(ZonedDateTime start, Period period) { 2570a5570d49df7d438b618616e439192f3c216cfe8Jeff Sharkey if (period.isZero() || period.isNegative()) { 2580a5570d49df7d438b618616e439192f3c216cfe8Jeff Sharkey throw new IllegalArgumentException("Period " + period + " must be positive"); 2590a5570d49df7d438b618616e439192f3c216cfe8Jeff Sharkey } 2600fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey return new Builder(start, null, period); 2610fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey } 2620fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey 2630fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey /** {@hide} */ 2640fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey @SystemApi 2650fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey @Deprecated 26653313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static Builder createRecurringMonthly(ZonedDateTime start) { 26717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new Builder(start, null, Period.ofMonths(1)); 26853313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 26953313d7e8153982f842910118371e1dc061248cdJeff Sharkey 2700fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey /** {@hide} */ 2710fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey @SystemApi 2720fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey @Deprecated 27353313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static Builder createRecurringWeekly(ZonedDateTime start) { 27417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new Builder(start, null, Period.ofDays(7)); 27553313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 27653313d7e8153982f842910118371e1dc061248cdJeff Sharkey 2770fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey /** {@hide} */ 2780fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey @SystemApi 2790fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey @Deprecated 28053313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static Builder createRecurringDaily(ZonedDateTime start) { 28117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new Builder(start, null, Period.ofDays(1)); 28253313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 28353313d7e8153982f842910118371e1dc061248cdJeff Sharkey 28453313d7e8153982f842910118371e1dc061248cdJeff Sharkey public SubscriptionPlan build() { 28553313d7e8153982f842910118371e1dc061248cdJeff Sharkey return plan; 28653313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 28753313d7e8153982f842910118371e1dc061248cdJeff Sharkey 28817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Set the short title of this plan. */ 28953313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Builder setTitle(@Nullable CharSequence title) { 29053313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.title = title; 29153313d7e8153982f842910118371e1dc061248cdJeff Sharkey return this; 29253313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 29353313d7e8153982f842910118371e1dc061248cdJeff Sharkey 29417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Set the short summary of this plan. */ 29553313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Builder setSummary(@Nullable CharSequence summary) { 29653313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.summary = summary; 29753313d7e8153982f842910118371e1dc061248cdJeff Sharkey return this; 29853313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 29953313d7e8153982f842910118371e1dc061248cdJeff Sharkey 30017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 30117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Set the usage threshold at which data access changes. 30217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 30317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @param dataLimitBytes the usage threshold at which data access 30417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * changes 30517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @param dataLimitBehavior the behavior of data access when usage 30617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * reaches the threshold 30717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 30853313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Builder setDataLimit(@BytesLong long dataLimitBytes, 30953313d7e8153982f842910118371e1dc061248cdJeff Sharkey @LimitBehavior int dataLimitBehavior) { 31017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (dataLimitBytes < 0) { 31117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey throw new IllegalArgumentException("Limit bytes must be positive"); 31217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 31317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (dataLimitBehavior < 0) { 31417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey throw new IllegalArgumentException("Limit behavior must be defined"); 31553313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 31653313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.dataLimitBytes = dataLimitBytes; 31753313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.dataLimitBehavior = dataLimitBehavior; 31853313d7e8153982f842910118371e1dc061248cdJeff Sharkey return this; 31953313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 32053313d7e8153982f842910118371e1dc061248cdJeff Sharkey 32117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 32217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Set a snapshot of currently known mobile data usage. 32317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 32417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @param dataUsageBytes the currently known mobile data usage 32517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @param dataUsageTime the time at which this snapshot was valid 32617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 32753313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Builder setDataUsage(@BytesLong long dataUsageBytes, 32853313d7e8153982f842910118371e1dc061248cdJeff Sharkey @CurrentTimeMillisLong long dataUsageTime) { 32917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (dataUsageBytes < 0) { 33017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey throw new IllegalArgumentException("Usage bytes must be positive"); 33153313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 33217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (dataUsageTime < 0) { 33317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey throw new IllegalArgumentException("Usage time must be positive"); 33453313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 33553313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.dataUsageBytes = dataUsageBytes; 33653313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.dataUsageTime = dataUsageTime; 33753313d7e8153982f842910118371e1dc061248cdJeff Sharkey return this; 33853313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 33953313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 34053313d7e8153982f842910118371e1dc061248cdJeff Sharkey} 341