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; 2753313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport android.util.Pair; 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; 3753313d7e8153982f842910118371e1dc061248cdJeff Sharkey 3817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey/** 3917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Description of a billing relationship plan between a carrier and a specific 4017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * subscriber. This information is used to present more useful UI to users, such 4117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * as explaining how much mobile data they have remaining, and what will happen 4217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * when they run out. 4317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 4417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List) 4517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @see SubscriptionManager#getSubscriptionPlans(int) 46b7479988d248add39ba6ce1fe71dea6f810fd54fJeff Sharkey * @hide 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 12853313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static final Parcelable.Creator<SubscriptionPlan> CREATOR = new Parcelable.Creator<SubscriptionPlan>() { 12953313d7e8153982f842910118371e1dc061248cdJeff Sharkey @Override 13053313d7e8153982f842910118371e1dc061248cdJeff Sharkey public SubscriptionPlan createFromParcel(Parcel source) { 13153313d7e8153982f842910118371e1dc061248cdJeff Sharkey return new SubscriptionPlan(source); 13253313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 13353313d7e8153982f842910118371e1dc061248cdJeff Sharkey 13453313d7e8153982f842910118371e1dc061248cdJeff Sharkey @Override 13553313d7e8153982f842910118371e1dc061248cdJeff Sharkey public SubscriptionPlan[] newArray(int size) { 13653313d7e8153982f842910118371e1dc061248cdJeff Sharkey return new SubscriptionPlan[size]; 13753313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 13853313d7e8153982f842910118371e1dc061248cdJeff Sharkey }; 13953313d7e8153982f842910118371e1dc061248cdJeff Sharkey 14017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** {@hide} */ 14117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public @NonNull RecurrenceRule getCycleRule() { 14217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return cycleRule; 14353313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 14453313d7e8153982f842910118371e1dc061248cdJeff Sharkey 14517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Return the short title of this plan. */ 14653313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @Nullable CharSequence getTitle() { 14753313d7e8153982f842910118371e1dc061248cdJeff Sharkey return title; 14853313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 14953313d7e8153982f842910118371e1dc061248cdJeff Sharkey 15017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Return the short summary of this plan. */ 15153313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @Nullable CharSequence getSummary() { 15253313d7e8153982f842910118371e1dc061248cdJeff Sharkey return summary; 15353313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 15453313d7e8153982f842910118371e1dc061248cdJeff Sharkey 15517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 15617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return the usage threshold at which data access changes according to 15717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * {@link #getDataLimitBehavior()}. 15817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 15953313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @BytesLong long getDataLimitBytes() { 16053313d7e8153982f842910118371e1dc061248cdJeff Sharkey return dataLimitBytes; 16153313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 16253313d7e8153982f842910118371e1dc061248cdJeff Sharkey 16317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 16417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return the behavior of data access when usage reaches 16517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * {@link #getDataLimitBytes()}. 16617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 16753313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @LimitBehavior int getDataLimitBehavior() { 16853313d7e8153982f842910118371e1dc061248cdJeff Sharkey return dataLimitBehavior; 16953313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 17053313d7e8153982f842910118371e1dc061248cdJeff Sharkey 17117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 17217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return a snapshot of currently known mobile data usage at 17317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * {@link #getDataUsageTime()}. 17417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 17553313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @BytesLong long getDataUsageBytes() { 17653313d7e8153982f842910118371e1dc061248cdJeff Sharkey return dataUsageBytes; 17753313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 17853313d7e8153982f842910118371e1dc061248cdJeff Sharkey 17917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 18017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return the time at which {@link #getDataUsageBytes()} was valid. 18117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 18253313d7e8153982f842910118371e1dc061248cdJeff Sharkey public @CurrentTimeMillisLong long getDataUsageTime() { 18353313d7e8153982f842910118371e1dc061248cdJeff Sharkey return dataUsageTime; 18453313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 18553313d7e8153982f842910118371e1dc061248cdJeff Sharkey 18653313d7e8153982f842910118371e1dc061248cdJeff Sharkey /** 18717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Return an iterator that will return all valid data usage cycles based on 18817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * any recurrence rules. The iterator starts from the currently active cycle 18917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * and walks backwards through time. 19053313d7e8153982f842910118371e1dc061248cdJeff Sharkey */ 19153313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() { 19217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return cycleRule.cycleIterator(); 19353313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 19453313d7e8153982f842910118371e1dc061248cdJeff Sharkey 19517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 19617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Builder for a {@link SubscriptionPlan}. 19717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 19853313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static class Builder { 19953313d7e8153982f842910118371e1dc061248cdJeff Sharkey private final SubscriptionPlan plan; 20053313d7e8153982f842910118371e1dc061248cdJeff Sharkey 20117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** {@hide} */ 20217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public Builder(ZonedDateTime start, ZonedDateTime end, Period period) { 20317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey plan = new SubscriptionPlan(new RecurrenceRule(start, end, period)); 20453313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 20553313d7e8153982f842910118371e1dc061248cdJeff Sharkey 20617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 20717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Start defining a {@link SubscriptionPlan} that covers a very specific 20817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * window of time, and never automatically recurs. 20917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 21053313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static Builder createNonrecurring(ZonedDateTime start, ZonedDateTime end) { 21153313d7e8153982f842910118371e1dc061248cdJeff Sharkey if (!end.isAfter(start)) { 21253313d7e8153982f842910118371e1dc061248cdJeff Sharkey throw new IllegalArgumentException( 21353313d7e8153982f842910118371e1dc061248cdJeff Sharkey "End " + end + " isn't after start " + start); 21453313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 21517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new Builder(start, end, null); 21653313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 21753313d7e8153982f842910118371e1dc061248cdJeff Sharkey 21817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 21917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Start defining a {@link SubscriptionPlan} that will recur 22017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * automatically every month. It will always recur on the same day of a 22117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * particular month. When a particular month ends before the defined 22217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * recurrence day, the plan will recur on the last instant of that 22317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * month. 22417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 22553313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static Builder createRecurringMonthly(ZonedDateTime start) { 22617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new Builder(start, null, Period.ofMonths(1)); 22753313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 22853313d7e8153982f842910118371e1dc061248cdJeff Sharkey 22917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 23017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Start defining a {@link SubscriptionPlan} that will recur 23117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * automatically every week. 23217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 23353313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static Builder createRecurringWeekly(ZonedDateTime start) { 23417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new Builder(start, null, Period.ofDays(7)); 23553313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 23653313d7e8153982f842910118371e1dc061248cdJeff Sharkey 23717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 23817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Start defining a {@link SubscriptionPlan} that will recur 23917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * automatically every day. 24017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 24153313d7e8153982f842910118371e1dc061248cdJeff Sharkey public static Builder createRecurringDaily(ZonedDateTime start) { 24217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey return new Builder(start, null, Period.ofDays(1)); 24353313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 24453313d7e8153982f842910118371e1dc061248cdJeff Sharkey 24553313d7e8153982f842910118371e1dc061248cdJeff Sharkey public SubscriptionPlan build() { 24653313d7e8153982f842910118371e1dc061248cdJeff Sharkey return plan; 24753313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 24853313d7e8153982f842910118371e1dc061248cdJeff Sharkey 24917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Set the short title of this plan. */ 25053313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Builder setTitle(@Nullable CharSequence title) { 25153313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.title = title; 25253313d7e8153982f842910118371e1dc061248cdJeff Sharkey return this; 25353313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 25453313d7e8153982f842910118371e1dc061248cdJeff Sharkey 25517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** Set the short summary of this plan. */ 25653313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Builder setSummary(@Nullable CharSequence summary) { 25753313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.summary = summary; 25853313d7e8153982f842910118371e1dc061248cdJeff Sharkey return this; 25953313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 26053313d7e8153982f842910118371e1dc061248cdJeff Sharkey 26117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 26217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Set the usage threshold at which data access changes. 26317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 26417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @param dataLimitBytes the usage threshold at which data access 26517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * changes 26617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @param dataLimitBehavior the behavior of data access when usage 26717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * reaches the threshold 26817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 26953313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Builder setDataLimit(@BytesLong long dataLimitBytes, 27053313d7e8153982f842910118371e1dc061248cdJeff Sharkey @LimitBehavior int dataLimitBehavior) { 27117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (dataLimitBytes < 0) { 27217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey throw new IllegalArgumentException("Limit bytes must be positive"); 27317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 27417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (dataLimitBehavior < 0) { 27517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey throw new IllegalArgumentException("Limit behavior must be defined"); 27653313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 27753313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.dataLimitBytes = dataLimitBytes; 27853313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.dataLimitBehavior = dataLimitBehavior; 27953313d7e8153982f842910118371e1dc061248cdJeff Sharkey return this; 28053313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 28153313d7e8153982f842910118371e1dc061248cdJeff Sharkey 28217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey /** 28317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Set a snapshot of currently known mobile data usage. 28417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 28517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @param dataUsageBytes the currently known mobile data usage 28617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * @param dataUsageTime the time at which this snapshot was valid 28717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 28853313d7e8153982f842910118371e1dc061248cdJeff Sharkey public Builder setDataUsage(@BytesLong long dataUsageBytes, 28953313d7e8153982f842910118371e1dc061248cdJeff Sharkey @CurrentTimeMillisLong long dataUsageTime) { 29017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (dataUsageBytes < 0) { 29117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey throw new IllegalArgumentException("Usage bytes must be positive"); 29253313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 29317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (dataUsageTime < 0) { 29417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey throw new IllegalArgumentException("Usage time must be positive"); 29553313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 29653313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.dataUsageBytes = dataUsageBytes; 29753313d7e8153982f842910118371e1dc061248cdJeff Sharkey plan.dataUsageTime = dataUsageTime; 29853313d7e8153982f842910118371e1dc061248cdJeff Sharkey return this; 29953313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 30053313d7e8153982f842910118371e1dc061248cdJeff Sharkey } 30153313d7e8153982f842910118371e1dc061248cdJeff Sharkey} 302