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.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SystemApi; 24 import android.app.compat.CompatChanges; 25 import android.compat.annotation.ChangeId; 26 import android.compat.annotation.EnabledSince; 27 import android.os.Build; 28 import android.os.Parcel; 29 import android.os.Parcelable; 30 import android.telephony.AccessNetworkConstants.TransportType; 31 import android.telephony.Annotation.NetworkType; 32 import android.text.TextUtils; 33 34 import com.android.internal.telephony.flags.Flags; 35 36 import java.lang.annotation.Retention; 37 import java.lang.annotation.RetentionPolicy; 38 import java.util.ArrayList; 39 import java.util.Collections; 40 import java.util.List; 41 import java.util.Objects; 42 import java.util.stream.Collectors; 43 44 /** 45 * Description of a mobile network registration info 46 */ 47 public final class NetworkRegistrationInfo implements Parcelable { 48 49 /** 50 * A new registration state, REGISTRATION_STATE_EMERGENCY, is added to 51 * {@link NetworkRegistrationInfo}. This change will affect the result of getRegistration(). 52 * @hide 53 */ 54 @ChangeId 55 @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 56 public static final long RETURN_REGISTRATION_STATE_EMERGENCY = 255938466L; 57 58 /** 59 * Network domain 60 * @hide 61 */ 62 @Retention(RetentionPolicy.SOURCE) 63 @IntDef(prefix = "DOMAIN_", value = {DOMAIN_UNKNOWN, DOMAIN_CS, DOMAIN_PS, DOMAIN_CS_PS}) 64 public @interface Domain {} 65 66 /** Unknown / Unspecified domain */ 67 public static final int DOMAIN_UNKNOWN = 0; 68 /** Circuit switched domain */ 69 public static final int DOMAIN_CS = android.hardware.radio.network.Domain.CS; 70 /** Packet switched domain */ 71 public static final int DOMAIN_PS = android.hardware.radio.network.Domain.PS; 72 /** Applicable to both CS and PS Domain */ 73 public static final int DOMAIN_CS_PS = DOMAIN_CS | DOMAIN_PS; 74 75 /** 76 * Network registration state 77 * @hide 78 */ 79 @Retention(RetentionPolicy.SOURCE) 80 @IntDef(prefix = "REGISTRATION_STATE_", 81 value = {REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, REGISTRATION_STATE_HOME, 82 REGISTRATION_STATE_NOT_REGISTERED_SEARCHING, REGISTRATION_STATE_DENIED, 83 REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING, 84 REGISTRATION_STATE_EMERGENCY}) 85 public @interface RegistrationState {} 86 87 /** 88 * Not registered. The device is not currently searching a new operator to register. 89 * @hide 90 */ 91 @SystemApi 92 public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; 93 /** 94 * Registered on home network. 95 * @hide 96 */ 97 @SystemApi 98 public static final int REGISTRATION_STATE_HOME = 1; 99 /** 100 * Not registered. The device is currently searching a new operator to register. 101 * @hide 102 */ 103 @SystemApi 104 public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; 105 /** 106 * Registration denied. 107 * @hide 108 */ 109 @SystemApi 110 public static final int REGISTRATION_STATE_DENIED = 3; 111 /** 112 * Registration state is unknown. 113 * @hide 114 */ 115 @SystemApi 116 public static final int REGISTRATION_STATE_UNKNOWN = 4; 117 /** 118 * Registered on roaming network. 119 * @hide 120 */ 121 @SystemApi 122 public static final int REGISTRATION_STATE_ROAMING = 5; 123 /** 124 * Emergency attached in EPS or in 5GS. 125 * IMS service will skip emergency registration if the device is in 126 * emergency attached state. {@link #mEmergencyOnly} can be true 127 * even in case it's not in emergency attached state. 128 * 129 * Reference: 3GPP TS 24.301 9.9.3.11 EPS attach type. 130 * Reference: 3GPP TS 24.501 9.11.3.6 5GS registration result. 131 * @hide 132 */ 133 @SystemApi 134 public static final int REGISTRATION_STATE_EMERGENCY = 6; 135 136 /** @hide */ 137 @Retention(RetentionPolicy.SOURCE) 138 @IntDef(prefix = "NR_STATE_", 139 value = {NR_STATE_NONE, NR_STATE_RESTRICTED, NR_STATE_NOT_RESTRICTED, 140 NR_STATE_CONNECTED}) 141 public @interface NRState {} 142 143 /** 144 * The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR 145 * Dual Connectivity(EN-DC). 146 */ 147 public static final int NR_STATE_NONE = 0; 148 149 /** 150 * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but 151 * either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by 152 * the selected PLMN. 153 */ 154 public static final int NR_STATE_RESTRICTED = 1; 155 156 /** 157 * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both 158 * the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the 159 * selected PLMN. 160 */ 161 public static final int NR_STATE_NOT_RESTRICTED = 2; 162 163 /** 164 * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and 165 * also connected to at least one 5G cell as a secondary serving cell. 166 */ 167 public static final int NR_STATE_CONNECTED = 3; 168 169 /** 170 * Supported service type 171 * @hide 172 */ 173 @Retention(RetentionPolicy.SOURCE) 174 @IntDef(prefix = "SERVICE_TYPE_", 175 value = {SERVICE_TYPE_UNKNOWN, SERVICE_TYPE_VOICE, SERVICE_TYPE_DATA, SERVICE_TYPE_SMS, 176 SERVICE_TYPE_VIDEO, SERVICE_TYPE_EMERGENCY, SERVICE_TYPE_MMS}) 177 public @interface ServiceType {} 178 179 /** 180 * Unknown service 181 */ 182 public static final int SERVICE_TYPE_UNKNOWN = 0; 183 184 /** 185 * Voice service 186 */ 187 public static final int SERVICE_TYPE_VOICE = 1; 188 189 /** 190 * Data service 191 */ 192 public static final int SERVICE_TYPE_DATA = 2; 193 194 /** 195 * SMS service 196 */ 197 public static final int SERVICE_TYPE_SMS = 3; 198 199 /** 200 * Video service 201 */ 202 public static final int SERVICE_TYPE_VIDEO = 4; 203 204 /** 205 * Emergency service 206 */ 207 public static final int SERVICE_TYPE_EMERGENCY = 5; 208 209 /** 210 * MMS service 211 */ 212 public static final int SERVICE_TYPE_MMS = 6; 213 214 /** @hide */ 215 public static final int FIRST_SERVICE_TYPE = SERVICE_TYPE_VOICE; 216 217 /** @hide */ 218 public static final int LAST_SERVICE_TYPE = SERVICE_TYPE_MMS; 219 220 @Domain 221 private final int mDomain; 222 223 @TransportType 224 private final int mTransportType; 225 226 /** 227 * The true registration state of network, This is not affected by any carrier config or 228 * resource overlay. 229 */ 230 @RegistrationState 231 private final int mNetworkRegistrationState; 232 233 /** 234 * The registration state that might have been overridden by config 235 */ 236 @RegistrationState 237 private int mRegistrationState; 238 239 /** 240 * Save the {@link ServiceState.RoamingType roaming type}. it can be overridden roaming type 241 * from resource overlay or carrier config. 242 */ 243 @ServiceState.RoamingType 244 private int mRoamingType; 245 246 @NetworkType 247 private int mAccessNetworkTechnology; 248 249 @NRState 250 private int mNrState; 251 252 private final int mRejectCause; 253 254 private final boolean mEmergencyOnly; 255 256 @ServiceType 257 private ArrayList<Integer> mAvailableServices; 258 259 @Nullable 260 private CellIdentity mCellIdentity; 261 262 @Nullable 263 private VoiceSpecificRegistrationInfo mVoiceSpecificInfo; 264 265 @Nullable 266 private DataSpecificRegistrationInfo mDataSpecificInfo; 267 268 @NonNull 269 private String mRplmn; 270 271 // Updated based on the accessNetworkTechnology 272 private boolean mIsUsingCarrierAggregation; 273 274 // Set to {@code true} when network is a non-terrestrial network. 275 private boolean mIsNonTerrestrialNetwork; 276 277 /** 278 * @param domain Network domain. Must be a {@link Domain}. For transport type 279 * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}. 280 * @param transportType Transport type. 281 * @param registrationState Network registration state. For transport type 282 * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, only 283 * {@link #REGISTRATION_STATE_HOME} and {@link #REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING} 284 * are valid states. 285 * @param accessNetworkTechnology Access network technology.For transport type 286 * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, set to 287 * {@link TelephonyManager#NETWORK_TYPE_IWLAN}. 288 * @param rejectCause Reason for denial if the registration state is 289 * {@link #REGISTRATION_STATE_DENIED}. Depending on {@code accessNetworkTechnology}, the values 290 * 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 291 * A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set it to 0. 292 * // TODO: Add IWLAN reject cause reference 293 * @param emergencyOnly True if this registration is for emergency only. 294 * @param availableServices The list of the supported services. 295 * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the 296 * information is not available. 297 * @param rplmn the registered plmn or the last plmn for attempted registration if reg failed. 298 * @param voiceSpecificInfo Voice specific registration information. 299 * @param dataSpecificInfo Data specific registration information. 300 * @param isNonTerrestrialNetwork {@code true} if network is a non-terrestrial network. 301 */ 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, boolean isNonTerrestrialNetwork)302 private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType, 303 @RegistrationState int registrationState, 304 @NetworkType int accessNetworkTechnology, int rejectCause, 305 boolean emergencyOnly, @Nullable @ServiceType List<Integer> availableServices, 306 @Nullable CellIdentity cellIdentity, @Nullable String rplmn, 307 @Nullable VoiceSpecificRegistrationInfo voiceSpecificInfo, 308 @Nullable DataSpecificRegistrationInfo dataSpecificInfo, 309 boolean isNonTerrestrialNetwork) { 310 mDomain = domain; 311 mTransportType = transportType; 312 mRegistrationState = registrationState; 313 mNetworkRegistrationState = registrationState; 314 mRoamingType = (registrationState == REGISTRATION_STATE_ROAMING) 315 ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING; 316 setAccessNetworkTechnology(accessNetworkTechnology); 317 mRejectCause = rejectCause; 318 mAvailableServices = (availableServices != null) 319 ? new ArrayList<>(availableServices) : new ArrayList<>(); 320 mCellIdentity = cellIdentity; 321 mEmergencyOnly = emergencyOnly; 322 mNrState = NR_STATE_NONE; 323 mRplmn = rplmn; 324 mVoiceSpecificInfo = voiceSpecificInfo; 325 mDataSpecificInfo = dataSpecificInfo; 326 mIsNonTerrestrialNetwork = isNonTerrestrialNetwork; 327 328 updateNrState(); 329 } 330 331 /** 332 * Constructor for voice network registration info. 333 * @hide 334 */ 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)335 public NetworkRegistrationInfo(int domain, @TransportType int transportType, 336 int registrationState, int accessNetworkTechnology, 337 int rejectCause, boolean emergencyOnly, 338 @Nullable List<Integer> availableServices, 339 @Nullable CellIdentity cellIdentity, @Nullable String rplmn, 340 boolean cssSupported, int roamingIndicator, int systemIsInPrl, 341 int defaultRoamingIndicator) { 342 this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, 343 emergencyOnly, availableServices, cellIdentity, rplmn, 344 new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator, 345 systemIsInPrl, defaultRoamingIndicator), null, false); 346 } 347 348 /** 349 * Constructor for data network registration info. 350 * @hide 351 */ 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)352 public NetworkRegistrationInfo(int domain, @TransportType int transportType, 353 int registrationState, int accessNetworkTechnology, 354 int rejectCause, boolean emergencyOnly, 355 @Nullable List<Integer> availableServices, 356 @Nullable CellIdentity cellIdentity, @Nullable String rplmn, 357 int maxDataCalls, boolean isDcNrRestricted, 358 boolean isNrAvailable, boolean isEndcAvailable, 359 @Nullable VopsSupportInfo vopsSupportInfo) { 360 this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, 361 emergencyOnly, availableServices, cellIdentity, rplmn, null, 362 new DataSpecificRegistrationInfo.Builder(maxDataCalls) 363 .setDcNrRestricted(isDcNrRestricted) 364 .setNrAvailable(isNrAvailable) 365 .setEnDcAvailable(isEndcAvailable) 366 .setVopsSupportInfo(vopsSupportInfo) 367 .build(), false); 368 } 369 NetworkRegistrationInfo(Parcel source)370 private NetworkRegistrationInfo(Parcel source) { 371 mDomain = source.readInt(); 372 mTransportType = source.readInt(); 373 mRegistrationState = source.readInt(); 374 mNetworkRegistrationState = source.readInt(); 375 mRoamingType = source.readInt(); 376 mAccessNetworkTechnology = source.readInt(); 377 mRejectCause = source.readInt(); 378 mEmergencyOnly = source.readBoolean(); 379 mAvailableServices = new ArrayList<>(); 380 source.readList(mAvailableServices, Integer.class.getClassLoader(), java.lang.Integer.class); 381 mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader(), android.telephony.CellIdentity.class); 382 mVoiceSpecificInfo = source.readParcelable( 383 VoiceSpecificRegistrationInfo.class.getClassLoader(), android.telephony.VoiceSpecificRegistrationInfo.class); 384 mDataSpecificInfo = source.readParcelable( 385 DataSpecificRegistrationInfo.class.getClassLoader(), android.telephony.DataSpecificRegistrationInfo.class); 386 mNrState = source.readInt(); 387 mRplmn = source.readString(); 388 mIsUsingCarrierAggregation = source.readBoolean(); 389 mIsNonTerrestrialNetwork = source.readBoolean(); 390 } 391 392 /** 393 * Constructor from another network registration info 394 * 395 * @param nri Another network registration info 396 * @hide 397 */ NetworkRegistrationInfo(NetworkRegistrationInfo nri)398 public NetworkRegistrationInfo(NetworkRegistrationInfo nri) { 399 mDomain = nri.mDomain; 400 mTransportType = nri.mTransportType; 401 mRegistrationState = nri.mRegistrationState; 402 mNetworkRegistrationState = nri.mNetworkRegistrationState; 403 mRoamingType = nri.mRoamingType; 404 mAccessNetworkTechnology = nri.mAccessNetworkTechnology; 405 mIsUsingCarrierAggregation = nri.mIsUsingCarrierAggregation; 406 mIsNonTerrestrialNetwork = nri.mIsNonTerrestrialNetwork; 407 mRejectCause = nri.mRejectCause; 408 mEmergencyOnly = nri.mEmergencyOnly; 409 mAvailableServices = new ArrayList<>(nri.mAvailableServices); 410 if (nri.mCellIdentity != null) { 411 Parcel p = Parcel.obtain(); 412 nri.mCellIdentity.writeToParcel(p, 0); 413 p.setDataPosition(0); 414 // TODO: Instead of doing this, we should create a formal way for cloning cell identity. 415 // Cell identity is not an immutable object so we have to deep copy it. 416 mCellIdentity = CellIdentity.CREATOR.createFromParcel(p); 417 p.recycle(); 418 } 419 420 if (nri.mVoiceSpecificInfo != null) { 421 mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(nri.mVoiceSpecificInfo); 422 } 423 if (nri.mDataSpecificInfo != null) { 424 mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo); 425 } 426 mNrState = nri.mNrState; 427 mRplmn = nri.mRplmn; 428 } 429 430 /** 431 * @return The transport type. 432 */ getTransportType()433 public @TransportType int getTransportType() { return mTransportType; } 434 435 /** 436 * @return The network domain. 437 */ getDomain()438 public @Domain int getDomain() { return mDomain; } 439 440 /** 441 * Get the 5G NR connection state. 442 * 443 * @return the 5G NR connection state. 444 * @hide 445 */ getNrState()446 public @NRState int getNrState() { 447 return mNrState; 448 } 449 450 /** @hide */ setNrState(@RState int nrState)451 public void setNrState(@NRState int nrState) { 452 mNrState = nrState; 453 } 454 455 /** 456 * @return The registration state. Note this value can be affected by the carrier config 457 * override. 458 * 459 * @deprecated Use {@link #getNetworkRegistrationState}, which is not affected by any carrier 460 * config or resource overlay, instead. 461 * @hide 462 */ 463 @Deprecated 464 @SystemApi getRegistrationState()465 public @RegistrationState int getRegistrationState() { 466 if (mRegistrationState == REGISTRATION_STATE_EMERGENCY) { 467 if (!CompatChanges.isChangeEnabled(RETURN_REGISTRATION_STATE_EMERGENCY)) { 468 if (mAccessNetworkTechnology == TelephonyManager.NETWORK_TYPE_LTE) { 469 return REGISTRATION_STATE_DENIED; 470 } else if (mAccessNetworkTechnology == TelephonyManager.NETWORK_TYPE_NR) { 471 return REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; 472 } 473 } 474 } 475 return mRegistrationState; 476 } 477 478 /** 479 * @return The true registration state of network. (This value is not affected by any carrier 480 * config or resource overlay override). 481 * 482 * @hide 483 */ 484 @SystemApi getNetworkRegistrationState()485 public @RegistrationState int getNetworkRegistrationState() { 486 return mNetworkRegistrationState; 487 } 488 489 /** 490 * @return {@code true} if registered on roaming or home network. Note this value can be 491 * affected by the carrier config override. 492 * 493 * @deprecated Use {@link #isNetworkRegistered}, which is not affected by any carrier config or 494 * resource overlay, instead. 495 */ 496 @Deprecated isRegistered()497 public boolean isRegistered() { 498 return mRegistrationState == REGISTRATION_STATE_HOME 499 || mRegistrationState == REGISTRATION_STATE_ROAMING; 500 } 501 502 /** 503 * @return {@code true} if registered on roaming or home network, {@code false} otherwise. (This 504 * value is not affected by any carrier config or resource overlay override). 505 */ isNetworkRegistered()506 public boolean isNetworkRegistered() { 507 return mNetworkRegistrationState == REGISTRATION_STATE_HOME 508 || mNetworkRegistrationState == REGISTRATION_STATE_ROAMING; 509 } 510 511 /** 512 * @return {@code true} if searching for service, {@code false} otherwise. 513 * 514 * @deprecated Use {@link #isNetworkRegistered}, which is not affected by any carrier config or 515 * resource overlay, instead. 516 */ 517 @Deprecated isSearching()518 public boolean isSearching() { 519 return mRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING; 520 } 521 522 /** 523 * @return {@code true} if searching for service, {@code false} otherwise. (This value is not 524 * affected by any carrier config or resource overlay override). 525 */ isNetworkSearching()526 public boolean isNetworkSearching() { 527 return mNetworkRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING; 528 } 529 530 /** 531 * Get the PLMN-ID for this Network Registration, also known as the RPLMN. 532 * 533 * <p>If the device is registered, this will return the registered PLMN-ID. If registration 534 * has failed, then this will return the PLMN ID of the last attempted registration. If the 535 * device is not registered, or if is registered to a non-3GPP radio technology, then this 536 * will return null. 537 * 538 * <p>See 3GPP TS 23.122 for further information about the Registered PLMN. 539 * 540 * @return the registered PLMN-ID or null. 541 */ getRegisteredPlmn()542 @Nullable public String getRegisteredPlmn() { 543 return mRplmn; 544 } 545 546 /** 547 * @return {@code true} if registered on roaming network overridden by config. Note this value 548 * can be affected by the carrier config override. 549 * 550 * @deprecated Use {@link TelephonyDisplayInfo#isRoaming} instead. 551 */ 552 @Deprecated isRoaming()553 public boolean isRoaming() { 554 return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING; 555 } 556 557 /** 558 * @return {@code true} if registered on roaming network. (This value is not affected by any 559 * carrier config or resource overlay override). 560 */ isNetworkRoaming()561 public boolean isNetworkRoaming() { 562 return mNetworkRegistrationState == REGISTRATION_STATE_ROAMING; 563 } 564 565 /** 566 * @hide 567 * @return {@code true} if in service. 568 */ isInService()569 public boolean isInService() { 570 return mRegistrationState == REGISTRATION_STATE_HOME 571 || mRegistrationState == REGISTRATION_STATE_ROAMING; 572 } 573 574 /** 575 * Set {@link ServiceState.RoamingType roaming type}. This could override 576 * roaming type based on resource overlay or carrier config. 577 * @hide 578 */ setRoamingType(@erviceState.RoamingType int roamingType)579 public void setRoamingType(@ServiceState.RoamingType int roamingType) { 580 mRoamingType = roamingType; 581 582 // make sure mRegistrationState to be consistent in case of any roaming type override 583 if (isRoaming()) { 584 if (mRegistrationState == REGISTRATION_STATE_HOME) { 585 mRegistrationState = REGISTRATION_STATE_ROAMING; 586 } 587 } else { 588 if (mRegistrationState == REGISTRATION_STATE_ROAMING) { 589 mRegistrationState = REGISTRATION_STATE_HOME; 590 } 591 } 592 } 593 594 /** 595 * @return the current network roaming type. Note that this value can be possibly overridden by 596 * the carrier config or resource overlay. 597 * @hide 598 */ 599 @SystemApi getRoamingType()600 public @ServiceState.RoamingType int getRoamingType() { 601 return mRoamingType; 602 } 603 604 /** 605 * @return Whether emergency is enabled. 606 * @hide 607 */ 608 @SystemApi isEmergencyEnabled()609 public boolean isEmergencyEnabled() { return mEmergencyOnly; } 610 611 /** 612 * @return List of available service types. 613 */ 614 @NonNull 615 @ServiceType getAvailableServices()616 public List<Integer> getAvailableServices() { 617 return Collections.unmodifiableList(mAvailableServices); 618 } 619 620 /** 621 * Set available service types. 622 * 623 * @param availableServices The list of available services for this network. 624 * @hide 625 */ setAvailableServices(@onNull @erviceType List<Integer> availableServices)626 public void setAvailableServices(@NonNull @ServiceType List<Integer> availableServices) { 627 mAvailableServices = new ArrayList<>(availableServices); 628 } 629 630 /** 631 * @return The access network technology network type.. 632 */ getAccessNetworkTechnology()633 public @NetworkType int getAccessNetworkTechnology() { 634 return mAccessNetworkTechnology; 635 } 636 637 /** 638 * override the access network technology {@link NetworkType} e.g, rat ratchet. 639 * @hide 640 */ setAccessNetworkTechnology(@etworkType int tech)641 public void setAccessNetworkTechnology(@NetworkType int tech) { 642 if (tech == TelephonyManager.NETWORK_TYPE_LTE_CA) { 643 // For old device backward compatibility support 644 tech = TelephonyManager.NETWORK_TYPE_LTE; 645 mIsUsingCarrierAggregation = true; 646 } 647 mAccessNetworkTechnology = tech; 648 } 649 650 /** 651 * Get the 3GPP/3GPP2 reason code indicating why registration failed. 652 * 653 * Returns the reason code for non-transient registration failures. Typically this method will 654 * only return the last reason code received during a network selection procedure. The reason 655 * code is system-specific; however, the reason codes for both 3GPP and 3GPP2 systems are 656 * largely equivalent across generations. 657 * 658 * @return registration reject cause if available, otherwise 0. Depending on 659 * {@link #getAccessNetworkTechnology}, the values are defined in 3GPP TS 24.008 10.5.3.6 for 660 * WCDMA/UMTS, 3GPP TS 24.301 9.9.3.9 for LTE/EPS, 3GPP 24.501 Annex A for NR/5GS, or 3GPP2 661 * A.S0001 6.2.2.44 for CDMA. 662 */ 663 @FlaggedApi(Flags.FLAG_NETWORK_REGISTRATION_INFO_REJECT_CAUSE) getRejectCause()664 public int getRejectCause() { 665 return mRejectCause; 666 } 667 668 /** 669 * Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION}, otherwise return null. 670 * 671 * @return The cell information. 672 */ 673 @Nullable getCellIdentity()674 public CellIdentity getCellIdentity() { 675 return mCellIdentity; 676 } 677 678 /** 679 * Set whether network has configured carrier aggregation or not. 680 * 681 * @param isUsingCarrierAggregation set whether or not carrier aggregation is used. 682 * 683 * @hide 684 */ setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation)685 public void setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation) { 686 mIsUsingCarrierAggregation = isUsingCarrierAggregation; 687 } 688 689 /** 690 * Get whether network has configured carrier aggregation or not. 691 * 692 * @return {@code true} if using carrier aggregation. 693 * @hide 694 */ isUsingCarrierAggregation()695 public boolean isUsingCarrierAggregation() { 696 return mIsUsingCarrierAggregation; 697 } 698 699 /** 700 * Set whether the network is a non-terrestrial network. 701 * 702 * @param isNonTerrestrialNetwork {@code true} if network is a non-terrestrial network 703 * else {@code false}. 704 * @hide 705 */ setIsNonTerrestrialNetwork(boolean isNonTerrestrialNetwork)706 public void setIsNonTerrestrialNetwork(boolean isNonTerrestrialNetwork) { 707 mIsNonTerrestrialNetwork = isNonTerrestrialNetwork; 708 } 709 710 /** 711 * Get whether the network is a non-terrestrial network. 712 * 713 * @return {@code true} if network is a non-terrestrial network else {@code false}. 714 */ isNonTerrestrialNetwork()715 public boolean isNonTerrestrialNetwork() { 716 return mIsNonTerrestrialNetwork; 717 } 718 719 /** 720 * @hide 721 */ 722 @Nullable getVoiceSpecificInfo()723 public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() { 724 return mVoiceSpecificInfo; 725 } 726 727 /** 728 * @return Data registration related info 729 * @hide 730 */ 731 @Nullable 732 @SystemApi getDataSpecificInfo()733 public DataSpecificRegistrationInfo getDataSpecificInfo() { 734 return mDataSpecificInfo; 735 } 736 737 @Override describeContents()738 public int describeContents() { 739 return 0; 740 } 741 742 /** 743 * Convert service type to string 744 * 745 * @hide 746 * 747 * @param serviceType The service type 748 * @return The service type in string format 749 */ serviceTypeToString(@erviceType int serviceType)750 public static String serviceTypeToString(@ServiceType int serviceType) { 751 switch (serviceType) { 752 case SERVICE_TYPE_VOICE: return "VOICE"; 753 case SERVICE_TYPE_DATA: return "DATA"; 754 case SERVICE_TYPE_SMS: return "SMS"; 755 case SERVICE_TYPE_VIDEO: return "VIDEO"; 756 case SERVICE_TYPE_EMERGENCY: return "EMERGENCY"; 757 case SERVICE_TYPE_MMS: return "MMS"; 758 } 759 return "Unknown service type " + serviceType; 760 } 761 762 /** 763 * Convert registration state to string 764 * 765 * @hide 766 * 767 * @param registrationState The registration state 768 * @return The reg state in string 769 */ registrationStateToString(@egistrationState int registrationState)770 public static String registrationStateToString(@RegistrationState int registrationState) { 771 switch (registrationState) { 772 case REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING: return "NOT_REG_OR_SEARCHING"; 773 case REGISTRATION_STATE_HOME: return "HOME"; 774 case REGISTRATION_STATE_NOT_REGISTERED_SEARCHING: return "NOT_REG_SEARCHING"; 775 case REGISTRATION_STATE_DENIED: return "DENIED"; 776 case REGISTRATION_STATE_UNKNOWN: return "UNKNOWN"; 777 case REGISTRATION_STATE_ROAMING: return "ROAMING"; 778 case REGISTRATION_STATE_EMERGENCY: return "EMERGENCY"; 779 } 780 return "Unknown reg state " + registrationState; 781 } 782 783 /** @hide */ nrStateToString(@RState int nrState)784 public static String nrStateToString(@NRState int nrState) { 785 switch (nrState) { 786 case NR_STATE_RESTRICTED: 787 return "RESTRICTED"; 788 case NR_STATE_NOT_RESTRICTED: 789 return "NOT_RESTRICTED"; 790 case NR_STATE_CONNECTED: 791 return "CONNECTED"; 792 default: 793 return "NONE"; 794 } 795 } 796 797 /** @hide */ domainToString(@omain int domain)798 static @NonNull String domainToString(@Domain int domain) { 799 switch (domain) { 800 case DOMAIN_CS: return "CS"; 801 case DOMAIN_PS: return "PS"; 802 case DOMAIN_CS_PS: return "CS_PS"; 803 default: return "UNKNOWN"; 804 } 805 } 806 807 /** 808 * Convert isNonTerrestrialNetwork to string 809 * 810 * @param isNonTerrestrialNetwork boolean indicating whether network is a non-terrestrial 811 * network 812 * @return string format of isNonTerrestrialNetwork. 813 * @hide 814 */ isNonTerrestrialNetworkToString(boolean isNonTerrestrialNetwork)815 public static String isNonTerrestrialNetworkToString(boolean isNonTerrestrialNetwork) { 816 return isNonTerrestrialNetwork ? "NON-TERRESTRIAL" : "TERRESTRIAL"; 817 } 818 819 @NonNull 820 @Override toString()821 public String toString() { 822 return new StringBuilder("NetworkRegistrationInfo{") 823 .append(" domain=").append(domainToString(mDomain)) 824 .append(" transportType=").append( 825 AccessNetworkConstants.transportTypeToString(mTransportType)) 826 .append(" registrationState=").append(registrationStateToString(mRegistrationState)) 827 .append(" networkRegistrationState=") 828 .append(registrationStateToString(mNetworkRegistrationState)) 829 .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType)) 830 .append(" accessNetworkTechnology=") 831 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology)) 832 .append(" rejectCause=").append(mRejectCause) 833 .append(" emergencyEnabled=").append(mEmergencyOnly) 834 .append(" availableServices=").append("[" + (mAvailableServices != null 835 ? mAvailableServices.stream().map(type -> serviceTypeToString(type)) 836 .collect(Collectors.joining(",")) : null) + "]") 837 .append(" cellIdentity=").append(mCellIdentity) 838 .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo) 839 .append(" dataSpecificInfo=").append(mDataSpecificInfo) 840 .append(" nrState=").append(Build.IS_DEBUGGABLE 841 ? nrStateToString(mNrState) : "****") 842 .append(" rRplmn=").append(mRplmn) 843 .append(" isUsingCarrierAggregation=").append(mIsUsingCarrierAggregation) 844 .append(" isNonTerrestrialNetwork=").append( 845 isNonTerrestrialNetworkToString(mIsNonTerrestrialNetwork)) 846 .append("}").toString(); 847 } 848 849 @Override hashCode()850 public int hashCode() { 851 return Objects.hash(mDomain, mTransportType, mRegistrationState, mNetworkRegistrationState, 852 mRoamingType, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, 853 mAvailableServices, mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, 854 mRplmn, mIsUsingCarrierAggregation, mIsNonTerrestrialNetwork); 855 } 856 857 @Override equals(@ullable Object o)858 public boolean equals(@Nullable Object o) { 859 if (this == o) return true; 860 861 if (!(o instanceof NetworkRegistrationInfo)) { 862 return false; 863 } 864 865 NetworkRegistrationInfo other = (NetworkRegistrationInfo) o; 866 return mDomain == other.mDomain 867 && mTransportType == other.mTransportType 868 && mRegistrationState == other.mRegistrationState 869 && mNetworkRegistrationState == other.mNetworkRegistrationState 870 && mRoamingType == other.mRoamingType 871 && mAccessNetworkTechnology == other.mAccessNetworkTechnology 872 && mRejectCause == other.mRejectCause 873 && mEmergencyOnly == other.mEmergencyOnly 874 && mAvailableServices.equals(other.mAvailableServices) 875 && mIsUsingCarrierAggregation == other.mIsUsingCarrierAggregation 876 && Objects.equals(mCellIdentity, other.mCellIdentity) 877 && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo) 878 && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo) 879 && TextUtils.equals(mRplmn, other.mRplmn) 880 && mNrState == other.mNrState 881 && mIsNonTerrestrialNetwork == other.mIsNonTerrestrialNetwork; 882 } 883 884 /** 885 * @hide 886 */ 887 @Override 888 @SystemApi writeToParcel(Parcel dest, int flags)889 public void writeToParcel(Parcel dest, int flags) { 890 dest.writeInt(mDomain); 891 dest.writeInt(mTransportType); 892 dest.writeInt(mRegistrationState); 893 dest.writeInt(mNetworkRegistrationState); 894 dest.writeInt(mRoamingType); 895 dest.writeInt(mAccessNetworkTechnology); 896 dest.writeInt(mRejectCause); 897 dest.writeBoolean(mEmergencyOnly); 898 dest.writeList(mAvailableServices); 899 dest.writeParcelable(mCellIdentity, 0); 900 dest.writeParcelable(mVoiceSpecificInfo, 0); 901 dest.writeParcelable(mDataSpecificInfo, 0); 902 dest.writeInt(mNrState); 903 dest.writeString(mRplmn); 904 dest.writeBoolean(mIsUsingCarrierAggregation); 905 dest.writeBoolean(mIsNonTerrestrialNetwork); 906 } 907 908 /** 909 * Use the 5G NR Non-Standalone indicators from the network registration state to update the 910 * NR state. There are 3 indicators in the network registration state: 911 * 912 * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell. 913 * 2. if NR is supported by the selected PLMN. 914 * 3. if the use of dual connectivity with NR is restricted. 915 * 916 * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary 917 * serving cell. 918 * 919 * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of 920 * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G 921 * NR is restricted. 922 * 923 * @hide 924 */ updateNrState()925 public void updateNrState() { 926 mNrState = NR_STATE_NONE; 927 if (mDataSpecificInfo != null && mDataSpecificInfo.isEnDcAvailable) { 928 if (!mDataSpecificInfo.isDcNrRestricted && mDataSpecificInfo.isNrAvailable) { 929 mNrState = NR_STATE_NOT_RESTRICTED; 930 } else { 931 mNrState = NR_STATE_RESTRICTED; 932 } 933 } 934 } 935 936 public static final @NonNull Parcelable.Creator<NetworkRegistrationInfo> CREATOR = 937 new Parcelable.Creator<NetworkRegistrationInfo>() { 938 @Override 939 public NetworkRegistrationInfo createFromParcel(Parcel source) { 940 return new NetworkRegistrationInfo(source); 941 } 942 943 @Override 944 public NetworkRegistrationInfo[] newArray(int size) { 945 return new NetworkRegistrationInfo[size]; 946 } 947 }; 948 949 /** 950 * @hide 951 */ sanitizeLocationInfo()952 public NetworkRegistrationInfo sanitizeLocationInfo() { 953 NetworkRegistrationInfo result = copy(); 954 result.mCellIdentity = null; 955 return result; 956 } 957 copy()958 private NetworkRegistrationInfo copy() { 959 Parcel p = Parcel.obtain(); 960 this.writeToParcel(p, 0); 961 p.setDataPosition(0); 962 NetworkRegistrationInfo result = new NetworkRegistrationInfo(p); 963 p.recycle(); 964 return result; 965 } 966 967 /** 968 * Provides a convenient way to set the fields of a {@link NetworkRegistrationInfo} when 969 * creating a new instance. 970 * 971 * <p>The example below shows how you might create a new {@code NetworkRegistrationInfo}: 972 * 973 * <pre><code> 974 * 975 * NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder() 976 * .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) 977 * .setRegistrationState(REGISTRATION_STATE_HOME) 978 * .build(); 979 * </code></pre> 980 * @hide 981 */ 982 @SystemApi 983 public static final class Builder { 984 @Domain 985 private int mDomain; 986 987 @TransportType 988 private int mTransportType; 989 990 @RegistrationState 991 private int mNetworkRegistrationState; 992 993 @NetworkType 994 private int mAccessNetworkTechnology; 995 996 private int mRejectCause; 997 998 private boolean mEmergencyOnly; 999 1000 @ServiceType 1001 private List<Integer> mAvailableServices; 1002 1003 @Nullable 1004 private CellIdentity mCellIdentity; 1005 1006 @NonNull 1007 private String mRplmn = ""; 1008 1009 @Nullable 1010 private DataSpecificRegistrationInfo mDataSpecificRegistrationInfo; 1011 1012 @Nullable 1013 private VoiceSpecificRegistrationInfo mVoiceSpecificRegistrationInfo; 1014 1015 private boolean mIsNonTerrestrialNetwork; 1016 1017 /** 1018 * Default constructor for Builder. 1019 */ Builder()1020 public Builder() {} 1021 1022 /** 1023 * Builder from the existing {@link NetworkRegistrationInfo}. 1024 * 1025 * @param nri The network registration info object. 1026 * @hide 1027 */ Builder(@onNull NetworkRegistrationInfo nri)1028 public Builder(@NonNull NetworkRegistrationInfo nri) { 1029 mDomain = nri.mDomain; 1030 mTransportType = nri.mTransportType; 1031 mNetworkRegistrationState = nri.mNetworkRegistrationState; 1032 mAccessNetworkTechnology = nri.mAccessNetworkTechnology; 1033 mRejectCause = nri.mRejectCause; 1034 mEmergencyOnly = nri.mEmergencyOnly; 1035 mAvailableServices = new ArrayList<>(nri.mAvailableServices); 1036 mCellIdentity = nri.mCellIdentity; 1037 if (nri.mDataSpecificInfo != null) { 1038 mDataSpecificRegistrationInfo = new DataSpecificRegistrationInfo( 1039 nri.mDataSpecificInfo); 1040 } 1041 if (nri.mVoiceSpecificInfo != null) { 1042 mVoiceSpecificRegistrationInfo = new VoiceSpecificRegistrationInfo( 1043 nri.mVoiceSpecificInfo); 1044 } 1045 mIsNonTerrestrialNetwork = nri.mIsNonTerrestrialNetwork; 1046 } 1047 1048 /** 1049 * Set the network domain. 1050 * 1051 * @param domain Network domain. 1052 * 1053 * @return The same instance of the builder. 1054 */ setDomain(@omain int domain)1055 public @NonNull Builder setDomain(@Domain int domain) { 1056 mDomain = domain; 1057 return this; 1058 } 1059 1060 /** 1061 * Set the transport type. 1062 * 1063 * @param transportType Transport type. 1064 * 1065 * @return The same instance of the builder. 1066 */ setTransportType(@ransportType int transportType)1067 public @NonNull Builder setTransportType(@TransportType int transportType) { 1068 mTransportType = transportType; 1069 return this; 1070 } 1071 1072 /** 1073 * Set the registration state. 1074 * 1075 * @param registrationState The registration state. 1076 * 1077 * @return The same instance of the builder. 1078 */ setRegistrationState(@egistrationState int registrationState)1079 public @NonNull Builder setRegistrationState(@RegistrationState int registrationState) { 1080 mNetworkRegistrationState = registrationState; 1081 return this; 1082 } 1083 1084 /** 1085 * Set tne access network technology. 1086 * 1087 * @return The same instance of the builder. 1088 * 1089 * @param accessNetworkTechnology The access network technology 1090 */ setAccessNetworkTechnology( @etworkType int accessNetworkTechnology)1091 public @NonNull Builder setAccessNetworkTechnology( 1092 @NetworkType int accessNetworkTechnology) { 1093 mAccessNetworkTechnology = accessNetworkTechnology; 1094 return this; 1095 } 1096 1097 /** 1098 * Set the network reject cause. 1099 * 1100 * @param rejectCause Reason for denial if the registration state is 1101 * {@link #REGISTRATION_STATE_DENIED}.Depending on {@code accessNetworkTechnology}, the 1102 * values are defined in 3GPP TS 24.008 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, 1103 * and 3GPP2 A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set 1104 * it to 0. 1105 * 1106 * @return The same instance of the builder. 1107 */ setRejectCause(int rejectCause)1108 public @NonNull Builder setRejectCause(int rejectCause) { 1109 mRejectCause = rejectCause; 1110 return this; 1111 } 1112 1113 /** 1114 * Set emergency only. 1115 * 1116 * @param emergencyOnly True if this network registration is for emergency use only. 1117 * 1118 * @return The same instance of the builder. 1119 * @hide 1120 */ 1121 @SystemApi setEmergencyOnly(boolean emergencyOnly)1122 public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) { 1123 mEmergencyOnly = emergencyOnly; 1124 return this; 1125 } 1126 1127 /** 1128 * Set the available services. 1129 * 1130 * @param availableServices Available services. 1131 * 1132 * @return The same instance of the builder. 1133 * @hide 1134 */ 1135 @SystemApi setAvailableServices( @onNull @erviceType List<Integer> availableServices)1136 public @NonNull Builder setAvailableServices( 1137 @NonNull @ServiceType List<Integer> availableServices) { 1138 mAvailableServices = availableServices; 1139 return this; 1140 } 1141 1142 /** 1143 * Set the cell identity. 1144 * 1145 * @param cellIdentity The cell identity. 1146 * 1147 * @return The same instance of the builder. 1148 * @hide 1149 */ 1150 @SystemApi setCellIdentity(@ullable CellIdentity cellIdentity)1151 public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) { 1152 mCellIdentity = cellIdentity; 1153 return this; 1154 } 1155 1156 /** 1157 * Set the registered PLMN. 1158 * 1159 * @param rplmn the registered plmn. 1160 * 1161 * @return The same instance of the builder. 1162 */ setRegisteredPlmn(@ullable String rplmn)1163 public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) { 1164 mRplmn = rplmn; 1165 return this; 1166 } 1167 1168 /** 1169 * Set voice specific registration information. 1170 * 1171 * @param info The voice specific registration information. 1172 * @return The builder. 1173 * @hide 1174 */ setVoiceSpecificInfo(@onNull VoiceSpecificRegistrationInfo info)1175 public @NonNull Builder setVoiceSpecificInfo(@NonNull VoiceSpecificRegistrationInfo info) { 1176 mVoiceSpecificRegistrationInfo = info; 1177 return this; 1178 } 1179 1180 /** 1181 * Set data specific registration information. 1182 * 1183 * @param info The data specific registration information. 1184 * @return The builder. 1185 * @hide 1186 */ setDataSpecificInfo(@onNull DataSpecificRegistrationInfo info)1187 public @NonNull Builder setDataSpecificInfo(@NonNull DataSpecificRegistrationInfo info) { 1188 mDataSpecificRegistrationInfo = info; 1189 return this; 1190 } 1191 1192 /** 1193 * Set whether the network is a non-terrestrial network. 1194 * 1195 * @param isNonTerrestrialNetwork {@code true} if network is a non-terrestrial network 1196 * else {@code false}. 1197 * @return The builder. 1198 */ setIsNonTerrestrialNetwork(boolean isNonTerrestrialNetwork)1199 public @NonNull Builder setIsNonTerrestrialNetwork(boolean isNonTerrestrialNetwork) { 1200 mIsNonTerrestrialNetwork = isNonTerrestrialNetwork; 1201 return this; 1202 } 1203 1204 /** 1205 * Build the NetworkRegistrationInfo. 1206 * @return the NetworkRegistrationInfo object. 1207 * @hide 1208 */ 1209 @SystemApi build()1210 public @NonNull NetworkRegistrationInfo build() { 1211 return new NetworkRegistrationInfo(mDomain, mTransportType, mNetworkRegistrationState, 1212 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, 1213 mCellIdentity, mRplmn, mVoiceSpecificRegistrationInfo, 1214 mDataSpecificRegistrationInfo, mIsNonTerrestrialNetwork); 1215 } 1216 } 1217 } 1218