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      */
175     @Deprecated
176     @SystemApi
getDataConnectionNetworkType()177     public @NetworkType int getDataConnectionNetworkType() {
178         return mNetworkType;
179     }
180 
181     /**
182      * Returns the network type associated with this data connection.
183      *
184      * Return the current/latest (radio) bearer technology that carries this data connection.
185      * For a variety of reasons, the network type can change during the life of the data
186      * connection, and this information is not reliable unless the physical link is currently
187      * active; (there is currently no mechanism to know whether the physical link is active at
188      * any given moment). Thus, this value is generally correct but may not be relied-upon to
189      * represent the status of the radio bearer at any given moment.
190      */
getNetworkType()191     public @NetworkType int getNetworkType() {
192         return mNetworkType;
193     }
194 
195     /**
196      * Returns the APN types mapped to this data connection.
197      *
198      * @deprecated use {@link #getApnSetting()}
199      * @hide
200      */
201     @Deprecated
202     @SystemApi
getDataConnectionApnTypeBitMask()203     public @ApnType int getDataConnectionApnTypeBitMask() {
204         return mApnTypes;
205     }
206 
207     /**
208      * Returns APN of this data connection.
209      *
210      * @deprecated use {@link #getApnSetting()}
211      * @hide
212      */
213     @NonNull
214     @SystemApi
215     @Deprecated
getDataConnectionApn()216     public String getDataConnectionApn() {
217         return mApn;
218     }
219 
220     /**
221      * Get the properties of the network link {@link LinkProperties}.
222      *
223      * @deprecated use {@link #getLinkProperties()}
224      * @hide
225      */
226     @Deprecated
227     @SystemApi
228     @Nullable
getDataConnectionLinkProperties()229     public LinkProperties getDataConnectionLinkProperties() {
230         return mLinkProperties;
231     }
232 
233     /**
234      * Get the properties of the network link {@link LinkProperties}.
235      */
236     @Nullable
getLinkProperties()237     public LinkProperties getLinkProperties() {
238         return mLinkProperties;
239     }
240 
241     /**
242      * Returns the cause code generated by the most recent state change.
243      *
244      * @deprecated use {@link #getLastCauseCode()}
245      * @hide
246      */
247     @Deprecated
248     @SystemApi
getDataConnectionFailCause()249     public int getDataConnectionFailCause() {
250         return mFailCause;
251     }
252 
253     /**
254      * Returns the cause code generated by the most recent state change.
255      *
256      * Return the cause code for the most recent change in {@link #getState}. In the event of an
257      * error, this cause code will be non-zero.
258      */
259     // FIXME(b144774287): some of these cause codes should have a prescribed meaning.
getLastCauseCode()260     public int getLastCauseCode() {
261         return mFailCause;
262     }
263 
264     /**
265      * Return the APN Settings for this data connection.
266      *
267      * @return the ApnSetting that was used to configure this data connection.
268      */
getApnSetting()269     public @Nullable ApnSetting getApnSetting() {
270         return mApnSetting;
271     }
272 
273     @Override
describeContents()274     public int describeContents() {
275         return 0;
276     }
277 
278     @Override
writeToParcel(@onNull Parcel out, int flags)279     public void writeToParcel(@NonNull Parcel out, int flags) {
280         out.writeInt(mState);
281         out.writeInt(mNetworkType);
282         out.writeInt(mApnTypes);
283         out.writeString(mApn);
284         out.writeParcelable(mLinkProperties, flags);
285         out.writeInt(mFailCause);
286         out.writeParcelable(mApnSetting, flags);
287     }
288 
289     public static final @NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR
290             = new Parcelable.Creator<PreciseDataConnectionState>() {
291 
292         public PreciseDataConnectionState createFromParcel(Parcel in) {
293             return new PreciseDataConnectionState(in);
294         }
295 
296         public PreciseDataConnectionState[] newArray(int size) {
297             return new PreciseDataConnectionState[size];
298         }
299     };
300 
301     @Override
hashCode()302     public int hashCode() {
303         return Objects.hash(mState, mNetworkType, mApnTypes, mApn, mLinkProperties,
304                 mFailCause, mApnSetting);
305     }
306 
307     @Override
equals(@ullable Object obj)308     public boolean equals(@Nullable Object obj) {
309 
310         if (!(obj instanceof PreciseDataConnectionState)) {
311             return false;
312         }
313 
314         PreciseDataConnectionState other = (PreciseDataConnectionState) obj;
315         return Objects.equals(mApn, other.mApn) && mApnTypes == other.mApnTypes
316                 && mFailCause == other.mFailCause
317                 && Objects.equals(mLinkProperties, other.mLinkProperties)
318                 && mNetworkType == other.mNetworkType
319                 && mState == other.mState
320                 && Objects.equals(mApnSetting, other.mApnSetting);
321     }
322 
323     @NonNull
324     @Override
toString()325     public String toString() {
326         StringBuilder sb = new StringBuilder();
327 
328         sb.append("Data Connection state: " + mState);
329         sb.append(", Network type: " + mNetworkType);
330         sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mApnTypes));
331         sb.append(", APN: " + mApn);
332         sb.append(", Link properties: " + mLinkProperties);
333         sb.append(", Fail cause: " + DataFailCause.toString(mFailCause));
334         sb.append(", Apn Setting: " + mApnSetting);
335 
336         return sb.toString();
337     }
338 }
339