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