1 /* 2 * Copyright 2019 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.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SuppressLint; 23 import android.annotation.SystemApi; 24 import android.annotation.TestApi; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 import android.util.SparseArray; 28 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.util.Objects; 32 33 /** 34 * Provides the barring configuration for a particular service type. 35 * 36 * Provides indication about the barring of a particular service for use. Certain barring types 37 * are only valid for certain technology families. Any service that does not have a barring 38 * configuration is unbarred by default. 39 */ 40 public final class BarringInfo implements Parcelable { 41 42 /** 43 * Barring Service Type 44 * 45 * @hide 46 */ 47 @Retention(RetentionPolicy.SOURCE) 48 @IntDef(prefix = "BARRING_SERVICE_TYPE_", value = { 49 BARRING_SERVICE_TYPE_CS_SERVICE, 50 BARRING_SERVICE_TYPE_PS_SERVICE, 51 BARRING_SERVICE_TYPE_CS_VOICE, 52 BARRING_SERVICE_TYPE_MO_SIGNALLING, 53 BARRING_SERVICE_TYPE_MO_DATA, 54 BARRING_SERVICE_TYPE_CS_FALLBACK, 55 BARRING_SERVICE_TYPE_MMTEL_VOICE, 56 BARRING_SERVICE_TYPE_MMTEL_VIDEO, 57 BARRING_SERVICE_TYPE_EMERGENCY, 58 BARRING_SERVICE_TYPE_SMS}) 59 public @interface BarringServiceType {} 60 61 /* Applicabe to UTRAN */ 62 /** Barring indicator for circuit-switched service; applicable to UTRAN */ 63 public static final int BARRING_SERVICE_TYPE_CS_SERVICE = 64 android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_SERVICE; 65 /** Barring indicator for packet-switched service; applicable to UTRAN */ 66 public static final int BARRING_SERVICE_TYPE_PS_SERVICE = 67 android.hardware.radio.V1_5.BarringInfo.ServiceType.PS_SERVICE; 68 /** Barring indicator for circuit-switched voice service; applicable to UTRAN */ 69 public static final int BARRING_SERVICE_TYPE_CS_VOICE = 70 android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_VOICE; 71 72 /* Applicable to EUTRAN, NGRAN */ 73 /** Barring indicator for mobile-originated signalling; applicable to EUTRAN and NGRAN */ 74 public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING = 75 android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_SIGNALLING; 76 /** Barring indicator for mobile-originated data traffic; applicable to EUTRAN and NGRAN */ 77 public static final int BARRING_SERVICE_TYPE_MO_DATA = 78 android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_DATA; 79 /** Barring indicator for circuit-switched fallback for voice; applicable to EUTRAN and NGRAN */ 80 public static final int BARRING_SERVICE_TYPE_CS_FALLBACK = 81 android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_FALLBACK; 82 /** Barring indicator for MMTEL (IMS) voice; applicable to EUTRAN and NGRAN */ 83 public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE = 84 android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VOICE; 85 /** Barring indicator for MMTEL (IMS) video; applicable to EUTRAN and NGRAN */ 86 public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO = 87 android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VIDEO; 88 89 /* Applicable to UTRAN, EUTRAN, NGRAN */ 90 /** Barring indicator for emergency services; applicable to UTRAN, EUTRAN, and NGRAN */ 91 public static final int BARRING_SERVICE_TYPE_EMERGENCY = 92 android.hardware.radio.V1_5.BarringInfo.ServiceType.EMERGENCY; 93 /** Barring indicator for SMS sending; applicable to UTRAN, EUTRAN, and NGRAN */ 94 public static final int BARRING_SERVICE_TYPE_SMS = 95 android.hardware.radio.V1_5.BarringInfo.ServiceType.SMS; 96 97 //TODO: add barring constants for Operator-Specific barring codes 98 99 /** Describe the current barring configuration of a cell */ 100 public static final class BarringServiceInfo implements Parcelable { 101 /** 102 * Barring Type 103 * @hide 104 */ 105 @Retention(RetentionPolicy.SOURCE) 106 @IntDef(prefix = "BARRING_TYPE_", value = 107 {BARRING_TYPE_NONE, 108 BARRING_TYPE_UNCONDITIONAL, 109 BARRING_TYPE_CONDITIONAL, 110 BARRING_TYPE_UNKNOWN}) 111 public @interface BarringType {} 112 113 /** Barring is inactive */ 114 public static final int BARRING_TYPE_NONE = 115 android.hardware.radio.V1_5.BarringInfo.BarringType.NONE; 116 /** The service is barred */ 117 public static final int BARRING_TYPE_UNCONDITIONAL = 118 android.hardware.radio.V1_5.BarringInfo.BarringType.UNCONDITIONAL; 119 /** The service may be barred based on additional factors */ 120 public static final int BARRING_TYPE_CONDITIONAL = 121 android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL; 122 123 /** If a modem does not report barring info, then the barring type will be UNKNOWN */ 124 public static final int BARRING_TYPE_UNKNOWN = -1; 125 126 private final @BarringType int mBarringType; 127 128 private final boolean mIsConditionallyBarred; 129 private final int mConditionalBarringFactor; 130 private final int mConditionalBarringTimeSeconds; 131 132 /** @hide */ BarringServiceInfo(@arringType int type)133 public BarringServiceInfo(@BarringType int type) { 134 this(type, false, 0, 0); 135 } 136 137 /** @hide */ 138 @TestApi BarringServiceInfo(@arringType int barringType, boolean isConditionallyBarred, int conditionalBarringFactor, int conditionalBarringTimeSeconds)139 public BarringServiceInfo(@BarringType int barringType, boolean isConditionallyBarred, 140 int conditionalBarringFactor, int conditionalBarringTimeSeconds) { 141 mBarringType = barringType; 142 mIsConditionallyBarred = isConditionallyBarred; 143 mConditionalBarringFactor = conditionalBarringFactor; 144 mConditionalBarringTimeSeconds = conditionalBarringTimeSeconds; 145 } 146 getBarringType()147 public @BarringType int getBarringType() { 148 return mBarringType; 149 } 150 151 /** 152 * @return true if the conditional barring parameters have resulted in the service being 153 * barred; false if the service has either not been evaluated for conditional 154 * barring or has been evaluated and isn't barred. 155 */ isConditionallyBarred()156 public boolean isConditionallyBarred() { 157 return mIsConditionallyBarred; 158 } 159 160 /** 161 * @return the conditional barring factor as a percentage 0-100, which is the probability of 162 * a random device being barred for the service type. 163 */ getConditionalBarringFactor()164 public int getConditionalBarringFactor() { 165 return mConditionalBarringFactor; 166 } 167 168 /** 169 * @return the conditional barring time seconds, which is the interval between successive 170 * evaluations for conditional barring based on the barring factor. 171 */ 172 @SuppressLint("MethodNameUnits") getConditionalBarringTimeSeconds()173 public int getConditionalBarringTimeSeconds() { 174 return mConditionalBarringTimeSeconds; 175 } 176 177 /** 178 * Return whether a service is currently barred based on the BarringInfo 179 * 180 * @return true if the service is currently being barred, otherwise false 181 */ isBarred()182 public boolean isBarred() { 183 return mBarringType == BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL 184 || (mBarringType == BarringServiceInfo.BARRING_TYPE_CONDITIONAL 185 && mIsConditionallyBarred); 186 } 187 188 @Override hashCode()189 public int hashCode() { 190 return Objects.hash(mBarringType, mIsConditionallyBarred, 191 mConditionalBarringFactor, mConditionalBarringTimeSeconds); 192 } 193 194 @Override equals(Object rhs)195 public boolean equals(Object rhs) { 196 if (!(rhs instanceof BarringServiceInfo)) return false; 197 198 BarringServiceInfo other = (BarringServiceInfo) rhs; 199 return mBarringType == other.mBarringType 200 && mIsConditionallyBarred == other.mIsConditionallyBarred 201 && mConditionalBarringFactor == other.mConditionalBarringFactor 202 && mConditionalBarringTimeSeconds == other.mConditionalBarringTimeSeconds; 203 } 204 205 /** @hide */ BarringServiceInfo(Parcel p)206 public BarringServiceInfo(Parcel p) { 207 mBarringType = p.readInt(); 208 mIsConditionallyBarred = p.readBoolean(); 209 mConditionalBarringFactor = p.readInt(); 210 mConditionalBarringTimeSeconds = p.readInt(); 211 } 212 213 @Override writeToParcel(@onNull Parcel dest, int flags)214 public void writeToParcel(@NonNull Parcel dest, int flags) { 215 dest.writeInt(mBarringType); 216 dest.writeBoolean(mIsConditionallyBarred); 217 dest.writeInt(mConditionalBarringFactor); 218 dest.writeInt(mConditionalBarringTimeSeconds); 219 } 220 221 /* @inheritDoc */ 222 public static final @NonNull Parcelable.Creator<BarringServiceInfo> CREATOR = 223 new Parcelable.Creator<BarringServiceInfo>() { 224 @Override 225 public BarringServiceInfo createFromParcel(Parcel source) { 226 return new BarringServiceInfo(source); 227 } 228 229 @Override 230 public BarringServiceInfo[] newArray(int size) { 231 return new BarringServiceInfo[size]; 232 } 233 }; 234 235 @Override describeContents()236 public int describeContents() { 237 return 0; 238 } 239 } 240 241 private static final BarringServiceInfo BARRING_SERVICE_INFO_UNKNOWN = 242 new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_UNKNOWN); 243 244 private static final BarringServiceInfo BARRING_SERVICE_INFO_UNBARRED = 245 new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_NONE); 246 247 private CellIdentity mCellIdentity; 248 249 // A SparseArray potentially mapping each BarringService type to a BarringServiceInfo config 250 // that describes the current barring status of that particular service. 251 private SparseArray<BarringServiceInfo> mBarringServiceInfos; 252 253 /** @hide */ 254 @SystemApi BarringInfo()255 public BarringInfo() { 256 mBarringServiceInfos = new SparseArray<>(); 257 } 258 259 /** 260 * Constructor for new BarringInfo instances. 261 * 262 * @hide 263 */ 264 @TestApi BarringInfo(@ullable CellIdentity barringCellId, @NonNull SparseArray<BarringServiceInfo> barringServiceInfos)265 public BarringInfo(@Nullable CellIdentity barringCellId, 266 @NonNull SparseArray<BarringServiceInfo> barringServiceInfos) { 267 mCellIdentity = barringCellId; 268 mBarringServiceInfos = barringServiceInfos; 269 } 270 271 /** 272 * Get the BarringServiceInfo for a specified service. 273 * 274 * @return a BarringServiceInfo struct describing the current barring status for a service 275 */ getBarringServiceInfo(@arringServiceType int service)276 public @NonNull BarringServiceInfo getBarringServiceInfo(@BarringServiceType int service) { 277 BarringServiceInfo bsi = mBarringServiceInfos.get(service); 278 // If barring is reported but not for a particular service, then we report the barring 279 // type as UNKNOWN; if the modem reports barring info but doesn't report for a particular 280 // service then we can safely assume that the service isn't barred (for instance because 281 // that particular service isn't applicable to the current RAN). 282 return (bsi != null) ? bsi : mBarringServiceInfos.size() > 0 283 ? BARRING_SERVICE_INFO_UNBARRED : BARRING_SERVICE_INFO_UNKNOWN; 284 } 285 286 /** @hide */ 287 @SystemApi createLocationInfoSanitizedCopy()288 public @NonNull BarringInfo createLocationInfoSanitizedCopy() { 289 // The only thing that would need sanitizing is the CellIdentity 290 if (mCellIdentity == null) return this; 291 292 return new BarringInfo(mCellIdentity.sanitizeLocationInfo(), mBarringServiceInfos); 293 } 294 295 /** @hide */ BarringInfo(Parcel p)296 public BarringInfo(Parcel p) { 297 mCellIdentity = p.readParcelable(CellIdentity.class.getClassLoader(), android.telephony.CellIdentity.class); 298 mBarringServiceInfos = p.readSparseArray(BarringServiceInfo.class.getClassLoader(), android.telephony.BarringInfo.BarringServiceInfo.class); 299 } 300 301 @Override writeToParcel(@onNull Parcel dest, int flags)302 public void writeToParcel(@NonNull Parcel dest, int flags) { 303 dest.writeParcelable(mCellIdentity, flags); 304 dest.writeSparseArray(mBarringServiceInfos); 305 } 306 307 public static final @NonNull Parcelable.Creator<BarringInfo> CREATOR = 308 new Parcelable.Creator<BarringInfo>() { 309 @Override 310 public BarringInfo createFromParcel(Parcel source) { 311 return new BarringInfo(source); 312 } 313 314 @Override 315 public BarringInfo[] newArray(int size) { 316 return new BarringInfo[size]; 317 } 318 }; 319 320 @Override describeContents()321 public int describeContents() { 322 return 0; 323 } 324 325 @Override hashCode()326 public int hashCode() { 327 int hash = mCellIdentity != null ? mCellIdentity.hashCode() : 7; 328 for (int i = 0; i < mBarringServiceInfos.size(); i++) { 329 hash = hash + 15 * mBarringServiceInfos.keyAt(i); 330 hash = hash + 31 * mBarringServiceInfos.valueAt(i).hashCode(); 331 } 332 return hash; 333 } 334 335 @Override equals(Object rhs)336 public boolean equals(Object rhs) { 337 if (!(rhs instanceof BarringInfo)) return false; 338 339 BarringInfo bi = (BarringInfo) rhs; 340 341 if (hashCode() != bi.hashCode()) return false; 342 343 if (mBarringServiceInfos.size() != bi.mBarringServiceInfos.size()) return false; 344 345 for (int i = 0; i < mBarringServiceInfos.size(); i++) { 346 if (mBarringServiceInfos.keyAt(i) != bi.mBarringServiceInfos.keyAt(i)) return false; 347 if (!Objects.equals(mBarringServiceInfos.valueAt(i), 348 bi.mBarringServiceInfos.valueAt(i))) { 349 return false; 350 } 351 } 352 return true; 353 } 354 355 @Override toString()356 public String toString() { 357 return "BarringInfo {mCellIdentity=" + mCellIdentity 358 + ", mBarringServiceInfos=" + mBarringServiceInfos + "}"; 359 } 360 } 361