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 575 /** @hide */ nrStateToString(@RState int nrState)576 public static String nrStateToString(@NRState int nrState) { 577 switch (nrState) { 578 case NR_STATE_RESTRICTED: 579 return "RESTRICTED"; 580 case NR_STATE_NOT_RESTRICTED: 581 return "NOT_RESTRICTED"; 582 case NR_STATE_CONNECTED: 583 return "CONNECTED"; 584 default: 585 return "NONE"; 586 } 587 } 588 589 /** @hide */ domainToString(@omain int domain)590 static @NonNull String domainToString(@Domain int domain) { 591 switch (domain) { 592 case DOMAIN_CS: return "CS"; 593 case DOMAIN_PS: return "PS"; 594 case DOMAIN_CS_PS: return "CS_PS"; 595 default: return "UNKNOWN"; 596 } 597 } 598 599 @NonNull 600 @Override toString()601 public String toString() { 602 return new StringBuilder("NetworkRegistrationInfo{") 603 .append(" domain=").append(domainToString(mDomain)) 604 .append(" transportType=").append( 605 AccessNetworkConstants.transportTypeToString(mTransportType)) 606 .append(" registrationState=").append(registrationStateToString(mRegistrationState)) 607 .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType)) 608 .append(" accessNetworkTechnology=") 609 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology)) 610 .append(" rejectCause=").append(mRejectCause) 611 .append(" emergencyEnabled=").append(mEmergencyOnly) 612 .append(" availableServices=").append("[" + (mAvailableServices != null 613 ? mAvailableServices.stream().map(type -> serviceTypeToString(type)) 614 .collect(Collectors.joining(",")) : null) + "]") 615 .append(" cellIdentity=").append(mCellIdentity) 616 .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo) 617 .append(" dataSpecificInfo=").append(mDataSpecificInfo) 618 .append(" nrState=").append(nrStateToString(mNrState)) 619 .append(" rRplmn=").append(mRplmn) 620 .append("}").toString(); 621 } 622 623 @Override hashCode()624 public int hashCode() { 625 return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType, 626 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, 627 mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn); 628 } 629 630 @Override equals(@ullable Object o)631 public boolean equals(@Nullable Object o) { 632 if (this == o) return true; 633 634 if (!(o instanceof NetworkRegistrationInfo)) { 635 return false; 636 } 637 638 NetworkRegistrationInfo other = (NetworkRegistrationInfo) o; 639 return mDomain == other.mDomain 640 && mTransportType == other.mTransportType 641 && mRegistrationState == other.mRegistrationState 642 && mRoamingType == other.mRoamingType 643 && mAccessNetworkTechnology == other.mAccessNetworkTechnology 644 && mRejectCause == other.mRejectCause 645 && mEmergencyOnly == other.mEmergencyOnly 646 && mAvailableServices.equals(other.mAvailableServices) 647 && Objects.equals(mCellIdentity, other.mCellIdentity) 648 && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo) 649 && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo) 650 && TextUtils.equals(mRplmn, other.mRplmn) 651 && mNrState == other.mNrState; 652 } 653 654 /** 655 * @hide 656 */ 657 @Override 658 @SystemApi @TestApi writeToParcel(Parcel dest, int flags)659 public void writeToParcel(Parcel dest, int flags) { 660 dest.writeInt(mDomain); 661 dest.writeInt(mTransportType); 662 dest.writeInt(mRegistrationState); 663 dest.writeInt(mRoamingType); 664 dest.writeInt(mAccessNetworkTechnology); 665 dest.writeInt(mRejectCause); 666 dest.writeBoolean(mEmergencyOnly); 667 dest.writeList(mAvailableServices); 668 dest.writeParcelable(mCellIdentity, 0); 669 dest.writeParcelable(mVoiceSpecificInfo, 0); 670 dest.writeParcelable(mDataSpecificInfo, 0); 671 dest.writeInt(mNrState); 672 dest.writeString(mRplmn); 673 } 674 675 /** 676 * Use the 5G NR Non-Standalone indicators from the network registration state to update the 677 * NR state. There are 3 indicators in the network registration state: 678 * 679 * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell. 680 * 2. if NR is supported by the selected PLMN. 681 * 3. if the use of dual connectivity with NR is restricted. 682 * 683 * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary 684 * serving cell. 685 * 686 * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of 687 * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G 688 * NR is restricted. 689 * 690 * @hide 691 */ updateNrState()692 public void updateNrState() { 693 mNrState = NR_STATE_NONE; 694 if (mDataSpecificInfo != null && mDataSpecificInfo.isEnDcAvailable) { 695 if (!mDataSpecificInfo.isDcNrRestricted && mDataSpecificInfo.isNrAvailable) { 696 mNrState = NR_STATE_NOT_RESTRICTED; 697 } else { 698 mNrState = NR_STATE_RESTRICTED; 699 } 700 } 701 } 702 703 public static final @NonNull Parcelable.Creator<NetworkRegistrationInfo> CREATOR = 704 new Parcelable.Creator<NetworkRegistrationInfo>() { 705 @Override 706 public NetworkRegistrationInfo createFromParcel(Parcel source) { 707 return new NetworkRegistrationInfo(source); 708 } 709 710 @Override 711 public NetworkRegistrationInfo[] newArray(int size) { 712 return new NetworkRegistrationInfo[size]; 713 } 714 }; 715 716 /** 717 * @hide 718 */ sanitizeLocationInfo()719 public NetworkRegistrationInfo sanitizeLocationInfo() { 720 NetworkRegistrationInfo result = copy(); 721 result.mCellIdentity = null; 722 return result; 723 } 724 copy()725 private NetworkRegistrationInfo copy() { 726 Parcel p = Parcel.obtain(); 727 this.writeToParcel(p, 0); 728 p.setDataPosition(0); 729 NetworkRegistrationInfo result = new NetworkRegistrationInfo(p); 730 p.recycle(); 731 return result; 732 } 733 734 /** 735 * Provides a convenient way to set the fields of a {@link NetworkRegistrationInfo} when 736 * creating a new instance. 737 * 738 * <p>The example below shows how you might create a new {@code NetworkRegistrationInfo}: 739 * 740 * <pre><code> 741 * 742 * NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder() 743 * .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) 744 * .setRegistrationState(REGISTRATION_STATE_HOME) 745 * .build(); 746 * </code></pre> 747 * @hide 748 */ 749 @SystemApi @TestApi 750 public static final class Builder { 751 @Domain 752 private int mDomain; 753 754 @TransportType 755 private int mTransportType; 756 757 @RegistrationState 758 private int mRegistrationState; 759 760 @NetworkType 761 private int mAccessNetworkTechnology; 762 763 private int mRejectCause; 764 765 private boolean mEmergencyOnly; 766 767 @ServiceType 768 private List<Integer> mAvailableServices; 769 770 @Nullable 771 private CellIdentity mCellIdentity; 772 773 @NonNull 774 private String mRplmn = ""; 775 776 /** 777 * Default constructor for Builder. 778 */ Builder()779 public Builder() {} 780 781 /** 782 * Set the network domain. 783 * 784 * @param domain Network domain. 785 * 786 * @return The same instance of the builder. 787 */ setDomain(@omain int domain)788 public @NonNull Builder setDomain(@Domain int domain) { 789 mDomain = domain; 790 return this; 791 } 792 793 /** 794 * Set the transport type. 795 * 796 * @param transportType Transport type. 797 * 798 * @return The same instance of the builder. 799 */ setTransportType(@ransportType int transportType)800 public @NonNull Builder setTransportType(@TransportType int transportType) { 801 mTransportType = transportType; 802 return this; 803 } 804 805 /** 806 * Set the registration state. 807 * 808 * @param registrationState The registration state. 809 * 810 * @return The same instance of the builder. 811 */ setRegistrationState(@egistrationState int registrationState)812 public @NonNull Builder setRegistrationState(@RegistrationState int registrationState) { 813 mRegistrationState = registrationState; 814 return this; 815 } 816 817 /** 818 * Set tne access network technology. 819 * 820 * @return The same instance of the builder. 821 * 822 * @param accessNetworkTechnology The access network technology 823 */ setAccessNetworkTechnology( @etworkType int accessNetworkTechnology)824 public @NonNull Builder setAccessNetworkTechnology( 825 @NetworkType int accessNetworkTechnology) { 826 mAccessNetworkTechnology = accessNetworkTechnology; 827 return this; 828 } 829 830 /** 831 * Set the network reject cause. 832 * 833 * @param rejectCause Reason for denial if the registration state is 834 * {@link #REGISTRATION_STATE_DENIED}.Depending on {@code accessNetworkTechnology}, the 835 * values are defined in 3GPP TS 24.008 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, 836 * and 3GPP2 A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set 837 * it to 0. 838 * 839 * @return The same instance of the builder. 840 */ setRejectCause(int rejectCause)841 public @NonNull Builder setRejectCause(int rejectCause) { 842 mRejectCause = rejectCause; 843 return this; 844 } 845 846 /** 847 * Set emergency only. 848 * 849 * @param emergencyOnly True if this network registration is for emergency use only. 850 * 851 * @return The same instance of the builder. 852 * @hide 853 */ 854 @SystemApi @TestApi setEmergencyOnly(boolean emergencyOnly)855 public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) { 856 mEmergencyOnly = emergencyOnly; 857 return this; 858 } 859 860 /** 861 * Set the available services. 862 * 863 * @param availableServices Available services. 864 * 865 * @return The same instance of the builder. 866 * @hide 867 */ 868 @SystemApi @TestApi setAvailableServices( @onNull @erviceType List<Integer> availableServices)869 public @NonNull Builder setAvailableServices( 870 @NonNull @ServiceType List<Integer> availableServices) { 871 mAvailableServices = availableServices; 872 return this; 873 } 874 875 /** 876 * Set the cell identity. 877 * 878 * @param cellIdentity The cell identity. 879 * 880 * @return The same instance of the builder. 881 * @hide 882 */ 883 @SystemApi @TestApi setCellIdentity(@ullable CellIdentity cellIdentity)884 public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) { 885 mCellIdentity = cellIdentity; 886 return this; 887 } 888 889 /** 890 * Set the registered PLMN. 891 * 892 * @param rplmn the registered plmn. 893 * 894 * @return The same instance of the builder. 895 */ setRegisteredPlmn(@ullable String rplmn)896 public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) { 897 mRplmn = rplmn; 898 return this; 899 } 900 901 /** 902 * Build the NetworkRegistrationInfo. 903 * @return the NetworkRegistrationInfo object. 904 * @hide 905 */ 906 @SystemApi @TestApi build()907 public @NonNull NetworkRegistrationInfo build() { 908 return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState, 909 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, 910 mCellIdentity, mRplmn); 911 } 912 } 913 } 914