1 /*
2  * Copyright (C) 2009 Qualcomm Innovation Center, Inc.  All Rights Reserved.
3  * Copyright (C) 2009 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package android.telephony.data;
19 
20 import android.annotation.FlaggedApi;
21 import android.annotation.IntDef;
22 import android.annotation.IntRange;
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.SystemApi;
26 import android.net.LinkAddress;
27 import android.os.Parcel;
28 import android.os.Parcelable;
29 import android.telephony.Annotation.DataFailureCause;
30 import android.telephony.DataFailCause;
31 import android.telephony.PreciseDataConnectionState;
32 import android.telephony.data.ApnSetting.ProtocolType;
33 
34 import com.android.internal.annotations.VisibleForTesting;
35 import com.android.internal.telephony.flags.Flags;
36 import com.android.internal.util.Preconditions;
37 
38 import java.lang.annotation.Retention;
39 import java.lang.annotation.RetentionPolicy;
40 import java.net.InetAddress;
41 import java.util.ArrayList;
42 import java.util.Collections;
43 import java.util.List;
44 import java.util.Objects;
45 import java.util.Set;
46 
47 /**
48  * Description of the response of a setup data call connection request.
49  *
50  * @hide
51  */
52 @SystemApi
53 public final class DataCallResponse implements Parcelable {
54 
55     /** {@hide} */
56     @IntDef(prefix = "LINK_STATUS_", value = {
57             LINK_STATUS_UNKNOWN,
58             LINK_STATUS_INACTIVE,
59             LINK_STATUS_DORMANT,
60             LINK_STATUS_ACTIVE
61     })
62     @Retention(RetentionPolicy.SOURCE)
63     public @interface LinkStatus {}
64 
65     /** Unknown status */
66     public static final int LINK_STATUS_UNKNOWN = -1;
67 
68     /** Indicates the data connection is inactive. */
69     public static final int LINK_STATUS_INACTIVE = 0;
70 
71     /** Indicates the data connection is active with physical link dormant. */
72     public static final int LINK_STATUS_DORMANT = 1;
73 
74     /** Indicates the data connection is active with physical link up. */
75     public static final int LINK_STATUS_ACTIVE = 2;
76 
77     /** {@hide} */
78     @IntDef(prefix = "HANDOVER_FAILURE_MODE_", value = {
79             HANDOVER_FAILURE_MODE_UNKNOWN,
80             HANDOVER_FAILURE_MODE_LEGACY,
81             HANDOVER_FAILURE_MODE_DO_FALLBACK,
82             HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER,
83             HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL
84     })
85     @Retention(RetentionPolicy.SOURCE)
86     public @interface HandoverFailureMode {}
87 
88     /**
89      * Data handover failure mode is unknown.
90      */
91     public static final int HANDOVER_FAILURE_MODE_UNKNOWN = -1;
92 
93     /**
94      * Perform fallback to the source data transport on data handover failure using
95      * the legacy logic, which is fallback if the fail cause is
96      * {@link DataFailCause#HANDOFF_PREFERENCE_CHANGED}.
97      */
98     public static final int HANDOVER_FAILURE_MODE_LEGACY = 0;
99 
100     /**
101      * Perform fallback to the source data transport on data handover failure.
102      */
103     public static final int HANDOVER_FAILURE_MODE_DO_FALLBACK = 1;
104 
105     /**
106      * Do not perform fallback to the source data transport on data handover failure.
107      * Framework will retry setting up a new data connection by sending
108      * {@link DataService#REQUEST_REASON_HANDOVER} request to the underlying {@link DataService}.
109      */
110     public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER = 2;
111 
112     /**
113      * Do not perform fallback to the source transport on data handover failure.
114      * Framework will retry setting up a new data connection by sending
115      * {@link DataService#REQUEST_REASON_NORMAL} request to the underlying {@link DataService}.
116      */
117     public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 3;
118 
119     /**
120      * Indicates that data retry duration is not specified. Platform can determine when to
121      * perform data setup appropriately.
122      */
123     public static final int RETRY_DURATION_UNDEFINED = -1;
124 
125     /**
126      * Indicates that the pdu session id is not set.
127      */
128     public static final int PDU_SESSION_ID_NOT_SET = 0;
129     private final @DataFailureCause int mCause;
130     private final long mSuggestedRetryTime;
131     private final int mId;
132     private final @LinkStatus int mLinkStatus;
133     private final @ProtocolType int mProtocolType;
134     private final String mInterfaceName;
135     private final List<LinkAddress> mAddresses;
136     private final List<InetAddress> mDnsAddresses;
137     private final List<InetAddress> mGatewayAddresses;
138     private final List<InetAddress> mPcscfAddresses;
139     private final int mMtu;
140     private final int mMtuV4;
141     private final int mMtuV6;
142     private final @HandoverFailureMode int mHandoverFailureMode;
143     private final int mPduSessionId;
144     private final Qos mDefaultQos;
145     private final List<QosBearerSession> mQosBearerSessions;
146     private final NetworkSliceInfo mSliceInfo;
147     private final List<TrafficDescriptor> mTrafficDescriptors;
148     private final @PreciseDataConnectionState.NetworkValidationStatus int mNetworkValidationStatus;
149 
150     /**
151      * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error.
152      * @param suggestedRetryTime The suggested data retry time in milliseconds.
153      * @param id The unique id of the data connection.
154      * @param linkStatus Data connection link status.
155      * @param protocolType The connection protocol, should be one of the PDP_type values in 3GPP
156      * TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6", or "PPP".
157      * @param interfaceName The network interface name.
158      * @param addresses A list of addresses with optional "/" prefix length, e.g.,
159      * "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". Typically 1 IPv4 or 1 IPv6 or
160      * one of each. If the prefix length is absent the addresses are assumed to be
161      * point to point with IPv4 having a prefix length of 32 and IPv6 128.
162      * @param dnsAddresses A list of DNS server addresses, e.g., "192.0.1.3" or
163      * "192.0.1.11 2001:db8::1". Null if no dns server addresses returned.
164      * @param gatewayAddresses A list of default gateway addresses, e.g., "192.0.1.3" or
165      * "192.0.1.11 2001:db8::1". When null, the addresses represent point to point connections.
166      * @param pcscfAddresses A list of Proxy Call State Control Function address via PCO (Protocol
167      * Configuration Option) for IMS client.
168      * @param mtu MTU (maximum transmission unit) in bytes received from network.
169      * Zero or negative values means network has either not sent a value or sent an invalid value.
170      *
171      * @removed Use the {@link Builder()} instead.
172      */
DataCallResponse(@ataFailureCause int cause, int suggestedRetryTime, int id, @LinkStatus int linkStatus, @ProtocolType int protocolType, @Nullable String interfaceName, @Nullable List<LinkAddress> addresses, @Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses, @Nullable List<InetAddress> pcscfAddresses, int mtu)173     public DataCallResponse(@DataFailureCause int cause, int suggestedRetryTime, int id,
174                             @LinkStatus int linkStatus,
175                             @ProtocolType int protocolType, @Nullable String interfaceName,
176                             @Nullable List<LinkAddress> addresses,
177                             @Nullable List<InetAddress> dnsAddresses,
178                             @Nullable List<InetAddress> gatewayAddresses,
179                             @Nullable List<InetAddress> pcscfAddresses, int mtu) {
180         this(cause, suggestedRetryTime, id,
181                 linkStatus, protocolType,
182                 interfaceName == null ? "" : interfaceName,
183                 addresses == null ? Collections.emptyList() : addresses,
184                 dnsAddresses == null ? Collections.emptyList() : dnsAddresses,
185                 gatewayAddresses == null ? Collections.emptyList() : gatewayAddresses,
186                 pcscfAddresses == null ? Collections.emptyList() : pcscfAddresses,
187                 mtu, mtu /* mtuV4 */, mtu /* mtuV6 */,
188                 HANDOVER_FAILURE_MODE_LEGACY, PDU_SESSION_ID_NOT_SET,
189                 null /* defaultQos */, Collections.emptyList() /* qosBearerSessions */,
190                 null /* sliceInfo */,
191                 Collections.emptyList(), /* trafficDescriptors */
192                 PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED);
193     }
194 
DataCallResponse(@ataFailureCause int cause, long suggestedRetryTime, int id, @LinkStatus int linkStatus, @ProtocolType int protocolType, @NonNull String interfaceName, @NonNull List<LinkAddress> addresses, @NonNull List<InetAddress> dnsAddresses, @NonNull List<InetAddress> gatewayAddresses, @NonNull List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6, @HandoverFailureMode int handoverFailureMode, int pduSessionId, @Nullable Qos defaultQos, @NonNull List<QosBearerSession> qosBearerSessions, @Nullable NetworkSliceInfo sliceInfo, @NonNull List<TrafficDescriptor> trafficDescriptors, @PreciseDataConnectionState.NetworkValidationStatus int networkValidationStatus)195     private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id,
196             @LinkStatus int linkStatus, @ProtocolType int protocolType,
197             @NonNull String interfaceName, @NonNull List<LinkAddress> addresses,
198             @NonNull List<InetAddress> dnsAddresses, @NonNull List<InetAddress> gatewayAddresses,
199             @NonNull List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6,
200             @HandoverFailureMode int handoverFailureMode, int pduSessionId,
201             @Nullable Qos defaultQos, @NonNull List<QosBearerSession> qosBearerSessions,
202             @Nullable NetworkSliceInfo sliceInfo,
203             @NonNull List<TrafficDescriptor> trafficDescriptors,
204             @PreciseDataConnectionState.NetworkValidationStatus int networkValidationStatus) {
205         mCause = cause;
206         mSuggestedRetryTime = suggestedRetryTime;
207         mId = id;
208         mLinkStatus = linkStatus;
209         mProtocolType = protocolType;
210         mInterfaceName = interfaceName;
211         mAddresses = new ArrayList<>(addresses);
212         mDnsAddresses = new ArrayList<>(dnsAddresses);
213         mGatewayAddresses = new ArrayList<>(gatewayAddresses);
214         mPcscfAddresses = new ArrayList<>(pcscfAddresses);
215         mMtu = mtu;
216         mMtuV4 = mtuV4;
217         mMtuV6 = mtuV6;
218         mHandoverFailureMode = handoverFailureMode;
219         mPduSessionId = pduSessionId;
220         mDefaultQos = defaultQos;
221         mQosBearerSessions = new ArrayList<>(qosBearerSessions);
222         mSliceInfo = sliceInfo;
223         mTrafficDescriptors = new ArrayList<>(trafficDescriptors);
224         mNetworkValidationStatus = networkValidationStatus;
225 
226         if (mLinkStatus == LINK_STATUS_ACTIVE
227                 || mLinkStatus == LINK_STATUS_DORMANT) {
228             Objects.requireNonNull(
229                     mInterfaceName, "Active data calls must be on a valid interface!");
230             if (mCause != DataFailCause.NONE) {
231                 throw new IllegalStateException("Active data call must not have a failure!");
232             }
233         }
234     }
235 
236     /** @hide */
237     @VisibleForTesting
DataCallResponse(Parcel source)238     public DataCallResponse(Parcel source) {
239         mCause = source.readInt();
240         mSuggestedRetryTime = source.readLong();
241         mId = source.readInt();
242         mLinkStatus = source.readInt();
243         mProtocolType = source.readInt();
244         mInterfaceName = source.readString();
245         mAddresses = new ArrayList<>();
246         source.readList(mAddresses,
247                 LinkAddress.class.getClassLoader(),
248                 android.net.LinkAddress.class);
249         mDnsAddresses = new ArrayList<>();
250         source.readList(mDnsAddresses,
251                 InetAddress.class.getClassLoader(),
252                 java.net.InetAddress.class);
253         mGatewayAddresses = new ArrayList<>();
254         source.readList(mGatewayAddresses,
255                 InetAddress.class.getClassLoader(),
256                 java.net.InetAddress.class);
257         mPcscfAddresses = new ArrayList<>();
258         source.readList(mPcscfAddresses,
259                 InetAddress.class.getClassLoader(),
260                 java.net.InetAddress.class);
261         mMtu = source.readInt();
262         mMtuV4 = source.readInt();
263         mMtuV6 = source.readInt();
264         mHandoverFailureMode = source.readInt();
265         mPduSessionId = source.readInt();
266         mDefaultQos = source.readParcelable(Qos.class.getClassLoader(),
267                 android.telephony.data.Qos.class);
268         mQosBearerSessions = new ArrayList<>();
269         source.readList(mQosBearerSessions,
270                 QosBearerSession.class.getClassLoader(),
271                 android.telephony.data.QosBearerSession.class);
272         mSliceInfo = source.readParcelable(
273                 NetworkSliceInfo.class.getClassLoader(),
274                 android.telephony.data.NetworkSliceInfo.class);
275         mTrafficDescriptors = new ArrayList<>();
276         source.readList(mTrafficDescriptors,
277                 TrafficDescriptor.class.getClassLoader(),
278                 android.telephony.data.TrafficDescriptor.class);
279         mNetworkValidationStatus = source.readInt();
280     }
281 
282     /**
283      * @return Data call fail cause. {@link DataFailCause#NONE} indicates no error.
284      */
285     @DataFailureCause
getCause()286     public int getCause() { return mCause; }
287 
288     /**
289      * @return The suggested data retry time in milliseconds. 0 when network does not
290      * suggest a retry time (Note this is different from the replacement
291      * {@link #getRetryDurationMillis()}).
292      *
293      * @deprecated Use {@link #getRetryDurationMillis()} instead.
294      */
295     @Deprecated
getSuggestedRetryTime()296     public int getSuggestedRetryTime() {
297         // To match the pre-deprecated getSuggestedRetryTime() behavior.
298         if (mSuggestedRetryTime == RETRY_DURATION_UNDEFINED) {
299             return 0;
300         } else if (mSuggestedRetryTime > Integer.MAX_VALUE) {
301             return Integer.MAX_VALUE;
302         }
303         return (int) mSuggestedRetryTime;
304     }
305 
306     /**
307      * @return The network suggested data retry duration in milliseconds as specified in
308      * 3GPP TS 24.302 section 8.2.9.1.  The APN associated to this data call will be throttled for
309      * the specified duration unless {@link DataServiceCallback#onApnUnthrottled} is called.
310      * {@code Long.MAX_VALUE} indicates data retry should not occur.
311      * {@link #RETRY_DURATION_UNDEFINED} indicates network did not suggest any retry duration.
312      */
getRetryDurationMillis()313     public long getRetryDurationMillis() {
314         return mSuggestedRetryTime;
315     }
316 
317     /**
318      * @return The unique id of the data connection.
319      */
getId()320     public int getId() { return mId; }
321 
322     /**
323      * @return The link status
324      */
getLinkStatus()325     @LinkStatus public int getLinkStatus() { return mLinkStatus; }
326 
327     /**
328      * @return The connection protocol type.
329      */
330     @ProtocolType
getProtocolType()331     public int getProtocolType() { return mProtocolType; }
332 
333     /**
334      * @return The network interface name (e.g. "rmnet_data1").
335      */
336     @NonNull
getInterfaceName()337     public String getInterfaceName() { return mInterfaceName; }
338 
339     /**
340      * @return A list of addresses of this data connection.
341      */
342     @NonNull
getAddresses()343     public List<LinkAddress> getAddresses() {
344         return Collections.unmodifiableList(mAddresses);
345     }
346 
347     /**
348      * @return A list of DNS server addresses, e.g., "192.0.1.3" or
349      * "192.0.1.11 2001:db8::1". Empty list if no dns server addresses returned.
350      */
351     @NonNull
getDnsAddresses()352     public List<InetAddress> getDnsAddresses() {
353         return Collections.unmodifiableList(mDnsAddresses);
354     }
355 
356     /**
357      * @return A list of default gateway addresses, e.g., "192.0.1.3" or
358      * "192.0.1.11 2001:db8::1". Empty list if the addresses represent point to point connections.
359      */
360     @NonNull
getGatewayAddresses()361     public List<InetAddress> getGatewayAddresses() {
362         return Collections.unmodifiableList(mGatewayAddresses);
363     }
364 
365     /**
366      * @return A list of Proxy Call State Control Function address via PCO (Protocol Configuration
367      * Option) for IMS client.
368      */
369     @NonNull
getPcscfAddresses()370     public List<InetAddress> getPcscfAddresses() {
371         return Collections.unmodifiableList(mPcscfAddresses);
372     }
373 
374     /**
375      * @return MTU (maximum transmission unit) in bytes received from network. Zero or negative
376      * values means network has either not sent a value or sent an invalid value.
377      * @deprecated For IRadio 1.5 and up, use {@link #getMtuV4} or {@link #getMtuV6} instead.
378      */
379     @Deprecated
getMtu()380     public int getMtu() {
381         return mMtu;
382     }
383 
384     /**
385      * This replaces the deprecated method getMtu.
386      * @return MTU (maximum transmission unit) in bytes received from network, for IPv4.
387      * Zero or negative values means network has either not sent a value or sent an invalid value.
388      */
getMtuV4()389     public int getMtuV4() {
390         return mMtuV4;
391     }
392 
393     /**
394      * @return MTU (maximum transmission unit) in bytes received from network, for IPv6.
395      * Zero or negative values means network has either not sent a value or sent an invalid value.
396      */
getMtuV6()397     public int getMtuV6() {
398         return mMtuV6;
399     }
400 
401     /**
402      * @return The data handover failure mode.
403      */
getHandoverFailureMode()404     public @HandoverFailureMode int getHandoverFailureMode() {
405         return mHandoverFailureMode;
406     }
407 
408     /**
409      * @return The pdu session id
410      */
getPduSessionId()411     public int getPduSessionId() {
412         return mPduSessionId;
413     }
414 
415     /**
416      * @return default QOS of the data connection received from the network
417      *
418      * @hide
419      */
420     @Nullable
getDefaultQos()421     public Qos getDefaultQos() {
422         return mDefaultQos;
423     }
424 
425     /**
426      * @return All the dedicated bearer QOS sessions of the data connection received from the
427      * network.
428      *
429      * @hide
430      */
431     @NonNull
getQosBearerSessions()432     public List<QosBearerSession> getQosBearerSessions() {
433         return Collections.unmodifiableList(mQosBearerSessions);
434     }
435 
436     /**
437      * @return The slice info related to this data connection.
438      */
439     @Nullable
getSliceInfo()440     public NetworkSliceInfo getSliceInfo() {
441         return mSliceInfo;
442     }
443 
444     /**
445      * @return The traffic descriptors related to this data connection.
446      */
447     @NonNull
getTrafficDescriptors()448     public List<TrafficDescriptor> getTrafficDescriptors() {
449         return Collections.unmodifiableList(mTrafficDescriptors);
450     }
451 
452     /**
453      * Return the network validation status that was initiated by {@link
454      * DataService.DataServiceProvider#requestNetworkValidation}
455      *
456      * @return The network validation status of data connection.
457      */
458     @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
getNetworkValidationStatus()459     public @PreciseDataConnectionState.NetworkValidationStatus int getNetworkValidationStatus() {
460         return mNetworkValidationStatus;
461     }
462 
463     @NonNull
464     @Override
toString()465     public String toString() {
466         StringBuffer sb = new StringBuffer();
467         sb.append("DataCallResponse: {")
468            .append(" cause=").append(DataFailCause.toString(mCause))
469            .append(" retry=").append(mSuggestedRetryTime)
470            .append(" cid=").append(mId)
471            .append(" linkStatus=").append(mLinkStatus)
472            .append(" protocolType=").append(mProtocolType)
473            .append(" ifname=").append(mInterfaceName)
474            .append(" addresses=").append(mAddresses)
475            .append(" dnses=").append(mDnsAddresses)
476            .append(" gateways=").append(mGatewayAddresses)
477            .append(" pcscf=").append(mPcscfAddresses)
478            .append(" mtu=").append(getMtu())
479            .append(" mtuV4=").append(getMtuV4())
480            .append(" mtuV6=").append(getMtuV6())
481            .append(" handoverFailureMode=").append(failureModeToString(mHandoverFailureMode))
482            .append(" pduSessionId=").append(getPduSessionId())
483            .append(" defaultQos=").append(mDefaultQos)
484            .append(" qosBearerSessions=").append(mQosBearerSessions)
485            .append(" sliceInfo=").append(mSliceInfo)
486            .append(" trafficDescriptors=").append(mTrafficDescriptors)
487            .append(" networkValidationStatus=").append(PreciseDataConnectionState
488                         .networkValidationStatusToString(mNetworkValidationStatus))
489            .append("}");
490         return sb.toString();
491     }
492 
493     @Override
equals(@ullable Object o)494     public boolean equals(@Nullable Object o) {
495         if (this == o) return true;
496 
497         if (!(o instanceof DataCallResponse)) {
498             return false;
499         }
500 
501         DataCallResponse other = (DataCallResponse) o;
502 
503         return mCause == other.mCause
504                 && mSuggestedRetryTime == other.mSuggestedRetryTime
505                 && mId == other.mId
506                 && mLinkStatus == other.mLinkStatus
507                 && mProtocolType == other.mProtocolType
508                 && mInterfaceName.equals(other.mInterfaceName)
509                 && mAddresses.size() == other.mAddresses.size()
510                 && mAddresses.containsAll(other.mAddresses)
511                 && mDnsAddresses.size() == other.mDnsAddresses.size()
512                 && mDnsAddresses.containsAll(other.mDnsAddresses)
513                 && mGatewayAddresses.size() == other.mGatewayAddresses.size()
514                 && mGatewayAddresses.containsAll(other.mGatewayAddresses)
515                 && mPcscfAddresses.size() == other.mPcscfAddresses.size()
516                 && mPcscfAddresses.containsAll(other.mPcscfAddresses)
517                 && mMtu == other.mMtu
518                 && mMtuV4 == other.mMtuV4
519                 && mMtuV6 == other.mMtuV6
520                 && mHandoverFailureMode == other.mHandoverFailureMode
521                 && mPduSessionId == other.mPduSessionId
522                 && Objects.equals(mDefaultQos, other.mDefaultQos)
523                 && mQosBearerSessions.size() == other.mQosBearerSessions.size() // non-null
524                 && mQosBearerSessions.containsAll(other.mQosBearerSessions) // non-null
525                 && Objects.equals(mSliceInfo, other.mSliceInfo)
526                 && mTrafficDescriptors.size() == other.mTrafficDescriptors.size() // non-null
527                 && mTrafficDescriptors.containsAll(other.mTrafficDescriptors) // non-null
528                 && mNetworkValidationStatus == other.mNetworkValidationStatus;
529     }
530 
531     @Override
hashCode()532     public int hashCode() {
533         return Objects.hash(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType,
534                 mInterfaceName, Set.copyOf(mAddresses), Set.copyOf(mDnsAddresses),
535                 Set.copyOf(mGatewayAddresses), Set.copyOf(mPcscfAddresses), mMtu, mMtuV4, mMtuV6,
536                 mHandoverFailureMode, mPduSessionId, mDefaultQos, Set.copyOf(mQosBearerSessions),
537                 mSliceInfo, Set.copyOf(mTrafficDescriptors), mNetworkValidationStatus);
538     }
539 
540     @Override
describeContents()541     public int describeContents() {
542         return 0;
543     }
544 
545     @Override
writeToParcel(Parcel dest, int flags)546     public void writeToParcel(Parcel dest, int flags) {
547         dest.writeInt(mCause);
548         dest.writeLong(mSuggestedRetryTime);
549         dest.writeInt(mId);
550         dest.writeInt(mLinkStatus);
551         dest.writeInt(mProtocolType);
552         dest.writeString(mInterfaceName);
553         dest.writeList(mAddresses);
554         dest.writeList(mDnsAddresses);
555         dest.writeList(mGatewayAddresses);
556         dest.writeList(mPcscfAddresses);
557         dest.writeInt(mMtu);
558         dest.writeInt(mMtuV4);
559         dest.writeInt(mMtuV6);
560         dest.writeInt(mHandoverFailureMode);
561         dest.writeInt(mPduSessionId);
562         dest.writeParcelable(mDefaultQos, flags);
563         dest.writeList(mQosBearerSessions);
564         dest.writeParcelable(mSliceInfo, flags);
565         dest.writeList(mTrafficDescriptors);
566         dest.writeInt(mNetworkValidationStatus);
567     }
568 
569     public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR =
570             new Parcelable.Creator<DataCallResponse>() {
571                 @Override
572                 public DataCallResponse createFromParcel(Parcel source) {
573                     return new DataCallResponse(source);
574                 }
575 
576                 @Override
577                 public DataCallResponse[] newArray(int size) {
578                     return new DataCallResponse[size];
579                 }
580             };
581 
582     /**
583      * Convert handover failure mode to string.
584      *
585      * @param handoverFailureMode Handover failure mode
586      * @return Handover failure mode in string
587      *
588      * @hide
589      */
failureModeToString(@andoverFailureMode int handoverFailureMode)590     public static String failureModeToString(@HandoverFailureMode int handoverFailureMode) {
591         switch (handoverFailureMode) {
592             case HANDOVER_FAILURE_MODE_UNKNOWN: return "unknown";
593             case HANDOVER_FAILURE_MODE_LEGACY: return "legacy";
594             case HANDOVER_FAILURE_MODE_DO_FALLBACK: return "fallback";
595             case HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER: return "retry handover";
596             case HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL: return "retry setup new one";
597             default: return Integer.toString(handoverFailureMode);
598         }
599     }
600 
601     /**
602      * Provides a convenient way to set the fields of a {@link DataCallResponse} when creating a new
603      * instance.
604      *
605      * <p>The example below shows how you might create a new {@code DataCallResponse}:
606      *
607      * <pre><code>
608      *
609      * DataCallResponse response = new DataCallResponse.Builder()
610      *     .setAddresses(Arrays.asList("192.168.1.2"))
611      *     .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
612      *     .build();
613      * </code></pre>
614      */
615     public static final class Builder {
616         private @DataFailureCause int mCause;
617 
618         private long mSuggestedRetryTime = RETRY_DURATION_UNDEFINED;
619 
620         private int mId;
621 
622         private @LinkStatus int mLinkStatus;
623 
624         private @ProtocolType int mProtocolType;
625 
626         private String mInterfaceName = "";
627 
628         private List<LinkAddress> mAddresses = Collections.emptyList();
629 
630         private List<InetAddress> mDnsAddresses = Collections.emptyList();
631 
632         private List<InetAddress> mGatewayAddresses = Collections.emptyList();
633 
634         private List<InetAddress> mPcscfAddresses = Collections.emptyList();
635 
636         private int mMtu;
637 
638         private int mMtuV4;
639 
640         private int mMtuV6;
641 
642         private @HandoverFailureMode int mHandoverFailureMode = HANDOVER_FAILURE_MODE_LEGACY;
643 
644         private int mPduSessionId = PDU_SESSION_ID_NOT_SET;
645 
646         private @Nullable Qos mDefaultQos;
647 
648         private List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
649 
650         private @Nullable NetworkSliceInfo mSliceInfo;
651 
652         private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>();
653 
654         private @PreciseDataConnectionState.NetworkValidationStatus int mNetworkValidationStatus =
655                 PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED;
656 
657         /**
658          * Default constructor for Builder.
659          */
Builder()660         public Builder() {
661         }
662 
663         /**
664          * Set data call fail cause.
665          *
666          * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error, which
667          * is the only valid value for data calls that are {@link LINK_STATUS_ACTIVE} or
668          * {@link LINK_STATUS_DORMANT}.
669          * @return The same instance of the builder.
670          */
setCause(@ataFailureCause int cause)671         public @NonNull Builder setCause(@DataFailureCause int cause) {
672             mCause = cause;
673             return this;
674         }
675 
676         /**
677          * Set the suggested data retry time.
678          *
679          * @param suggestedRetryTime The suggested data retry time in milliseconds.
680          * @return The same instance of the builder.
681          *
682          * @deprecated Use {@link #setRetryDurationMillis(long)} instead.
683          */
684         @Deprecated
setSuggestedRetryTime(int suggestedRetryTime)685         public @NonNull Builder setSuggestedRetryTime(int suggestedRetryTime) {
686             mSuggestedRetryTime = (long) suggestedRetryTime;
687             return this;
688         }
689 
690         /**
691          * Set the network suggested data retry duration.
692          *
693          * @param retryDurationMillis The suggested data retry duration in milliseconds.
694          * @return The same instance of the builder.
695          */
setRetryDurationMillis(long retryDurationMillis)696         public @NonNull Builder setRetryDurationMillis(long retryDurationMillis) {
697             mSuggestedRetryTime = retryDurationMillis;
698             return this;
699         }
700 
701         /**
702          * Set the unique id of the data connection.
703          *
704          * @param id The unique id of the data connection.
705          * @return The same instance of the builder.
706          */
setId(int id)707         public @NonNull Builder setId(int id) {
708             mId = id;
709             return this;
710         }
711 
712         /**
713          * Set the link status
714          *
715          * @param linkStatus The link status
716          * @return The same instance of the builder.
717          */
setLinkStatus(@inkStatus int linkStatus)718         public @NonNull Builder setLinkStatus(@LinkStatus int linkStatus) {
719             mLinkStatus = linkStatus;
720             return this;
721         }
722 
723         /**
724          * Set the connection protocol type.
725          *
726          * @param protocolType The connection protocol type.
727          * @return The same instance of the builder.
728          */
setProtocolType(@rotocolType int protocolType)729         public @NonNull Builder setProtocolType(@ProtocolType int protocolType) {
730             mProtocolType = protocolType;
731             return this;
732         }
733 
734         /**
735          * Set the network interface name.
736          *
737          * @param interfaceName The network interface name (e.g. "rmnet_data1"). This value may not
738          * be null for valid data calls (those that are {@link LINK_STATUS_ACTIVE} or
739          * {@link LINK_STATUS_DORMANT}).
740          * @return The same instance of the builder.
741          */
setInterfaceName(@ullable String interfaceName)742         public @NonNull Builder setInterfaceName(@Nullable String interfaceName) {
743             if (interfaceName == null) interfaceName = "";
744             mInterfaceName = interfaceName;
745             return this;
746         }
747 
748         /**
749          * Set the addresses of this data connection.
750          *
751          * @param addresses The list of address of the data connection.
752          * @return The same instance of the builder.
753          */
setAddresses(@onNull List<LinkAddress> addresses)754         public @NonNull Builder setAddresses(@NonNull List<LinkAddress> addresses) {
755             Objects.requireNonNull(addresses);
756             mAddresses = addresses;
757             return this;
758         }
759 
760         /**
761          * Set the DNS addresses of this data connection
762          *
763          * @param dnsAddresses The list of DNS address of the data connection.
764          * @return The same instance of the builder.
765          */
setDnsAddresses(@onNull List<InetAddress> dnsAddresses)766         public @NonNull Builder setDnsAddresses(@NonNull List<InetAddress> dnsAddresses) {
767             Objects.requireNonNull(dnsAddresses);
768             mDnsAddresses = dnsAddresses;
769             return this;
770         }
771 
772         /**
773          * Set the gateway addresses of this data connection
774          *
775          * @param gatewayAddresses The list of gateway address of the data connection.
776          * @return The same instance of the builder.
777          */
setGatewayAddresses(@onNull List<InetAddress> gatewayAddresses)778         public @NonNull Builder setGatewayAddresses(@NonNull List<InetAddress> gatewayAddresses) {
779             Objects.requireNonNull(gatewayAddresses);
780             mGatewayAddresses = gatewayAddresses;
781             return this;
782         }
783 
784         /**
785          * Set the Proxy Call State Control Function address via PCO(Protocol Configuration
786          * Option) for IMS client.
787          *
788          * @param pcscfAddresses The list of pcscf address of the data connection.
789          * @return The same instance of the builder.
790          */
setPcscfAddresses(@onNull List<InetAddress> pcscfAddresses)791         public @NonNull Builder setPcscfAddresses(@NonNull List<InetAddress> pcscfAddresses) {
792             Objects.requireNonNull(pcscfAddresses);
793             mPcscfAddresses = pcscfAddresses;
794             return this;
795         }
796 
797         /**
798          * Set maximum transmission unit of the data connection.
799          *
800          * @param mtu MTU (maximum transmission unit) in bytes received from network. Zero or
801          * negative values means network has either not sent a value or sent an invalid value.
802          *
803          * @return The same instance of the builder.
804          * @deprecated For IRadio 1.5 and up, use {@link #setMtuV4} or {@link #setMtuV6} instead.
805          */
setMtu(int mtu)806         public @NonNull Builder setMtu(int mtu) {
807             mMtu = mtu;
808             return this;
809         }
810 
811         /**
812          * Set maximum transmission unit of the data connection, for IPv4.
813          *
814          * @param mtu MTU (maximum transmission unit) in bytes received from network. Zero or
815          * negative values means network has either not sent a value or sent an invalid value.
816          *
817          * @return The same instance of the builder.
818          */
setMtuV4(int mtu)819         public @NonNull Builder setMtuV4(int mtu) {
820             mMtuV4 = mtu;
821             return this;
822         }
823 
824         /**
825          * Set maximum transmission unit of the data connection, for IPv6.
826          *
827          * @param mtu MTU (maximum transmission unit) in bytes received from network. Zero or
828          * negative values means network has either not sent a value or sent an invalid value.
829          *
830          * @return The same instance of the builder.
831          */
setMtuV6(int mtu)832         public @NonNull Builder setMtuV6(int mtu) {
833             mMtuV6 = mtu;
834             return this;
835         }
836 
837         /**
838          * Set data handover failure mode for the data call response.
839          *
840          * @param failureMode Handover failure mode.
841          * @return The same instance of the builder.
842          */
setHandoverFailureMode(@andoverFailureMode int failureMode)843         public @NonNull Builder setHandoverFailureMode(@HandoverFailureMode int failureMode) {
844             mHandoverFailureMode = failureMode;
845             return this;
846         }
847 
848         /**
849          * Set pdu session id.
850          * <p/>
851          * The id must be between 1 and 15 when linked to a pdu session. If no pdu session
852          * exists for the current data call, the id must be set to {@link #PDU_SESSION_ID_NOT_SET}.
853          *
854          * @param pduSessionId Pdu Session Id of the data call.
855          * @return The same instance of the builder.
856          */
setPduSessionId( @ntRangefrom = PDU_SESSION_ID_NOT_SET, to = 15) int pduSessionId)857         public @NonNull Builder setPduSessionId(
858                 @IntRange(from = PDU_SESSION_ID_NOT_SET, to = 15) int pduSessionId) {
859             Preconditions.checkArgument(pduSessionId >= PDU_SESSION_ID_NOT_SET,
860                     "pduSessionId must be greater than or equal to" + PDU_SESSION_ID_NOT_SET);
861             Preconditions.checkArgument(pduSessionId <= 15,
862                     "pduSessionId must be less than or equal to 15.");
863             mPduSessionId = pduSessionId;
864             return this;
865         }
866 
867         /**
868          * Set the default QOS for this data connection.
869          *
870          * @param defaultQos QOS (Quality Of Service) received from network.
871          *
872          * @return The same instance of the builder.
873          *
874          * @hide
875          */
setDefaultQos(@ullable Qos defaultQos)876         public @NonNull Builder setDefaultQos(@Nullable Qos defaultQos) {
877             mDefaultQos = defaultQos;
878             return this;
879         }
880 
881         /**
882          * Set the dedicated bearer QOS sessions for this data connection.
883          *
884          * @param qosBearerSessions Dedicated bearer QOS (Quality Of Service) sessions received
885          * from network.
886          *
887          * @return The same instance of the builder.
888          *
889          * @hide
890          */
setQosBearerSessions( @onNull List<QosBearerSession> qosBearerSessions)891         public @NonNull Builder setQosBearerSessions(
892                 @NonNull List<QosBearerSession> qosBearerSessions) {
893             Objects.requireNonNull(qosBearerSessions);
894             mQosBearerSessions = qosBearerSessions;
895             return this;
896         }
897 
898         /**
899          * The Slice used for this data connection.
900          * <p/>
901          * If a handover occurs from EPDG to 5G,
902          * this is the {@link NetworkSliceInfo} used in {@link DataService#setupDataCall}.
903          *
904          * @param sliceInfo the slice info for the data call
905          *
906          * @return The same instance of the builder.
907          */
setSliceInfo(@ullable NetworkSliceInfo sliceInfo)908         public @NonNull Builder setSliceInfo(@Nullable NetworkSliceInfo sliceInfo) {
909             mSliceInfo = sliceInfo;
910             return this;
911         }
912 
913         /**
914          * The traffic descriptors for this data connection, as defined in 3GPP TS 24.526
915          * Section 5.2. They are used for URSP traffic matching as described in 3GPP TS 24.526
916          * Section 4.2.2. They includes an optional DNN, which, if present, must be used for traffic
917          * matching; it does not specify the end point to be used for the data call. The end point
918          * is specified by {@link DataProfile}, which must be used as the end point if one is not
919          * specified through URSP rules.
920          *
921          * @param trafficDescriptors the traffic descriptors for the data call.
922          *
923          * @return The same instance of the builder.
924          */
setTrafficDescriptors( @onNull List<TrafficDescriptor> trafficDescriptors)925         public @NonNull Builder setTrafficDescriptors(
926                 @NonNull List<TrafficDescriptor> trafficDescriptors) {
927             Objects.requireNonNull(trafficDescriptors);
928             mTrafficDescriptors = trafficDescriptors;
929             return this;
930         }
931 
932         /**
933          * Set the network validation status that corresponds to the state of the network validation
934          * request started by {@link DataService.DataServiceProvider#requestNetworkValidation}
935          *
936          * @param status The network validation status.
937          * @return The same instance of the builder.
938          */
939         @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
setNetworkValidationStatus( @reciseDataConnectionState.NetworkValidationStatus int status)940         public @NonNull Builder setNetworkValidationStatus(
941                 @PreciseDataConnectionState.NetworkValidationStatus int status) {
942             mNetworkValidationStatus = status;
943             return this;
944         }
945 
946         /**
947          * Build the DataCallResponse.
948          *
949          * @return the DataCallResponse object.
950          */
build()951         public @NonNull DataCallResponse build() {
952             return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus,
953                     mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses,
954                     mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId,
955                     mDefaultQos, mQosBearerSessions, mSliceInfo, mTrafficDescriptors,
956                     mNetworkValidationStatus);
957         }
958     }
959 }
960