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