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