1 /* 2 * Copyright (C) 2018 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.telephony; 18 19 import android.annotation.NonNull; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 import android.telephony.RadioAccessSpecifier; 23 24 import java.util.ArrayList; 25 import java.util.Arrays; 26 import java.util.List; 27 import java.util.Objects; 28 29 /** 30 * Defines available network information which includes corresponding subscription id, 31 * network plmns and corresponding priority to be used for network selection by Opportunistic 32 * Network Service when passed through {@link TelephonyManager#updateAvailableNetworks} 33 */ 34 public final class AvailableNetworkInfo implements Parcelable { 35 36 /* 37 * Defines number of priority level high. 38 */ 39 public static final int PRIORITY_HIGH = 1; 40 41 /* 42 * Defines number of priority level medium. 43 */ 44 public static final int PRIORITY_MED = 2; 45 46 /* 47 * Defines number of priority level low. 48 */ 49 public static final int PRIORITY_LOW = 3; 50 51 /** 52 * subscription Id of the available network. This value must be one of the entry retrieved from 53 * {@link SubscriptionManager#getOpportunisticSubscriptions} 54 */ 55 private int mSubId; 56 57 /** 58 * Priority for the subscription id. 59 * Priorities are in the range of {@link AvailableNetworkInfo#PRIORITY_LOW} to 60 * {@link AvailableNetworkInfo#PRIORITY_HIGH} 61 * Among all networks available after network scan, subId with highest priority is chosen 62 * for network selection. If there are more than one subId with highest priority then the 63 * network with highest RSRP is chosen. 64 */ 65 private int mPriority; 66 67 /** 68 * Describes the List of PLMN ids (MCC-MNC) associated with mSubId. 69 * Opportunistic Network Service will scan and verify specified PLMNs are available. 70 * If this entry is left empty, then the Opportunistic Network Service will not scan the network 71 * to validate the network availability. 72 */ 73 private ArrayList<String> mMccMncs; 74 75 /** 76 * Returns the frequency bands associated with the {@link #getMccMncs() MCC/MNCs}. 77 * Opportunistic network service will use these bands to scan. 78 * 79 * When no specific bands are specified (empty array or null) CBRS band 80 * {@link AccessNetworkConstants.EutranBand.BAND_48 81 * } will be used for network scan. 82 * 83 * See {@link AccessNetworkConstants} for details. 84 * 85 * @deprecated use {@link #mRadioAccessSpecifiers} instead 86 */ 87 @Deprecated 88 private ArrayList<Integer> mBands; 89 90 /** 91 * Returns a list of {@link RadioAccessSpecifier} associated with the available network. 92 * Opportunistic network service will use this to determine which bands to scan for. 93 * 94 * If this entry is left empty, {@link RadioAcccessSpecifier}s with {@link AccessNetworkType}s 95 * of {@link AccessNetworkConstants.AccessNetworkType.EUTRAN} and {@link 96 * AccessNetworkConstants.AccessNetworkType.NGRAN} with bands 48 and 71 on each will be assumed 97 * by Opportunistic network service. 98 */ 99 private ArrayList<RadioAccessSpecifier> mRadioAccessSpecifiers; 100 101 /** 102 * Return subscription Id of the available network. 103 * This value must be one of the entry retrieved from 104 * {@link SubscriptionManager#getOpportunisticSubscriptions} 105 * @return subscription id 106 */ getSubId()107 public int getSubId() { 108 return mSubId; 109 } 110 111 /** 112 * Return priority for the subscription id. 113 * Priorities are in the range of {@link AvailableNetworkInfo#PRIORITY_LOW} to 114 * {@link AvailableNetworkInfo#PRIORITY_HIGH} 115 * Among all networks available after network scan, subId with highest priority is chosen 116 * for network selection. If there are more than one subId with highest priority then the 117 * network with highest RSRP is chosen. 118 * @return priority level 119 */ getPriority()120 public int getPriority() { 121 return mPriority; 122 } 123 124 /** 125 * Return List of PLMN ids (MCC-MNC) associated with the sub ID. 126 * Opportunistic Network Service will scan and verify specified PLMNs are available. 127 * If this entry is left empty, then the Opportunistic Network Service will not scan the network 128 * to validate the network availability. 129 * @return list of PLMN ids 130 */ getMccMncs()131 public @NonNull List<String> getMccMncs() { 132 return (List<String>) mMccMncs.clone(); 133 } 134 135 /** 136 * Returns the frequency bands that need to be scanned by opportunistic network service 137 * 138 * The returned value is defined in either of {@link AccessNetworkConstants.GeranBand}, 139 * {@link AccessNetworkConstants.UtranBand} and {@link AccessNetworkConstants.EutranBand} 140 * See {@link AccessNetworkConstants.AccessNetworkType} for details regarding different network 141 * types. When no specific bands are specified (empty array or null) CBRS band 142 * {@link AccessNetworkConstants.EutranBand#BAND_48} will be used for network scan. 143 */ getBands()144 public @NonNull List<Integer> getBands() { 145 return (List<Integer>) mBands.clone(); 146 } 147 148 /** 149 * Returns a list of {@link RadioAccessSpecifier} associated with the available network. 150 * Opportunistic network service will use this to determine which bands to scan for. 151 * 152 * the returned value is one of {@link AccessNetworkConstants.AccessNetworkType}. When no 153 * specific access network type is specified, {@link RadioAccessSpecifier}s with {@link 154 * AccessNetworkType}s of {@link AccessNetworkConstants.AccessNetworkType.EUTRAN} and {@link 155 * AccessNetworkConstants.AccessNetworkType.NGRAN} with bands 48 and 71 on each will be assumed 156 * by Opportunistic network service. 157 * @return the access network type associated with the available network. 158 * @hide 159 */ getRadioAccessSpecifiers()160 public List<RadioAccessSpecifier> getRadioAccessSpecifiers() { 161 return (List<RadioAccessSpecifier>) mRadioAccessSpecifiers.clone(); 162 } 163 164 @Override describeContents()165 public int describeContents() { 166 return 0; 167 } 168 169 @Override writeToParcel(Parcel dest, int flags)170 public void writeToParcel(Parcel dest, int flags) { 171 dest.writeInt(mSubId); 172 dest.writeInt(mPriority); 173 dest.writeStringList(mMccMncs); 174 dest.writeList(mBands); 175 dest.writeList(mRadioAccessSpecifiers); 176 } 177 AvailableNetworkInfo(Parcel in)178 private AvailableNetworkInfo(Parcel in) { 179 mSubId = in.readInt(); 180 mPriority = in.readInt(); 181 mMccMncs = new ArrayList<>(); 182 in.readStringList(mMccMncs); 183 mBands = new ArrayList<>(); 184 in.readList(mBands, Integer.class.getClassLoader()); 185 mRadioAccessSpecifiers = new ArrayList<>(); 186 in.readList(mRadioAccessSpecifiers, RadioAccessSpecifier.class.getClassLoader()); 187 } 188 AvailableNetworkInfo(int subId, int priority, @NonNull List<String> mccMncs, @NonNull List<Integer> bands)189 public AvailableNetworkInfo(int subId, int priority, @NonNull List<String> mccMncs, 190 @NonNull List<Integer> bands) { 191 this(subId, priority, mccMncs, bands, 192 new ArrayList<RadioAccessSpecifier>()); 193 } 194 195 /** @hide */ AvailableNetworkInfo(int subId, int priority, @NonNull List<String> mccMncs, @NonNull List<Integer> bands, @NonNull List<RadioAccessSpecifier> radioAccessSpecifiers)196 private AvailableNetworkInfo(int subId, int priority, @NonNull List<String> mccMncs, 197 @NonNull List<Integer> bands, @NonNull List<RadioAccessSpecifier> 198 radioAccessSpecifiers) { 199 mSubId = subId; 200 mPriority = priority; 201 mMccMncs = new ArrayList<String>(mccMncs); 202 mBands = new ArrayList<Integer>(bands); 203 mRadioAccessSpecifiers = new ArrayList<RadioAccessSpecifier>(radioAccessSpecifiers); 204 } 205 206 @Override equals(Object o)207 public boolean equals(Object o) { 208 AvailableNetworkInfo ani; 209 210 try { 211 ani = (AvailableNetworkInfo) o; 212 } catch (ClassCastException ex) { 213 return false; 214 } 215 216 if (o == null) { 217 return false; 218 } 219 220 return (mSubId == ani.mSubId 221 && mPriority == ani.mPriority 222 && (((mMccMncs != null) 223 && mMccMncs.equals(ani.mMccMncs))) 224 && mBands.equals(ani.mBands)) 225 && mRadioAccessSpecifiers.equals(ani.getRadioAccessSpecifiers()); 226 } 227 228 @Override hashCode()229 public int hashCode() { 230 return Objects.hash(mSubId, mPriority, mMccMncs, mBands, mRadioAccessSpecifiers); 231 } 232 233 public static final @android.annotation.NonNull Parcelable.Creator<AvailableNetworkInfo> CREATOR = 234 new Creator<AvailableNetworkInfo>() { 235 @Override 236 public AvailableNetworkInfo createFromParcel(Parcel in) { 237 return new AvailableNetworkInfo(in); 238 } 239 240 @Override 241 public AvailableNetworkInfo[] newArray(int size) { 242 return new AvailableNetworkInfo[size]; 243 } 244 }; 245 246 @Override toString()247 public String toString() { 248 return ("AvailableNetworkInfo:" 249 + " mSubId: " + mSubId 250 + " mPriority: " + mPriority 251 + " mMccMncs: " + Arrays.toString(mMccMncs.toArray()) 252 + " mBands: " + Arrays.toString(mBands.toArray()) 253 + " mRadioAccessSpecifiers: " + Arrays.toString(mRadioAccessSpecifiers.toArray())); 254 } 255 256 /** 257 * Provides a convenient way to set the fields of a {@link AvailableNetworkInfo} when 258 * creating a new instance. 259 * 260 * <p>The example below shows how you might create a new {@code AvailableNetworkInfo}: 261 * 262 * <pre><code> 263 * 264 * AvailableNetworkInfo aNI = new AvailableNetworkInfo.Builder() 265 * .setSubId(1) 266 * .setPriority(AvailableNetworkInfo.PRIORITY_MED) 267 * .build(); 268 * </code></pre> 269 * 270 * @hide 271 */ 272 public static final class Builder { 273 private int mSubId = Integer.MIN_VALUE; 274 private int mPriority = AvailableNetworkInfo.PRIORITY_LOW; 275 private ArrayList<String> mMccMncs = new ArrayList<>(); 276 private ArrayList<Integer> mBands = new ArrayList<>(); 277 private ArrayList<RadioAccessSpecifier> mRadioAccessSpecifiers = new ArrayList<>(); 278 setSubId(int subId)279 public @NonNull Builder setSubId(int subId) { 280 mSubId = subId; 281 return this; 282 } 283 setPriority(int priority)284 public @NonNull Builder setPriority(int priority) { 285 if (priority > AvailableNetworkInfo.PRIORITY_LOW 286 || priority < AvailableNetworkInfo.PRIORITY_HIGH) { 287 throw new IllegalArgumentException("A valid priority must be set"); 288 } 289 mPriority = priority; 290 return this; 291 } 292 setMccMncs(@onNull ArrayList<String> mccMncs)293 public @NonNull Builder setMccMncs(@NonNull ArrayList<String> mccMncs) { 294 Objects.requireNonNull(mccMncs, "A non-null ArrayList of mccmncs must be set. An empty " 295 + "list is still accepted. Please read documentation in " 296 + "AvailableNetworkService to see consequences of an empty Arraylist."); 297 mMccMncs = mccMncs; 298 return this; 299 } 300 setRadioAccessSpecifiers( @onNull ArrayList<RadioAccessSpecifier> radioAccessSpecifiers)301 public @NonNull Builder setRadioAccessSpecifiers( 302 @NonNull ArrayList<RadioAccessSpecifier> radioAccessSpecifiers) { 303 Objects.requireNonNull(radioAccessSpecifiers, "A non-null ArrayList of " 304 + "RadioAccessSpecifiers must be set. An empty list is still accepted. Please " 305 + "read documentation in AvailableNetworkService to see consequences of an " 306 + "empty Arraylist."); 307 mRadioAccessSpecifiers = radioAccessSpecifiers; 308 return this; 309 } 310 build()311 public @NonNull AvailableNetworkInfo build() { 312 if (mSubId == Integer.MIN_VALUE) { 313 throw new IllegalArgumentException("A valid subId must be set"); 314 } 315 316 return new AvailableNetworkInfo(mSubId, mPriority, mMccMncs, mBands, 317 mRadioAccessSpecifiers); 318 } 319 } 320 } 321