content: /*
   * Copyright 2017 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.telephony;
  
  import android.annotation.IntDef;
  import android.annotation.NonNull;
  import android.annotation.Nullable;
  import android.annotation.SystemApi;
  import android.annotation.TestApi;
  import android.os.Parcel;
  import android.os.Parcelable;
  import android.telephony.AccessNetworkConstants.TransportType;
  import android.telephony.TelephonyManager.NetworkType;
  
  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  import java.util.Objects;
  import java.util.stream.Collectors;
  
  /**
   * Description of a mobile network registration info
   * @hide
   */
  @SystemApi
  @TestApi
  public final class NetworkRegistrationInfo implements Parcelable {
      /**
       * Network domain
       * @hide
       */
      @Retention(RetentionPolicy.SOURCE)
      @IntDef(prefix = "DOMAIN_", value = {DOMAIN_CS, DOMAIN_PS})
      public @interface Domain {}
  
      /** Circuit switching domain */
      public static final int DOMAIN_CS = 1;
      /** Packet switching domain */
      public static final int DOMAIN_PS = 2;
  
      /**
       * Network registration state
       * @hide
       */
      @Retention(RetentionPolicy.SOURCE)
      @IntDef(prefix = "REGISTRATION_STATE_",
              value = {REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, REGISTRATION_STATE_HOME,
                      REGISTRATION_STATE_NOT_REGISTERED_SEARCHING, REGISTRATION_STATE_DENIED,
                      REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING})
      public @interface RegistrationState {}
  
      /** Not registered. The device is not currently searching a new operator to register. */
      public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0;
      /** Registered on home network. */
      public static final int REGISTRATION_STATE_HOME = 1;
      /** Not registered. The device is currently searching a new operator to register. */
      public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2;
      /** Registration denied. */
      public static final int REGISTRATION_STATE_DENIED = 3;
      /** Registration state is unknown. */
      public static final int REGISTRATION_STATE_UNKNOWN = 4;
      /** Registered on roaming network. */
      public static final int REGISTRATION_STATE_ROAMING = 5;
  
      /** @hide */
      @Retention(RetentionPolicy.SOURCE)
      @IntDef(prefix = "NR_STATE_",
              value = {NR_STATE_NONE, NR_STATE_RESTRICTED, NR_STATE_NOT_RESTRICTED,
                      NR_STATE_CONNECTED})
      public @interface NRState {}
  
      /**
       * The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR
       * Dual Connectivity(EN-DC).
       * @hide
       */
      public static final int NR_STATE_NONE = -1;
  
      /**
       * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but
       * either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by
       * the selected PLMN.
       * @hide
       */
      public static final int NR_STATE_RESTRICTED = 1;
  
      /**
       * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both
       * the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the
       * selected PLMN.
       * @hide
       */
      public static final int NR_STATE_NOT_RESTRICTED = 2;
  
      /**
       * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and
       * also connected to at least one 5G cell as a secondary serving cell.
       * @hide
       */
      public static final int NR_STATE_CONNECTED = 3;
  
      /**
       * Supported service type
       * @hide
       */
      @Retention(RetentionPolicy.SOURCE)
      @IntDef(prefix = "SERVICE_TYPE_",
              value = {SERVICE_TYPE_UNKNOWN, SERVICE_TYPE_VOICE, SERVICE_TYPE_DATA, SERVICE_TYPE_SMS,
                      SERVICE_TYPE_VIDEO, SERVICE_TYPE_EMERGENCY})
      public @interface ServiceType {}
  
      /** Unkown service */
      public static final int SERVICE_TYPE_UNKNOWN    = 0;
  
      /** Voice service */
      public static final int SERVICE_TYPE_VOICE      = 1;
  
      /** Data service */
      public static final int SERVICE_TYPE_DATA       = 2;
  
      /** SMS service */
      public static final int SERVICE_TYPE_SMS        = 3;
  
      /** Video service */
      public static final int SERVICE_TYPE_VIDEO      = 4;
  
      /** Emergency service */
      public static final int SERVICE_TYPE_EMERGENCY  = 5;
  
      @Domain
      private final int mDomain;
  
      @TransportType
      private final int mTransportType;
  
      @RegistrationState
      private final int mRegistrationState;
  
      /**
       * Save the {@link ServiceState.RoamingType roaming type}. it can be overridden roaming type
       * from resource overlay or carrier config.
       */
      @ServiceState.RoamingType
      private int mRoamingType;
  
      @NetworkType
      private int mAccessNetworkTechnology;
  
      @NRState
      private int mNrState;
  
      private final int mRejectCause;
  
      private final boolean mEmergencyOnly;
  
      @ServiceType
      private final ArrayList<Integer> mAvailableServices;
  
      @Nullable
      private CellIdentity mCellIdentity;
  
      @Nullable
      private VoiceSpecificRegistrationInfo mVoiceSpecificInfo;
  
      @Nullable
      private DataSpecificRegistrationInfo mDataSpecificInfo;
  
      /**
       * @param domain Network domain. Must be a {@link Domain}. For transport type
       * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}.
       * @param transportType Transport type.
       * @param registrationState Network registration state. For transport type
       * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, only
       * {@link #REGISTRATION_STATE_HOME} and {@link #REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING}
       * are valid states.
       * @param accessNetworkTechnology Access network technology.For transport type
       * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, set to
       * {@link TelephonyManager#NETWORK_TYPE_IWLAN}.
       * @param rejectCause Reason for denial if the registration state is
       * {@link #REGISTRATION_STATE_DENIED}. Depending on {@code accessNetworkTechnology}, the values
       * 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
       * A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set it to 0.
       * // TODO: Add IWLAN reject cause reference
       * @param emergencyOnly True if this registration is for emergency only.
       * @param availableServices The list of the supported services.
       * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the
       * information is not available.
       */
      private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType,
                                     @RegistrationState int registrationState,
                                     @NetworkType int accessNetworkTechnology, int rejectCause,
                                     boolean emergencyOnly,
                                     @Nullable @ServiceType List<Integer> availableServices,
                                     @Nullable CellIdentity cellIdentity) {
          mDomain = domain;
          mTransportType = transportType;
          mRegistrationState = registrationState;
          mRoamingType = (registrationState == REGISTRATION_STATE_ROAMING)
                  ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING;
          mAccessNetworkTechnology = accessNetworkTechnology;
          mRejectCause = rejectCause;
          mAvailableServices = (availableServices != null)
                  ? new ArrayList<>(availableServices) : new ArrayList<>();
          mCellIdentity = cellIdentity;
          mEmergencyOnly = emergencyOnly;
          mNrState = NR_STATE_NONE;
      }
  
      /**
       * Constructor for voice network registration info.
       * @hide
       */
      public NetworkRegistrationInfo(int domain, @TransportType int transportType,
                                     int registrationState, int accessNetworkTechnology,
                                     int rejectCause, boolean emergencyOnly,
                                     @Nullable List<Integer> availableServices,
                                     @Nullable CellIdentity cellIdentity, boolean cssSupported,
                                     int roamingIndicator, int systemIsInPrl,
                                     int defaultRoamingIndicator) {
          this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                  emergencyOnly, availableServices, cellIdentity);
  
          mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator,
                  systemIsInPrl, defaultRoamingIndicator);
      }
  
      /**
       * Constructor for data network registration info.
       * @hide
       */
      public NetworkRegistrationInfo(int domain, @TransportType int transportType,
                                     int registrationState, int accessNetworkTechnology,
                                     int rejectCause, boolean emergencyOnly,
                                     @Nullable List<Integer> availableServices,
                                     @Nullable CellIdentity cellIdentity, int maxDataCalls,
                                     boolean isDcNrRestricted, boolean isNrAvailable,
                                     boolean isEndcAvailable,
                                     LteVopsSupportInfo lteVopsSupportInfo,
                                     boolean isUsingCarrierAggregation) {
          this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                  emergencyOnly, availableServices, cellIdentity);
          mDataSpecificInfo = new DataSpecificRegistrationInfo(
                  maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo,
                  isUsingCarrierAggregation);
          updateNrState(mDataSpecificInfo);
      }
  
      private NetworkRegistrationInfo(Parcel source) {
          mDomain = source.readInt();
          mTransportType = source.readInt();
          mRegistrationState = source.readInt();
          mRoamingType = source.readInt();
          mAccessNetworkTechnology = source.readInt();
          mRejectCause = source.readInt();
          mEmergencyOnly = source.readBoolean();
          mAvailableServices = new ArrayList<>();
          source.readList(mAvailableServices, Integer.class.getClassLoader());
          mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader());
          mVoiceSpecificInfo = source.readParcelable(
                  VoiceSpecificRegistrationInfo.class.getClassLoader());
          mDataSpecificInfo = source.readParcelable(
                  DataSpecificRegistrationInfo.class.getClassLoader());
          mNrState = source.readInt();
      }
  
      /**
       * Constructor from another network registration info
       *
       * @param nri Another network registration info
       * @hide
       */
      public NetworkRegistrationInfo(NetworkRegistrationInfo nri) {
          mDomain = nri.mDomain;
          mTransportType = nri.mTransportType;
          mRegistrationState = nri.mRegistrationState;
          mRoamingType = nri.mRoamingType;
          mAccessNetworkTechnology = nri.mAccessNetworkTechnology;
          mRejectCause = nri.mRejectCause;
          mEmergencyOnly = nri.mEmergencyOnly;
          mAvailableServices = new ArrayList<>(nri.mAvailableServices);
          if (nri.mCellIdentity != null) {
              Parcel p = Parcel.obtain();
              nri.mCellIdentity.writeToParcel(p, 0);
              p.setDataPosition(0);
              // TODO: Instead of doing this, we should create a formal way for cloning cell identity.
              // Cell identity is not an immutable object so we have to deep copy it.
              mCellIdentity = CellIdentity.CREATOR.createFromParcel(p);
          }
  
          if (nri.mVoiceSpecificInfo != null) {
              mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(nri.mVoiceSpecificInfo);
          }
          if (nri.mDataSpecificInfo != null) {
              mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo);
          }
          mNrState = nri.mNrState;
      }
  
      /**
       * @return The transport type.
       */
      public @TransportType int getTransportType() { return mTransportType; }
  
      /**
       * @return The network domain.
       */
      public @Domain int getDomain() { return mDomain; }
  
      /**
       * @return the 5G NR connection state.
       * @hide
       */
      public @NRState int getNrState() {
          return mNrState;
      }
  
      /** @hide */
      public void setNrState(@NRState int nrState) {
          mNrState = nrState;
      }
  
      /**
       * @return The registration state.
       */
      public @RegistrationState int getRegistrationState() {
          return mRegistrationState;
      }
  
      /**
       * @return {@code true} if registered on roaming network, {@code false} otherwise.
       */
      public boolean isRoaming() {
          return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING;
      }
  
      /**
       * @hide
       * @return {@code true} if in service.
       */
      public boolean isInService() {
          return mRegistrationState == REGISTRATION_STATE_HOME
                  || mRegistrationState == REGISTRATION_STATE_ROAMING;
      }
  
      /**
       * Set {@link ServiceState.RoamingType roaming type}. This could override
       * roaming type based on resource overlay or carrier config.
       * @hide
       */
      public void setRoamingType(@ServiceState.RoamingType int roamingType) {
          mRoamingType = roamingType;
      }
  
      /**
       * @return the current network roaming type.
       */
  
      public @ServiceState.RoamingType int getRoamingType() {
          return mRoamingType;
      }
  
      /**
       * @return Whether emergency is enabled.
       */
      public boolean isEmergencyEnabled() { return mEmergencyOnly; }
  
      /**
       * @return List of available service types.
       */
      @NonNull
      @ServiceType
      public List<Integer> getAvailableServices() {
          return Collections.unmodifiableList(mAvailableServices);
      }
  
      /**
       * @return The access network technology {@link NetworkType}.
       */
      public @NetworkType int getAccessNetworkTechnology() {
          return mAccessNetworkTechnology;
      }
  
      /**
       * override the access network technology {@link NetworkType} e.g, rat ratchet.
       * @hide
       */
      public void setAccessNetworkTechnology(@NetworkType int tech) {
          if (tech == TelephonyManager.NETWORK_TYPE_LTE_CA) {
              // For old device backward compatibility support
              tech = TelephonyManager.NETWORK_TYPE_LTE;
              if (mDataSpecificInfo != null) {
                  mDataSpecificInfo.setIsUsingCarrierAggregation(true);
              }
          }
          mAccessNetworkTechnology = tech;
      }
  
      /**
       * @return Reason for denial if the registration state is {@link #REGISTRATION_STATE_DENIED}.
       * Depending on {@code accessNetworkTechnology}, the values 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 A.S0001 6.2.2.44 for CDMA
       */
      public int getRejectCause() {
          return mRejectCause;
      }
  
      /**
       * @return The cell information.
       */
      @Nullable
      public CellIdentity getCellIdentity() {
          return mCellIdentity;
      }
  
      /**
       * @hide
       */
      @Nullable
      public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() {
          return mVoiceSpecificInfo;
      }
  
      /**
       * @return Data registration related info
       */
      @Nullable
      public DataSpecificRegistrationInfo getDataSpecificInfo() {
          return mDataSpecificInfo;
      }
  
      @Override
      public int describeContents() {
          return 0;
      }
  
      /**
       * Convert service type to string
       *
       * @hide
       *
       * @param serviceType The service type
       * @return The service type in string format
       */
      public static String serviceTypeToString(@ServiceType int serviceType) {
          switch (serviceType) {
              case SERVICE_TYPE_VOICE: return "VOICE";
              case SERVICE_TYPE_DATA: return "DATA";
              case SERVICE_TYPE_SMS: return "SMS";
              case SERVICE_TYPE_VIDEO: return "VIDEO";
              case SERVICE_TYPE_EMERGENCY: return "EMERGENCY";
          }
          return "Unknown service type " + serviceType;
      }
  
      /**
       * Convert registration state to string
       *
       * @hide
       *
       * @param registrationState The registration state
       * @return The reg state in string
       */
      public static String registrationStateToString(@RegistrationState int registrationState) {
          switch (registrationState) {
              case REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING: return "NOT_REG_OR_SEARCHING";
              case REGISTRATION_STATE_HOME: return "HOME";
              case REGISTRATION_STATE_NOT_REGISTERED_SEARCHING: return "NOT_REG_SEARCHING";
              case REGISTRATION_STATE_DENIED: return "DENIED";
              case REGISTRATION_STATE_UNKNOWN: return "UNKNOWN";
              case REGISTRATION_STATE_ROAMING: return "ROAMING";
          }
          return "Unknown reg state " + registrationState;
      }
  
      private static String nrStateToString(@NRState int nrState) {
          switch (nrState) {
              case NR_STATE_RESTRICTED:
                  return "RESTRICTED";
              case NR_STATE_NOT_RESTRICTED:
                  return "NOT_RESTRICTED";
              case NR_STATE_CONNECTED:
                  return "CONNECTED";
              default:
                  return "NONE";
          }
      }
  
      @Override
      public String toString() {
          return new StringBuilder("NetworkRegistrationInfo{")
                  .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS")
                  .append(" transportType=").append(
                          AccessNetworkConstants.transportTypeToString(mTransportType))
                  .append(" registrationState=").append(registrationStateToString(mRegistrationState))
                  .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType))
                  .append(" accessNetworkTechnology=")
                  .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
                  .append(" rejectCause=").append(mRejectCause)
                  .append(" emergencyEnabled=").append(mEmergencyOnly)
                  .append(" availableServices=").append("[" + (mAvailableServices != null
                          ? mAvailableServices.stream().map(type -> serviceTypeToString(type))
                          .collect(Collectors.joining(",")) : null) + "]")
                  .append(" cellIdentity=").append(mCellIdentity)
                  .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
                  .append(" dataSpecificInfo=").append(mDataSpecificInfo)
                  .append(" nrState=").append(nrStateToString(mNrState))
                  .append("}").toString();
      }
  
      @Override
      public int hashCode() {
          return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
                  mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
                  mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState);
      }
  
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
  
          if (!(o instanceof NetworkRegistrationInfo)) {
              return false;
          }
  
          NetworkRegistrationInfo other = (NetworkRegistrationInfo) o;
          return mDomain == other.mDomain
                  && mTransportType == other.mTransportType
                  && mRegistrationState == other.mRegistrationState
                  && mRoamingType == other.mRoamingType
                  && mAccessNetworkTechnology == other.mAccessNetworkTechnology
                  && mRejectCause == other.mRejectCause
                  && mEmergencyOnly == other.mEmergencyOnly
                  && mAvailableServices.equals(other.mAvailableServices)
                  && Objects.equals(mCellIdentity, other.mCellIdentity)
                  && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
                  && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
                  && mNrState == other.mNrState;
      }
  
      @Override
      public void writeToParcel(Parcel dest, int flags) {
          dest.writeInt(mDomain);
          dest.writeInt(mTransportType);
          dest.writeInt(mRegistrationState);
          dest.writeInt(mRoamingType);
          dest.writeInt(mAccessNetworkTechnology);
          dest.writeInt(mRejectCause);
          dest.writeBoolean(mEmergencyOnly);
          dest.writeList(mAvailableServices);
          dest.writeParcelable(mCellIdentity, 0);
          dest.writeParcelable(mVoiceSpecificInfo, 0);
          dest.writeParcelable(mDataSpecificInfo, 0);
          dest.writeInt(mNrState);
      }
  
      /**
       * Use the 5G NR Non-Standalone indicators from the network registration state to update the
       * NR state. There are 3 indicators in the network registration state:
       *
       * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell.
       * 2. if NR is supported by the selected PLMN.
       * 3. if the use of dual connectivity with NR is restricted.
       *
       * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary
       * serving cell.
       *
       * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of
       * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G
       * NR is restricted.
       *
       * @param state data specific registration state contains the 5G NR indicators.
       */
      private void updateNrState(DataSpecificRegistrationInfo state) {
          mNrState = NR_STATE_NONE;
          if (state.isEnDcAvailable) {
              if (!state.isDcNrRestricted && state.isNrAvailable) {
                  mNrState = NR_STATE_NOT_RESTRICTED;
              } else {
                  mNrState = NR_STATE_RESTRICTED;
              }
          }
      }
  
      public static final @NonNull Parcelable.Creator<NetworkRegistrationInfo> CREATOR =
              new Parcelable.Creator<NetworkRegistrationInfo>() {
                  @Override
                  public NetworkRegistrationInfo createFromParcel(Parcel source) {
                      return new NetworkRegistrationInfo(source);
                  }
  
                  @Override
                  public NetworkRegistrationInfo[] newArray(int size) {
                      return new NetworkRegistrationInfo[size];
                  }
              };
  
      /**
       * @hide
       */
      public NetworkRegistrationInfo sanitizeLocationInfo() {
          NetworkRegistrationInfo result = copy();
          result.mCellIdentity = null;
          return result;
      }
  
      private NetworkRegistrationInfo copy() {
          Parcel p = Parcel.obtain();
          this.writeToParcel(p, 0);
          p.setDataPosition(0);
          NetworkRegistrationInfo result = new NetworkRegistrationInfo(p);
          p.recycle();
          return result;
      }
  
      /**
       * Provides a convenient way to set the fields of a {@link NetworkRegistrationInfo} when
       * creating a new instance.
       *
       * <p>The example below shows how you might create a new {@code NetworkRegistrationInfo}:
       *
       * <pre><code>
       *
       * NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
       *     .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
       *     .setRegistrationState(REGISTRATION_STATE_HOME)
       *     .build();
       * </code></pre>
       */
      public static final class Builder{
          @Domain
          private int mDomain;
  
          @TransportType
          private int mTransportType;
  
          @RegistrationState
          private int mRegistrationState;
  
          @NetworkType
          private int mAccessNetworkTechnology;
  
          private int mRejectCause;
  
          private boolean mEmergencyOnly;
  
          @ServiceType
          private List<Integer> mAvailableServices;
  
          @Nullable
          private CellIdentity mCellIdentity;
  
          /**
           * Default constructor for Builder.
           */
          public Builder() {}
  
          /**
           * Set the network domain.
           *
           * @param domain Network domain.
           *
           * @return The same instance of the builder.
           */
          public @NonNull Builder setDomain(@Domain int domain) {
              mDomain = domain;
              return this;
          }
  
          /**
           * Set the transport type.
           *
           * @param transportType Transport type.
           *
           * @return The same instance of the builder.
           */
          public @NonNull Builder setTransportType(@TransportType int transportType) {
              mTransportType = transportType;
              return this;
          }
  
          /**
           * Set the registration state.
           *
           * @param registrationState The registration state.
           *
           * @return The same instance of the builder.
           */
          public @NonNull Builder setRegistrationState(@RegistrationState int registrationState) {
              mRegistrationState = registrationState;
              return this;
          }
  
          /**
           * Set tne access network technology.
           *
           * @return The same instance of the builder.
           *
           * @param accessNetworkTechnology The access network technology
           */
          public @NonNull Builder setAccessNetworkTechnology(
                  @NetworkType int accessNetworkTechnology) {
              mAccessNetworkTechnology = accessNetworkTechnology;
              return this;
          }
  
          /**
           * Set the network reject cause.
           *
           * @param rejectCause Reason for denial if the registration state is
           * {@link #REGISTRATION_STATE_DENIED}.Depending on {@code accessNetworkTechnology}, the
           * values 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 A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set
           * it to 0.
           *
           * @return The same instance of the builder.
           */
          public @NonNull Builder setRejectCause(int rejectCause) {
              mRejectCause = rejectCause;
              return this;
          }
  
          /**
           * Set emergency only.
           *
           * @param emergencyOnly True if this network registration is for emergency use only.
           *
           * @return The same instance of the builder.
           */
          public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
              mEmergencyOnly = emergencyOnly;
              return this;
          }
  
          /**
           * Set the available services.
           *
           * @param availableServices Available services.
           *
           * @return The same instance of the builder.
           */
          public @NonNull Builder setAvailableServices(
                  @NonNull @ServiceType List<Integer> availableServices) {
              mAvailableServices = availableServices;
              return this;
          }
  
          /**
           * Set the cell identity.
           *
           * @param cellIdentity The cell identity.
           *
           * @return The same instance of the builder.
           */
          public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
              mCellIdentity = cellIdentity;
              return this;
          }
  
          /**
           * Build the NetworkRegistrationInfo.
           *
           * @return the NetworkRegistrationInfo object.
           */
          public @NonNull NetworkRegistrationInfo build() {
              return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
                      mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
                      mCellIdentity);
          }
      }
  }
  