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