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