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