1 /*
2  * Copyright (C) 2014 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.FlaggedApi;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 import android.annotation.TestApi;
25 import android.compat.Compatibility;
26 import android.compat.annotation.ChangeId;
27 import android.compat.annotation.EnabledAfter;
28 import android.compat.annotation.UnsupportedAppUsage;
29 import android.net.LinkProperties;
30 import android.os.Build;
31 import android.os.Parcel;
32 import android.os.Parcelable;
33 import android.telephony.AccessNetworkConstants.TransportType;
34 import android.telephony.Annotation.ApnType;
35 import android.telephony.Annotation.DataFailureCause;
36 import android.telephony.Annotation.DataState;
37 import android.telephony.Annotation.NetworkType;
38 import android.telephony.data.ApnSetting;
39 import android.telephony.data.DataCallResponse;
40 import android.telephony.data.Qos;
41 
42 import com.android.internal.telephony.flags.Flags;
43 import com.android.internal.telephony.util.TelephonyUtils;
44 
45 import java.lang.annotation.Retention;
46 import java.lang.annotation.RetentionPolicy;
47 import java.util.Objects;
48 
49 
50 /**
51  * Contains precise data connection state.
52  *
53  * The following data connection information is included in returned PreciseDataConnectionState:
54  *
55  * <ul>
56  *   <li>Data connection state.
57  *   <li>Network type of the connection.
58  *   <li>APN types.
59  *   <li>APN.
60  *   <li>The properties of the network link.
61  *   <li>Data connection fail cause.
62  * </ul>
63  *
64  */
65 public final class PreciseDataConnectionState implements Parcelable {
66     private final @TransportType int mTransportType;
67     private final int mId;
68     private final int mNetId;
69     private final @DataState int mState;
70     private final @NetworkType int mNetworkType;
71     private final @DataFailureCause int mFailCause;
72     private final LinkProperties mLinkProperties;
73     private final ApnSetting mApnSetting;
74     private final Qos mDefaultQos;
75     private final @NetworkValidationStatus int mNetworkValidationStatus;
76 
77     /** @hide */
78     @IntDef(prefix = "NETWORK_VALIDATION_", value = {
79             NETWORK_VALIDATION_UNSUPPORTED,
80             NETWORK_VALIDATION_NOT_REQUESTED,
81             NETWORK_VALIDATION_IN_PROGRESS,
82             NETWORK_VALIDATION_SUCCESS,
83             NETWORK_VALIDATION_FAILURE,
84     })
85     @Retention(RetentionPolicy.SOURCE)
86     public @interface NetworkValidationStatus {}
87 
88     /**
89      * Unsupported. The unsupported state is used when the data network cannot support the network
90      * validation function for the current data connection state.
91      */
92     @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
93     public static final int NETWORK_VALIDATION_UNSUPPORTED = 0;
94 
95     /**
96      * Not Requested. The not requested status is used when the data network supports the network
97      * validation function, but no network validation is being performed yet.
98      */
99     @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
100     public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1;
101 
102     /**
103      * In progress. The in progress state is used when the network validation process for the data
104      * network is in progress. This state is followed by either success or failure.
105      */
106     @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
107     public static final int NETWORK_VALIDATION_IN_PROGRESS = 2;
108 
109     /**
110      * Success. The Success status is used when network validation has been completed for the data
111      * network and the result is successful.
112      */
113     @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
114     public static final int NETWORK_VALIDATION_SUCCESS = 3;
115 
116     /**
117      * Failure. The Failure status is used when network validation has been completed for the data
118      * network and the result is failure.
119      */
120     @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
121     public static final int NETWORK_VALIDATION_FAILURE = 4;
122 
123     /**
124      * Constructor
125      *
126      * @deprecated this constructor has been superseded and should not be used.
127      * @hide
128      */
129     @TestApi
130     @Deprecated
131     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) // (maxTargetSdk = Build.VERSION_CODES.Q)
132     // FIXME: figure out how to remove the UnsupportedAppUsage and delete this constructor
PreciseDataConnectionState(@ataState int state, @NetworkType int networkType, @ApnType int apnTypes, @NonNull String apn, @Nullable LinkProperties linkProperties, @DataFailureCause int failCause)133     public PreciseDataConnectionState(@DataState int state,
134                                       @NetworkType int networkType,
135                                       @ApnType int apnTypes, @NonNull String apn,
136                                       @Nullable LinkProperties linkProperties,
137                                       @DataFailureCause int failCause) {
138         this(AccessNetworkConstants.TRANSPORT_TYPE_INVALID, -1, -1, state, networkType,
139                 linkProperties, failCause, new ApnSetting.Builder()
140                         .setApnTypeBitmask(apnTypes)
141                         .setApnName(apn)
142                         .setEntryName(apn)
143                         .build(), null, NETWORK_VALIDATION_UNSUPPORTED);
144     }
145 
146 
147     /**
148      * Constructor of PreciseDataConnectionState
149      *
150      * @param transportType The transport of the data connection
151      * @param id The id of the data connection
152      * @param state The state of the data connection
153      * @param networkType The access network that is/would carry this data connection
154      * @param linkProperties If the data connection is connected, the properties of the connection
155      * @param failCause In case a procedure related to this data connection fails, a non-zero error
156      *        code indicating the cause of the failure.
157      * @param apnSetting If there is a valid APN for this Data Connection, then the APN Settings;
158      *        if there is no valid APN setting for the specific type, then this will be null
159      * @param defaultQos If there is a valid QoS for the default bearer supporting this data call,
160      *        (supported for LTE and NR), then this is specified. Otherwise it should be null.
161      */
PreciseDataConnectionState(@ransportType int transportType, int id, int netId, @DataState int state, @NetworkType int networkType, @Nullable LinkProperties linkProperties, @DataFailureCause int failCause, @Nullable ApnSetting apnSetting, @Nullable Qos defaultQos, @NetworkValidationStatus int networkValidationStatus)162     private PreciseDataConnectionState(@TransportType int transportType, int id, int netId,
163             @DataState int state, @NetworkType int networkType,
164             @Nullable LinkProperties linkProperties, @DataFailureCause int failCause,
165             @Nullable ApnSetting apnSetting, @Nullable Qos defaultQos,
166             @NetworkValidationStatus int networkValidationStatus) {
167         mTransportType = transportType;
168         mId = id;
169         mNetId = netId;
170         mState = state;
171         mNetworkType = networkType;
172         mLinkProperties = linkProperties;
173         mFailCause = failCause;
174         mApnSetting = apnSetting;
175         mDefaultQos = defaultQos;
176         mNetworkValidationStatus = networkValidationStatus;
177     }
178 
179     /**
180      * Construct a PreciseDataConnectionState object from the given parcel.
181      *
182      * @hide
183      */
PreciseDataConnectionState(Parcel in)184     private PreciseDataConnectionState(Parcel in) {
185         mTransportType = in.readInt();
186         mId = in.readInt();
187         mNetId = in.readInt();
188         mState = in.readInt();
189         mNetworkType = in.readInt();
190         mLinkProperties = in.readParcelable(
191                 LinkProperties.class.getClassLoader(),
192                 android.net.LinkProperties.class);
193         mFailCause = in.readInt();
194         mApnSetting = in.readParcelable(
195                 ApnSetting.class.getClassLoader(),
196                 android.telephony.data.ApnSetting.class);
197         mDefaultQos = in.readParcelable(
198                 Qos.class.getClassLoader(),
199                 android.telephony.data.Qos.class);
200         mNetworkValidationStatus = in.readInt();
201     }
202 
203     /**
204      * Used for checking if the SDK version for
205      * {@code PreciseDataConnectionState#getDataConnectionState} is above Q.
206      */
207     @ChangeId
208     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
209     private static final long GET_DATA_CONNECTION_STATE_R_VERSION = 148535736L;
210 
211     /**
212      * Returns the state of data connection that supported the apn types returned by
213      * {@link #getDataConnectionApnTypeBitMask()}
214      *
215      * @deprecated use {@link #getState()}
216      * @hide
217      */
218     @Deprecated
219     @SystemApi
getDataConnectionState()220     public @DataState int getDataConnectionState() {
221         if (mState == TelephonyManager.DATA_DISCONNECTING
222                 && !Compatibility.isChangeEnabled(GET_DATA_CONNECTION_STATE_R_VERSION)) {
223             return TelephonyManager.DATA_CONNECTED;
224         }
225 
226         return mState;
227     }
228 
229     /**
230      * @return The transport type of this data connection.
231      */
getTransportType()232     public @TransportType int getTransportType() {
233         return mTransportType;
234     }
235 
236     /**
237      * @return The unique id of the data connection
238      *
239      * Note this is the id assigned by the data service.
240      * The id remains the same for data connection handover between
241      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN} and
242      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN}
243      *
244      */
getId()245     public int getId() {
246         return mId;
247     }
248 
249     /**
250      * @return the current TelephonyNetworkAgent ID. {@code -1} if no network agent.
251      * @hide
252      */
getNetId()253     public int getNetId() {
254         return mNetId;
255     }
256 
257     /**
258      * @return The high-level state of this data connection.
259      */
getState()260     public @DataState int getState() {
261         return mState;
262     }
263 
264     /**
265      * Get the network type associated with this data connection.
266      *
267      * @return The current/latest (radio) bearer technology that carries this data connection.
268      * For a variety of reasons, the network type can change during the life of the data
269      * connection, and this information is not reliable unless the physical link is currently
270      * active; (there is currently no mechanism to know whether the physical link is active at
271      * any given moment). Thus, this value is generally correct but may not be relied-upon to
272      * represent the status of the radio bearer at any given moment.
273      */
getNetworkType()274     public @NetworkType int getNetworkType() {
275         return mNetworkType;
276     }
277 
278     /**
279      * Returns the APN types mapped to this data connection.
280      *
281      * @deprecated use {@link #getApnSetting()}
282      * @hide
283      */
284     @Deprecated
285     @SystemApi
getDataConnectionApnTypeBitMask()286     public @ApnType int getDataConnectionApnTypeBitMask() {
287         return (mApnSetting != null) ? mApnSetting.getApnTypeBitmask() : ApnSetting.TYPE_NONE;
288     }
289 
290     /**
291      * Returns APN of this data connection.
292      *
293      * @deprecated use {@link #getApnSetting()}
294      * @hide
295      */
296     @NonNull
297     @SystemApi
298     @Deprecated
getDataConnectionApn()299     public String getDataConnectionApn() {
300         return (mApnSetting != null) ? mApnSetting.getApnName() : "";
301     }
302 
303     /**
304      * Get the properties of the network link {@link LinkProperties}.
305      */
306     @Nullable
getLinkProperties()307     public LinkProperties getLinkProperties() {
308         return mLinkProperties;
309     }
310 
311     /**
312      * Returns the cause code generated by the most recent state change.
313      *
314      * @deprecated use {@link #getLastCauseCode()}
315      * @hide
316      */
317     @Deprecated
318     @SystemApi
getDataConnectionFailCause()319     public int getDataConnectionFailCause() {
320         return mFailCause;
321     }
322 
323     /**
324      * Returns the cause code generated by the most recent state change.
325      *
326      * Return the cause code for the most recent change in {@link #getState}. In the event of an
327      * error, this cause code will be non-zero.
328      */
getLastCauseCode()329     public @DataFailureCause int getLastCauseCode() {
330         return mFailCause;
331     }
332 
333     /**
334      * Return the APN Settings for this data connection.
335      *
336      * @return the ApnSetting that was used to configure this data connection. Note that a data
337      * connection cannot be established without a valid {@link ApnSetting}. The return value would
338      * never be {@code null} even though it has {@link Nullable} annotation.
339      */
getApnSetting()340     public @Nullable ApnSetting getApnSetting() {
341         return mApnSetting;
342     }
343 
344     /**
345      * Return the QoS for the default bearer of this data connection.
346      *
347      * @return the default QoS if known or {@code null} if it is unknown. If the value is reported
348      * for LTE, then it will be an {@link android.telephony.data.EpsQos EpsQos}. If the value is
349      * reported for 5G, then it will be an {@link android.telehpony.data.NrQos NrQos}. Otherwise it
350      * shall always be {@code null}.
351      *
352      * @hide
353      */
getDefaultQos()354     public @Nullable Qos getDefaultQos() {
355         return mDefaultQos;
356     }
357 
358     /**
359      * Returns the network validation state.
360      *
361      * @return the network validation status of the data call
362      */
363     @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
getNetworkValidationStatus()364     public @NetworkValidationStatus int getNetworkValidationStatus() {
365         return mNetworkValidationStatus;
366     }
367 
368     @Override
describeContents()369     public int describeContents() {
370         return 0;
371     }
372 
373     @Override
writeToParcel(@onNull Parcel out, int flags)374     public void writeToParcel(@NonNull Parcel out, int flags) {
375         out.writeInt(mTransportType);
376         out.writeInt(mId);
377         out.writeInt(mNetId);
378         out.writeInt(mState);
379         out.writeInt(mNetworkType);
380         out.writeParcelable(mLinkProperties, flags);
381         out.writeInt(mFailCause);
382         out.writeParcelable(mApnSetting, flags);
383         out.writeParcelable(mDefaultQos, flags);
384         out.writeInt(mNetworkValidationStatus);
385     }
386 
387     public static final @NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR
388             = new Parcelable.Creator<PreciseDataConnectionState>() {
389 
390         public PreciseDataConnectionState createFromParcel(Parcel in) {
391             return new PreciseDataConnectionState(in);
392         }
393 
394         public PreciseDataConnectionState[] newArray(int size) {
395             return new PreciseDataConnectionState[size];
396         }
397     };
398 
399     @Override
hashCode()400     public int hashCode() {
401         return Objects.hash(mTransportType, mId, mNetId, mState, mNetworkType, mFailCause,
402                 mLinkProperties, mApnSetting, mDefaultQos, mNetworkValidationStatus);
403     }
404 
405 
406     @Override
equals(Object o)407     public boolean equals(Object o) {
408         if (this == o) return true;
409         if (o == null || getClass() != o.getClass()) return false;
410         PreciseDataConnectionState that = (PreciseDataConnectionState) o;
411         return mTransportType == that.mTransportType
412                 && mId == that.mId
413                 && mNetId == that.mNetId
414                 && mState == that.mState
415                 && mNetworkType == that.mNetworkType
416                 && mFailCause == that.mFailCause
417                 && Objects.equals(mLinkProperties, that.mLinkProperties)
418                 && Objects.equals(mApnSetting, that.mApnSetting)
419                 && Objects.equals(mDefaultQos, that.mDefaultQos)
420                 && mNetworkValidationStatus == that.mNetworkValidationStatus;
421     }
422 
423     @NonNull
424     @Override
toString()425     public String toString() {
426         StringBuilder sb = new StringBuilder();
427 
428         sb.append(" state: ").append(TelephonyUtils.dataStateToString(mState));
429         sb.append(", transport: ").append(
430                 AccessNetworkConstants.transportTypeToString(mTransportType));
431         sb.append(", id: ").append(mId);
432         sb.append(", netId: ").append(mNetId);
433         sb.append(", network type: ").append(TelephonyManager.getNetworkTypeName(mNetworkType));
434         sb.append(", APN Setting: ").append(mApnSetting);
435         sb.append(", link properties: ").append(mLinkProperties);
436         sb.append(", default QoS: ").append(mDefaultQos);
437         sb.append(", fail cause: ").append(DataFailCause.toString(mFailCause));
438         sb.append(", network validation status: ").append(
439                 networkValidationStatusToString(mNetworkValidationStatus));
440 
441         return sb.toString();
442     }
443 
444     /**
445      * Convert a network validation status to string.
446      *
447      * @param networkValidationStatus network validation status.
448      * @return string of validation status.
449      *
450      * @hide
451      */
452     @NonNull
networkValidationStatusToString( @etworkValidationStatus int networkValidationStatus)453     public static String networkValidationStatusToString(
454             @NetworkValidationStatus int networkValidationStatus) {
455         switch (networkValidationStatus) {
456             case NETWORK_VALIDATION_UNSUPPORTED: return "unsupported";
457             case NETWORK_VALIDATION_NOT_REQUESTED: return "not requested";
458             case NETWORK_VALIDATION_IN_PROGRESS: return "in progress";
459             case NETWORK_VALIDATION_SUCCESS: return "success";
460             case NETWORK_VALIDATION_FAILURE: return "failure";
461             default: return Integer.toString(networkValidationStatus);
462         }
463     }
464 
465     /**
466      * {@link PreciseDataConnectionState} builder
467      *
468      * @hide
469      */
470     public static final class Builder {
471         /** The transport type of the data connection */
472         private @TransportType int mTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
473 
474         /**
475          * The unique ID of the data connection. This is the id assigned in
476          * {@link DataCallResponse)}.
477          */
478         private int mId = -1;
479 
480         /**
481          * The current TelephonyNetworkAgent ID. {@code -1} if no network agent.
482          */
483         private int mNetworkAgentId = -1;
484 
485         /** The state of the data connection */
486         private @DataState int mState = TelephonyManager.DATA_UNKNOWN;
487 
488         /** The network type associated with this data connection */
489         private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
490 
491         /** If the data connection is connected, the properties of the connection */
492         private @Nullable LinkProperties mLinkProperties;
493 
494         /**
495          * In case a procedure related to this data connection fails, a non-zero error code
496          * indicating the cause of the failure.
497          */
498         private @DataFailureCause int mFailCause = DataFailCause.NONE;
499 
500         /** The APN Setting for this data connection */
501         private @Nullable ApnSetting mApnSetting;
502 
503         /** The Default QoS for this EPS/5GS bearer or null otherwise */
504         private @Nullable Qos mDefaultQos;
505 
506         /** The network validation status for the data connection. */
507         private @NetworkValidationStatus int mNetworkValidationStatus =
508                 NETWORK_VALIDATION_UNSUPPORTED;
509 
510         /**
511          * Set the transport type of the data connection.
512          *
513          * @param transportType The transport type of the data connection
514          * @return The builder
515          */
setTransportType(@ransportType int transportType)516         public @NonNull Builder setTransportType(@TransportType int transportType) {
517             mTransportType = transportType;
518             return this;
519         }
520 
521         /**
522          * Set the id of the data connection.
523          *
524          * @param id The id of the data connection
525          * @return The builder
526          */
setId(int id)527         public @NonNull Builder setId(int id) {
528             mId = id;
529             return this;
530         }
531 
532         /**
533          * Set the id of the data connection.
534          *
535          * @param agentId The id of the data connection
536          * @return The builder
537          */
setNetworkAgentId(int agentId)538         public @NonNull Builder setNetworkAgentId(int agentId) {
539             mNetworkAgentId = agentId;
540             return this;
541         }
542 
543         /**
544          * Set the state of the data connection.
545          *
546          * @param state The state of the data connection
547          * @return The builder
548          */
setState(@ataState int state)549         public @NonNull Builder setState(@DataState int state) {
550             mState = state;
551             return this;
552         }
553 
554         /**
555          * Set the network type associated with this data connection.
556          *
557          * @param networkType The network type
558          * @return The builder
559          */
setNetworkType(@etworkType int networkType)560         public @NonNull Builder setNetworkType(@NetworkType int networkType) {
561             mNetworkType = networkType;
562             return this;
563         }
564 
565         /**
566          * Set the link properties of the connection.
567          *
568          * @param linkProperties Link properties
569          * @return The builder
570          */
setLinkProperties(LinkProperties linkProperties)571         public @NonNull Builder setLinkProperties(LinkProperties linkProperties) {
572             mLinkProperties = linkProperties;
573             return this;
574         }
575 
576         /**
577          * Set the fail cause of the data connection.
578          *
579          * @param failCause In case a procedure related to this data connection fails, a non-zero
580          * error code indicating the cause of the failure.
581          * @return The builder
582          */
setFailCause(@ataFailureCause int failCause)583         public @NonNull Builder setFailCause(@DataFailureCause int failCause) {
584             mFailCause = failCause;
585             return this;
586         }
587 
588         /**
589          * Set the APN Setting for this data connection.
590          *
591          * @param apnSetting APN setting
592          * @return This builder
593          */
setApnSetting(@onNull ApnSetting apnSetting)594         public @NonNull Builder setApnSetting(@NonNull ApnSetting apnSetting) {
595             mApnSetting = apnSetting;
596             return this;
597         }
598 
599         /**
600          * Set the default QoS for this data connection.
601          *
602          * @param qos The qos information, if any, associated with the default bearer of the
603          * data connection.
604          * @return The builder
605          * @hide
606          */
setDefaultQos(@ullable Qos qos)607         public @NonNull Builder setDefaultQos(@Nullable Qos qos) {
608             mDefaultQos = qos;
609             return this;
610         }
611 
612         /**
613          * Set the network validation state for the data connection.
614          *
615          * @param networkValidationStatus the network validation status of the data call
616          * @return The builder
617          */
618         @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
setNetworkValidationStatus( @etworkValidationStatus int networkValidationStatus)619         public @NonNull Builder setNetworkValidationStatus(
620                 @NetworkValidationStatus int networkValidationStatus) {
621             mNetworkValidationStatus = networkValidationStatus;
622             return this;
623         }
624 
625         /**
626          * Build the {@link PreciseDataConnectionState} instance.
627          *
628          * @return The {@link PreciseDataConnectionState} instance
629          */
build()630         public PreciseDataConnectionState build() {
631             return new PreciseDataConnectionState(mTransportType, mId, mNetworkAgentId, mState,
632                     mNetworkType, mLinkProperties, mFailCause, mApnSetting, mDefaultQos,
633                     mNetworkValidationStatus);
634         }
635     }
636 }
637