• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telephony;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.annotation.TestApi;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.telephony.AccessNetworkConstants.TransportType;
27 import android.telephony.TelephonyManager.NetworkType;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.Objects;
35 import java.util.stream.Collectors;
36 
37 /**
38  * Description of a mobile network registration info
39  * @hide
40  */
41 @SystemApi
42 @TestApi
43 public final class NetworkRegistrationInfo implements Parcelable {
44     /**
45      * Network domain
46      * @hide
47      */
48     @Retention(RetentionPolicy.SOURCE)
49     @IntDef(prefix = "DOMAIN_", value = {DOMAIN_CS, DOMAIN_PS})
50     public @interface Domain {}
51 
52     /** Circuit switching domain */
53     public static final int DOMAIN_CS = 1;
54     /** Packet switching domain */
55     public static final int DOMAIN_PS = 2;
56 
57     /**
58      * Network registration state
59      * @hide
60      */
61     @Retention(RetentionPolicy.SOURCE)
62     @IntDef(prefix = "REGISTRATION_STATE_",
63             value = {REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, REGISTRATION_STATE_HOME,
64                     REGISTRATION_STATE_NOT_REGISTERED_SEARCHING, REGISTRATION_STATE_DENIED,
65                     REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING})
66     public @interface RegistrationState {}
67 
68     /** Not registered. The device is not currently searching a new operator to register. */
69     public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0;
70     /** Registered on home network. */
71     public static final int REGISTRATION_STATE_HOME = 1;
72     /** Not registered. The device is currently searching a new operator to register. */
73     public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2;
74     /** Registration denied. */
75     public static final int REGISTRATION_STATE_DENIED = 3;
76     /** Registration state is unknown. */
77     public static final int REGISTRATION_STATE_UNKNOWN = 4;
78     /** Registered on roaming network. */
79     public static final int REGISTRATION_STATE_ROAMING = 5;
80 
81     /** @hide */
82     @Retention(RetentionPolicy.SOURCE)
83     @IntDef(prefix = "NR_STATE_",
84             value = {NR_STATE_NONE, NR_STATE_RESTRICTED, NR_STATE_NOT_RESTRICTED,
85                     NR_STATE_CONNECTED})
86     public @interface NRState {}
87 
88     /**
89      * The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR
90      * Dual Connectivity(EN-DC).
91      * @hide
92      */
93     public static final int NR_STATE_NONE = -1;
94 
95     /**
96      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but
97      * either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by
98      * the selected PLMN.
99      * @hide
100      */
101     public static final int NR_STATE_RESTRICTED = 1;
102 
103     /**
104      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both
105      * the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the
106      * selected PLMN.
107      * @hide
108      */
109     public static final int NR_STATE_NOT_RESTRICTED = 2;
110 
111     /**
112      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and
113      * also connected to at least one 5G cell as a secondary serving cell.
114      * @hide
115      */
116     public static final int NR_STATE_CONNECTED = 3;
117 
118     /**
119      * Supported service type
120      * @hide
121      */
122     @Retention(RetentionPolicy.SOURCE)
123     @IntDef(prefix = "SERVICE_TYPE_",
124             value = {SERVICE_TYPE_UNKNOWN, SERVICE_TYPE_VOICE, SERVICE_TYPE_DATA, SERVICE_TYPE_SMS,
125                     SERVICE_TYPE_VIDEO, SERVICE_TYPE_EMERGENCY})
126     public @interface ServiceType {}
127 
128     /** Unkown service */
129     public static final int SERVICE_TYPE_UNKNOWN    = 0;
130 
131     /** Voice service */
132     public static final int SERVICE_TYPE_VOICE      = 1;
133 
134     /** Data service */
135     public static final int SERVICE_TYPE_DATA       = 2;
136 
137     /** SMS service */
138     public static final int SERVICE_TYPE_SMS        = 3;
139 
140     /** Video service */
141     public static final int SERVICE_TYPE_VIDEO      = 4;
142 
143     /** Emergency service */
144     public static final int SERVICE_TYPE_EMERGENCY  = 5;
145 
146     @Domain
147     private final int mDomain;
148 
149     @TransportType
150     private final int mTransportType;
151 
152     @RegistrationState
153     private final int mRegistrationState;
154 
155     /**
156      * Save the {@link ServiceState.RoamingType roaming type}. it can be overridden roaming type
157      * from resource overlay or carrier config.
158      */
159     @ServiceState.RoamingType
160     private int mRoamingType;
161 
162     @NetworkType
163     private int mAccessNetworkTechnology;
164 
165     @NRState
166     private int mNrState;
167 
168     private final int mRejectCause;
169 
170     private final boolean mEmergencyOnly;
171 
172     @ServiceType
173     private final ArrayList<Integer> mAvailableServices;
174 
175     @Nullable
176     private CellIdentity mCellIdentity;
177 
178     @Nullable
179     private VoiceSpecificRegistrationInfo mVoiceSpecificInfo;
180 
181     @Nullable
182     private DataSpecificRegistrationInfo mDataSpecificInfo;
183 
184     /**
185      * @param domain Network domain. Must be a {@link Domain}. For transport type
186      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}.
187      * @param transportType Transport type.
188      * @param registrationState Network registration state. For transport type
189      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, only
190      * {@link #REGISTRATION_STATE_HOME} and {@link #REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING}
191      * are valid states.
192      * @param accessNetworkTechnology Access network technology.For transport type
193      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, set to
194      * {@link TelephonyManager#NETWORK_TYPE_IWLAN}.
195      * @param rejectCause Reason for denial if the registration state is
196      * {@link #REGISTRATION_STATE_DENIED}. Depending on {@code accessNetworkTechnology}, the values
197      * 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
198      * A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set it to 0.
199      * // TODO: Add IWLAN reject cause reference
200      * @param emergencyOnly True if this registration is for emergency only.
201      * @param availableServices The list of the supported services.
202      * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the
203      * information is not available.
204      */
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)205     private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType,
206                                    @RegistrationState int registrationState,
207                                    @NetworkType int accessNetworkTechnology, int rejectCause,
208                                    boolean emergencyOnly,
209                                    @Nullable @ServiceType List<Integer> availableServices,
210                                    @Nullable CellIdentity cellIdentity) {
211         mDomain = domain;
212         mTransportType = transportType;
213         mRegistrationState = registrationState;
214         mRoamingType = (registrationState == REGISTRATION_STATE_ROAMING)
215                 ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING;
216         mAccessNetworkTechnology = accessNetworkTechnology;
217         mRejectCause = rejectCause;
218         mAvailableServices = (availableServices != null)
219                 ? new ArrayList<>(availableServices) : new ArrayList<>();
220         mCellIdentity = cellIdentity;
221         mEmergencyOnly = emergencyOnly;
222         mNrState = NR_STATE_NONE;
223     }
224 
225     /**
226      * Constructor for voice network registration info.
227      * @hide
228      */
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)229     public NetworkRegistrationInfo(int domain, @TransportType int transportType,
230                                    int registrationState, int accessNetworkTechnology,
231                                    int rejectCause, boolean emergencyOnly,
232                                    @Nullable List<Integer> availableServices,
233                                    @Nullable CellIdentity cellIdentity, boolean cssSupported,
234                                    int roamingIndicator, int systemIsInPrl,
235                                    int defaultRoamingIndicator) {
236         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
237                 emergencyOnly, availableServices, cellIdentity);
238 
239         mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator,
240                 systemIsInPrl, defaultRoamingIndicator);
241     }
242 
243     /**
244      * Constructor for data network registration info.
245      * @hide
246      */
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)247     public NetworkRegistrationInfo(int domain, @TransportType int transportType,
248                                    int registrationState, int accessNetworkTechnology,
249                                    int rejectCause, boolean emergencyOnly,
250                                    @Nullable List<Integer> availableServices,
251                                    @Nullable CellIdentity cellIdentity, int maxDataCalls,
252                                    boolean isDcNrRestricted, boolean isNrAvailable,
253                                    boolean isEndcAvailable,
254                                    LteVopsSupportInfo lteVopsSupportInfo,
255                                    boolean isUsingCarrierAggregation) {
256         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
257                 emergencyOnly, availableServices, cellIdentity);
258         mDataSpecificInfo = new DataSpecificRegistrationInfo(
259                 maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo,
260                 isUsingCarrierAggregation);
261         updateNrState(mDataSpecificInfo);
262     }
263 
NetworkRegistrationInfo(Parcel source)264     private NetworkRegistrationInfo(Parcel source) {
265         mDomain = source.readInt();
266         mTransportType = source.readInt();
267         mRegistrationState = source.readInt();
268         mRoamingType = source.readInt();
269         mAccessNetworkTechnology = source.readInt();
270         mRejectCause = source.readInt();
271         mEmergencyOnly = source.readBoolean();
272         mAvailableServices = new ArrayList<>();
273         source.readList(mAvailableServices, Integer.class.getClassLoader());
274         mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader());
275         mVoiceSpecificInfo = source.readParcelable(
276                 VoiceSpecificRegistrationInfo.class.getClassLoader());
277         mDataSpecificInfo = source.readParcelable(
278                 DataSpecificRegistrationInfo.class.getClassLoader());
279         mNrState = source.readInt();
280     }
281 
282     /**
283      * Constructor from another network registration info
284      *
285      * @param nri Another network registration info
286      * @hide
287      */
NetworkRegistrationInfo(NetworkRegistrationInfo nri)288     public NetworkRegistrationInfo(NetworkRegistrationInfo nri) {
289         mDomain = nri.mDomain;
290         mTransportType = nri.mTransportType;
291         mRegistrationState = nri.mRegistrationState;
292         mRoamingType = nri.mRoamingType;
293         mAccessNetworkTechnology = nri.mAccessNetworkTechnology;
294         mRejectCause = nri.mRejectCause;
295         mEmergencyOnly = nri.mEmergencyOnly;
296         mAvailableServices = new ArrayList<>(nri.mAvailableServices);
297         if (nri.mCellIdentity != null) {
298             Parcel p = Parcel.obtain();
299             nri.mCellIdentity.writeToParcel(p, 0);
300             p.setDataPosition(0);
301             // TODO: Instead of doing this, we should create a formal way for cloning cell identity.
302             // Cell identity is not an immutable object so we have to deep copy it.
303             mCellIdentity = CellIdentity.CREATOR.createFromParcel(p);
304         }
305 
306         if (nri.mVoiceSpecificInfo != null) {
307             mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(nri.mVoiceSpecificInfo);
308         }
309         if (nri.mDataSpecificInfo != null) {
310             mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo);
311         }
312         mNrState = nri.mNrState;
313     }
314 
315     /**
316      * @return The transport type.
317      */
getTransportType()318     public @TransportType int getTransportType() { return mTransportType; }
319 
320     /**
321      * @return The network domain.
322      */
getDomain()323     public @Domain int getDomain() { return mDomain; }
324 
325     /**
326      * @return the 5G NR connection state.
327      * @hide
328      */
getNrState()329     public @NRState int getNrState() {
330         return mNrState;
331     }
332 
333     /** @hide */
setNrState(@RState int nrState)334     public void setNrState(@NRState int nrState) {
335         mNrState = nrState;
336     }
337 
338     /**
339      * @return The registration state.
340      */
getRegistrationState()341     public @RegistrationState int getRegistrationState() {
342         return mRegistrationState;
343     }
344 
345     /**
346      * @return {@code true} if registered on roaming network, {@code false} otherwise.
347      */
isRoaming()348     public boolean isRoaming() {
349         return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING;
350     }
351 
352     /**
353      * @hide
354      * @return {@code true} if in service.
355      */
isInService()356     public boolean isInService() {
357         return mRegistrationState == REGISTRATION_STATE_HOME
358                 || mRegistrationState == REGISTRATION_STATE_ROAMING;
359     }
360 
361     /**
362      * Set {@link ServiceState.RoamingType roaming type}. This could override
363      * roaming type based on resource overlay or carrier config.
364      * @hide
365      */
setRoamingType(@erviceState.RoamingType int roamingType)366     public void setRoamingType(@ServiceState.RoamingType int roamingType) {
367         mRoamingType = roamingType;
368     }
369 
370     /**
371      * @return the current network roaming type.
372      */
373 
getRoamingType()374     public @ServiceState.RoamingType int getRoamingType() {
375         return mRoamingType;
376     }
377 
378     /**
379      * @return Whether emergency is enabled.
380      */
isEmergencyEnabled()381     public boolean isEmergencyEnabled() { return mEmergencyOnly; }
382 
383     /**
384      * @return List of available service types.
385      */
386     @NonNull
387     @ServiceType
getAvailableServices()388     public List<Integer> getAvailableServices() {
389         return Collections.unmodifiableList(mAvailableServices);
390     }
391 
392     /**
393      * @return The access network technology {@link NetworkType}.
394      */
getAccessNetworkTechnology()395     public @NetworkType int getAccessNetworkTechnology() {
396         return mAccessNetworkTechnology;
397     }
398 
399     /**
400      * override the access network technology {@link NetworkType} e.g, rat ratchet.
401      * @hide
402      */
setAccessNetworkTechnology(@etworkType int tech)403     public void setAccessNetworkTechnology(@NetworkType int tech) {
404         if (tech == TelephonyManager.NETWORK_TYPE_LTE_CA) {
405             // For old device backward compatibility support
406             tech = TelephonyManager.NETWORK_TYPE_LTE;
407             if (mDataSpecificInfo != null) {
408                 mDataSpecificInfo.setIsUsingCarrierAggregation(true);
409             }
410         }
411         mAccessNetworkTechnology = tech;
412     }
413 
414     /**
415      * @return Reason for denial if the registration state is {@link #REGISTRATION_STATE_DENIED}.
416      * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
417      * 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
418      */
getRejectCause()419     public int getRejectCause() {
420         return mRejectCause;
421     }
422 
423     /**
424      * @return The cell information.
425      */
426     @Nullable
getCellIdentity()427     public CellIdentity getCellIdentity() {
428         return mCellIdentity;
429     }
430 
431     /**
432      * @hide
433      */
434     @Nullable
getVoiceSpecificInfo()435     public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() {
436         return mVoiceSpecificInfo;
437     }
438 
439     /**
440      * @return Data registration related info
441      */
442     @Nullable
getDataSpecificInfo()443     public DataSpecificRegistrationInfo getDataSpecificInfo() {
444         return mDataSpecificInfo;
445     }
446 
447     @Override
describeContents()448     public int describeContents() {
449         return 0;
450     }
451 
452     /**
453      * Convert service type to string
454      *
455      * @hide
456      *
457      * @param serviceType The service type
458      * @return The service type in string format
459      */
serviceTypeToString(@erviceType int serviceType)460     public static String serviceTypeToString(@ServiceType int serviceType) {
461         switch (serviceType) {
462             case SERVICE_TYPE_VOICE: return "VOICE";
463             case SERVICE_TYPE_DATA: return "DATA";
464             case SERVICE_TYPE_SMS: return "SMS";
465             case SERVICE_TYPE_VIDEO: return "VIDEO";
466             case SERVICE_TYPE_EMERGENCY: return "EMERGENCY";
467         }
468         return "Unknown service type " + serviceType;
469     }
470 
471     /**
472      * Convert registration state to string
473      *
474      * @hide
475      *
476      * @param registrationState The registration state
477      * @return The reg state in string
478      */
registrationStateToString(@egistrationState int registrationState)479     public static String registrationStateToString(@RegistrationState int registrationState) {
480         switch (registrationState) {
481             case REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING: return "NOT_REG_OR_SEARCHING";
482             case REGISTRATION_STATE_HOME: return "HOME";
483             case REGISTRATION_STATE_NOT_REGISTERED_SEARCHING: return "NOT_REG_SEARCHING";
484             case REGISTRATION_STATE_DENIED: return "DENIED";
485             case REGISTRATION_STATE_UNKNOWN: return "UNKNOWN";
486             case REGISTRATION_STATE_ROAMING: return "ROAMING";
487         }
488         return "Unknown reg state " + registrationState;
489     }
490 
nrStateToString(@RState int nrState)491     private static String nrStateToString(@NRState int nrState) {
492         switch (nrState) {
493             case NR_STATE_RESTRICTED:
494                 return "RESTRICTED";
495             case NR_STATE_NOT_RESTRICTED:
496                 return "NOT_RESTRICTED";
497             case NR_STATE_CONNECTED:
498                 return "CONNECTED";
499             default:
500                 return "NONE";
501         }
502     }
503 
504     @Override
toString()505     public String toString() {
506         return new StringBuilder("NetworkRegistrationInfo{")
507                 .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS")
508                 .append(" transportType=").append(
509                         AccessNetworkConstants.transportTypeToString(mTransportType))
510                 .append(" registrationState=").append(registrationStateToString(mRegistrationState))
511                 .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType))
512                 .append(" accessNetworkTechnology=")
513                 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
514                 .append(" rejectCause=").append(mRejectCause)
515                 .append(" emergencyEnabled=").append(mEmergencyOnly)
516                 .append(" availableServices=").append("[" + (mAvailableServices != null
517                         ? mAvailableServices.stream().map(type -> serviceTypeToString(type))
518                         .collect(Collectors.joining(",")) : null) + "]")
519                 .append(" cellIdentity=").append(mCellIdentity)
520                 .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
521                 .append(" dataSpecificInfo=").append(mDataSpecificInfo)
522                 .append(" nrState=").append(nrStateToString(mNrState))
523                 .append("}").toString();
524     }
525 
526     @Override
hashCode()527     public int hashCode() {
528         return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
529                 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
530                 mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState);
531     }
532 
533     @Override
equals(Object o)534     public boolean equals(Object o) {
535         if (this == o) return true;
536 
537         if (!(o instanceof NetworkRegistrationInfo)) {
538             return false;
539         }
540 
541         NetworkRegistrationInfo other = (NetworkRegistrationInfo) o;
542         return mDomain == other.mDomain
543                 && mTransportType == other.mTransportType
544                 && mRegistrationState == other.mRegistrationState
545                 && mRoamingType == other.mRoamingType
546                 && mAccessNetworkTechnology == other.mAccessNetworkTechnology
547                 && mRejectCause == other.mRejectCause
548                 && mEmergencyOnly == other.mEmergencyOnly
549                 && mAvailableServices.equals(other.mAvailableServices)
550                 && Objects.equals(mCellIdentity, other.mCellIdentity)
551                 && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
552                 && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
553                 && mNrState == other.mNrState;
554     }
555 
556     @Override
writeToParcel(Parcel dest, int flags)557     public void writeToParcel(Parcel dest, int flags) {
558         dest.writeInt(mDomain);
559         dest.writeInt(mTransportType);
560         dest.writeInt(mRegistrationState);
561         dest.writeInt(mRoamingType);
562         dest.writeInt(mAccessNetworkTechnology);
563         dest.writeInt(mRejectCause);
564         dest.writeBoolean(mEmergencyOnly);
565         dest.writeList(mAvailableServices);
566         dest.writeParcelable(mCellIdentity, 0);
567         dest.writeParcelable(mVoiceSpecificInfo, 0);
568         dest.writeParcelable(mDataSpecificInfo, 0);
569         dest.writeInt(mNrState);
570     }
571 
572     /**
573      * Use the 5G NR Non-Standalone indicators from the network registration state to update the
574      * NR state. There are 3 indicators in the network registration state:
575      *
576      * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell.
577      * 2. if NR is supported by the selected PLMN.
578      * 3. if the use of dual connectivity with NR is restricted.
579      *
580      * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary
581      * serving cell.
582      *
583      * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of
584      * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G
585      * NR is restricted.
586      *
587      * @param state data specific registration state contains the 5G NR indicators.
588      */
updateNrState(DataSpecificRegistrationInfo state)589     private void updateNrState(DataSpecificRegistrationInfo state) {
590         mNrState = NR_STATE_NONE;
591         if (state.isEnDcAvailable) {
592             if (!state.isDcNrRestricted && state.isNrAvailable) {
593                 mNrState = NR_STATE_NOT_RESTRICTED;
594             } else {
595                 mNrState = NR_STATE_RESTRICTED;
596             }
597         }
598     }
599 
600     public static final @NonNull Parcelable.Creator<NetworkRegistrationInfo> CREATOR =
601             new Parcelable.Creator<NetworkRegistrationInfo>() {
602                 @Override
603                 public NetworkRegistrationInfo createFromParcel(Parcel source) {
604                     return new NetworkRegistrationInfo(source);
605                 }
606 
607                 @Override
608                 public NetworkRegistrationInfo[] newArray(int size) {
609                     return new NetworkRegistrationInfo[size];
610                 }
611             };
612 
613     /**
614      * @hide
615      */
sanitizeLocationInfo()616     public NetworkRegistrationInfo sanitizeLocationInfo() {
617         NetworkRegistrationInfo result = copy();
618         result.mCellIdentity = null;
619         return result;
620     }
621 
copy()622     private NetworkRegistrationInfo copy() {
623         Parcel p = Parcel.obtain();
624         this.writeToParcel(p, 0);
625         p.setDataPosition(0);
626         NetworkRegistrationInfo result = new NetworkRegistrationInfo(p);
627         p.recycle();
628         return result;
629     }
630 
631     /**
632      * Provides a convenient way to set the fields of a {@link NetworkRegistrationInfo} when
633      * creating a new instance.
634      *
635      * <p>The example below shows how you might create a new {@code NetworkRegistrationInfo}:
636      *
637      * <pre><code>
638      *
639      * NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
640      *     .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
641      *     .setRegistrationState(REGISTRATION_STATE_HOME)
642      *     .build();
643      * </code></pre>
644      */
645     public static final class Builder{
646         @Domain
647         private int mDomain;
648 
649         @TransportType
650         private int mTransportType;
651 
652         @RegistrationState
653         private int mRegistrationState;
654 
655         @NetworkType
656         private int mAccessNetworkTechnology;
657 
658         private int mRejectCause;
659 
660         private boolean mEmergencyOnly;
661 
662         @ServiceType
663         private List<Integer> mAvailableServices;
664 
665         @Nullable
666         private CellIdentity mCellIdentity;
667 
668         /**
669          * Default constructor for Builder.
670          */
Builder()671         public Builder() {}
672 
673         /**
674          * Set the network domain.
675          *
676          * @param domain Network domain.
677          *
678          * @return The same instance of the builder.
679          */
setDomain(@omain int domain)680         public @NonNull Builder setDomain(@Domain int domain) {
681             mDomain = domain;
682             return this;
683         }
684 
685         /**
686          * Set the transport type.
687          *
688          * @param transportType Transport type.
689          *
690          * @return The same instance of the builder.
691          */
setTransportType(@ransportType int transportType)692         public @NonNull Builder setTransportType(@TransportType int transportType) {
693             mTransportType = transportType;
694             return this;
695         }
696 
697         /**
698          * Set the registration state.
699          *
700          * @param registrationState The registration state.
701          *
702          * @return The same instance of the builder.
703          */
setRegistrationState(@egistrationState int registrationState)704         public @NonNull Builder setRegistrationState(@RegistrationState int registrationState) {
705             mRegistrationState = registrationState;
706             return this;
707         }
708 
709         /**
710          * Set tne access network technology.
711          *
712          * @return The same instance of the builder.
713          *
714          * @param accessNetworkTechnology The access network technology
715          */
setAccessNetworkTechnology( @etworkType int accessNetworkTechnology)716         public @NonNull Builder setAccessNetworkTechnology(
717                 @NetworkType int accessNetworkTechnology) {
718             mAccessNetworkTechnology = accessNetworkTechnology;
719             return this;
720         }
721 
722         /**
723          * Set the network reject cause.
724          *
725          * @param rejectCause Reason for denial if the registration state is
726          * {@link #REGISTRATION_STATE_DENIED}.Depending on {@code accessNetworkTechnology}, the
727          * values are defined in 3GPP TS 24.008 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE,
728          * and 3GPP2 A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set
729          * it to 0.
730          *
731          * @return The same instance of the builder.
732          */
setRejectCause(int rejectCause)733         public @NonNull Builder setRejectCause(int rejectCause) {
734             mRejectCause = rejectCause;
735             return this;
736         }
737 
738         /**
739          * Set emergency only.
740          *
741          * @param emergencyOnly True if this network registration is for emergency use only.
742          *
743          * @return The same instance of the builder.
744          */
setEmergencyOnly(boolean emergencyOnly)745         public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
746             mEmergencyOnly = emergencyOnly;
747             return this;
748         }
749 
750         /**
751          * Set the available services.
752          *
753          * @param availableServices Available services.
754          *
755          * @return The same instance of the builder.
756          */
setAvailableServices( @onNull @erviceType List<Integer> availableServices)757         public @NonNull Builder setAvailableServices(
758                 @NonNull @ServiceType List<Integer> availableServices) {
759             mAvailableServices = availableServices;
760             return this;
761         }
762 
763         /**
764          * Set the cell identity.
765          *
766          * @param cellIdentity The cell identity.
767          *
768          * @return The same instance of the builder.
769          */
setCellIdentity(@ullable CellIdentity cellIdentity)770         public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
771             mCellIdentity = cellIdentity;
772             return this;
773         }
774 
775         /**
776          * Build the NetworkRegistrationInfo.
777          *
778          * @return the NetworkRegistrationInfo object.
779          */
build()780         public @NonNull NetworkRegistrationInfo build() {
781             return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
782                     mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
783                     mCellIdentity);
784         }
785     }
786 }
787