1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 /**
25  * NetworkSpecifier object for cellular network request. Apps should use the
26  * {@link TelephonyNetworkSpecifier.Builder} class to create an instance.
27  */
28 public final class TelephonyNetworkSpecifier extends NetworkSpecifier implements Parcelable {
29 
30     private final int mSubId;
31 
32     /**
33      * Return the subscription Id of current TelephonyNetworkSpecifier object.
34      *
35      * @return The subscription id.
36      */
getSubscriptionId()37     public int getSubscriptionId() {
38         return mSubId;
39     }
40 
41     /**
42      * @hide
43      */
TelephonyNetworkSpecifier(int subId)44     public TelephonyNetworkSpecifier(int subId) {
45         this.mSubId = subId;
46     }
47 
48     public static final @NonNull Creator<TelephonyNetworkSpecifier> CREATOR =
49             new Creator<TelephonyNetworkSpecifier>() {
50                 @Override
51                 public TelephonyNetworkSpecifier createFromParcel(Parcel in) {
52                     int subId = in.readInt();
53                     return new TelephonyNetworkSpecifier(subId);
54                 }
55 
56                 @Override
57                 public TelephonyNetworkSpecifier[] newArray(int size) {
58                     return new TelephonyNetworkSpecifier[size];
59                 }
60             };
61 
62     @Override
describeContents()63     public int describeContents() {
64         return 0;
65     }
66 
67     @Override
writeToParcel(@onNull Parcel dest, int flags)68     public void writeToParcel(@NonNull Parcel dest, int flags) {
69         dest.writeInt(mSubId);
70     }
71 
72     @Override
hashCode()73     public int hashCode() {
74         return mSubId;
75     }
76 
77     @Override
equals(@ullable Object obj)78     public boolean equals(@Nullable Object obj) {
79         if (this == obj) {
80             return true;
81         }
82         if (!(obj instanceof TelephonyNetworkSpecifier)) {
83             return false;
84         }
85 
86         TelephonyNetworkSpecifier lhs = (TelephonyNetworkSpecifier) obj;
87         return mSubId == lhs.mSubId;
88     }
89 
90     @Override
toString()91     public String toString() {
92         return new StringBuilder()
93                 .append("TelephonyNetworkSpecifier [")
94                 .append("mSubId = ").append(mSubId)
95                 .append("]")
96                 .toString();
97     }
98 
99     /** @hide */
100     @Override
canBeSatisfiedBy(NetworkSpecifier other)101     public boolean canBeSatisfiedBy(NetworkSpecifier other) {
102         // Although the only caller, NetworkCapabilities, already handled the case of
103         // MatchAllNetworkSpecifier, we do it again here in case the API will be used by others.
104         // TODO(b/154959809): consider implementing bi-directional specifier instead.
105         return equals(other) || other instanceof MatchAllNetworkSpecifier;
106     }
107 
108 
109     /**
110      * Builder to create {@link TelephonyNetworkSpecifier} object.
111      */
112     public static final class Builder {
113         // Integer.MIN_VALUE which is not a valid subId, services as the sentinel to check if
114         // subId was set
115         private static final int SENTINEL_SUB_ID = Integer.MIN_VALUE;
116 
117         private int mSubId;
118 
Builder()119         public Builder() {
120             mSubId = SENTINEL_SUB_ID;
121         }
122 
123         /**
124          * Set the subscription id.
125          *
126          * @param subId The subscription Id.
127          * @return Instance of {@link Builder} to enable the chaining of the builder method.
128          */
setSubscriptionId(int subId)129         public @NonNull Builder setSubscriptionId(int subId) {
130             mSubId = subId;
131             return this;
132         }
133 
134         /**
135          * Create a NetworkSpecifier for the cellular network request.
136          *
137          * @return TelephonyNetworkSpecifier object.
138          * @throws IllegalArgumentException when subscription Id is not provided through
139          *         {@link #setSubscriptionId(int)}.
140          */
build()141         public @NonNull TelephonyNetworkSpecifier build() {
142             if (mSubId == SENTINEL_SUB_ID) {
143                 throw new IllegalArgumentException("Subscription Id is not provided.");
144             }
145             return new TelephonyNetworkSpecifier(mSubId);
146         }
147     }
148 }
149