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