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.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.SystemApi;
22 import android.annotation.TestApi;
23 import android.compat.Compatibility;
24 import android.compat.annotation.ChangeId;
25 import android.compat.annotation.EnabledAfter;
26 import android.compat.annotation.UnsupportedAppUsage;
27 import android.net.LinkProperties;
28 import android.os.Build;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 import android.telephony.Annotation.ApnType;
32 import android.telephony.Annotation.DataFailureCause;
33 import android.telephony.Annotation.DataState;
34 import android.telephony.Annotation.NetworkType;
35 import android.telephony.data.ApnSetting;
36 
37 import java.util.Objects;
38 
39 
40 /**
41  * Contains precise data connection state.
42  *
43  * The following data connection information is included in returned PreciseDataConnectionState:
44  *
45  * <ul>
46  *   <li>Data connection state.
47  *   <li>Network type of the connection.
48  *   <li>APN types.
49  *   <li>APN.
50  *   <li>The properties of the network link.
51  *   <li>Data connection fail cause.
52  * </ul>
53  *
54  */
55 public final class PreciseDataConnectionState implements Parcelable {
56 
57     private @DataState int mState = TelephonyManager.DATA_UNKNOWN;
58     private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
59     private @DataFailureCause int mFailCause = DataFailCause.NONE;
60     private @ApnType int mApnTypes = ApnSetting.TYPE_NONE;
61     private String mApn = "";
62     private LinkProperties mLinkProperties = null;
63     private ApnSetting mApnSetting = null;
64 
65     /**
66      * Constructor
67      *
68      * @deprecated this constructor has been superseded and should not be used.
69      * @hide
70      */
71     @TestApi
72     @Deprecated
73     @UnsupportedAppUsage // (maxTargetSdk = Build.VERSION_CODES.Q)
74     // 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)75     public PreciseDataConnectionState(@DataState int state,
76                                       @NetworkType int networkType,
77                                       @ApnType int apnTypes, @NonNull String apn,
78                                       @Nullable LinkProperties linkProperties,
79                                       @DataFailureCause int failCause) {
80         this(state, networkType, apnTypes, apn, linkProperties, failCause, null);
81     }
82 
83 
84     /**
85      * Constructor of PreciseDataConnectionState
86      *
87      * @param state the state of the data connection
88      * @param networkType the access network that is/would carry this data connection
89      * @param apnTypes the APN types that this data connection carries
90      * @param apn the APN of this data connection
91      * @param linkProperties if the data connection is connected, the properties of the connection
92      * @param failCause in case a procedure related to this data connection fails, a non-zero error
93      *        code indicating the cause of the failure.
94      * @param apnSetting if there is a valid APN for this Data Connection, then the APN Settings;
95      *        if there is no valid APN setting for the specific type, then this will be null
96      * @hide
97      */
PreciseDataConnectionState(@ataState int state, @NetworkType int networkType, @ApnType int apnTypes, @NonNull String apn, @Nullable LinkProperties linkProperties, @DataFailureCause int failCause, @Nullable ApnSetting apnSetting)98     public PreciseDataConnectionState(@DataState int state,
99                                       @NetworkType int networkType,
100                                       @ApnType int apnTypes, @NonNull String apn,
101                                       @Nullable LinkProperties linkProperties,
102                                       @DataFailureCause int failCause,
103                                       @Nullable ApnSetting apnSetting) {
104         mState = state;
105         mNetworkType = networkType;
106         mApnTypes = apnTypes;
107         mApn = apn;
108         mLinkProperties = linkProperties;
109         mFailCause = failCause;
110         mApnSetting = apnSetting;
111     }
112 
113     /**
114      * Empty Constructor
115      *
116      * @hide
117      */
PreciseDataConnectionState()118     public PreciseDataConnectionState() {
119     }
120 
121     /**
122      * Construct a PreciseDataConnectionState object from the given parcel.
123      *
124      * @hide
125      */
PreciseDataConnectionState(Parcel in)126     private PreciseDataConnectionState(Parcel in) {
127         mState = in.readInt();
128         mNetworkType = in.readInt();
129         mApnTypes = in.readInt();
130         mApn = in.readString();
131         mLinkProperties = (LinkProperties) in.readParcelable(null);
132         mFailCause = in.readInt();
133         mApnSetting = (ApnSetting) in.readParcelable(null);
134     }
135 
136     /**
137      * Used for checking if the SDK version for
138      * {@code PreciseDataConnectionState#getDataConnectionState} is above Q.
139      */
140     @ChangeId
141     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
142     private static final long GET_DATA_CONNECTION_STATE_R_VERSION = 148535736L;
143 
144     /**
145      * Returns the state of data connection that supported the apn types returned by
146      * {@link #getDataConnectionApnTypeBitMask()}
147      *
148      * @deprecated use {@link #getState()}
149      * @hide
150      */
151     @Deprecated
152     @SystemApi
getDataConnectionState()153     public @DataState int getDataConnectionState() {
154         if (mState == TelephonyManager.DATA_DISCONNECTING
155                 && !Compatibility.isChangeEnabled(GET_DATA_CONNECTION_STATE_R_VERSION)) {
156             return TelephonyManager.DATA_CONNECTED;
157         }
158 
159         return mState;
160     }
161 
162     /**
163      * Returns the high-level state of this data connection.
164      */
getState()165     public @DataState int getState() {
166         return mState;
167     }
168 
169     /**
170      * Returns the network type associated with this data connection.
171      *
172      * @deprecated use {@link getNetworkType()}
173      * @hide
174      * @removed Removed from the R preview SDK but was never part of the stable API surface.
175      */
176     @Deprecated
177     @SystemApi
getDataConnectionNetworkType()178     public @NetworkType int getDataConnectionNetworkType() {
179         return mNetworkType;
180     }
181 
182     /**
183      * Returns the network type associated with this data connection.
184      *
185      * Return the current/latest (radio) bearer technology that carries this data connection.
186      * For a variety of reasons, the network type can change during the life of the data
187      * connection, and this information is not reliable unless the physical link is currently
188      * active; (there is currently no mechanism to know whether the physical link is active at
189      * any given moment). Thus, this value is generally correct but may not be relied-upon to
190      * represent the status of the radio bearer at any given moment.
191      */
getNetworkType()192     public @NetworkType int getNetworkType() {
193         return mNetworkType;
194     }
195 
196     /**
197      * Returns the APN types mapped to this data connection.
198      *
199      * @deprecated use {@link #getApnSetting()}
200      * @hide
201      */
202     @Deprecated
203     @SystemApi
getDataConnectionApnTypeBitMask()204     public @ApnType int getDataConnectionApnTypeBitMask() {
205         return mApnTypes;
206     }
207 
208     /**
209      * Returns APN of this data connection.
210      *
211      * @deprecated use {@link #getApnSetting()}
212      * @hide
213      */
214     @NonNull
215     @SystemApi
216     @Deprecated
getDataConnectionApn()217     public String getDataConnectionApn() {
218         return mApn;
219     }
220 
221     /**
222      * Get the properties of the network link {@link LinkProperties}.
223      *
224      * @deprecated use {@link #getLinkProperties()}
225      * @hide
226      * @removed Removed from the R preview SDK but was never part of the stable API surface.
227      */
228     @Deprecated
229     @SystemApi
230     @Nullable
getDataConnectionLinkProperties()231     public LinkProperties getDataConnectionLinkProperties() {
232         return mLinkProperties;
233     }
234 
235     /**
236      * Get the properties of the network link {@link LinkProperties}.
237      */
238     @Nullable
getLinkProperties()239     public LinkProperties getLinkProperties() {
240         return mLinkProperties;
241     }
242 
243     /**
244      * Returns the cause code generated by the most recent state change.
245      *
246      * @deprecated use {@link #getLastCauseCode()}
247      * @hide
248      */
249     @Deprecated
250     @SystemApi
getDataConnectionFailCause()251     public int getDataConnectionFailCause() {
252         return mFailCause;
253     }
254 
255     /**
256      * Returns the cause code generated by the most recent state change.
257      *
258      * Return the cause code for the most recent change in {@link #getState}. In the event of an
259      * error, this cause code will be non-zero.
260      */
getLastCauseCode()261     public @DataFailureCause int getLastCauseCode() {
262         return mFailCause;
263     }
264 
265     /**
266      * Return the APN Settings for this data connection.
267      *
268      * @return the ApnSetting that was used to configure this data connection.
269      */
getApnSetting()270     public @Nullable ApnSetting getApnSetting() {
271         return mApnSetting;
272     }
273 
274     @Override
describeContents()275     public int describeContents() {
276         return 0;
277     }
278 
279     @Override
writeToParcel(@onNull Parcel out, int flags)280     public void writeToParcel(@NonNull Parcel out, int flags) {
281         out.writeInt(mState);
282         out.writeInt(mNetworkType);
283         out.writeInt(mApnTypes);
284         out.writeString(mApn);
285         out.writeParcelable(mLinkProperties, flags);
286         out.writeInt(mFailCause);
287         out.writeParcelable(mApnSetting, flags);
288     }
289 
290     public static final @NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR
291             = new Parcelable.Creator<PreciseDataConnectionState>() {
292 
293         public PreciseDataConnectionState createFromParcel(Parcel in) {
294             return new PreciseDataConnectionState(in);
295         }
296 
297         public PreciseDataConnectionState[] newArray(int size) {
298             return new PreciseDataConnectionState[size];
299         }
300     };
301 
302     @Override
hashCode()303     public int hashCode() {
304         return Objects.hash(mState, mNetworkType, mApnTypes, mApn, mLinkProperties,
305                 mFailCause, mApnSetting);
306     }
307 
308     @Override
equals(@ullable Object obj)309     public boolean equals(@Nullable Object obj) {
310 
311         if (!(obj instanceof PreciseDataConnectionState)) {
312             return false;
313         }
314 
315         PreciseDataConnectionState other = (PreciseDataConnectionState) obj;
316         return Objects.equals(mApn, other.mApn) && mApnTypes == other.mApnTypes
317                 && mFailCause == other.mFailCause
318                 && Objects.equals(mLinkProperties, other.mLinkProperties)
319                 && mNetworkType == other.mNetworkType
320                 && mState == other.mState
321                 && Objects.equals(mApnSetting, other.mApnSetting);
322     }
323 
324     @NonNull
325     @Override
toString()326     public String toString() {
327         StringBuilder sb = new StringBuilder();
328 
329         sb.append("Data Connection state: " + mState);
330         sb.append(", Network type: " + mNetworkType);
331         sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mApnTypes));
332         sb.append(", APN: " + mApn);
333         sb.append(", Link properties: " + mLinkProperties);
334         sb.append(", Fail cause: " + DataFailCause.toString(mFailCause));
335         sb.append(", Apn Setting: " + mApnSetting);
336 
337         return sb.toString();
338     }
339 }
340