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.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 @TestApi
75     public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0;
76     /**
77      * Registered on home network.
78      * @hide
79      */
80     @SystemApi @TestApi
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 @TestApi
87     public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2;
88     /**
89      * Registration denied.
90      * @hide
91      */
92     @SystemApi @TestApi
93     public static final int REGISTRATION_STATE_DENIED = 3;
94     /**
95      * Registration state is unknown.
96      * @hide
97      */
98     @SystemApi @TestApi
99     public static final int REGISTRATION_STATE_UNKNOWN = 4;
100     /**
101      * Registered on roaming network.
102      * @hide
103      */
104     @SystemApi @TestApi
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, LteVopsSupportInfo lteVopsSupportInfo)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                                    LteVopsSupportInfo lteVopsSupportInfo) {
297         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
298                 emergencyOnly, availableServices, cellIdentity, rplmn);
299         mDataSpecificInfo = new DataSpecificRegistrationInfo(
300                 maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo);
301         updateNrState();
302     }
303 
NetworkRegistrationInfo(Parcel source)304     private NetworkRegistrationInfo(Parcel source) {
305         mDomain = source.readInt();
306         mTransportType = source.readInt();
307         mRegistrationState = source.readInt();
308         mRoamingType = source.readInt();
309         mAccessNetworkTechnology = source.readInt();
310         mRejectCause = source.readInt();
311         mEmergencyOnly = source.readBoolean();
312         mAvailableServices = new ArrayList<>();
313         source.readList(mAvailableServices, Integer.class.getClassLoader());
314         mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader());
315         mVoiceSpecificInfo = source.readParcelable(
316                 VoiceSpecificRegistrationInfo.class.getClassLoader());
317         mDataSpecificInfo = source.readParcelable(
318                 DataSpecificRegistrationInfo.class.getClassLoader());
319         mNrState = source.readInt();
320         mRplmn = source.readString();
321         mIsUsingCarrierAggregation = source.readBoolean();
322     }
323 
324     /**
325      * Constructor from another network registration info
326      *
327      * @param nri Another network registration info
328      * @hide
329      */
NetworkRegistrationInfo(NetworkRegistrationInfo nri)330     public NetworkRegistrationInfo(NetworkRegistrationInfo nri) {
331         mDomain = nri.mDomain;
332         mTransportType = nri.mTransportType;
333         mRegistrationState = nri.mRegistrationState;
334         mRoamingType = nri.mRoamingType;
335         mAccessNetworkTechnology = nri.mAccessNetworkTechnology;
336         mIsUsingCarrierAggregation = nri.mIsUsingCarrierAggregation;
337         mRejectCause = nri.mRejectCause;
338         mEmergencyOnly = nri.mEmergencyOnly;
339         mAvailableServices = new ArrayList<>(nri.mAvailableServices);
340         if (nri.mCellIdentity != null) {
341             Parcel p = Parcel.obtain();
342             nri.mCellIdentity.writeToParcel(p, 0);
343             p.setDataPosition(0);
344             // TODO: Instead of doing this, we should create a formal way for cloning cell identity.
345             // Cell identity is not an immutable object so we have to deep copy it.
346             mCellIdentity = CellIdentity.CREATOR.createFromParcel(p);
347         }
348 
349         if (nri.mVoiceSpecificInfo != null) {
350             mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(nri.mVoiceSpecificInfo);
351         }
352         if (nri.mDataSpecificInfo != null) {
353             mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo);
354         }
355         mNrState = nri.mNrState;
356         mRplmn = nri.mRplmn;
357     }
358 
359     /**
360      * @return The transport type.
361      */
getTransportType()362     public @TransportType int getTransportType() { return mTransportType; }
363 
364     /**
365      * @return The network domain.
366      */
getDomain()367     public @Domain int getDomain() { return mDomain; }
368 
369     /**
370      * Get the 5G NR connection state.
371      *
372      * @return the 5G NR connection state.
373      * @hide
374      */
getNrState()375     public @NRState int getNrState() {
376         return mNrState;
377     }
378 
379     /** @hide */
setNrState(@RState int nrState)380     public void setNrState(@NRState int nrState) {
381         mNrState = nrState;
382     }
383 
384     /**
385      * @return The registration state.
386      *
387      * @hide
388      */
389     @SystemApi @TestApi
getRegistrationState()390     public @RegistrationState int getRegistrationState() {
391         return mRegistrationState;
392     }
393 
394     /**
395      * @return {@code true} if registered on roaming or home network, {@code false} otherwise.
396      */
isRegistered()397     public boolean isRegistered() {
398         return mRegistrationState == REGISTRATION_STATE_HOME
399                 || mRegistrationState == REGISTRATION_STATE_ROAMING;
400     }
401 
402     /**
403      * @return {@code true} if searching for service, {@code false} otherwise.
404      */
isSearching()405     public boolean isSearching() {
406         return mRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING;
407     }
408 
409     /**
410      * Get the PLMN-ID for this Network Registration, also known as the RPLMN.
411      *
412      * <p>If the device is registered, this will return the registered PLMN-ID. If registration
413      * has failed, then this will return the PLMN ID of the last attempted registration. If the
414      * device is not registered, or if is registered to a non-3GPP radio technology, then this
415      * will return null.
416      *
417      * <p>See 3GPP TS 23.122 for further information about the Registered PLMN.
418      *
419      * @return the registered PLMN-ID or null.
420      */
getRegisteredPlmn()421     @Nullable public String getRegisteredPlmn() {
422         return mRplmn;
423     }
424 
425     /**
426      * @return {@code true} if registered on roaming network, {@code false} otherwise.
427      */
isRoaming()428     public boolean isRoaming() {
429         return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING;
430     }
431 
432     /**
433      * @hide
434      * @return {@code true} if in service.
435      */
isInService()436     public boolean isInService() {
437         return mRegistrationState == REGISTRATION_STATE_HOME
438                 || mRegistrationState == REGISTRATION_STATE_ROAMING;
439     }
440 
441     /**
442      * Set {@link ServiceState.RoamingType roaming type}. This could override
443      * roaming type based on resource overlay or carrier config.
444      * @hide
445      */
setRoamingType(@erviceState.RoamingType int roamingType)446     public void setRoamingType(@ServiceState.RoamingType int roamingType) {
447         mRoamingType = roamingType;
448     }
449 
450     /**
451      * @return the current network roaming type.
452      * @hide
453      */
454     @SystemApi @TestApi
getRoamingType()455     public @ServiceState.RoamingType int getRoamingType() {
456         return mRoamingType;
457     }
458 
459     /**
460      * @return Whether emergency is enabled.
461      * @hide
462      */
463     @SystemApi @TestApi
isEmergencyEnabled()464     public boolean isEmergencyEnabled() { return mEmergencyOnly; }
465 
466     /**
467      * @return List of available service types.
468      */
469     @NonNull
470     @ServiceType
getAvailableServices()471     public List<Integer> getAvailableServices() {
472         return Collections.unmodifiableList(mAvailableServices);
473     }
474 
475     /**
476      * @return The access network technology {@link NetworkType}.
477      */
getAccessNetworkTechnology()478     public @NetworkType int getAccessNetworkTechnology() {
479         return mAccessNetworkTechnology;
480     }
481 
482     /**
483      * override the access network technology {@link NetworkType} e.g, rat ratchet.
484      * @hide
485      */
setAccessNetworkTechnology(@etworkType int tech)486     public void setAccessNetworkTechnology(@NetworkType int tech) {
487         if (tech == TelephonyManager.NETWORK_TYPE_LTE_CA) {
488             // For old device backward compatibility support
489             tech = TelephonyManager.NETWORK_TYPE_LTE;
490             mIsUsingCarrierAggregation = true;
491         }
492         mAccessNetworkTechnology = tech;
493     }
494 
495     /**
496      * @return Reason for denial if the registration state is {@link #REGISTRATION_STATE_DENIED}.
497      * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
498      * 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
499      * @hide
500      */
501     @SystemApi @TestApi
getRejectCause()502     public int getRejectCause() {
503         return mRejectCause;
504     }
505 
506     /**
507      * @return The cell information.
508      */
509     @Nullable
getCellIdentity()510     public CellIdentity getCellIdentity() {
511         return mCellIdentity;
512     }
513 
514     /**
515      * Set whether network has configured carrier aggregation or not.
516      *
517      * @param isUsingCarrierAggregation set whether or not carrier aggregation is used.
518      *
519      * @hide
520      */
setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation)521     public void setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation) {
522         mIsUsingCarrierAggregation = isUsingCarrierAggregation;
523     }
524 
525     /**
526      * Get whether network has configured carrier aggregation or not.
527      *
528      * @return {@code true} if using carrier aggregation.
529      * @hide
530      */
isUsingCarrierAggregation()531     public boolean isUsingCarrierAggregation() {
532         return mIsUsingCarrierAggregation;
533     }
534 
535     /**
536      * @hide
537      */
538     @Nullable
getVoiceSpecificInfo()539     public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() {
540         return mVoiceSpecificInfo;
541     }
542 
543     /**
544      * @return Data registration related info
545      * @hide
546      */
547     @Nullable
548     @SystemApi @TestApi
getDataSpecificInfo()549     public DataSpecificRegistrationInfo getDataSpecificInfo() {
550         return mDataSpecificInfo;
551     }
552 
553     @Override
describeContents()554     public int describeContents() {
555         return 0;
556     }
557 
558     /**
559      * Convert service type to string
560      *
561      * @hide
562      *
563      * @param serviceType The service type
564      * @return The service type in string format
565      */
serviceTypeToString(@erviceType int serviceType)566     public static String serviceTypeToString(@ServiceType int serviceType) {
567         switch (serviceType) {
568             case SERVICE_TYPE_VOICE: return "VOICE";
569             case SERVICE_TYPE_DATA: return "DATA";
570             case SERVICE_TYPE_SMS: return "SMS";
571             case SERVICE_TYPE_VIDEO: return "VIDEO";
572             case SERVICE_TYPE_EMERGENCY: return "EMERGENCY";
573         }
574         return "Unknown service type " + serviceType;
575     }
576 
577     /**
578      * Convert registration state to string
579      *
580      * @hide
581      *
582      * @param registrationState The registration state
583      * @return The reg state in string
584      */
registrationStateToString(@egistrationState int registrationState)585     public static String registrationStateToString(@RegistrationState int registrationState) {
586         switch (registrationState) {
587             case REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING: return "NOT_REG_OR_SEARCHING";
588             case REGISTRATION_STATE_HOME: return "HOME";
589             case REGISTRATION_STATE_NOT_REGISTERED_SEARCHING: return "NOT_REG_SEARCHING";
590             case REGISTRATION_STATE_DENIED: return "DENIED";
591             case REGISTRATION_STATE_UNKNOWN: return "UNKNOWN";
592             case REGISTRATION_STATE_ROAMING: return "ROAMING";
593         }
594         return "Unknown reg state " + registrationState;
595     }
596 
597     /** @hide */
nrStateToString(@RState int nrState)598     public static String nrStateToString(@NRState int nrState) {
599         switch (nrState) {
600             case NR_STATE_RESTRICTED:
601                 return "RESTRICTED";
602             case NR_STATE_NOT_RESTRICTED:
603                 return "NOT_RESTRICTED";
604             case NR_STATE_CONNECTED:
605                 return "CONNECTED";
606             default:
607                 return "NONE";
608         }
609     }
610 
611     /** @hide */
domainToString(@omain int domain)612     static @NonNull String domainToString(@Domain int domain) {
613         switch (domain) {
614             case DOMAIN_CS: return "CS";
615             case DOMAIN_PS: return "PS";
616             case DOMAIN_CS_PS: return "CS_PS";
617             default: return "UNKNOWN";
618         }
619     }
620 
621     @NonNull
622     @Override
toString()623     public String toString() {
624         return new StringBuilder("NetworkRegistrationInfo{")
625                 .append(" domain=").append(domainToString(mDomain))
626                 .append(" transportType=").append(
627                         AccessNetworkConstants.transportTypeToString(mTransportType))
628                 .append(" registrationState=").append(registrationStateToString(mRegistrationState))
629                 .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType))
630                 .append(" accessNetworkTechnology=")
631                 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
632                 .append(" rejectCause=").append(mRejectCause)
633                 .append(" emergencyEnabled=").append(mEmergencyOnly)
634                 .append(" availableServices=").append("[" + (mAvailableServices != null
635                         ? mAvailableServices.stream().map(type -> serviceTypeToString(type))
636                         .collect(Collectors.joining(",")) : null) + "]")
637                 .append(" cellIdentity=").append(mCellIdentity)
638                 .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
639                 .append(" dataSpecificInfo=").append(mDataSpecificInfo)
640                 .append(" nrState=").append(nrStateToString(mNrState))
641                 .append(" rRplmn=").append(mRplmn)
642                 .append(" isUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
643                 .append("}").toString();
644     }
645 
646     @Override
hashCode()647     public int hashCode() {
648         return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
649                 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
650                 mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn,
651                 mIsUsingCarrierAggregation);
652     }
653 
654     @Override
equals(@ullable Object o)655     public boolean equals(@Nullable Object o) {
656         if (this == o) return true;
657 
658         if (!(o instanceof NetworkRegistrationInfo)) {
659             return false;
660         }
661 
662         NetworkRegistrationInfo other = (NetworkRegistrationInfo) o;
663         return mDomain == other.mDomain
664                 && mTransportType == other.mTransportType
665                 && mRegistrationState == other.mRegistrationState
666                 && mRoamingType == other.mRoamingType
667                 && mAccessNetworkTechnology == other.mAccessNetworkTechnology
668                 && mRejectCause == other.mRejectCause
669                 && mEmergencyOnly == other.mEmergencyOnly
670                 && mAvailableServices.equals(other.mAvailableServices)
671                 && mIsUsingCarrierAggregation == other.mIsUsingCarrierAggregation
672                 && Objects.equals(mCellIdentity, other.mCellIdentity)
673                 && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
674                 && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
675                 && TextUtils.equals(mRplmn, other.mRplmn)
676                 && mNrState == other.mNrState;
677     }
678 
679     /**
680      * @hide
681      */
682     @Override
683     @SystemApi @TestApi
writeToParcel(Parcel dest, int flags)684     public void writeToParcel(Parcel dest, int flags) {
685         dest.writeInt(mDomain);
686         dest.writeInt(mTransportType);
687         dest.writeInt(mRegistrationState);
688         dest.writeInt(mRoamingType);
689         dest.writeInt(mAccessNetworkTechnology);
690         dest.writeInt(mRejectCause);
691         dest.writeBoolean(mEmergencyOnly);
692         dest.writeList(mAvailableServices);
693         dest.writeParcelable(mCellIdentity, 0);
694         dest.writeParcelable(mVoiceSpecificInfo, 0);
695         dest.writeParcelable(mDataSpecificInfo, 0);
696         dest.writeInt(mNrState);
697         dest.writeString(mRplmn);
698         dest.writeBoolean(mIsUsingCarrierAggregation);
699     }
700 
701     /**
702      * Use the 5G NR Non-Standalone indicators from the network registration state to update the
703      * NR state. There are 3 indicators in the network registration state:
704      *
705      * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell.
706      * 2. if NR is supported by the selected PLMN.
707      * 3. if the use of dual connectivity with NR is restricted.
708      *
709      * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary
710      * serving cell.
711      *
712      * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of
713      * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G
714      * NR is restricted.
715      *
716      * @hide
717      */
updateNrState()718     public void updateNrState() {
719         mNrState = NR_STATE_NONE;
720         if (mDataSpecificInfo != null && mDataSpecificInfo.isEnDcAvailable) {
721             if (!mDataSpecificInfo.isDcNrRestricted && mDataSpecificInfo.isNrAvailable) {
722                 mNrState = NR_STATE_NOT_RESTRICTED;
723             } else {
724                 mNrState = NR_STATE_RESTRICTED;
725             }
726         }
727     }
728 
729     public static final @NonNull Parcelable.Creator<NetworkRegistrationInfo> CREATOR =
730             new Parcelable.Creator<NetworkRegistrationInfo>() {
731                 @Override
732                 public NetworkRegistrationInfo createFromParcel(Parcel source) {
733                     return new NetworkRegistrationInfo(source);
734                 }
735 
736                 @Override
737                 public NetworkRegistrationInfo[] newArray(int size) {
738                     return new NetworkRegistrationInfo[size];
739                 }
740             };
741 
742     /**
743      * @hide
744      */
sanitizeLocationInfo()745     public NetworkRegistrationInfo sanitizeLocationInfo() {
746         NetworkRegistrationInfo result = copy();
747         result.mCellIdentity = null;
748         return result;
749     }
750 
copy()751     private NetworkRegistrationInfo copy() {
752         Parcel p = Parcel.obtain();
753         this.writeToParcel(p, 0);
754         p.setDataPosition(0);
755         NetworkRegistrationInfo result = new NetworkRegistrationInfo(p);
756         p.recycle();
757         return result;
758     }
759 
760     /**
761      * Provides a convenient way to set the fields of a {@link NetworkRegistrationInfo} when
762      * creating a new instance.
763      *
764      * <p>The example below shows how you might create a new {@code NetworkRegistrationInfo}:
765      *
766      * <pre><code>
767      *
768      * NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
769      *     .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
770      *     .setRegistrationState(REGISTRATION_STATE_HOME)
771      *     .build();
772      * </code></pre>
773      * @hide
774      */
775     @SystemApi @TestApi
776     public static final class Builder {
777         @Domain
778         private int mDomain;
779 
780         @TransportType
781         private int mTransportType;
782 
783         @RegistrationState
784         private int mRegistrationState;
785 
786         @NetworkType
787         private int mAccessNetworkTechnology;
788 
789         private int mRejectCause;
790 
791         private boolean mEmergencyOnly;
792 
793         @ServiceType
794         private List<Integer> mAvailableServices;
795 
796         @Nullable
797         private CellIdentity mCellIdentity;
798 
799         @NonNull
800         private String mRplmn = "";
801 
802         /**
803          * Default constructor for Builder.
804          */
Builder()805         public Builder() {}
806 
807         /**
808          * Set the network domain.
809          *
810          * @param domain Network domain.
811          *
812          * @return The same instance of the builder.
813          */
setDomain(@omain int domain)814         public @NonNull Builder setDomain(@Domain int domain) {
815             mDomain = domain;
816             return this;
817         }
818 
819         /**
820          * Set the transport type.
821          *
822          * @param transportType Transport type.
823          *
824          * @return The same instance of the builder.
825          */
setTransportType(@ransportType int transportType)826         public @NonNull Builder setTransportType(@TransportType int transportType) {
827             mTransportType = transportType;
828             return this;
829         }
830 
831         /**
832          * Set the registration state.
833          *
834          * @param registrationState The registration state.
835          *
836          * @return The same instance of the builder.
837          */
setRegistrationState(@egistrationState int registrationState)838         public @NonNull Builder setRegistrationState(@RegistrationState int registrationState) {
839             mRegistrationState = registrationState;
840             return this;
841         }
842 
843         /**
844          * Set tne access network technology.
845          *
846          * @return The same instance of the builder.
847          *
848          * @param accessNetworkTechnology The access network technology
849          */
setAccessNetworkTechnology( @etworkType int accessNetworkTechnology)850         public @NonNull Builder setAccessNetworkTechnology(
851                 @NetworkType int accessNetworkTechnology) {
852             mAccessNetworkTechnology = accessNetworkTechnology;
853             return this;
854         }
855 
856         /**
857          * Set the network reject cause.
858          *
859          * @param rejectCause Reason for denial if the registration state is
860          * {@link #REGISTRATION_STATE_DENIED}.Depending on {@code accessNetworkTechnology}, the
861          * values are defined in 3GPP TS 24.008 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE,
862          * and 3GPP2 A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set
863          * it to 0.
864          *
865          * @return The same instance of the builder.
866          */
setRejectCause(int rejectCause)867         public @NonNull Builder setRejectCause(int rejectCause) {
868             mRejectCause = rejectCause;
869             return this;
870         }
871 
872         /**
873          * Set emergency only.
874          *
875          * @param emergencyOnly True if this network registration is for emergency use only.
876          *
877          * @return The same instance of the builder.
878          * @hide
879          */
880         @SystemApi @TestApi
setEmergencyOnly(boolean emergencyOnly)881         public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
882             mEmergencyOnly = emergencyOnly;
883             return this;
884         }
885 
886         /**
887          * Set the available services.
888          *
889          * @param availableServices Available services.
890          *
891          * @return The same instance of the builder.
892          * @hide
893          */
894         @SystemApi @TestApi
setAvailableServices( @onNull @erviceType List<Integer> availableServices)895         public @NonNull Builder setAvailableServices(
896                 @NonNull @ServiceType List<Integer> availableServices) {
897             mAvailableServices = availableServices;
898             return this;
899         }
900 
901         /**
902          * Set the cell identity.
903          *
904          * @param cellIdentity The cell identity.
905          *
906          * @return The same instance of the builder.
907          * @hide
908          */
909         @SystemApi @TestApi
setCellIdentity(@ullable CellIdentity cellIdentity)910         public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
911             mCellIdentity = cellIdentity;
912             return this;
913         }
914 
915         /**
916          * Set the registered PLMN.
917          *
918          * @param rplmn the registered plmn.
919          *
920          * @return The same instance of the builder.
921          */
setRegisteredPlmn(@ullable String rplmn)922         public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) {
923             mRplmn = rplmn;
924             return this;
925         }
926 
927         /**
928          * Build the NetworkRegistrationInfo.
929          * @return the NetworkRegistrationInfo object.
930          * @hide
931          */
932         @SystemApi @TestApi
build()933         public @NonNull NetworkRegistrationInfo build() {
934             return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
935                     mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
936                     mCellIdentity, mRplmn);
937         }
938     }
939 }
940