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