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