1 /* 2 * Copyright 2017 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.SystemApi; 23 import android.annotation.TestApi; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.telephony.AccessNetworkConstants.TransportType; 27 import android.telephony.Annotation.NetworkType; 28 import android.text.TextUtils; 29 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 import java.util.ArrayList; 33 import java.util.Collections; 34 import java.util.List; 35 import java.util.Objects; 36 import java.util.stream.Collectors; 37 38 /** 39 * Description of a mobile network registration info 40 */ 41 public final class NetworkRegistrationInfo implements Parcelable { 42 /** 43 * Network domain 44 * @hide 45 */ 46 @Retention(RetentionPolicy.SOURCE) 47 @IntDef(prefix = "DOMAIN_", value = {DOMAIN_UNKNOWN, DOMAIN_CS, DOMAIN_PS, DOMAIN_CS_PS}) 48 public @interface Domain {} 49 50 /** Unknown / Unspecified domain */ 51 public static final int DOMAIN_UNKNOWN = 0; 52 /** Circuit switched domain */ 53 public static final int DOMAIN_CS = android.hardware.radio.V1_5.Domain.CS; 54 /** Packet switched domain */ 55 public static final int DOMAIN_PS = android.hardware.radio.V1_5.Domain.PS; 56 /** Applicable to both CS and PS Domain */ 57 public static final int DOMAIN_CS_PS = DOMAIN_CS | DOMAIN_PS; 58 59 /** 60 * Network registration state 61 * @hide 62 */ 63 @Retention(RetentionPolicy.SOURCE) 64 @IntDef(prefix = "REGISTRATION_STATE_", 65 value = {REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, REGISTRATION_STATE_HOME, 66 REGISTRATION_STATE_NOT_REGISTERED_SEARCHING, REGISTRATION_STATE_DENIED, 67 REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING}) 68 public @interface RegistrationState {} 69 70 /** 71 * Not registered. The device is not currently searching a new operator to register. 72 * @hide 73 */ 74 @SystemApi @TestApi 75 public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; 76 /** 77 * Registered on home network. 78 * @hide 79 */ 80 @SystemApi @TestApi 81 public static final int REGISTRATION_STATE_HOME = 1; 82 /** 83 * Not registered. The device is currently searching a new operator to register. 84 * @hide 85 */ 86 @SystemApi @TestApi 87 public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; 88 /** 89 * Registration denied. 90 * @hide 91 */ 92 @SystemApi @TestApi 93 public static final int REGISTRATION_STATE_DENIED = 3; 94 /** 95 * Registration state is unknown. 96 * @hide 97 */ 98 @SystemApi @TestApi 99 public static final int REGISTRATION_STATE_UNKNOWN = 4; 100 /** 101 * Registered on roaming network. 102 * @hide 103 */ 104 @SystemApi @TestApi 105 public static final int REGISTRATION_STATE_ROAMING = 5; 106 107 /** @hide */ 108 @Retention(RetentionPolicy.SOURCE) 109 @IntDef(prefix = "NR_STATE_", 110 value = {NR_STATE_NONE, NR_STATE_RESTRICTED, NR_STATE_NOT_RESTRICTED, 111 NR_STATE_CONNECTED}) 112 public @interface NRState {} 113 114 /** 115 * The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR 116 * Dual Connectivity(EN-DC). 117 */ 118 public static final int NR_STATE_NONE = 0; 119 120 /** 121 * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but 122 * either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by 123 * the selected PLMN. 124 */ 125 public static final int NR_STATE_RESTRICTED = 1; 126 127 /** 128 * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both 129 * the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the 130 * selected PLMN. 131 */ 132 public static final int NR_STATE_NOT_RESTRICTED = 2; 133 134 /** 135 * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and 136 * also connected to at least one 5G cell as a secondary serving cell. 137 */ 138 public static final int NR_STATE_CONNECTED = 3; 139 140 /** 141 * Supported service type 142 * @hide 143 */ 144 @Retention(RetentionPolicy.SOURCE) 145 @IntDef(prefix = "SERVICE_TYPE_", 146 value = {SERVICE_TYPE_UNKNOWN, SERVICE_TYPE_VOICE, SERVICE_TYPE_DATA, SERVICE_TYPE_SMS, 147 SERVICE_TYPE_VIDEO, SERVICE_TYPE_EMERGENCY}) 148 public @interface ServiceType {} 149 150 /** 151 * Unknown service 152 */ 153 public static final int SERVICE_TYPE_UNKNOWN = 0; 154 155 /** 156 * Voice service 157 */ 158 public static final int SERVICE_TYPE_VOICE = 1; 159 160 /** 161 * Data service 162 */ 163 public static final int SERVICE_TYPE_DATA = 2; 164 165 /** 166 * SMS service 167 */ 168 public static final int SERVICE_TYPE_SMS = 3; 169 170 /** 171 * Video service 172 */ 173 public static final int SERVICE_TYPE_VIDEO = 4; 174 175 /** 176 * Emergency service 177 */ 178 public static final int SERVICE_TYPE_EMERGENCY = 5; 179 180 @Domain 181 private final int mDomain; 182 183 @TransportType 184 private final int mTransportType; 185 186 @RegistrationState 187 private final int mRegistrationState; 188 189 /** 190 * Save the {@link ServiceState.RoamingType roaming type}. it can be overridden roaming type 191 * from resource overlay or carrier config. 192 */ 193 @ServiceState.RoamingType 194 private int mRoamingType; 195 196 @NetworkType 197 private int mAccessNetworkTechnology; 198 199 @NRState 200 private int mNrState; 201 202 private final int mRejectCause; 203 204 private final boolean mEmergencyOnly; 205 206 @ServiceType 207 private final ArrayList<Integer> mAvailableServices; 208 209 @Nullable 210 private CellIdentity mCellIdentity; 211 212 @Nullable 213 private VoiceSpecificRegistrationInfo mVoiceSpecificInfo; 214 215 @Nullable 216 private DataSpecificRegistrationInfo mDataSpecificInfo; 217 218 @NonNull 219 private String mRplmn; 220 221 /** 222 * @param domain Network domain. Must be a {@link Domain}. For transport type 223 * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}. 224 * @param transportType Transport type. 225 * @param registrationState Network registration state. For transport type 226 * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, only 227 * {@link #REGISTRATION_STATE_HOME} and {@link #REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING} 228 * are valid states. 229 * @param accessNetworkTechnology Access network technology.For transport type 230 * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, set to 231 * {@link TelephonyManager#NETWORK_TYPE_IWLAN}. 232 * @param rejectCause Reason for denial if the registration state is 233 * {@link #REGISTRATION_STATE_DENIED}. Depending on {@code accessNetworkTechnology}, the values 234 * are defined in 3GPP TS 24.008 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 235 * A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set it to 0. 236 * // TODO: Add IWLAN reject cause reference 237 * @param emergencyOnly True if this registration is for emergency only. 238 * @param availableServices The list of the supported services. 239 * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the 240 * information is not available. 241 * @param rplmn the registered plmn or the last plmn for attempted registration if reg failed. 242 */ NetworkRegistrationInfo(@omain int domain, @TransportType int transportType, @RegistrationState int registrationState, @NetworkType int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable @ServiceType List<Integer> availableServices, @Nullable CellIdentity cellIdentity, @Nullable String rplmn)243 private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType, 244 @RegistrationState int registrationState, 245 @NetworkType int accessNetworkTechnology, int rejectCause, 246 boolean emergencyOnly, 247 @Nullable @ServiceType List<Integer> availableServices, 248 @Nullable CellIdentity cellIdentity, @Nullable String rplmn) { 249 mDomain = domain; 250 mTransportType = transportType; 251 mRegistrationState = registrationState; 252 mRoamingType = (registrationState == REGISTRATION_STATE_ROAMING) 253 ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING; 254 mAccessNetworkTechnology = accessNetworkTechnology; 255 mRejectCause = rejectCause; 256 mAvailableServices = (availableServices != null) 257 ? new ArrayList<>(availableServices) : new ArrayList<>(); 258 mCellIdentity = cellIdentity; 259 mEmergencyOnly = emergencyOnly; 260 mNrState = NR_STATE_NONE; 261 mRplmn = rplmn; 262 } 263 264 /** 265 * Constructor for voice network registration info. 266 * @hide 267 */ NetworkRegistrationInfo(int domain, @TransportType int transportType, int registrationState, int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable List<Integer> availableServices, @Nullable CellIdentity cellIdentity, @Nullable String rplmn, boolean cssSupported, int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator)268 public NetworkRegistrationInfo(int domain, @TransportType int transportType, 269 int registrationState, int accessNetworkTechnology, 270 int rejectCause, boolean emergencyOnly, 271 @Nullable List<Integer> availableServices, 272 @Nullable CellIdentity cellIdentity, @Nullable String rplmn, 273 boolean cssSupported, int roamingIndicator, int systemIsInPrl, 274 int defaultRoamingIndicator) { 275 this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, 276 emergencyOnly, availableServices, cellIdentity, rplmn); 277 278 mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator, 279 systemIsInPrl, defaultRoamingIndicator); 280 } 281 282 /** 283 * Constructor for data network registration info. 284 * @hide 285 */ NetworkRegistrationInfo(int domain, @TransportType int transportType, int registrationState, int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable List<Integer> availableServices, @Nullable CellIdentity cellIdentity, @Nullable String rplmn, int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable, LteVopsSupportInfo lteVopsSupportInfo, boolean isUsingCarrierAggregation)286 public NetworkRegistrationInfo(int domain, @TransportType int transportType, 287 int registrationState, int accessNetworkTechnology, 288 int rejectCause, boolean emergencyOnly, 289 @Nullable List<Integer> availableServices, 290 @Nullable CellIdentity cellIdentity, @Nullable String rplmn, 291 int maxDataCalls, boolean isDcNrRestricted, 292 boolean isNrAvailable, boolean isEndcAvailable, 293 LteVopsSupportInfo lteVopsSupportInfo, 294 boolean isUsingCarrierAggregation) { 295 this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, 296 emergencyOnly, availableServices, cellIdentity, rplmn); 297 mDataSpecificInfo = new DataSpecificRegistrationInfo( 298 maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo, 299 isUsingCarrierAggregation); 300 updateNrState(); 301 } 302 NetworkRegistrationInfo(Parcel source)303 private NetworkRegistrationInfo(Parcel source) { 304 mDomain = source.readInt(); 305 mTransportType = source.readInt(); 306 mRegistrationState = source.readInt(); 307 mRoamingType = source.readInt(); 308 mAccessNetworkTechnology = source.readInt(); 309 mRejectCause = source.readInt(); 310 mEmergencyOnly = source.readBoolean(); 311 mAvailableServices = new ArrayList<>(); 312 source.readList(mAvailableServices, Integer.class.getClassLoader()); 313 mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader()); 314 mVoiceSpecificInfo = source.readParcelable( 315 VoiceSpecificRegistrationInfo.class.getClassLoader()); 316 mDataSpecificInfo = source.readParcelable( 317 DataSpecificRegistrationInfo.class.getClassLoader()); 318 mNrState = source.readInt(); 319 mRplmn = source.readString(); 320 } 321 322 /** 323 * Constructor from another network registration info 324 * 325 * @param nri Another network registration info 326 * @hide 327 */ NetworkRegistrationInfo(NetworkRegistrationInfo nri)328 public NetworkRegistrationInfo(NetworkRegistrationInfo nri) { 329 mDomain = nri.mDomain; 330 mTransportType = nri.mTransportType; 331 mRegistrationState = nri.mRegistrationState; 332 mRoamingType = nri.mRoamingType; 333 mAccessNetworkTechnology = nri.mAccessNetworkTechnology; 334 mRejectCause = nri.mRejectCause; 335 mEmergencyOnly = nri.mEmergencyOnly; 336 mAvailableServices = new ArrayList<>(nri.mAvailableServices); 337 if (nri.mCellIdentity != null) { 338 Parcel p = Parcel.obtain(); 339 nri.mCellIdentity.writeToParcel(p, 0); 340 p.setDataPosition(0); 341 // TODO: Instead of doing this, we should create a formal way for cloning cell identity. 342 // Cell identity is not an immutable object so we have to deep copy it. 343 mCellIdentity = CellIdentity.CREATOR.createFromParcel(p); 344 } 345 346 if (nri.mVoiceSpecificInfo != null) { 347 mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(nri.mVoiceSpecificInfo); 348 } 349 if (nri.mDataSpecificInfo != null) { 350 mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo); 351 } 352 mNrState = nri.mNrState; 353 mRplmn = nri.mRplmn; 354 } 355 356 /** 357 * @return The transport type. 358 */ getTransportType()359 public @TransportType int getTransportType() { return mTransportType; } 360 361 /** 362 * @return The network domain. 363 */ getDomain()364 public @Domain int getDomain() { return mDomain; } 365 366 /** 367 * Get the 5G NR connection state. 368 * 369 * @return the 5G NR connection state. 370 * @hide 371 */ getNrState()372 public @NRState int getNrState() { 373 return mNrState; 374 } 375 376 /** @hide */ setNrState(@RState int nrState)377 public void setNrState(@NRState int nrState) { 378 mNrState = nrState; 379 } 380 381 /** 382 * @return The registration state. 383 * 384 * @hide 385 */ 386 @SystemApi @TestApi getRegistrationState()387 public @RegistrationState int getRegistrationState() { 388 return mRegistrationState; 389 } 390 391 /** 392 * @return {@code true} if registered on roaming network, {@code false} otherwise. 393 */ isRegistered()394 public boolean isRegistered() { 395 return mRegistrationState == REGISTRATION_STATE_HOME 396 || mRegistrationState == REGISTRATION_STATE_ROAMING; 397 } 398 399 /** 400 * @return {@code true} if registered on roaming network, {@code false} otherwise. 401 */ isSearching()402 public boolean isSearching() { 403 return mRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING; 404 } 405 406 /** 407 * Get the PLMN-ID for this Network Registration, also known as the RPLMN. 408 * 409 * <p>If the device is registered, this will return the registered PLMN-ID. If registration 410 * has failed, then this will return the PLMN ID of the last attempted registration. If the 411 * device is not registered, or if is registered to a non-3GPP radio technology, then this 412 * will return null. 413 * 414 * <p>See 3GPP TS 23.122 for further information about the Registered PLMN. 415 * 416 * @return the registered PLMN-ID or null. 417 */ getRegisteredPlmn()418 @Nullable public String getRegisteredPlmn() { 419 return mRplmn; 420 } 421 422 /** 423 * @return {@code true} if registered on roaming network, {@code false} otherwise. 424 */ isRoaming()425 public boolean isRoaming() { 426 return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING; 427 } 428 429 /** 430 * @hide 431 * @return {@code true} if in service. 432 */ isInService()433 public boolean isInService() { 434 return mRegistrationState == REGISTRATION_STATE_HOME 435 || mRegistrationState == REGISTRATION_STATE_ROAMING; 436 } 437 438 /** 439 * Set {@link ServiceState.RoamingType roaming type}. This could override 440 * roaming type based on resource overlay or carrier config. 441 * @hide 442 */ setRoamingType(@erviceState.RoamingType int roamingType)443 public void setRoamingType(@ServiceState.RoamingType int roamingType) { 444 mRoamingType = roamingType; 445 } 446 447 /** 448 * @return the current network roaming type. 449 * @hide 450 */ 451 @SystemApi @TestApi getRoamingType()452 public @ServiceState.RoamingType int getRoamingType() { 453 return mRoamingType; 454 } 455 456 /** 457 * @return Whether emergency is enabled. 458 * @hide 459 */ 460 @SystemApi @TestApi isEmergencyEnabled()461 public boolean isEmergencyEnabled() { return mEmergencyOnly; } 462 463 /** 464 * @return List of available service types. 465 */ 466 @NonNull 467 @ServiceType getAvailableServices()468 public List<Integer> getAvailableServices() { 469 return Collections.unmodifiableList(mAvailableServices); 470 } 471 472 /** 473 * @return The access network technology {@link NetworkType}. 474 */ getAccessNetworkTechnology()475 public @NetworkType int getAccessNetworkTechnology() { 476 return mAccessNetworkTechnology; 477 } 478 479 /** 480 * override the access network technology {@link NetworkType} e.g, rat ratchet. 481 * @hide 482 */ setAccessNetworkTechnology(@etworkType int tech)483 public void setAccessNetworkTechnology(@NetworkType int tech) { 484 if (tech == TelephonyManager.NETWORK_TYPE_LTE_CA) { 485 // For old device backward compatibility support 486 tech = TelephonyManager.NETWORK_TYPE_LTE; 487 if (mDataSpecificInfo != null) { 488 mDataSpecificInfo.setIsUsingCarrierAggregation(true); 489 } 490 } 491 mAccessNetworkTechnology = tech; 492 } 493 494 /** 495 * @return Reason for denial if the registration state is {@link #REGISTRATION_STATE_DENIED}. 496 * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008 497 * 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA 498 * @hide 499 */ 500 @SystemApi @TestApi getRejectCause()501 public int getRejectCause() { 502 return mRejectCause; 503 } 504 505 /** 506 * @return The cell information. 507 */ 508 @Nullable getCellIdentity()509 public CellIdentity getCellIdentity() { 510 return mCellIdentity; 511 } 512 513 /** 514 * @hide 515 */ 516 @Nullable getVoiceSpecificInfo()517 public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() { 518 return mVoiceSpecificInfo; 519 } 520 521 /** 522 * @return Data registration related info 523 * @hide 524 */ 525 @Nullable 526 @SystemApi @TestApi getDataSpecificInfo()527 public DataSpecificRegistrationInfo getDataSpecificInfo() { 528 return mDataSpecificInfo; 529 } 530 531 @Override describeContents()532 public int describeContents() { 533 return 0; 534 } 535 536 /** 537 * Convert service type to string 538 * 539 * @hide 540 * 541 * @param serviceType The service type 542 * @return The service type in string format 543 */ serviceTypeToString(@erviceType int serviceType)544 public static String serviceTypeToString(@ServiceType int serviceType) { 545 switch (serviceType) { 546 case SERVICE_TYPE_VOICE: return "VOICE"; 547 case SERVICE_TYPE_DATA: return "DATA"; 548 case SERVICE_TYPE_SMS: return "SMS"; 549 case SERVICE_TYPE_VIDEO: return "VIDEO"; 550 case SERVICE_TYPE_EMERGENCY: return "EMERGENCY"; 551 } 552 return "Unknown service type " + serviceType; 553 } 554 555 /** 556 * Convert registration state to string 557 * 558 * @hide 559 * 560 * @param registrationState The registration state 561 * @return The reg state in string 562 */ registrationStateToString(@egistrationState int registrationState)563 public static String registrationStateToString(@RegistrationState int registrationState) { 564 switch (registrationState) { 565 case REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING: return "NOT_REG_OR_SEARCHING"; 566 case REGISTRATION_STATE_HOME: return "HOME"; 567 case REGISTRATION_STATE_NOT_REGISTERED_SEARCHING: return "NOT_REG_SEARCHING"; 568 case REGISTRATION_STATE_DENIED: return "DENIED"; 569 case REGISTRATION_STATE_UNKNOWN: return "UNKNOWN"; 570 case REGISTRATION_STATE_ROAMING: return "ROAMING"; 571 } 572 return "Unknown reg state " + registrationState; 573 } 574 nrStateToString(@RState int nrState)575 private static String nrStateToString(@NRState int nrState) { 576 switch (nrState) { 577 case NR_STATE_RESTRICTED: 578 return "RESTRICTED"; 579 case NR_STATE_NOT_RESTRICTED: 580 return "NOT_RESTRICTED"; 581 case NR_STATE_CONNECTED: 582 return "CONNECTED"; 583 default: 584 return "NONE"; 585 } 586 } 587 588 /** @hide */ domainToString(@omain int domain)589 static @NonNull String domainToString(@Domain int domain) { 590 switch (domain) { 591 case DOMAIN_CS: return "CS"; 592 case DOMAIN_PS: return "PS"; 593 case DOMAIN_CS_PS: return "CS_PS"; 594 default: return "UNKNOWN"; 595 } 596 } 597 598 @NonNull 599 @Override toString()600 public String toString() { 601 return new StringBuilder("NetworkRegistrationInfo{") 602 .append(" domain=").append(domainToString(mDomain)) 603 .append(" transportType=").append( 604 AccessNetworkConstants.transportTypeToString(mTransportType)) 605 .append(" registrationState=").append(registrationStateToString(mRegistrationState)) 606 .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType)) 607 .append(" accessNetworkTechnology=") 608 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology)) 609 .append(" rejectCause=").append(mRejectCause) 610 .append(" emergencyEnabled=").append(mEmergencyOnly) 611 .append(" availableServices=").append("[" + (mAvailableServices != null 612 ? mAvailableServices.stream().map(type -> serviceTypeToString(type)) 613 .collect(Collectors.joining(",")) : null) + "]") 614 .append(" cellIdentity=").append(mCellIdentity) 615 .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo) 616 .append(" dataSpecificInfo=").append(mDataSpecificInfo) 617 .append(" nrState=").append(nrStateToString(mNrState)) 618 .append(" rRplmn=").append(mRplmn) 619 .append("}").toString(); 620 } 621 622 @Override hashCode()623 public int hashCode() { 624 return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType, 625 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, 626 mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn); 627 } 628 629 @Override equals(@ullable Object o)630 public boolean equals(@Nullable Object o) { 631 if (this == o) return true; 632 633 if (!(o instanceof NetworkRegistrationInfo)) { 634 return false; 635 } 636 637 NetworkRegistrationInfo other = (NetworkRegistrationInfo) o; 638 return mDomain == other.mDomain 639 && mTransportType == other.mTransportType 640 && mRegistrationState == other.mRegistrationState 641 && mRoamingType == other.mRoamingType 642 && mAccessNetworkTechnology == other.mAccessNetworkTechnology 643 && mRejectCause == other.mRejectCause 644 && mEmergencyOnly == other.mEmergencyOnly 645 && mAvailableServices.equals(other.mAvailableServices) 646 && Objects.equals(mCellIdentity, other.mCellIdentity) 647 && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo) 648 && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo) 649 && TextUtils.equals(mRplmn, other.mRplmn) 650 && mNrState == other.mNrState; 651 } 652 653 /** 654 * @hide 655 */ 656 @Override 657 @SystemApi @TestApi writeToParcel(Parcel dest, int flags)658 public void writeToParcel(Parcel dest, int flags) { 659 dest.writeInt(mDomain); 660 dest.writeInt(mTransportType); 661 dest.writeInt(mRegistrationState); 662 dest.writeInt(mRoamingType); 663 dest.writeInt(mAccessNetworkTechnology); 664 dest.writeInt(mRejectCause); 665 dest.writeBoolean(mEmergencyOnly); 666 dest.writeList(mAvailableServices); 667 dest.writeParcelable(mCellIdentity, 0); 668 dest.writeParcelable(mVoiceSpecificInfo, 0); 669 dest.writeParcelable(mDataSpecificInfo, 0); 670 dest.writeInt(mNrState); 671 dest.writeString(mRplmn); 672 } 673 674 /** 675 * Use the 5G NR Non-Standalone indicators from the network registration state to update the 676 * NR state. There are 3 indicators in the network registration state: 677 * 678 * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell. 679 * 2. if NR is supported by the selected PLMN. 680 * 3. if the use of dual connectivity with NR is restricted. 681 * 682 * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary 683 * serving cell. 684 * 685 * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of 686 * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G 687 * NR is restricted. 688 * 689 * @hide 690 */ updateNrState()691 public void updateNrState() { 692 mNrState = NR_STATE_NONE; 693 if (mDataSpecificInfo != null && mDataSpecificInfo.isEnDcAvailable) { 694 if (!mDataSpecificInfo.isDcNrRestricted && mDataSpecificInfo.isNrAvailable) { 695 mNrState = NR_STATE_NOT_RESTRICTED; 696 } else { 697 mNrState = NR_STATE_RESTRICTED; 698 } 699 } 700 } 701 702 public static final @NonNull Parcelable.Creator<NetworkRegistrationInfo> CREATOR = 703 new Parcelable.Creator<NetworkRegistrationInfo>() { 704 @Override 705 public NetworkRegistrationInfo createFromParcel(Parcel source) { 706 return new NetworkRegistrationInfo(source); 707 } 708 709 @Override 710 public NetworkRegistrationInfo[] newArray(int size) { 711 return new NetworkRegistrationInfo[size]; 712 } 713 }; 714 715 /** 716 * @hide 717 */ sanitizeLocationInfo()718 public NetworkRegistrationInfo sanitizeLocationInfo() { 719 NetworkRegistrationInfo result = copy(); 720 result.mCellIdentity = null; 721 return result; 722 } 723 copy()724 private NetworkRegistrationInfo copy() { 725 Parcel p = Parcel.obtain(); 726 this.writeToParcel(p, 0); 727 p.setDataPosition(0); 728 NetworkRegistrationInfo result = new NetworkRegistrationInfo(p); 729 p.recycle(); 730 return result; 731 } 732 733 /** 734 * Provides a convenient way to set the fields of a {@link NetworkRegistrationInfo} when 735 * creating a new instance. 736 * 737 * <p>The example below shows how you might create a new {@code NetworkRegistrationInfo}: 738 * 739 * <pre><code> 740 * 741 * NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder() 742 * .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) 743 * .setRegistrationState(REGISTRATION_STATE_HOME) 744 * .build(); 745 * </code></pre> 746 * @hide 747 */ 748 @SystemApi @TestApi 749 public static final class Builder { 750 @Domain 751 private int mDomain; 752 753 @TransportType 754 private int mTransportType; 755 756 @RegistrationState 757 private int mRegistrationState; 758 759 @NetworkType 760 private int mAccessNetworkTechnology; 761 762 private int mRejectCause; 763 764 private boolean mEmergencyOnly; 765 766 @ServiceType 767 private List<Integer> mAvailableServices; 768 769 @Nullable 770 private CellIdentity mCellIdentity; 771 772 @NonNull 773 private String mRplmn = ""; 774 775 /** 776 * Default constructor for Builder. 777 */ Builder()778 public Builder() {} 779 780 /** 781 * Set the network domain. 782 * 783 * @param domain Network domain. 784 * 785 * @return The same instance of the builder. 786 */ setDomain(@omain int domain)787 public @NonNull Builder setDomain(@Domain int domain) { 788 mDomain = domain; 789 return this; 790 } 791 792 /** 793 * Set the transport type. 794 * 795 * @param transportType Transport type. 796 * 797 * @return The same instance of the builder. 798 */ setTransportType(@ransportType int transportType)799 public @NonNull Builder setTransportType(@TransportType int transportType) { 800 mTransportType = transportType; 801 return this; 802 } 803 804 /** 805 * Set the registration state. 806 * 807 * @param registrationState The registration state. 808 * 809 * @return The same instance of the builder. 810 */ setRegistrationState(@egistrationState int registrationState)811 public @NonNull Builder setRegistrationState(@RegistrationState int registrationState) { 812 mRegistrationState = registrationState; 813 return this; 814 } 815 816 /** 817 * Set tne access network technology. 818 * 819 * @return The same instance of the builder. 820 * 821 * @param accessNetworkTechnology The access network technology 822 */ setAccessNetworkTechnology( @etworkType int accessNetworkTechnology)823 public @NonNull Builder setAccessNetworkTechnology( 824 @NetworkType int accessNetworkTechnology) { 825 mAccessNetworkTechnology = accessNetworkTechnology; 826 return this; 827 } 828 829 /** 830 * Set the network reject cause. 831 * 832 * @param rejectCause Reason for denial if the registration state is 833 * {@link #REGISTRATION_STATE_DENIED}.Depending on {@code accessNetworkTechnology}, the 834 * values are defined in 3GPP TS 24.008 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, 835 * and 3GPP2 A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set 836 * it to 0. 837 * 838 * @return The same instance of the builder. 839 */ setRejectCause(int rejectCause)840 public @NonNull Builder setRejectCause(int rejectCause) { 841 mRejectCause = rejectCause; 842 return this; 843 } 844 845 /** 846 * Set emergency only. 847 * 848 * @param emergencyOnly True if this network registration is for emergency use only. 849 * 850 * @return The same instance of the builder. 851 * @hide 852 */ 853 @SystemApi @TestApi setEmergencyOnly(boolean emergencyOnly)854 public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) { 855 mEmergencyOnly = emergencyOnly; 856 return this; 857 } 858 859 /** 860 * Set the available services. 861 * 862 * @param availableServices Available services. 863 * 864 * @return The same instance of the builder. 865 * @hide 866 */ 867 @SystemApi @TestApi setAvailableServices( @onNull @erviceType List<Integer> availableServices)868 public @NonNull Builder setAvailableServices( 869 @NonNull @ServiceType List<Integer> availableServices) { 870 mAvailableServices = availableServices; 871 return this; 872 } 873 874 /** 875 * Set the cell identity. 876 * 877 * @param cellIdentity The cell identity. 878 * 879 * @return The same instance of the builder. 880 * @hide 881 */ 882 @SystemApi @TestApi setCellIdentity(@ullable CellIdentity cellIdentity)883 public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) { 884 mCellIdentity = cellIdentity; 885 return this; 886 } 887 888 /** 889 * Set the registered PLMN. 890 * 891 * @param rplmn the registered plmn. 892 * 893 * @return The same instance of the builder. 894 */ setRegisteredPlmn(@ullable String rplmn)895 public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) { 896 mRplmn = rplmn; 897 return this; 898 } 899 900 /** 901 * Build the NetworkRegistrationInfo. 902 * @return the NetworkRegistrationInfo object. 903 * @hide 904 */ 905 @SystemApi @TestApi build()906 public @NonNull NetworkRegistrationInfo build() { 907 return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState, 908 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, 909 mCellIdentity, mRplmn); 910 } 911 } 912 } 913