• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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 com.android.internal.telephony.dataconnection;
18 
19 import static android.telephony.data.DataCallResponse.PDU_SESSION_ID_NOT_SET;
20 
21 import static com.android.internal.telephony.dataconnection.DcTracker.REQUEST_TYPE_HANDOVER;
22 
23 import android.annotation.IntDef;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.app.PendingIntent;
27 import android.content.Context;
28 import android.net.ConnectivityManager;
29 import android.net.InetAddresses;
30 import android.net.KeepalivePacketData;
31 import android.net.LinkAddress;
32 import android.net.LinkProperties;
33 import android.net.NetworkAgentConfig;
34 import android.net.NetworkCapabilities;
35 import android.net.NetworkFactory;
36 import android.net.NetworkProvider;
37 import android.net.NetworkRequest;
38 import android.net.ProxyInfo;
39 import android.net.RouteInfo;
40 import android.net.SocketKeepalive;
41 import android.net.TelephonyNetworkSpecifier;
42 import android.net.vcn.VcnManager;
43 import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener;
44 import android.net.vcn.VcnNetworkPolicyResult;
45 import android.os.AsyncResult;
46 import android.os.HandlerExecutor;
47 import android.os.Message;
48 import android.os.PersistableBundle;
49 import android.os.SystemClock;
50 import android.os.SystemProperties;
51 import android.provider.Telephony;
52 import android.telephony.AccessNetworkConstants;
53 import android.telephony.AccessNetworkConstants.TransportType;
54 import android.telephony.Annotation.ApnType;
55 import android.telephony.Annotation.DataFailureCause;
56 import android.telephony.Annotation.DataState;
57 import android.telephony.Annotation.NetworkType;
58 import android.telephony.CarrierConfigManager;
59 import android.telephony.DataFailCause;
60 import android.telephony.LinkCapacityEstimate;
61 import android.telephony.NetworkRegistrationInfo;
62 import android.telephony.PreciseDataConnectionState;
63 import android.telephony.ServiceState;
64 import android.telephony.SubscriptionManager;
65 import android.telephony.TelephonyManager;
66 import android.telephony.data.ApnSetting;
67 import android.telephony.data.DataCallResponse;
68 import android.telephony.data.DataCallResponse.HandoverFailureMode;
69 import android.telephony.data.DataProfile;
70 import android.telephony.data.DataService;
71 import android.telephony.data.DataServiceCallback;
72 import android.telephony.data.NetworkSliceInfo;
73 import android.telephony.data.Qos;
74 import android.telephony.data.QosBearerSession;
75 import android.telephony.data.TrafficDescriptor;
76 import android.text.TextUtils;
77 import android.util.LocalLog;
78 import android.util.Pair;
79 import android.util.TimeUtils;
80 
81 import com.android.internal.annotations.VisibleForTesting;
82 import com.android.internal.telephony.CarrierSignalAgent;
83 import com.android.internal.telephony.DctConstants;
84 import com.android.internal.telephony.Phone;
85 import com.android.internal.telephony.PhoneConstants;
86 import com.android.internal.telephony.PhoneFactory;
87 import com.android.internal.telephony.RIL;
88 import com.android.internal.telephony.RILConstants;
89 import com.android.internal.telephony.RetryManager;
90 import com.android.internal.telephony.TelephonyStatsLog;
91 import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
92 import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
93 import com.android.internal.telephony.metrics.DataCallSessionStats;
94 import com.android.internal.telephony.metrics.TelephonyMetrics;
95 import com.android.internal.telephony.nano.TelephonyProto.RilDataCall;
96 import com.android.internal.telephony.uicc.IccUtils;
97 import com.android.internal.util.AsyncChannel;
98 import com.android.internal.util.IndentingPrintWriter;
99 import com.android.internal.util.Protocol;
100 import com.android.internal.util.State;
101 import com.android.internal.util.StateMachine;
102 import com.android.net.module.util.NetworkCapabilitiesUtils;
103 import com.android.telephony.Rlog;
104 
105 import java.io.FileDescriptor;
106 import java.io.PrintWriter;
107 import java.io.StringWriter;
108 import java.lang.annotation.Retention;
109 import java.lang.annotation.RetentionPolicy;
110 import java.net.InetAddress;
111 import java.net.UnknownHostException;
112 import java.nio.ByteBuffer;
113 import java.util.ArrayList;
114 import java.util.Arrays;
115 import java.util.Collection;
116 import java.util.Collections;
117 import java.util.List;
118 import java.util.Locale;
119 import java.util.Map;
120 import java.util.UUID;
121 import java.util.concurrent.ConcurrentHashMap;
122 import java.util.concurrent.atomic.AtomicInteger;
123 import java.util.function.Consumer;
124 
125 /**
126  * {@hide}
127  *
128  * DataConnection StateMachine.
129  *
130  * This a class for representing a single data connection, with instances of this
131  * class representing a connection via the cellular network. There may be multiple
132  * data connections and all of them are managed by the <code>DataConnectionTracker</code>.
133  *
134  * NOTE: All DataConnection objects must be running on the same looper, which is the default
135  * as the coordinator has members which are used without synchronization.
136  */
137 public class DataConnection extends StateMachine {
138     private static final boolean DBG = true;
139     private static final boolean VDBG = true;
140 
141     private static final String NETWORK_TYPE = "MOBILE";
142 
143     private static final String RAT_NAME_5G = "nr";
144     private static final String RAT_NAME_EVDO = "evdo";
145 
146     /**
147      * OSId for "Android", using UUID version 5 with namespace ISO OSI.
148      * Prepended to the OsAppId in TrafficDescriptor to use for URSP matching.
149      */
150     private static final UUID OS_ID = UUID.fromString("97a498e3-fc92-5c94-8986-0333d06e4e47");
151 
152     private static final int MIN_V6_MTU = 1280;
153 
154     /**
155      * The data connection is not being or been handovered. Note this is the state for the source
156      * data connection, not destination data connection
157      */
158     private static final int HANDOVER_STATE_IDLE = 1;
159 
160     /**
161      * The data connection is being handovered. Note this is the state for the source
162      * data connection, not destination data connection.
163      */
164     private static final int HANDOVER_STATE_BEING_TRANSFERRED = 2;
165 
166     /**
167      * The data connection is already handovered. Note this is the state for the source
168      * data connection, not destination data connection.
169      */
170     private static final int HANDOVER_STATE_COMPLETED = 3;
171 
172 
173     /** @hide */
174     @Retention(RetentionPolicy.SOURCE)
175     @IntDef(prefix = {"HANDOVER_STATE_"}, value = {
176             HANDOVER_STATE_IDLE,
177             HANDOVER_STATE_BEING_TRANSFERRED,
178             HANDOVER_STATE_COMPLETED})
179     public @interface HandoverState {}
180 
181     // The data connection providing default Internet connection will have a higher score of 50.
182     // Other connections will have a slightly lower score of 45. The intention is other connections
183     // will not cause ConnectivityService to tear down default internet connection. For example,
184     // to validate Internet connection on non-default data SIM, we'll set up a temporary Internet
185     // connection on that data SIM. In this case, score of 45 is assigned so ConnectivityService
186     // will not replace the default Internet connection with it.
187     private static final int DEFAULT_INTERNET_CONNECTION_SCORE = 50;
188     private static final int OTHER_CONNECTION_SCORE = 45;
189 
190     // The score we report to connectivity service
191     private int mScore;
192 
193     // The subscription id associated with this data connection.
194     private int mSubId;
195 
196     // The data connection controller
197     private DcController mDcController;
198 
199     // The Tester for failing all bringup's
200     private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
201 
202     // Whether or not the data connection should allocate its own pdu session id
203     private final boolean mDoAllocatePduSessionId;
204 
205     private static AtomicInteger mInstanceNumber = new AtomicInteger(0);
206     private AsyncChannel mAc;
207 
208     // The DCT that's talking to us, we only support one!
209     private DcTracker mDct = null;
210 
211     private String[] mPcscfAddr;
212 
213     private final String mTagSuffix;
214 
215     private final LocalLog mHandoverLocalLog = new LocalLog(100);
216 
217     private int[] mAdministratorUids = new int[0];
218 
219     // stats per data call
220     private DataCallSessionStats mDataCallSessionStats;
221 
222     /**
223      * Used internally for saving connecting parameters.
224      */
225     public static class ConnectionParams {
226         int mTag;
227         ApnContext mApnContext;
228         int mProfileId;
229         int mRilRat;
230         Message mOnCompletedMsg;
231         final int mConnectionGeneration;
232         @RequestNetworkType
233         final int mRequestType;
234         final int mSubId;
235         final boolean mIsPreferredApn;
236 
ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isPreferredApn)237         ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology,
238                          Message onCompletedMsg, int connectionGeneration,
239                          @RequestNetworkType int requestType, int subId,
240                          boolean isPreferredApn) {
241             mApnContext = apnContext;
242             mProfileId = profileId;
243             mRilRat = rilRadioTechnology;
244             mOnCompletedMsg = onCompletedMsg;
245             mConnectionGeneration = connectionGeneration;
246             mRequestType = requestType;
247             mSubId = subId;
248             mIsPreferredApn = isPreferredApn;
249         }
250 
251         @Override
toString()252         public String toString() {
253             return "{mTag=" + mTag + " mApnContext=" + mApnContext
254                     + " mProfileId=" + mProfileId
255                     + " mRat=" + mRilRat
256                     + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg)
257                     + " mRequestType=" + DcTracker.requestTypeToString(mRequestType)
258                     + " mSubId=" + mSubId
259                     + " mIsPreferredApn=" + mIsPreferredApn
260                     + "}";
261         }
262     }
263 
264     /**
265      * Used internally for saving disconnecting parameters.
266      */
267     public static class DisconnectParams {
268         int mTag;
269         public ApnContext mApnContext;
270         String mReason;
271         @ReleaseNetworkType
272         final int mReleaseType;
273         Message mOnCompletedMsg;
274 
DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)275         DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType,
276                          Message onCompletedMsg) {
277             mApnContext = apnContext;
278             mReason = reason;
279             mReleaseType = releaseType;
280             mOnCompletedMsg = onCompletedMsg;
281         }
282 
283         @Override
toString()284         public String toString() {
285             return "{mTag=" + mTag + " mApnContext=" + mApnContext
286                     + " mReason=" + mReason
287                     + " mReleaseType=" + DcTracker.releaseTypeToString(mReleaseType)
288                     + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) + "}";
289         }
290     }
291 
292     private volatile ApnSetting mApnSetting;
293     private ConnectionParams mConnectionParams;
294     private DisconnectParams mDisconnectParams;
295     @DataFailureCause
296     private int mDcFailCause;
297 
298     @HandoverFailureMode
299     private int mHandoverFailureMode;
300 
301     private Phone mPhone;
302     private DataServiceManager mDataServiceManager;
303     private VcnManager mVcnManager;
304     private final int mTransportType;
305     private LinkProperties mLinkProperties = new LinkProperties();
306     private int mPduSessionId;
307     private long mCreateTime;
308     private long mLastFailTime;
309     @DataFailureCause
310     private int mLastFailCause;
311     private static final String NULL_IP = "0.0.0.0";
312     private Object mUserData;
313     private boolean mCongestedOverride;
314     private boolean mUnmeteredOverride;
315     private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
316     private int mDataRegState = Integer.MAX_VALUE;
317     // Indicating data connection is suspended due to temporary reasons, for example, out of
318     // service, concurrency voice/data not supported, etc.. Note this flag is only meaningful when
319     // data is in active state. When data is in inactive, connecting, or disconnecting, this flag
320     // is unmeaningful.
321     private boolean mIsSuspended;
322     private int mDownlinkBandwidth = 14;
323     private int mUplinkBandwidth = 14;
324     private Qos mDefaultQos = null;
325     private List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
326     private NetworkSliceInfo mSliceInfo;
327     private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>();
328 
329     /** The corresponding network agent for this data connection. */
330     private DcNetworkAgent mNetworkAgent;
331 
332     /**
333      * The network agent from handover source data connection. This is the potential network agent
334      * that will be transferred here after handover completed.
335      */
336     private DcNetworkAgent mHandoverSourceNetworkAgent;
337 
338     private int mDisabledApnTypeBitMask = 0;
339 
340     int mTag;
341 
342     /** Data connection id assigned by the modem. This is unique across transports */
343     public int mCid;
344 
345     @HandoverState
346     private int mHandoverState = HANDOVER_STATE_IDLE;
347     private final Map<ApnContext, ConnectionParams> mApnContexts = new ConcurrentHashMap<>();
348     PendingIntent mReconnectIntent = null;
349 
350     /** Class used to track VCN-defined Network policies for this DcNetworkAgent. */
351     private final VcnNetworkPolicyChangeListener mVcnPolicyChangeListener =
352             new DataConnectionVcnNetworkPolicyChangeListener();
353 
354     // ***** Event codes for driving the state machine, package visible for Dcc
355     static final int BASE = Protocol.BASE_DATA_CONNECTION;
356     static final int EVENT_CONNECT = BASE + 0;
357     static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1;
358     static final int EVENT_DEACTIVATE_DONE = BASE + 3;
359     static final int EVENT_DISCONNECT = BASE + 4;
360     static final int EVENT_DISCONNECT_ALL = BASE + 6;
361     static final int EVENT_DATA_STATE_CHANGED = BASE + 7;
362     static final int EVENT_TEAR_DOWN_NOW = BASE + 8;
363     static final int EVENT_LOST_CONNECTION = BASE + 9;
364     static final int EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED = BASE + 11;
365     static final int EVENT_DATA_CONNECTION_ROAM_ON = BASE + 12;
366     static final int EVENT_DATA_CONNECTION_ROAM_OFF = BASE + 13;
367     static final int EVENT_BW_REFRESH_RESPONSE = BASE + 14;
368     static final int EVENT_DATA_CONNECTION_VOICE_CALL_STARTED = BASE + 15;
369     static final int EVENT_DATA_CONNECTION_VOICE_CALL_ENDED = BASE + 16;
370     static final int EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED = BASE + 17;
371     static final int EVENT_KEEPALIVE_STATUS = BASE + 18;
372     static final int EVENT_KEEPALIVE_STARTED = BASE + 19;
373     static final int EVENT_KEEPALIVE_STOPPED = BASE + 20;
374     static final int EVENT_KEEPALIVE_START_REQUEST = BASE + 21;
375     static final int EVENT_KEEPALIVE_STOP_REQUEST = BASE + 22;
376     static final int EVENT_LINK_CAPACITY_CHANGED = BASE + 23;
377     static final int EVENT_RESET = BASE + 24;
378     static final int EVENT_REEVALUATE_RESTRICTED_STATE = BASE + 25;
379     static final int EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES = BASE + 26;
380     static final int EVENT_NR_STATE_CHANGED = BASE + 27;
381     static final int EVENT_DATA_CONNECTION_METEREDNESS_CHANGED = BASE + 28;
382     static final int EVENT_NR_FREQUENCY_CHANGED = BASE + 29;
383     static final int EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED = BASE + 30;
384     static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = BASE + 31;
385     static final int EVENT_CSS_INDICATOR_CHANGED = BASE + 32;
386     static final int EVENT_UPDATE_SUSPENDED_STATE = BASE + 33;
387     static final int EVENT_START_HANDOVER = BASE + 34;
388     static final int EVENT_CANCEL_HANDOVER = BASE + 35;
389     static final int EVENT_START_HANDOVER_ON_TARGET = BASE + 36;
390     static final int EVENT_ALLOCATE_PDU_SESSION_ID = BASE + 37;
391     static final int EVENT_RELEASE_PDU_SESSION_ID = BASE + 38;
392     static final int EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE = BASE + 39;
393     private static final int CMD_TO_STRING_COUNT = EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE - BASE + 1;
394 
395     private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
396     static {
397         sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT";
398         sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] =
399                 "EVENT_SETUP_DATA_CONNECTION_DONE";
400         sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE";
401         sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT";
402         sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL";
403         sCmdToString[EVENT_DATA_STATE_CHANGED - BASE] = "EVENT_DATA_STATE_CHANGED";
404         sCmdToString[EVENT_TEAR_DOWN_NOW - BASE] = "EVENT_TEAR_DOWN_NOW";
405         sCmdToString[EVENT_LOST_CONNECTION - BASE] = "EVENT_LOST_CONNECTION";
406         sCmdToString[EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED - BASE] =
407                 "EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED";
408         sCmdToString[EVENT_DATA_CONNECTION_ROAM_ON - BASE] = "EVENT_DATA_CONNECTION_ROAM_ON";
409         sCmdToString[EVENT_DATA_CONNECTION_ROAM_OFF - BASE] = "EVENT_DATA_CONNECTION_ROAM_OFF";
410         sCmdToString[EVENT_BW_REFRESH_RESPONSE - BASE] = "EVENT_BW_REFRESH_RESPONSE";
411         sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_STARTED - BASE] =
412                 "EVENT_DATA_CONNECTION_VOICE_CALL_STARTED";
413         sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_ENDED - BASE] =
414                 "EVENT_DATA_CONNECTION_VOICE_CALL_ENDED";
415         sCmdToString[EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED - BASE] =
416                 "EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED";
417         sCmdToString[EVENT_KEEPALIVE_STATUS - BASE] = "EVENT_KEEPALIVE_STATUS";
418         sCmdToString[EVENT_KEEPALIVE_STARTED - BASE] = "EVENT_KEEPALIVE_STARTED";
419         sCmdToString[EVENT_KEEPALIVE_STOPPED - BASE] = "EVENT_KEEPALIVE_STOPPED";
420         sCmdToString[EVENT_KEEPALIVE_START_REQUEST - BASE] = "EVENT_KEEPALIVE_START_REQUEST";
421         sCmdToString[EVENT_KEEPALIVE_STOP_REQUEST - BASE] = "EVENT_KEEPALIVE_STOP_REQUEST";
422         sCmdToString[EVENT_LINK_CAPACITY_CHANGED - BASE] = "EVENT_LINK_CAPACITY_CHANGED";
423         sCmdToString[EVENT_RESET - BASE] = "EVENT_RESET";
424         sCmdToString[EVENT_REEVALUATE_RESTRICTED_STATE - BASE] =
425                 "EVENT_REEVALUATE_RESTRICTED_STATE";
426         sCmdToString[EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES - BASE] =
427                 "EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES";
428         sCmdToString[EVENT_NR_STATE_CHANGED - BASE] = "EVENT_NR_STATE_CHANGED";
429         sCmdToString[EVENT_DATA_CONNECTION_METEREDNESS_CHANGED - BASE] =
430                 "EVENT_DATA_CONNECTION_METEREDNESS_CHANGED";
431         sCmdToString[EVENT_NR_FREQUENCY_CHANGED - BASE] = "EVENT_NR_FREQUENCY_CHANGED";
432         sCmdToString[EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED - BASE] =
433                 "EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED";
434         sCmdToString[EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED - BASE] =
435                 "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED";
436         sCmdToString[EVENT_CSS_INDICATOR_CHANGED - BASE] = "EVENT_CSS_INDICATOR_CHANGED";
437         sCmdToString[EVENT_UPDATE_SUSPENDED_STATE - BASE] = "EVENT_UPDATE_SUSPENDED_STATE";
438         sCmdToString[EVENT_START_HANDOVER - BASE] = "EVENT_START_HANDOVER";
439         sCmdToString[EVENT_CANCEL_HANDOVER - BASE] = "EVENT_CANCEL_HANDOVER";
440         sCmdToString[EVENT_START_HANDOVER_ON_TARGET - BASE] = "EVENT_START_HANDOVER_ON_TARGET";
441         sCmdToString[EVENT_ALLOCATE_PDU_SESSION_ID - BASE] = "EVENT_ALLOCATE_PDU_SESSION_ID";
442         sCmdToString[EVENT_RELEASE_PDU_SESSION_ID - BASE] = "EVENT_RELEASE_PDU_SESSION_ID";
443         sCmdToString[EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE - BASE] =
444                 "EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE";
445     }
446     // Convert cmd to string or null if unknown
cmdToString(int cmd)447     static String cmdToString(int cmd) {
448         String value = null;
449         cmd -= BASE;
450         if ((cmd >= 0) && (cmd < sCmdToString.length)) {
451             value = sCmdToString[cmd];
452         }
453         if (value == null) {
454             value = "0x" + Integer.toHexString(cmd + BASE);
455         }
456         return value;
457     }
458 
459     /**
460      * Create the connection object
461      *
462      * @param phone the Phone
463      * @param id the connection id
464      * @return DataConnection that was created.
465      */
makeDataConnection(Phone phone, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc, boolean doAllocatePduSessionId)466     public static DataConnection makeDataConnection(Phone phone, int id, DcTracker dct,
467                                                     DataServiceManager dataServiceManager,
468                                                     DcTesterFailBringUpAll failBringUpAll,
469                                                     DcController dcc,
470                                                     boolean doAllocatePduSessionId) {
471         String transportType = (dataServiceManager.getTransportType()
472                 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
473                 ? "C"   // Cellular
474                 : "I";  // IWLAN
475         DataConnection dc = new DataConnection(phone, transportType + "-"
476                 + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll,
477                 dcc, doAllocatePduSessionId);
478         dc.start();
479         if (DBG) dc.log("Made " + dc.getName());
480         return dc;
481     }
482 
dispose()483     void dispose() {
484         log("dispose: call quiteNow()");
485         quitNow();
486     }
487 
488     /* Getter functions */
489 
getLinkProperties()490     LinkProperties getLinkProperties() {
491         return new LinkProperties(mLinkProperties);
492     }
493 
isDisconnecting()494     boolean isDisconnecting() {
495         return getCurrentState() == mDisconnectingState
496                 || getCurrentState() == mDisconnectingErrorCreatingConnection;
497     }
498 
499     @VisibleForTesting
isActive()500     public boolean isActive() {
501         return getCurrentState() == mActiveState;
502     }
503 
504     @VisibleForTesting
isInactive()505     public boolean isInactive() {
506         return getCurrentState() == mInactiveState;
507     }
508 
isActivating()509     boolean isActivating() {
510         return getCurrentState() == mActivatingState;
511     }
512 
hasBeenTransferred()513     boolean hasBeenTransferred() {
514         return mHandoverState == HANDOVER_STATE_COMPLETED;
515     }
516 
getCid()517     int getCid() {
518         return mCid;
519     }
520 
521     /**
522      * @return DataConnection's ApnSetting.
523      */
getApnSetting()524     public ApnSetting getApnSetting() {
525         return mApnSetting;
526     }
527 
528     /**
529      * Update http proxy of link properties based on current apn setting
530      */
updateLinkPropertiesHttpProxy()531     private void updateLinkPropertiesHttpProxy() {
532         if (mApnSetting == null
533                 || TextUtils.isEmpty(mApnSetting.getProxyAddressAsString())) {
534             return;
535         }
536         try {
537             int port = mApnSetting.getProxyPort();
538             if (port == -1) {
539                 port = 8080;
540             }
541             ProxyInfo proxy = ProxyInfo.buildDirectProxy(
542                     mApnSetting.getProxyAddressAsString(), port);
543             mLinkProperties.setHttpProxy(proxy);
544         } catch (NumberFormatException e) {
545             loge("onDataSetupComplete: NumberFormatException making ProxyProperties ("
546                     + mApnSetting.getProxyPort() + "): " + e);
547         }
548     }
549 
550     public static class UpdateLinkPropertyResult {
551         public SetupResult setupResult = SetupResult.SUCCESS;
552         public LinkProperties oldLp;
553         public LinkProperties newLp;
UpdateLinkPropertyResult(LinkProperties curLp)554         public UpdateLinkPropertyResult(LinkProperties curLp) {
555             oldLp = curLp;
556             newLp = curLp;
557         }
558     }
559 
560     /**
561      * Class returned by onSetupConnectionCompleted.
562      */
563     public enum SetupResult {
564         SUCCESS,
565         ERROR_RADIO_NOT_AVAILABLE,
566         ERROR_INVALID_ARG,
567         ERROR_STALE,
568         ERROR_DATA_SERVICE_SPECIFIC_ERROR,
569         ERROR_DUPLICATE_CID,
570         ERROR_NO_DEFAULT_CONNECTION;
571 
572         public int mFailCause;
573 
SetupResult()574         SetupResult() {
575             mFailCause = DataFailCause.getFailCause(0);
576         }
577 
578         @Override
toString()579         public String toString() {
580             return name() + "  SetupResult.mFailCause=" + DataFailCause.toString(mFailCause);
581         }
582     }
583 
isIpv4Connected()584     public boolean isIpv4Connected() {
585         boolean ret = false;
586         Collection <InetAddress> addresses = mLinkProperties.getAddresses();
587 
588         for (InetAddress addr: addresses) {
589             if (addr instanceof java.net.Inet4Address) {
590                 java.net.Inet4Address i4addr = (java.net.Inet4Address) addr;
591                 if (!i4addr.isAnyLocalAddress() && !i4addr.isLinkLocalAddress() &&
592                         !i4addr.isLoopbackAddress() && !i4addr.isMulticastAddress()) {
593                     ret = true;
594                     break;
595                 }
596             }
597         }
598         return ret;
599     }
600 
isIpv6Connected()601     public boolean isIpv6Connected() {
602         boolean ret = false;
603         Collection <InetAddress> addresses = mLinkProperties.getAddresses();
604 
605         for (InetAddress addr: addresses) {
606             if (addr instanceof java.net.Inet6Address) {
607                 java.net.Inet6Address i6addr = (java.net.Inet6Address) addr;
608                 if (!i6addr.isAnyLocalAddress() && !i6addr.isLinkLocalAddress() &&
609                         !i6addr.isLoopbackAddress() && !i6addr.isMulticastAddress()) {
610                     ret = true;
611                     break;
612                 }
613             }
614         }
615         return ret;
616     }
617 
getPduSessionId()618     public int getPduSessionId() {
619         return mPduSessionId;
620     }
621 
getSliceInfo()622     public NetworkSliceInfo getSliceInfo() {
623         return mSliceInfo;
624     }
625 
getTrafficDescriptors()626     public List<TrafficDescriptor> getTrafficDescriptors() {
627         return mTrafficDescriptors;
628     }
629 
630     /**
631      * Update DC fields based on a new DataCallResponse
632      * @param response the response to use to update DC fields
633      */
updateResponseFields(DataCallResponse response)634     public void updateResponseFields(DataCallResponse response) {
635         updateQosParameters(response);
636         updateSliceInfo(response);
637         updateTrafficDescriptors(response);
638     }
639 
updateQosParameters(final @Nullable DataCallResponse response)640     public void updateQosParameters(final @Nullable DataCallResponse response) {
641         if (response == null) {
642             mDefaultQos = null;
643             mQosBearerSessions.clear();
644             return;
645         }
646 
647         mDefaultQos = response.getDefaultQos();
648         mQosBearerSessions = response.getQosBearerSessions();
649 
650         if (mNetworkAgent != null) {
651             syncQosToNetworkAgent();
652         }
653     }
654 
syncQosToNetworkAgent()655     private void syncQosToNetworkAgent() {
656         final DcNetworkAgent networkAgent = mNetworkAgent;
657         final List<QosBearerSession> qosBearerSessions = mQosBearerSessions;
658         if (qosBearerSessions == null) {
659             networkAgent.updateQosBearerSessions(new ArrayList<>());
660             return;
661         }
662         networkAgent.updateQosBearerSessions(qosBearerSessions);
663     }
664 
665     /**
666      * Update the latest slice info on this data connection with
667      * {@link DataCallResponse#getSliceInfo}.
668      */
updateSliceInfo(DataCallResponse response)669     public void updateSliceInfo(DataCallResponse response) {
670         mSliceInfo = response.getSliceInfo();
671     }
672 
673     /**
674      * Update the latest traffic descriptor on this data connection with
675      * {@link DataCallResponse#getTrafficDescriptors}.
676      */
updateTrafficDescriptors(DataCallResponse response)677     public void updateTrafficDescriptors(DataCallResponse response) {
678         mTrafficDescriptors = response.getTrafficDescriptors();
679     }
680 
681     @VisibleForTesting
updateLinkProperty(DataCallResponse newState)682     public UpdateLinkPropertyResult updateLinkProperty(DataCallResponse newState) {
683         UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties);
684 
685         if (newState == null) return result;
686 
687         result.newLp = new LinkProperties();
688 
689         // set link properties based on data call response
690         result.setupResult = setLinkProperties(newState, result.newLp);
691         if (result.setupResult != SetupResult.SUCCESS) {
692             if (DBG) log("updateLinkProperty failed : " + result.setupResult);
693             return result;
694         }
695         // copy HTTP proxy as it is not part DataCallResponse.
696         result.newLp.setHttpProxy(mLinkProperties.getHttpProxy());
697 
698         checkSetMtu(mApnSetting, result.newLp);
699 
700         mLinkProperties = result.newLp;
701 
702         updateTcpBufferSizes(mRilRat);
703 
704         if (DBG && (! result.oldLp.equals(result.newLp))) {
705             log("updateLinkProperty old LP=" + result.oldLp);
706             log("updateLinkProperty new LP=" + result.newLp);
707         }
708 
709         if (result.newLp.equals(result.oldLp) == false &&
710                 mNetworkAgent != null) {
711             mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
712         }
713 
714         return result;
715     }
716 
717     /**
718      * Sets the pdu session id of the data connection
719      * @param pduSessionId pdu session id to set
720      */
721     @VisibleForTesting
setPduSessionId(int pduSessionId)722     public void setPduSessionId(int pduSessionId) {
723         if (mPduSessionId != pduSessionId) {
724             logd("Changing pdu session id from: " + mPduSessionId + " to: " + pduSessionId + ", "
725                     + "Handover state: " + handoverStateToString(this.mHandoverState));
726             mPduSessionId = pduSessionId;
727         }
728     }
729 
730     /**
731      * Read the MTU value from link properties where it can be set from network. In case
732      * not set by the network, set it again using the mtu szie value defined in the APN
733      * database for the connected APN
734      */
checkSetMtu(ApnSetting apn, LinkProperties lp)735     private void checkSetMtu(ApnSetting apn, LinkProperties lp) {
736         if (lp == null) return;
737 
738         if (apn == null || lp == null) return;
739 
740         if (lp.getMtu() != PhoneConstants.UNSET_MTU) {
741             if (DBG) log("MTU set by call response to: " + lp.getMtu());
742             return;
743         }
744 
745         if (apn != null && apn.getMtu() != PhoneConstants.UNSET_MTU) {
746             lp.setMtu(apn.getMtu());
747             if (DBG) log("MTU set by APN to: " + apn.getMtu());
748             return;
749         }
750 
751         int mtu = mPhone.getContext().getResources().getInteger(
752                 com.android.internal.R.integer.config_mobile_mtu);
753         if (mtu != PhoneConstants.UNSET_MTU) {
754             lp.setMtu(mtu);
755             if (DBG) log("MTU set by config resource to: " + mtu);
756         }
757     }
758 
759     //***** Constructor (NOTE: uses dcc.getHandler() as its Handler)
DataConnection(Phone phone, String tagSuffix, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc, boolean doAllocatePduSessionId)760     private DataConnection(Phone phone, String tagSuffix, int id,
761                            DcTracker dct, DataServiceManager dataServiceManager,
762                            DcTesterFailBringUpAll failBringUpAll, DcController dcc,
763                            boolean doAllocatePduSessionId) {
764         super("DC-" + tagSuffix, dcc);
765         mTagSuffix = tagSuffix;
766         setLogRecSize(300);
767         setLogOnlyTransitions(true);
768         if (DBG) log("DataConnection created");
769 
770         mPhone = phone;
771         mDct = dct;
772         mDataServiceManager = dataServiceManager;
773         mVcnManager = mPhone.getContext().getSystemService(VcnManager.class);
774         mTransportType = dataServiceManager.getTransportType();
775         mDcTesterFailBringUpAll = failBringUpAll;
776         mDcController = dcc;
777         mId = id;
778         mCid = -1;
779         mDataRegState = mPhone.getServiceState().getDataRegistrationState();
780         mIsSuspended = false;
781         mDataCallSessionStats = new DataCallSessionStats(mPhone);
782         mDoAllocatePduSessionId = doAllocatePduSessionId;
783 
784         int networkType = getNetworkType();
785         mRilRat = ServiceState.networkTypeToRilRadioTechnology(networkType);
786         updateLinkBandwidthsFromCarrierConfig(mRilRat);
787 
788         addState(mDefaultState);
789             addState(mInactiveState, mDefaultState);
790             addState(mActivatingState, mDefaultState);
791             addState(mActiveState, mDefaultState);
792             addState(mDisconnectingState, mDefaultState);
793             addState(mDisconnectingErrorCreatingConnection, mDefaultState);
794         setInitialState(mInactiveState);
795     }
796 
getNetworkType()797     private @NetworkType int getNetworkType() {
798         ServiceState ss = mPhone.getServiceState();
799         int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
800 
801         NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
802                 NetworkRegistrationInfo.DOMAIN_PS, mTransportType);
803         if (nri != null) {
804             networkType = nri.getAccessNetworkTechnology();
805         }
806 
807         return networkType;
808     }
809 
810     /**
811      * Get the source transport for handover. For example, handover from WWAN to WLAN, WWAN is the
812      * source transport, and vice versa.
813      */
getHandoverSourceTransport()814     private @TransportType int getHandoverSourceTransport() {
815         return mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
816                 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
817                 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
818     }
819 
820     /**
821      * API to generate the OsAppId for enterprise traffic category.
822      * @return byte[] representing OsId + length of OsAppId + OsAppId
823      */
824     @VisibleForTesting
getEnterpriseOsAppId()825     public static byte[] getEnterpriseOsAppId() {
826         byte[] osAppId = NetworkCapabilities.getCapabilityCarrierName(
827                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE).getBytes();
828         // 16 bytes for UUID, 1 byte for length of osAppId, and up to 255 bytes for osAppId
829         ByteBuffer bb = ByteBuffer.allocate(16 + 1 + osAppId.length);
830         bb.putLong(OS_ID.getMostSignificantBits());
831         bb.putLong(OS_ID.getLeastSignificantBits());
832         bb.put((byte) osAppId.length);
833         bb.put(osAppId);
834         if (VDBG) {
835             Rlog.d("DataConnection", "getEnterpriseOsAppId: "
836                     + IccUtils.bytesToHexString(bb.array()));
837         }
838         return bb.array();
839     }
840 
841     /**
842      * Begin setting up a data connection, calls setupDataCall
843      * and the ConnectionParams will be returned with the
844      * EVENT_SETUP_DATA_CONNECTION_DONE
845      *
846      * @param cp is the connection parameters
847      *
848      * @return Fail cause if failed to setup data connection. {@link DataFailCause#NONE} if success.
849      */
connect(ConnectionParams cp)850     private @DataFailureCause int connect(ConnectionParams cp) {
851         log("connect: carrier='" + mApnSetting.getEntryName()
852                 + "' APN='" + mApnSetting.getApnName()
853                 + "' proxy='" + mApnSetting.getProxyAddressAsString()
854                 + "' port='" + mApnSetting.getProxyPort() + "'");
855         if (cp.mApnContext != null) cp.mApnContext.requestLog("DataConnection.connect");
856 
857         // Check if we should fake an error.
858         if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter  > 0) {
859             DataCallResponse response = new DataCallResponse.Builder()
860                     .setCause(mDcTesterFailBringUpAll.getDcFailBringUp().mFailCause)
861                     .setRetryDurationMillis(
862                             mDcTesterFailBringUpAll.getDcFailBringUp().mSuggestedRetryTime)
863                     .setMtuV4(PhoneConstants.UNSET_MTU)
864                     .setMtuV6(PhoneConstants.UNSET_MTU)
865                     .build();
866 
867             Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
868             AsyncResult.forMessage(msg, response, null);
869             sendMessage(msg);
870             if (DBG) {
871                 log("connect: FailBringUpAll=" + mDcTesterFailBringUpAll.getDcFailBringUp()
872                         + " send error response=" + response);
873             }
874             mDcTesterFailBringUpAll.getDcFailBringUp().mCounter -= 1;
875             return DataFailCause.NONE;
876         }
877 
878         mCreateTime = -1;
879         mLastFailTime = -1;
880         mLastFailCause = DataFailCause.NONE;
881 
882         Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
883         msg.obj = cp;
884 
885         DataProfile dp = DcTracker.createDataProfile(mApnSetting, cp.mProfileId,
886                 cp.mIsPreferredApn);
887 
888         // We need to use the actual modem roaming state instead of the framework roaming state
889         // here. This flag is only passed down to ril_service for picking the correct protocol (for
890         // old modem backward compatibility).
891         boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration();
892 
893         // If the apn is NOT metered, we will allow data roaming regardless of the setting.
894         boolean isUnmeteredApnType = !ApnSettingUtils.isMeteredApnType(
895                 cp.mApnContext.getApnTypeBitmask(), mPhone);
896 
897         // Set this flag to true if the user turns on data roaming. Or if we override the roaming
898         // state in framework, we should set this flag to true as well so the modem will not reject
899         // the data call setup (because the modem actually thinks the device is roaming).
900         boolean allowRoaming = mPhone.getDataRoamingEnabled()
901                 || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()
902                 || isUnmeteredApnType));
903 
904         String dnn = null;
905         byte[] osAppId = null;
906         if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
907             osAppId = getEnterpriseOsAppId();
908         } else {
909             dnn = mApnSetting.getApnName();
910         }
911         final TrafficDescriptor td = osAppId == null && dnn == null ? null
912                 : new TrafficDescriptor(dnn, osAppId);
913         final boolean matchAllRuleAllowed = td == null || td.getOsAppId() == null;
914 
915         if (DBG) {
916             log("allowRoaming=" + allowRoaming
917                     + ", mPhone.getDataRoamingEnabled()=" + mPhone.getDataRoamingEnabled()
918                     + ", isModemRoaming=" + isModemRoaming
919                     + ", mPhone.getServiceState().getDataRoaming()="
920                     + mPhone.getServiceState().getDataRoaming()
921                     + ", isUnmeteredApnType=" + isUnmeteredApnType
922                     + ", trafficDescriptor=" + td
923                     + ", matchAllRuleAllowed=" + matchAllRuleAllowed
924             );
925         }
926 
927         // Check if this data setup is a handover.
928         LinkProperties linkProperties = null;
929         int reason = DataService.REQUEST_REASON_NORMAL;
930         if (cp.mRequestType == REQUEST_TYPE_HANDOVER) {
931             // If this is a data setup for handover, we need to pass the link properties
932             // of the existing data connection to the modem.
933             DcTracker srcDcTracker = mPhone.getDcTracker(getHandoverSourceTransport());
934             if (srcDcTracker == null || cp.mApnContext == null) {
935                 loge("connect: Handover failed. dcTracker=" + srcDcTracker + ", apnContext="
936                         + cp.mApnContext);
937                 return DataFailCause.HANDOVER_FAILED;
938             }
939 
940 
941             // srcDc is the source data connection while the current instance is the target
942             DataConnection srcDc =
943                     srcDcTracker.getDataConnectionByApnType(cp.mApnContext.getApnType());
944             if (srcDc == null) {
945                 loge("connect: Can't find data connection for handover.");
946                 return DataFailCause.HANDOVER_FAILED;
947             }
948 
949             // Helpful for logging purposes
950             DataServiceManager srcDsm = srcDc.mDataServiceManager;
951             String srcDsmTag = (srcDsm == null ? "(null)" : srcDsm.getTag());
952             logd("connect: REQUEST_TYPE_HANDOVER - Request handover from " + srcDc.getName()
953                     + ", targetDsm=" + mDataServiceManager.getTag()
954                     + ", sourceDsm=" + srcDsmTag);
955 
956 
957             /* startHandover is called on the source data connection, and if successful,
958                we ask the target data connection (which is the current instance) to call
959                #setupDataCall with request type handover.
960             */
961             Consumer<Integer> onCompleted = (dataServiceCallbackResultCode) ->
962                     /* startHandover is called on the srcDc handler, but the callback needs to
963                        be called on the current (which is the targetDc) handler which is why we
964                        call sendRunnableMessage. */
965                     sendRunnableMessage(EVENT_START_HANDOVER_ON_TARGET,
966                         (inCorrectState) -> requestHandover(inCorrectState, srcDc,
967                             dataServiceCallbackResultCode,
968                             cp, msg, dp, isModemRoaming, allowRoaming));
969             srcDc.startHandover(onCompleted);
970             return DataFailCause.NONE;
971         }
972 
973         // setup data call for REQUEST_TYPE_NORMAL
974         allocatePduSessionId(psi -> {
975             this.setPduSessionId(psi);
976             mDataServiceManager.setupDataCall(
977                     ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat),
978                     dp,
979                     isModemRoaming,
980                     allowRoaming,
981                     reason,
982                     linkProperties,
983                     psi,
984                     null, //slice info is null since this is not a handover
985                     td,
986                     matchAllRuleAllowed,
987                     msg);
988             TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat,
989                     dp.getProfileId(), dp.getApn(), dp.getProtocolType());
990         });
991         return DataFailCause.NONE;
992     }
993 
allocatePduSessionId(Consumer<Integer> allocateCallback)994     private void allocatePduSessionId(Consumer<Integer> allocateCallback) {
995         if (getDoAllocatePduSessionId()) {
996             Message msg = this.obtainMessage(EVENT_ALLOCATE_PDU_SESSION_ID);
997             msg.obj = allocateCallback;
998             mPhone.mCi.allocatePduSessionId(msg);
999         } else {
1000             allocateCallback.accept(PDU_SESSION_ID_NOT_SET);
1001         }
1002     }
1003 
onRquestHandoverFailed(ConnectionParams cp)1004     private void onRquestHandoverFailed(ConnectionParams cp) {
1005         sendMessage(obtainMessage(EVENT_CANCEL_HANDOVER));
1006         notifyConnectCompleted(cp, DataFailCause.UNKNOWN,
1007                 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
1008     }
1009 
requestHandover(boolean inCorrectState, DataConnection srcDc, @DataServiceCallback.ResultCode int resultCode, ConnectionParams cp, Message msg, DataProfile dp, boolean isModemRoaming, boolean allowRoaming)1010     private void requestHandover(boolean inCorrectState, DataConnection srcDc,
1011             @DataServiceCallback.ResultCode int resultCode,
1012             ConnectionParams cp, Message msg, DataProfile dp, boolean isModemRoaming,
1013             boolean allowRoaming) {
1014 
1015         if (!inCorrectState) {
1016             logd("requestHandover: Not in correct state");
1017             if (isResultCodeSuccess(resultCode)) {
1018                 if (srcDc != null) {
1019                     logd("requestHandover: Not in correct state - Success result code");
1020                     // We need to cancel the handover on source if we ended up in the wrong state.
1021                     srcDc.cancelHandover();
1022                 } else {
1023                     logd("requestHandover: Not in correct state - Success result code - "
1024                             + "srcdc = null");
1025                 }
1026             }
1027             onRquestHandoverFailed(cp);
1028             return;
1029         } else if (!isResultCodeSuccess(resultCode)) {
1030             if (DBG) {
1031                 logd("requestHandover: Non success result code from DataService, "
1032                         + "setupDataCall will not be called, result code = "
1033                         + DataServiceCallback.resultCodeToString(resultCode));
1034             }
1035             onRquestHandoverFailed(cp);
1036             return;
1037         }
1038 
1039         if (srcDc == null) {
1040             loge("requestHandover: Cannot find source data connection.");
1041             onRquestHandoverFailed(cp);
1042             return;
1043         }
1044 
1045         LinkProperties linkProperties;
1046         int reason;
1047 
1048         // Preserve the potential network agent from the source data connection. The ownership
1049         // is not transferred at this moment.
1050         mHandoverSourceNetworkAgent = srcDc.getNetworkAgent();
1051         if (mHandoverSourceNetworkAgent == null) {
1052             loge("requestHandover: Cannot get network agent from the source dc " + srcDc.getName());
1053             onRquestHandoverFailed(cp);
1054             return;
1055         }
1056 
1057         linkProperties = srcDc.getLinkProperties();
1058         if (linkProperties == null || linkProperties.getLinkAddresses().isEmpty()) {
1059             loge("requestHandover: Can't find link properties of handover data connection. dc="
1060                     + srcDc);
1061             onRquestHandoverFailed(cp);
1062             return;
1063         }
1064 
1065         mHandoverLocalLog.log("Handover started. Preserved the agent.");
1066         log("Get the handover source network agent: " + mHandoverSourceNetworkAgent);
1067 
1068         reason = DataService.REQUEST_REASON_HANDOVER;
1069 
1070         TrafficDescriptor td = dp.getApn() == null ? null
1071                 : new TrafficDescriptor(dp.getApn(), null);
1072         boolean matchAllRuleAllowed = true;
1073 
1074         mDataServiceManager.setupDataCall(
1075                 ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat),
1076                 dp,
1077                 isModemRoaming,
1078                 allowRoaming,
1079                 reason,
1080                 linkProperties,
1081                 srcDc.getPduSessionId(),
1082                 srcDc.getSliceInfo(),
1083                 td,
1084                 matchAllRuleAllowed,
1085                 msg);
1086         TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat,
1087                 dp.getProfileId(), dp.getApn(), dp.getProtocolType());
1088     }
1089 
1090     /**
1091      * Called on the source data connection from the target data connection.
1092      */
1093     @VisibleForTesting
startHandover(Consumer<Integer> onTargetDcComplete)1094     public void startHandover(Consumer<Integer> onTargetDcComplete) {
1095         logd("startHandover: " + toStringSimple());
1096         // Set the handover state to being transferred on "this" data connection which is the src.
1097         setHandoverState(HANDOVER_STATE_BEING_TRANSFERRED);
1098 
1099         Consumer<Integer> onSrcDcComplete =
1100                 resultCode -> onHandoverStarted(resultCode, onTargetDcComplete);
1101         /*
1102             The flow here is:
1103             srcDc#startHandover -> dataService#startHandover -> (onHandoverStarted) ->
1104                 onSrcDcComplete -> onTargetDcComplete
1105          */
1106         mDataServiceManager.startHandover(mCid,
1107                 this.obtainMessage(EVENT_START_HANDOVER,
1108                         onSrcDcComplete));
1109     }
1110 
1111     /**
1112      * Called on the source data connection when the async call to start handover is complete
1113      */
onHandoverStarted(@ataServiceCallback.ResultCode int resultCode, Consumer<Integer> onTargetDcComplete)1114     private void onHandoverStarted(@DataServiceCallback.ResultCode int resultCode,
1115             Consumer<Integer> onTargetDcComplete) {
1116         logd("onHandoverStarted: " + toStringSimple());
1117         if (!isResultCodeSuccess(resultCode)) {
1118             setHandoverState(HANDOVER_STATE_IDLE);
1119         }
1120         onTargetDcComplete.accept(resultCode);
1121     }
1122 
cancelHandover()1123     private void cancelHandover() {
1124         if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED) {
1125             logd("cancelHandover: handover state is " + handoverStateToString(mHandoverState)
1126                     + ", expecting HANDOVER_STATE_BEING_TRANSFERRED");
1127         }
1128         mDataServiceManager.cancelHandover(mCid, this.obtainMessage(EVENT_CANCEL_HANDOVER));
1129         setHandoverState(HANDOVER_STATE_IDLE);
1130     }
1131 
1132     /**
1133      * Update NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED based on congested override
1134      * @param isCongested whether this DC should be set to congested or not
1135      */
onCongestednessChanged(boolean isCongested)1136     public void onCongestednessChanged(boolean isCongested) {
1137         sendMessage(obtainMessage(EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED, isCongested));
1138     }
1139 
1140     /**
1141      * Update NetworkCapabilities.NET_CAPABILITY_NOT_METERED based on metered override
1142      * @param isUnmetered whether this DC should be set to unmetered or not
1143      */
onMeterednessChanged(boolean isUnmetered)1144     public void onMeterednessChanged(boolean isUnmetered) {
1145         sendMessage(obtainMessage(EVENT_DATA_CONNECTION_METEREDNESS_CHANGED, isUnmetered));
1146     }
1147 
1148     /**
1149      * TearDown the data connection when the deactivation is complete a Message with
1150      * msg.what == EVENT_DEACTIVATE_DONE
1151      *
1152      * @param o is the object returned in the AsyncResult.obj.
1153      */
tearDownData(Object o)1154     private void tearDownData(Object o) {
1155         int discReason = DataService.REQUEST_REASON_NORMAL;
1156         ApnContext apnContext = null;
1157         if ((o != null) && (o instanceof DisconnectParams)) {
1158             DisconnectParams dp = (DisconnectParams) o;
1159             apnContext = dp.mApnContext;
1160             if (TextUtils.equals(dp.mReason, Phone.REASON_RADIO_TURNED_OFF)
1161                     || TextUtils.equals(dp.mReason, Phone.REASON_PDP_RESET)) {
1162                 discReason = DataService.REQUEST_REASON_SHUTDOWN;
1163             } else if (dp.mReleaseType == DcTracker.RELEASE_TYPE_HANDOVER) {
1164                 discReason = DataService.REQUEST_REASON_HANDOVER;
1165             }
1166         }
1167 
1168         String str = "tearDownData. mCid=" + mCid + ", reason=" + discReason;
1169         if (DBG) log(str);
1170         if (apnContext != null) apnContext.requestLog(str);
1171 
1172 
1173         //Needed to be final to work in a closure
1174         final int fDiscReason = discReason;
1175         releasePduSessionId(() -> {
1176             // This is run after release pdu session id is complete
1177             this.setPduSessionId(PDU_SESSION_ID_NOT_SET);
1178             mDataServiceManager.deactivateDataCall(mCid, fDiscReason,
1179                     obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, o));
1180             mDataCallSessionStats.setDeactivateDataCallReason(fDiscReason);
1181         });
1182     }
1183 
releasePduSessionId(Runnable releaseCallback)1184     private void releasePduSessionId(Runnable releaseCallback) {
1185         // If we are not in the middle of a handover and have a real pdu session id, then we release
1186         if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED
1187                 && this.getPduSessionId() != PDU_SESSION_ID_NOT_SET) {
1188             Message msg = this.obtainMessage(EVENT_RELEASE_PDU_SESSION_ID);
1189             msg.obj = releaseCallback;
1190             mPhone.mCi.releasePduSessionId(msg, this.getPduSessionId());
1191         } else {
1192             // Just go and run the callback since we either have no pdu session id to release
1193             // or we are in the middle of a handover
1194             releaseCallback.run();
1195         }
1196     }
1197 
notifyAllWithEvent(ApnContext alreadySent, int event, String reason)1198     private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) {
1199         for (ConnectionParams cp : mApnContexts.values()) {
1200             ApnContext apnContext = cp.mApnContext;
1201             if (apnContext == alreadySent) continue;
1202             if (reason != null) apnContext.setReason(reason);
1203             Pair<ApnContext, Integer> pair = new Pair<>(apnContext, cp.mConnectionGeneration);
1204             Message msg = mDct.obtainMessage(event, cp.mRequestType,
1205                     DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, pair);
1206             AsyncResult.forMessage(msg);
1207             msg.sendToTarget();
1208         }
1209     }
1210 
1211     /**
1212      * Send the connectionCompletedMsg.
1213      *
1214      * @param cp is the ConnectionParams
1215      * @param cause and if no error the cause is DataFailCause.NONE
1216      * @param handoverFailureMode The action on handover failure
1217      * @param sendAll is true if all contexts are to be notified
1218      */
notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause, @HandoverFailureMode int handoverFailureMode, boolean sendAll)1219     private void notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause,
1220             @HandoverFailureMode int handoverFailureMode, boolean sendAll) {
1221         ApnContext alreadySent = null;
1222 
1223         if (cp != null && cp.mOnCompletedMsg != null) {
1224             // Get the completed message but only use it once
1225             Message connectionCompletedMsg = cp.mOnCompletedMsg;
1226             cp.mOnCompletedMsg = null;
1227             alreadySent = cp.mApnContext;
1228 
1229             long timeStamp = System.currentTimeMillis();
1230             connectionCompletedMsg.arg1 = cp.mRequestType;
1231             connectionCompletedMsg.arg2 = handoverFailureMode;
1232 
1233             if (cause == DataFailCause.NONE) {
1234                 mCreateTime = timeStamp;
1235                 AsyncResult.forMessage(connectionCompletedMsg);
1236             } else {
1237                 mLastFailCause = cause;
1238                 mLastFailTime = timeStamp;
1239 
1240                 // Return message with a Throwable exception to signify an error.
1241                 if (cause == DataFailCause.NONE) cause = DataFailCause.UNKNOWN;
1242                 AsyncResult.forMessage(connectionCompletedMsg, cause,
1243                         new Throwable(DataFailCause.toString(cause)));
1244             }
1245             if (DBG) {
1246                 log("notifyConnectCompleted at " + timeStamp + " cause="
1247                         + DataFailCause.toString(cause) + " connectionCompletedMsg="
1248                         + msgToString(connectionCompletedMsg));
1249             }
1250 
1251             connectionCompletedMsg.sendToTarget();
1252         }
1253         if (sendAll) {
1254             log("Send to all. " + alreadySent + " " + DataFailCause.toString(cause));
1255             notifyAllWithEvent(alreadySent, DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR,
1256                     DataFailCause.toString(cause));
1257         }
1258     }
1259 
1260     /**
1261      * Send ar.userObj if its a message, which is should be back to originator.
1262      *
1263      * @param dp is the DisconnectParams.
1264      */
notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll)1265     private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) {
1266         if (VDBG) log("NotifyDisconnectCompleted");
1267 
1268         ApnContext alreadySent = null;
1269         String reason = null;
1270 
1271         if (dp != null && dp.mOnCompletedMsg != null) {
1272             // Get the completed message but only use it once
1273             Message msg = dp.mOnCompletedMsg;
1274             dp.mOnCompletedMsg = null;
1275             if (msg.obj instanceof ApnContext) {
1276                 alreadySent = (ApnContext)msg.obj;
1277             }
1278             reason = dp.mReason;
1279             if (VDBG) {
1280                 log(String.format("msg=%s msg.obj=%s", msg.toString(),
1281                     ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
1282             }
1283             AsyncResult.forMessage(msg);
1284             msg.sendToTarget();
1285         }
1286         if (sendAll) {
1287             if (reason == null) {
1288                 reason = DataFailCause.toString(DataFailCause.UNKNOWN);
1289             }
1290             notifyAllWithEvent(alreadySent, DctConstants.EVENT_DISCONNECT_DONE, reason);
1291         }
1292         if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
1293     }
1294 
sendRunnableMessage(int eventCode, @NonNull final Consumer<Boolean> r)1295     private void sendRunnableMessage(int eventCode, @NonNull final Consumer<Boolean> r) {
1296         sendMessage(eventCode, r);
1297     }
1298 
1299     /*
1300      * **************************************************************************
1301      * Begin Members and methods owned by DataConnectionTracker but stored
1302      * in a DataConnection because there is one per connection.
1303      * **************************************************************************
1304      */
1305 
1306     /*
1307      * The id is owned by DataConnectionTracker.
1308      */
1309     private int mId;
1310 
1311     /**
1312      * Get the DataConnection ID
1313      */
getDataConnectionId()1314     public int getDataConnectionId() {
1315         return mId;
1316     }
1317 
1318     /*
1319      * **************************************************************************
1320      * End members owned by DataConnectionTracker
1321      * **************************************************************************
1322      */
1323 
1324     /**
1325      * Clear all settings called when entering mInactiveState.
1326      */
clearSettings()1327     private void clearSettings() {
1328         if (DBG) log("clearSettings");
1329 
1330         mCreateTime = -1;
1331         mLastFailTime = -1;
1332         mLastFailCause = DataFailCause.NONE;
1333         mCid = -1;
1334 
1335         mPcscfAddr = new String[5];
1336 
1337         mLinkProperties = new LinkProperties();
1338         mApnContexts.clear();
1339         mApnSetting = null;
1340         mUnmeteredUseOnly = false;
1341         mMmsUseOnly = false;
1342         mEnterpriseUse = false;
1343         mRestrictedNetworkOverride = false;
1344         mDcFailCause = DataFailCause.NONE;
1345         mDisabledApnTypeBitMask = 0;
1346         mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1347         mCongestedOverride = false;
1348         mUnmeteredOverride = false;
1349         mDownlinkBandwidth = 14;
1350         mUplinkBandwidth = 14;
1351         mIsSuspended = false;
1352         mHandoverState = HANDOVER_STATE_IDLE;
1353         mHandoverFailureMode = DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN;
1354         mSliceInfo = null;
1355         mDefaultQos = null;
1356         mQosBearerSessions.clear();
1357         mTrafficDescriptors.clear();
1358     }
1359 
1360     /**
1361      * Process setup data completion result from data service
1362      *
1363      * @param resultCode The result code returned by data service
1364      * @param response Data call setup response from data service
1365      * @param cp The original connection params used for data call setup
1366      * @return Setup result
1367      */
onSetupConnectionCompleted(@ataServiceCallback.ResultCode int resultCode, DataCallResponse response, ConnectionParams cp)1368     private SetupResult onSetupConnectionCompleted(@DataServiceCallback.ResultCode int resultCode,
1369                                                    DataCallResponse response,
1370                                                    ConnectionParams cp) {
1371         SetupResult result;
1372 
1373         log("onSetupConnectionCompleted: resultCode=" + resultCode + ", response=" + response);
1374         if (cp.mTag != mTag) {
1375             if (DBG) {
1376                 log("onSetupConnectionCompleted stale cp.tag=" + cp.mTag + ", mtag=" + mTag);
1377             }
1378             result = SetupResult.ERROR_STALE;
1379         } else if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) {
1380             result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
1381             result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
1382         } else if (resultCode == DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE) {
1383             result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
1384             result.mFailCause = DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE;
1385         } else if (resultCode == DataServiceCallback.RESULT_ERROR_INVALID_ARG) {
1386             result = SetupResult.ERROR_INVALID_ARG;
1387             result.mFailCause = DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER;
1388         } else if (response.getCause() != 0) {
1389             if (response.getCause() == DataFailCause.RADIO_NOT_AVAILABLE) {
1390                 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
1391                 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
1392             } else {
1393                 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
1394                 result.mFailCause = DataFailCause.getFailCause(response.getCause());
1395             }
1396         } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
1397                 && mDcController.getActiveDcByCid(response.getId()) != null) {
1398             if (DBG) log("DataConnection already exists for cid: " + response.getId());
1399             result = SetupResult.ERROR_DUPLICATE_CID;
1400             result.mFailCause = DataFailCause.DUPLICATE_CID;
1401         } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
1402                 && !mDcController.isDefaultDataActive()) {
1403             if (DBG) log("No default data connection currently active");
1404             mCid = response.getId();
1405             result = SetupResult.ERROR_NO_DEFAULT_CONNECTION;
1406             result.mFailCause = DataFailCause.NO_DEFAULT_DATA;
1407         } else {
1408             if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse");
1409             mCid = response.getId();
1410 
1411             if (response.getPduSessionId() != getPduSessionId()) {
1412                 if (getDoAllocatePduSessionId()) {
1413                     loge("The pdu session id on DataCallResponse is different than the one "
1414                             + "allocated.  response psi=" + response.getPduSessionId()
1415                             + ", allocated psi=" + getPduSessionId());
1416                 } else {
1417                     setPduSessionId(response.getPduSessionId());
1418                 }
1419             }
1420 
1421             updatePcscfAddr(response);
1422             updateResponseFields(response);
1423             result = updateLinkProperty(response).setupResult;
1424         }
1425 
1426         return result;
1427     }
1428 
isResultCodeSuccess(int resultCode)1429     private static boolean isResultCodeSuccess(int resultCode) {
1430         return resultCode == DataServiceCallback.RESULT_SUCCESS
1431                 || resultCode == DataServiceCallback.RESULT_ERROR_UNSUPPORTED;
1432     }
1433 
isDnsOk(String[] domainNameServers)1434     private boolean isDnsOk(String[] domainNameServers) {
1435         if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1])
1436                 && !mPhone.isDnsCheckDisabled()) {
1437             // Work around a race condition where QMI does not fill in DNS:
1438             // Deactivate PDP and let DataConnectionTracker retry.
1439             // Do not apply the race condition workaround for MMS APN
1440             // if Proxy is an IP-address.
1441             // Otherwise, the default APN will not be restored anymore.
1442             if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) {
1443                 log(String.format(
1444                         "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s",
1445                         mApnSetting.getApnTypeBitmask(), ApnSetting.TYPE_MMS_STRING,
1446                         mApnSetting.getMmsProxyAddressAsString(),
1447                         isIpAddress(mApnSetting.getMmsProxyAddressAsString())));
1448                 return false;
1449             }
1450         }
1451         return true;
1452     }
1453 
1454     /**
1455      * TCP buffer size config based on the ril technology. There are 6 parameters
1456      * read_min, read_default, read_max, write_min, write_default, write_max in the TCP buffer
1457      * config string and they are separated by a comma. The unit of these parameters is byte.
1458      */
1459     private static final String TCP_BUFFER_SIZES_GPRS = "4092,8760,48000,4096,8760,48000";
1460     private static final String TCP_BUFFER_SIZES_EDGE = "4093,26280,70800,4096,16384,70800";
1461     private static final String TCP_BUFFER_SIZES_UMTS = "58254,349525,1048576,58254,349525,1048576";
1462     private static final String TCP_BUFFER_SIZES_1XRTT = "16384,32768,131072,4096,16384,102400";
1463     private static final String TCP_BUFFER_SIZES_EVDO = "4094,87380,262144,4096,16384,262144";
1464     private static final String TCP_BUFFER_SIZES_EHRPD = "131072,262144,1048576,4096,16384,524288";
1465     private static final String TCP_BUFFER_SIZES_HSDPA = "61167,367002,1101005,8738,52429,262114";
1466     private static final String TCP_BUFFER_SIZES_HSPA = "40778,244668,734003,16777,100663,301990";
1467     private static final String TCP_BUFFER_SIZES_LTE =
1468             "524288,1048576,2097152,262144,524288,1048576";
1469     private static final String TCP_BUFFER_SIZES_HSPAP =
1470             "122334,734003,2202010,32040,192239,576717";
1471     private static final String TCP_BUFFER_SIZES_NR =
1472             "2097152,6291456,16777216,512000,2097152,8388608";
1473     private static final String TCP_BUFFER_SIZES_LTE_CA =
1474             "4096,6291456,12582912,4096,1048576,2097152";
1475 
updateTcpBufferSizes(int rilRat)1476     private void updateTcpBufferSizes(int rilRat) {
1477         String sizes = null;
1478         ServiceState ss = mPhone.getServiceState();
1479         if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE &&
1480                 ss.isUsingCarrierAggregation()) {
1481             rilRat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
1482         }
1483         String ratName = ServiceState.rilRadioTechnologyToString(rilRat).toLowerCase(Locale.ROOT);
1484         // ServiceState gives slightly different names for EVDO tech ("evdo-rev.0" for ex)
1485         // - patch it up:
1486         if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 ||
1487                 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A ||
1488                 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B) {
1489             ratName = RAT_NAME_EVDO;
1490         }
1491 
1492         // NR 5G Non-Standalone use LTE cell as the primary cell, the ril technology is LTE in this
1493         // case. We use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
1494         if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
1495                 && ((rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE ||
1496                 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) && isNRConnected())
1497                 && mPhone.getServiceStateTracker().getNrContextIds().contains(mCid)) {
1498             ratName = RAT_NAME_5G;
1499         }
1500 
1501         log("updateTcpBufferSizes: " + ratName);
1502 
1503         // in the form: "ratname:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
1504         String[] configOverride = mPhone.getContext().getResources().getStringArray(
1505                 com.android.internal.R.array.config_mobile_tcp_buffers);
1506         for (int i = 0; i < configOverride.length; i++) {
1507             String[] split = configOverride[i].split(":");
1508             if (ratName.equals(split[0]) && split.length == 2) {
1509                 sizes = split[1];
1510                 break;
1511             }
1512         }
1513 
1514         if (sizes == null) {
1515             // no override - use telephony defaults
1516             // doing it this way allows device or carrier to just override the types they
1517             // care about and inherit the defaults for the others.
1518             switch (rilRat) {
1519                 case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS:
1520                     sizes = TCP_BUFFER_SIZES_GPRS;
1521                     break;
1522                 case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE:
1523                     sizes = TCP_BUFFER_SIZES_EDGE;
1524                     break;
1525                 case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS:
1526                     sizes = TCP_BUFFER_SIZES_UMTS;
1527                     break;
1528                 case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT:
1529                     sizes = TCP_BUFFER_SIZES_1XRTT;
1530                     break;
1531                 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0:
1532                 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A:
1533                 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B:
1534                     sizes = TCP_BUFFER_SIZES_EVDO;
1535                     break;
1536                 case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD:
1537                     sizes = TCP_BUFFER_SIZES_EHRPD;
1538                     break;
1539                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA:
1540                     sizes = TCP_BUFFER_SIZES_HSDPA;
1541                     break;
1542                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA:
1543                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA:
1544                     sizes = TCP_BUFFER_SIZES_HSPA;
1545                     break;
1546                 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
1547                     // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
1548                     if (RAT_NAME_5G.equals(ratName)) {
1549                         sizes = TCP_BUFFER_SIZES_NR;
1550                     } else {
1551                         sizes = TCP_BUFFER_SIZES_LTE;
1552                     }
1553                     break;
1554                 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA:
1555                     // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
1556                     if (RAT_NAME_5G.equals(ratName)) {
1557                         sizes = TCP_BUFFER_SIZES_NR;
1558                     } else {
1559                         sizes = TCP_BUFFER_SIZES_LTE_CA;
1560                     }
1561                     break;
1562                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
1563                     sizes = TCP_BUFFER_SIZES_HSPAP;
1564                     break;
1565                 case ServiceState.RIL_RADIO_TECHNOLOGY_NR:
1566                     sizes = TCP_BUFFER_SIZES_NR;
1567                     break;
1568                 default:
1569                     // Leave empty - this will let ConnectivityService use the system default.
1570                     break;
1571             }
1572         }
1573         mLinkProperties.setTcpBufferSizes(sizes);
1574     }
1575 
updateLinkBandwidthsFromCarrierConfig(int rilRat)1576     private void updateLinkBandwidthsFromCarrierConfig(int rilRat) {
1577         String ratName = ServiceState.rilRadioTechnologyToString(rilRat);
1578         if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) {
1579             ratName = mPhone.getServiceState().getNrFrequencyRange()
1580                     == ServiceState.FREQUENCY_RANGE_MMWAVE
1581                     ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA;
1582         }
1583 
1584         if (DBG) log("updateLinkBandwidthsFromCarrierConfig: " + ratName);
1585 
1586         Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName);
1587         if (values == null) {
1588             values = new Pair<>(14, 14);
1589         }
1590         mDownlinkBandwidth = values.first;
1591         mUplinkBandwidth = values.second;
1592     }
1593 
1594 
updateLinkBandwidthsFromModem(List<LinkCapacityEstimate> lceList)1595     private void updateLinkBandwidthsFromModem(List<LinkCapacityEstimate> lceList) {
1596         if (DBG) log("updateLinkBandwidthsFromModem: lceList=" + lceList);
1597         boolean downlinkUpdated = false;
1598         boolean uplinkUpdated = false;
1599         LinkCapacityEstimate lce = lceList.get(0);
1600         // LCE status deprecated in IRadio 1.2, so only check for IRadio < 1.2
1601         if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2)
1602                 || mPhone.getLceStatus() == RILConstants.LCE_ACTIVE) {
1603             if (lce.getDownlinkCapacityKbps() != LinkCapacityEstimate.INVALID) {
1604                 mDownlinkBandwidth = lce.getDownlinkCapacityKbps();
1605                 downlinkUpdated = true;
1606             }
1607             if (lce.getUplinkCapacityKbps() != LinkCapacityEstimate.INVALID) {
1608                 mUplinkBandwidth = lce.getUplinkCapacityKbps();
1609                 uplinkUpdated = true;
1610             }
1611         }
1612 
1613         if (!downlinkUpdated || !uplinkUpdated) {
1614             fallBackToCarrierConfigValues(downlinkUpdated, uplinkUpdated);
1615         }
1616 
1617         if (mNetworkAgent != null) {
1618             mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this);
1619         }
1620     }
1621 
updateLinkBandwidthsFromBandwidthEstimator(int uplinkBandwidthKbps, int downlinkBandwidthKbps)1622     private void updateLinkBandwidthsFromBandwidthEstimator(int uplinkBandwidthKbps,
1623             int downlinkBandwidthKbps) {
1624         if (DBG) {
1625             log("updateLinkBandwidthsFromBandwidthEstimator, UL= "
1626                     + uplinkBandwidthKbps + " DL= " + downlinkBandwidthKbps);
1627         }
1628         boolean downlinkUpdated = false;
1629         boolean uplinkUpdated = false;
1630         if (downlinkBandwidthKbps > 0) {
1631             mDownlinkBandwidth = downlinkBandwidthKbps;
1632             downlinkUpdated = true;
1633         }
1634         if (uplinkBandwidthKbps > 0) {
1635             mUplinkBandwidth = uplinkBandwidthKbps;
1636             uplinkUpdated = true;
1637         }
1638 
1639         if (!downlinkUpdated || !uplinkUpdated) {
1640             fallBackToCarrierConfigValues(downlinkUpdated, uplinkUpdated);
1641         }
1642         if (mNetworkAgent != null) {
1643             mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this);
1644         }
1645     }
1646 
fallBackToCarrierConfigValues(boolean downlinkUpdated, boolean uplinkUpdated)1647     private void fallBackToCarrierConfigValues(boolean downlinkUpdated, boolean uplinkUpdated) {
1648         String ratName = ServiceState.rilRadioTechnologyToString(mRilRat);
1649         if (mRilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) {
1650             ratName = mPhone.getServiceState().getNrFrequencyRange()
1651                     == ServiceState.FREQUENCY_RANGE_MMWAVE
1652                     ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA;
1653         }
1654         Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName);
1655         if (values != null) {
1656             if (!downlinkUpdated) {
1657                 mDownlinkBandwidth = values.first;
1658             }
1659             if (!uplinkUpdated) {
1660                 mUplinkBandwidth = values.second;
1661             }
1662         }
1663     }
1664 
isBandwidthSourceKey(String source)1665     private boolean isBandwidthSourceKey(String source) {
1666         return source.equals(mPhone.getContext().getResources().getString(
1667                 com.android.internal.R.string.config_bandwidthEstimateSource));
1668     }
1669 
1670     /**
1671      * Indicates if this data connection was established for unmetered use only. Note that this
1672      * flag should be populated when data becomes active. And if it is set to true, it can be set to
1673      * false later when we are reevaluating the data connection. But if it is set to false, it
1674      * can never become true later because setting it to true will cause this data connection
1675      * losing some immutable network capabilities, which can cause issues in connectivity service.
1676      */
1677     private boolean mUnmeteredUseOnly = false;
1678 
1679     /**
1680      * Indicates if this data connection was established for MMS use only. This is true only when
1681      * mobile data is disabled but the user allows sending and receiving MMS messages. If the data
1682      * enabled settings indicate that MMS data is allowed unconditionally, MMS can be sent when data
1683      * is disabled even if it is a metered APN type.
1684      */
1685     private boolean mMmsUseOnly = false;
1686 
1687     /**
1688      * Indicates if when this connection was established we had a restricted/privileged
1689      * NetworkRequest and needed it to overcome data-enabled limitations.
1690      *
1691      * This flag overrides the APN-based restriction capability, restricting the network
1692      * based on both having a NetworkRequest with restricted AND needing a restricted
1693      * bit to overcome user-disabled status.  This allows us to handle the common case
1694      * of having both restricted requests and unrestricted requests for the same apn:
1695      * if conditions require a restricted network to overcome user-disabled then it must
1696      * be restricted, otherwise it is unrestricted (or restricted based on APN type).
1697      *
1698      * This supports a privileged app bringing up a network without general apps having access
1699      * to it when the network is otherwise unavailable (hipri).  The first use case is
1700      * pre-paid SIM reprovisioning over internet, where the carrier insists on no traffic
1701      * other than from the privileged carrier-app.
1702      *
1703      * Note that the data connection cannot go from unrestricted to restricted because the
1704      * connectivity service does not support dynamically closing TCP connections at this point.
1705      */
1706     private boolean mRestrictedNetworkOverride = false;
1707 
1708     /**
1709      * Indicates if this data connection supports enterprise use. Note that this flag should be
1710      * populated when data becomes active. Once it is set, the value cannot be changed because
1711      * setting it will cause this data connection to lose immutable network capabilities, which can
1712      * cause issues in connectivity service.
1713      */
1714     private boolean mEnterpriseUse = false;
1715 
1716     /**
1717      * Check if this data connection should be restricted. We should call this when data connection
1718      * becomes active, or when we want to re-evaluate the conditions to decide if we need to
1719      * unstrict the data connection.
1720      *
1721      * @return True if this data connection needs to be restricted.
1722      */
shouldRestrictNetwork()1723     private boolean shouldRestrictNetwork() {
1724         // first, check if there is any network request that containing restricted capability
1725         // (i.e. Do not have NET_CAPABILITY_NOT_RESTRICTED in the request)
1726         boolean isAnyRestrictedRequest = false;
1727         for (ApnContext apnContext : mApnContexts.keySet()) {
1728             if (apnContext.hasRestrictedRequests(true /* exclude DUN */)) {
1729                 isAnyRestrictedRequest = true;
1730                 break;
1731             }
1732         }
1733 
1734         // If all of the network requests are non-restricted, then we don't need to restrict
1735         // the network.
1736         if (!isAnyRestrictedRequest) {
1737             return false;
1738         }
1739 
1740         // If the network is unmetered, then we don't need to restrict the network because users
1741         // won't be charged anyway.
1742         if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
1743             return false;
1744         }
1745 
1746         // If the data is disabled, then we need to restrict the network so only privileged apps can
1747         // use the restricted network while data is disabled.
1748         if (!mPhone.getDataEnabledSettings().isDataEnabled()) {
1749             return true;
1750         }
1751 
1752         // If the device is roaming, and the user does not turn on data roaming, then we need to
1753         // restrict the network so only privileged apps can use it.
1754         if (!mDct.getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
1755             return true;
1756         }
1757 
1758         // Otherwise we should not restrict the network so anyone who requests can use it.
1759         return false;
1760     }
1761 
1762     /**
1763      * @return True if this data connection should only be used for unmetered purposes.
1764      */
isUnmeteredUseOnly()1765     private boolean isUnmeteredUseOnly() {
1766         // If this data connection is on IWLAN, then it's unmetered and can be used by everyone.
1767         // Should not be for unmetered used only.
1768         if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
1769             return false;
1770         }
1771 
1772         // If data is enabled, this data connection can't be for unmetered used only because
1773         // everyone should be able to use it if:
1774         // 1. Device is not roaming, or
1775         // 2. Device is roaming and data roaming is turned on
1776         if (mPhone.getDataEnabledSettings().isDataEnabled()) {
1777             if (!mPhone.getServiceState().getDataRoaming() || mDct.getDataRoamingEnabled()) {
1778                 return false;
1779             }
1780         }
1781 
1782         // The data connection can only be unmetered used only if all attached APN contexts
1783         // attached to this data connection are unmetered.
1784         for (ApnContext apnContext : mApnContexts.keySet()) {
1785             if (ApnSettingUtils.isMeteredApnType(apnContext.getApnTypeBitmask(), mPhone)) {
1786                 return false;
1787             }
1788         }
1789         return true;
1790     }
1791 
1792     /**
1793      * @return True if this data connection should only be used for MMS purposes.
1794      */
isMmsUseOnly()1795     private boolean isMmsUseOnly() {
1796         // MMS use only if data is disabled, MMS is allowed unconditionally, and MMS is the only
1797         // APN type for this data connection.
1798         DataEnabledSettings des = mPhone.getDataEnabledSettings();
1799         boolean mmsAllowedUnconditionally = !des.isDataEnabled() && des.isMmsAlwaysAllowed();
1800         boolean mmsApnOnly = isApnContextAttached(ApnSetting.TYPE_MMS, true);
1801         return mmsAllowedUnconditionally && mmsApnOnly;
1802     }
1803 
1804     /**
1805      * Check if this data connection supports enterprise use. We call this when the data connection
1806      * becomes active or when we want to reevaluate the conditions to decide if we need to update
1807      * the network agent capabilities.
1808      *
1809      * @return True if this data connection supports enterprise use.
1810      */
isEnterpriseUse()1811     private boolean isEnterpriseUse() {
1812         boolean enterpriseTrafficDescriptor = mTrafficDescriptors
1813                 .stream()
1814                 .anyMatch(td -> td.getOsAppId() != null && Arrays.equals(td.getOsAppId(),
1815                         getEnterpriseOsAppId()));
1816         boolean enterpriseApnContext = mApnContexts.keySet()
1817                 .stream()
1818                 .anyMatch(ac -> ac.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE);
1819         return enterpriseTrafficDescriptor || enterpriseApnContext;
1820     }
1821 
1822     /**
1823      * Get the network capabilities for this data connection.
1824      *
1825      * @return the {@link NetworkCapabilities} of this data connection.
1826      */
getNetworkCapabilities()1827     public NetworkCapabilities getNetworkCapabilities() {
1828         final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
1829                 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
1830         boolean unmeteredApns = false;
1831 
1832         if (mApnSetting != null && !mEnterpriseUse && !mMmsUseOnly) {
1833             final int[] types = ApnSetting.getApnTypesFromBitmask(
1834                     mApnSetting.getApnTypeBitmask() & ~mDisabledApnTypeBitMask);
1835             for (int type : types) {
1836                 if ((!mRestrictedNetworkOverride && mUnmeteredUseOnly)
1837                         && ApnSettingUtils.isMeteredApnType(type, mPhone)) {
1838                     log("Dropped the metered " + ApnSetting.getApnTypeString(type)
1839                             + " type for the unmetered data call.");
1840                     continue;
1841                 }
1842                 switch (type) {
1843                     case ApnSetting.TYPE_ALL: {
1844                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
1845                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1846                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
1847                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
1848                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
1849                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
1850                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
1851                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
1852                         break;
1853                     }
1854                     case ApnSetting.TYPE_DEFAULT: {
1855                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
1856                         break;
1857                     }
1858                     case ApnSetting.TYPE_MMS: {
1859                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1860                         break;
1861                     }
1862                     case ApnSetting.TYPE_SUPL: {
1863                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
1864                         break;
1865                     }
1866                     case ApnSetting.TYPE_DUN: {
1867                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
1868                         break;
1869                     }
1870                     case ApnSetting.TYPE_FOTA: {
1871                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
1872                         break;
1873                     }
1874                     case ApnSetting.TYPE_IMS: {
1875                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
1876                         break;
1877                     }
1878                     case ApnSetting.TYPE_CBS: {
1879                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
1880                         break;
1881                     }
1882                     case ApnSetting.TYPE_IA: {
1883                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
1884                         break;
1885                     }
1886                     case ApnSetting.TYPE_EMERGENCY: {
1887                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
1888                         break;
1889                     }
1890                     case ApnSetting.TYPE_MCX: {
1891                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX);
1892                         break;
1893                     }
1894                     case ApnSetting.TYPE_XCAP: {
1895                         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
1896                         break;
1897                     }
1898                     default:
1899                 }
1900             }
1901 
1902             if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
1903                 unmeteredApns = true;
1904             }
1905         }
1906 
1907         // Mark NOT_METERED in the following cases:
1908         // 1. All APNs in the APN settings are unmetered.
1909         // 2. The non-restricted data is intended for unmetered use only.
1910         if (unmeteredApns || (mUnmeteredUseOnly && !mRestrictedNetworkOverride)) {
1911             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1912         } else {
1913             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1914         }
1915 
1916         if (mEnterpriseUse) {
1917             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
1918             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
1919         }
1920 
1921         if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())) {
1922             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
1923         }
1924 
1925         if (mMmsUseOnly) {
1926             if (ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_MMS, mPhone)) {
1927                 log("Adding unmetered capability for the unmetered MMS-only data connection");
1928                 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1929             }
1930             log("Adding MMS capability for the MMS-only data connection");
1931             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1932         }
1933 
1934         if (mRestrictedNetworkOverride) {
1935             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
1936             // don't use dun on restriction-overriden networks.
1937             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
1938         }
1939 
1940         builder.setLinkDownstreamBandwidthKbps(mDownlinkBandwidth);
1941         builder.setLinkUpstreamBandwidthKbps(mUplinkBandwidth);
1942 
1943         builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
1944                 .setSubscriptionId(mSubId).build());
1945         builder.setSubscriptionIds(Collections.singleton(mSubId));
1946 
1947         if (!mPhone.getServiceState().getDataRoaming()) {
1948             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
1949         }
1950 
1951         if (!mCongestedOverride) {
1952             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
1953         }
1954 
1955         if (mUnmeteredOverride) {
1956             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
1957         }
1958 
1959         if (!mIsSuspended) {
1960             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
1961         }
1962 
1963         builder.setAdministratorUids(mAdministratorUids);
1964 
1965         // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a
1966         // VCN.
1967         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
1968         if (isVcnManaged(builder.build())) {
1969             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
1970         }
1971 
1972         return builder.build();
1973     }
1974 
1975     /**
1976      * Returns whether the Network represented by this DataConnection is VCN-managed.
1977      *
1978      * <p>Determining if the Network is VCN-managed requires polling VcnManager.
1979      */
isVcnManaged(NetworkCapabilities networkCapabilities)1980     private boolean isVcnManaged(NetworkCapabilities networkCapabilities) {
1981         VcnNetworkPolicyResult policyResult =
1982                 mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());
1983 
1984         // if the Network does have capability NOT_VCN_MANAGED, return false to indicate it's not
1985         // VCN-managed
1986         return !policyResult
1987                 .getNetworkCapabilities()
1988                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
1989     }
1990 
1991     /** @return {@code true} if validation is required, {@code false} otherwise. */
isValidationRequired()1992     public boolean isValidationRequired() {
1993         final NetworkCapabilities nc = getNetworkCapabilities();
1994         return nc != null
1995                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
1996                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
1997                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
1998                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
1999     }
2000 
2001     /**
2002      * @return {@code True} if 464xlat should be skipped.
2003      */
2004     @VisibleForTesting
shouldSkip464Xlat()2005     public boolean shouldSkip464Xlat() {
2006         switch (mApnSetting.getSkip464Xlat()) {
2007             case Telephony.Carriers.SKIP_464XLAT_ENABLE:
2008                 return true;
2009             case Telephony.Carriers.SKIP_464XLAT_DISABLE:
2010                 return false;
2011             case Telephony.Carriers.SKIP_464XLAT_DEFAULT:
2012             default:
2013                 break;
2014         }
2015 
2016         // As default, return true if ims and no internet
2017         final NetworkCapabilities nc = getNetworkCapabilities();
2018         return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
2019                 && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
2020     }
2021 
2022     /**
2023      * @return {@code} true iff. {@code address} is a literal IPv4 or IPv6 address.
2024      */
2025     @VisibleForTesting
isIpAddress(String address)2026     public static boolean isIpAddress(String address) {
2027         if (address == null) return false;
2028 
2029         // Accept IPv6 addresses (only) in square brackets for compatibility.
2030         if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {
2031             address = address.substring(1, address.length() - 1);
2032         }
2033         return InetAddresses.isNumericAddress(address);
2034     }
2035 
setLinkProperties(DataCallResponse response, LinkProperties linkProperties)2036     private SetupResult setLinkProperties(DataCallResponse response,
2037             LinkProperties linkProperties) {
2038         // Check if system property dns usable
2039         String propertyPrefix = "net." + response.getInterfaceName() + ".";
2040         String dnsServers[] = new String[2];
2041         dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
2042         dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
2043         boolean okToUseSystemPropertyDns = isDnsOk(dnsServers);
2044 
2045         SetupResult result;
2046 
2047         // Start with clean network properties and if we have
2048         // a failure we'll clear again at the bottom of this code.
2049         linkProperties.clear();
2050 
2051         if (response.getCause() == DataFailCause.NONE) {
2052             try {
2053                 // set interface name
2054                 linkProperties.setInterfaceName(response.getInterfaceName());
2055 
2056                 // set link addresses
2057                 if (response.getAddresses().size() > 0) {
2058                     for (LinkAddress la : response.getAddresses()) {
2059                         if (!la.getAddress().isAnyLocalAddress()) {
2060                             if (DBG) {
2061                                 log("addr/pl=" + la.getAddress() + "/"
2062                                         + la.getPrefixLength());
2063                             }
2064                             linkProperties.addLinkAddress(la);
2065                         }
2066                     }
2067                 } else {
2068                     throw new UnknownHostException("no address for ifname="
2069                             + response.getInterfaceName());
2070                 }
2071 
2072                 // set dns servers
2073                 if (response.getDnsAddresses().size() > 0) {
2074                     for (InetAddress dns : response.getDnsAddresses()) {
2075                         if (!dns.isAnyLocalAddress()) {
2076                             linkProperties.addDnsServer(dns);
2077                         }
2078                     }
2079                 } else if (okToUseSystemPropertyDns) {
2080                     for (String dnsAddr : dnsServers) {
2081                         dnsAddr = dnsAddr.trim();
2082                         if (dnsAddr.isEmpty()) continue;
2083                         InetAddress ia;
2084                         try {
2085                             ia = InetAddresses.parseNumericAddress(dnsAddr);
2086                         } catch (IllegalArgumentException e) {
2087                             throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr);
2088                         }
2089                         if (!ia.isAnyLocalAddress()) {
2090                             linkProperties.addDnsServer(ia);
2091                         }
2092                     }
2093                 } else {
2094                     throw new UnknownHostException("Empty dns response and no system default dns");
2095                 }
2096 
2097                 // set pcscf
2098                 if (response.getPcscfAddresses().size() > 0) {
2099                     for (InetAddress pcscf : response.getPcscfAddresses()) {
2100                         linkProperties.addPcscfServer(pcscf);
2101                     }
2102                 }
2103 
2104                 boolean useLowerMtuValue = false;
2105                 CarrierConfigManager configManager = (CarrierConfigManager)
2106                         mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
2107                 if (configManager != null) {
2108                     PersistableBundle bundle = configManager.getConfigForSubId(mSubId);
2109                     if (bundle != null) {
2110                         useLowerMtuValue = bundle.getBoolean(
2111                                 CarrierConfigManager.KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED)
2112                                 && response.getMtuV4() != PhoneConstants.UNSET_MTU
2113                                 && response.getMtuV6() != PhoneConstants.UNSET_MTU;
2114                     }
2115                 }
2116 
2117                 int interfaceMtu = response.getMtu();
2118                 for (InetAddress gateway : response.getGatewayAddresses()) {
2119                     int mtu = gateway instanceof java.net.Inet6Address ? response.getMtuV6()
2120                             : response.getMtuV4();
2121                     if (useLowerMtuValue) {
2122                         mtu = Math.min(response.getMtuV4(), response.getMtuV6());
2123                         // Never set an MTU below MIN_V6_MTU on a network that has IPv6.
2124                         if (mtu < MIN_V6_MTU) {
2125                             mtu = MIN_V6_MTU;
2126                         }
2127                         interfaceMtu = mtu;
2128                     }
2129                     // Allow 0.0.0.0 or :: as a gateway;
2130                     // this indicates a point-to-point interface.
2131                     linkProperties.addRoute(new RouteInfo(null, gateway, null,
2132                             RouteInfo.RTN_UNICAST, mtu));
2133                 }
2134 
2135                 // set interface MTU
2136                 // this may clobber the setting read from the APN db, but that's ok
2137                 // TODO: remove once LinkProperties#setMtu is deprecated
2138                 linkProperties.setMtu(interfaceMtu);
2139 
2140                 result = SetupResult.SUCCESS;
2141             } catch (UnknownHostException e) {
2142                 log("setLinkProperties: UnknownHostException " + e);
2143                 result = SetupResult.ERROR_INVALID_ARG;
2144             }
2145         } else {
2146             result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
2147         }
2148 
2149         // An error occurred so clear properties
2150         if (result != SetupResult.SUCCESS) {
2151             if (DBG) {
2152                 log("setLinkProperties: error clearing LinkProperties status="
2153                         + response.getCause() + " result=" + result);
2154             }
2155             linkProperties.clear();
2156         }
2157 
2158         return result;
2159     }
2160 
getDoAllocatePduSessionId()2161     private boolean getDoAllocatePduSessionId() {
2162         return mDoAllocatePduSessionId;
2163     }
2164 
2165     /**
2166      * Initialize connection, this will fail if the
2167      * apnSettings are not compatible.
2168      *
2169      * @param cp the Connection parameters
2170      * @return true if initialization was successful.
2171      */
initConnection(ConnectionParams cp)2172     private boolean initConnection(ConnectionParams cp) {
2173         ApnContext apnContext = cp.mApnContext;
2174         if (mApnSetting == null) {
2175             // Only change apn setting if it isn't set, it will
2176             // only NOT be set only if we're in DcInactiveState.
2177             mApnSetting = apnContext.getApnSetting();
2178         }
2179         if (mApnSetting == null || (!mApnSetting.canHandleType(apnContext.getApnTypeBitmask())
2180                 && apnContext.getApnTypeBitmask() != ApnSetting.TYPE_ENTERPRISE)) {
2181             if (DBG) {
2182                 log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp
2183                         + " dc=" + DataConnection.this);
2184             }
2185             return false;
2186         }
2187         mTag += 1;
2188         mConnectionParams = cp;
2189         mConnectionParams.mTag = mTag;
2190 
2191         // always update the ConnectionParams with the latest or the
2192         // connectionGeneration gets stale
2193         mApnContexts.put(apnContext, cp);
2194 
2195         if (DBG) {
2196             log("initConnection: "
2197                     + " RefCount=" + mApnContexts.size()
2198                     + " mApnList=" + mApnContexts
2199                     + " mConnectionParams=" + mConnectionParams);
2200         }
2201         return true;
2202     }
2203 
2204     /**
2205      * The parent state for all other states.
2206      */
2207     private class DcDefaultState extends State {
2208         @Override
enter()2209         public void enter() {
2210             if (DBG) log("DcDefaultState: enter");
2211 
2212             // Register for DRS or RAT change
2213             mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
2214                     mTransportType, getHandler(),
2215                     DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null);
2216 
2217             mPhone.getServiceStateTracker().registerForDataRoamingOn(getHandler(),
2218                     DataConnection.EVENT_DATA_CONNECTION_ROAM_ON, null);
2219             mPhone.getServiceStateTracker().registerForDataRoamingOff(getHandler(),
2220                     DataConnection.EVENT_DATA_CONNECTION_ROAM_OFF, null, true);
2221             mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(),
2222                     DataConnection.EVENT_NR_STATE_CHANGED, null);
2223             mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(),
2224                     DataConnection.EVENT_NR_FREQUENCY_CHANGED, null);
2225             mPhone.getServiceStateTracker().registerForCssIndicatorChanged(getHandler(),
2226                     DataConnection.EVENT_CSS_INDICATOR_CHANGED, null);
2227             if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
2228                 mPhone.getLinkBandwidthEstimator().registerForBandwidthChanged(getHandler(),
2229                         DataConnection.EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE, null);
2230             }
2231 
2232             // Add ourselves to the list of data connections
2233             mDcController.addDc(DataConnection.this);
2234         }
2235         @Override
exit()2236         public void exit() {
2237             if (DBG) log("DcDefaultState: exit");
2238 
2239             // Unregister for DRS or RAT change.
2240             mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(
2241                     mTransportType, getHandler());
2242 
2243             mPhone.getServiceStateTracker().unregisterForDataRoamingOn(getHandler());
2244             mPhone.getServiceStateTracker().unregisterForDataRoamingOff(getHandler());
2245             mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler());
2246             mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler());
2247             mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler());
2248             if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
2249                 mPhone.getLinkBandwidthEstimator().unregisterForBandwidthChanged(getHandler());
2250             }
2251 
2252             // Remove ourselves from the DC lists
2253             mDcController.removeDc(DataConnection.this);
2254 
2255             if (mAc != null) {
2256                 mAc.disconnected();
2257                 mAc = null;
2258             }
2259             mApnContexts.clear();
2260             mReconnectIntent = null;
2261             mDct = null;
2262             mApnSetting = null;
2263             mPhone = null;
2264             mDataServiceManager = null;
2265             mLinkProperties = null;
2266             mLastFailCause = DataFailCause.NONE;
2267             mUserData = null;
2268             mDcController = null;
2269             mDcTesterFailBringUpAll = null;
2270         }
2271 
2272         @Override
processMessage(Message msg)2273         public boolean processMessage(Message msg) {
2274             boolean retVal = HANDLED;
2275 
2276             if (VDBG) {
2277                 log("DcDefault msg=" + getWhatToString(msg.what)
2278                         + " RefCount=" + mApnContexts.size());
2279             }
2280             switch (msg.what) {
2281                 case EVENT_RESET:
2282                     if (VDBG) log("DcDefaultState: msg.what=REQ_RESET");
2283                     transitionTo(mInactiveState);
2284                     break;
2285                 case EVENT_CONNECT:
2286                     if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected");
2287                     ConnectionParams cp = (ConnectionParams) msg.obj;
2288                     notifyConnectCompleted(cp, DataFailCause.UNKNOWN,
2289                             DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
2290                     break;
2291 
2292                 case EVENT_DISCONNECT:
2293                 case EVENT_DISCONNECT_ALL:
2294                 case EVENT_REEVALUATE_RESTRICTED_STATE:
2295                     if (DBG) {
2296                         log("DcDefaultState deferring msg.what=" + getWhatToString(msg.what)
2297                                 + " RefCount=" + mApnContexts.size());
2298                     }
2299                     deferMessage(msg);
2300                     break;
2301                 case EVENT_TEAR_DOWN_NOW:
2302                     if (DBG) log("DcDefaultState EVENT_TEAR_DOWN_NOW");
2303                     mDataServiceManager.deactivateDataCall(mCid, DataService.REQUEST_REASON_NORMAL,
2304                             null);
2305                     mDataCallSessionStats.setDeactivateDataCallReason(
2306                             DataService.REQUEST_REASON_NORMAL);
2307                     break;
2308                 case EVENT_LOST_CONNECTION:
2309                     if (DBG) {
2310                         String s = "DcDefaultState ignore EVENT_LOST_CONNECTION"
2311                                 + " tag=" + msg.arg1 + ":mTag=" + mTag;
2312                         logAndAddLogRec(s);
2313                     }
2314                     break;
2315                 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED:
2316                     AsyncResult ar = (AsyncResult)msg.obj;
2317                     Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>)ar.result;
2318                     mDataRegState = drsRatPair.first;
2319                     updateTcpBufferSizes(drsRatPair.second);
2320                     if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
2321                         updateLinkBandwidthsFromCarrierConfig(drsRatPair.second);
2322                     }
2323                     mRilRat = drsRatPair.second;
2324                     if (DBG) {
2325                         log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"
2326                                 + " regState=" + ServiceState.rilServiceStateToString(mDataRegState)
2327                                 + " RAT=" + ServiceState.rilRadioTechnologyToString(mRilRat));
2328                     }
2329                     mDataCallSessionStats.onDrsOrRatChanged(mRilRat);
2330                     break;
2331 
2332                 case EVENT_START_HANDOVER:  //calls startHandover()
2333                     if (DBG) {
2334                         log("DcDefaultState: EVENT_START_HANDOVER not expected.");
2335                     }
2336                     Consumer<Integer> r = (Consumer<Integer>) msg.obj;
2337                     r.accept(DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
2338                     break;
2339                 case EVENT_START_HANDOVER_ON_TARGET:
2340                     if (DBG) {
2341                         log("DcDefaultState: EVENT_START_HANDOVER not expected, but will "
2342                                 + "clean up, result code: "
2343                                 + DataServiceCallback.resultCodeToString(msg.arg1));
2344                     }
2345                     ((Consumer<Boolean>) msg.obj).accept(false /* is in correct state*/);
2346                     break;
2347                 case EVENT_CANCEL_HANDOVER:
2348                     // We don't need to do anything in this case
2349                     if (DBG) {
2350                         log("DcDefaultState: EVENT_CANCEL_HANDOVER resultCode="
2351                                 + DataServiceCallback.resultCodeToString(msg.arg1));
2352                     }
2353                     break;
2354                 case EVENT_RELEASE_PDU_SESSION_ID: {
2355                     // We do the same thing in all state in order to preserve the existing workflow
2356                     final AsyncResult asyncResult = (AsyncResult) msg.obj;
2357                     if (asyncResult == null) {
2358                         loge("EVENT_RELEASE_PDU_SESSION_ID: asyncResult is null!");
2359                     } else {
2360                         if (msg.obj != null) {
2361                             if (DBG) logd("EVENT_RELEASE_PDU_SESSION_ID: id released");
2362                             Runnable runnable = (Runnable) asyncResult.userObj;
2363                             runnable.run();
2364                         } else {
2365                             loge("EVENT_RELEASE_PDU_SESSION_ID: no runnable set");
2366                         }
2367                     }
2368                     retVal = HANDLED;
2369                     break;
2370                 }
2371                 case EVENT_ALLOCATE_PDU_SESSION_ID: {
2372                     // We do the same thing in all state in order to preserve the existing workflow
2373                     final AsyncResult asyncResult = (AsyncResult) msg.obj;
2374                     if (asyncResult == null) {
2375                         loge("EVENT_ALLOCATE_PDU_SESSION_ID: asyncResult is null!");
2376                     } else {
2377                         Consumer<Integer> onAllocated = (Consumer<Integer>) asyncResult.userObj;
2378                         if (asyncResult.exception != null) {
2379                             loge("EVENT_ALLOCATE_PDU_SESSION_ID: exception",
2380                                     asyncResult.exception);
2381                             onAllocated.accept(PDU_SESSION_ID_NOT_SET);
2382                         } else if (asyncResult.result == null) {
2383                             loge("EVENT_ALLOCATE_PDU_SESSION_ID: result null, no id");
2384                             onAllocated.accept(PDU_SESSION_ID_NOT_SET);
2385                         } else {
2386                             int psi = (int) asyncResult.result;
2387                             if (DBG) logd("EVENT_ALLOCATE_PDU_SESSION_ID: psi=" + psi);
2388                             onAllocated.accept(psi);
2389                         }
2390                     }
2391                     retVal = HANDLED;
2392                     break;
2393                 }
2394                 default:
2395                     if (DBG) {
2396                         log("DcDefaultState: ignore msg.what=" + getWhatToString(msg.what));
2397                     }
2398                     break;
2399             }
2400 
2401             return retVal;
2402         }
2403     }
2404 
updateSuspendState()2405     private void updateSuspendState() {
2406         if (mNetworkAgent == null) {
2407             Rlog.d(getName(), "Setting suspend state without a NetworkAgent");
2408         }
2409 
2410         boolean newSuspendedState = false;
2411         // Data can only be (temporarily) suspended while data is in active state
2412         if (getCurrentState() == mActiveState) {
2413             // Never set suspended for emergency apn. Emergency data connection
2414             // can work while device is not in service.
2415             if (mApnSetting != null && mApnSetting.isEmergencyApn()) {
2416                 newSuspendedState = false;
2417             // If we are not in service, change to suspended.
2418             } else if (mDataRegState != ServiceState.STATE_IN_SERVICE) {
2419                 newSuspendedState = true;
2420             // Check voice/data concurrency.
2421             } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
2422                 newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE;
2423             }
2424         }
2425 
2426         // Only notify when there is a change.
2427         if (mIsSuspended != newSuspendedState) {
2428             mIsSuspended = newSuspendedState;
2429 
2430             // If data connection is active, we need to notify the new data connection state
2431             // changed event reflecting the latest suspended state.
2432             if (isActive()) {
2433                 notifyDataConnectionState();
2434             }
2435         }
2436     }
2437 
notifyDataConnectionState()2438     private void notifyDataConnectionState() {
2439         // The receivers of this have no way to differentiate between default and enterprise
2440         // connections. Do not notify for enterprise.
2441         if (!isEnterpriseUse()) {
2442             mPhone.notifyDataConnection(getPreciseDataConnectionState());
2443         } else {
2444             log("notifyDataConnectionState: Skipping for enterprise; state=" + getState());
2445         }
2446     }
2447 
2448     private DcDefaultState mDefaultState = new DcDefaultState();
2449 
getApnTypeBitmask()2450     private int getApnTypeBitmask() {
2451         return isEnterpriseUse() ? ApnSetting.TYPE_ENTERPRISE :
2452                 mApnSetting != null ? mApnSetting.getApnTypeBitmask() : 0;
2453     }
2454 
canHandleDefault()2455     private boolean canHandleDefault() {
2456         return !isEnterpriseUse() && mApnSetting != null
2457                 ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false;
2458     }
2459 
2460     /**
2461      * The state machine is inactive and expects a EVENT_CONNECT.
2462      */
2463     private class DcInactiveState extends State {
2464         // Inform all contexts we've failed connecting
setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause, @HandoverFailureMode int handoverFailureMode)2465         public void setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause,
2466                 @HandoverFailureMode int handoverFailureMode) {
2467             if (VDBG) log("DcInactiveState: setEnterNotificationParams cp,cause");
2468             mConnectionParams = cp;
2469             mDisconnectParams = null;
2470             mDcFailCause = cause;
2471             mHandoverFailureMode = handoverFailureMode;
2472         }
2473 
2474         // Inform all contexts we've failed disconnected
setEnterNotificationParams(DisconnectParams dp)2475         public void setEnterNotificationParams(DisconnectParams dp) {
2476             if (VDBG) log("DcInactiveState: setEnterNotificationParams dp");
2477             mConnectionParams = null;
2478             mDisconnectParams = dp;
2479             mDcFailCause = DataFailCause.NONE;
2480         }
2481 
2482         // Inform all contexts of the failure cause
setEnterNotificationParams(@ataFailureCause int cause)2483         public void setEnterNotificationParams(@DataFailureCause int cause) {
2484             mConnectionParams = null;
2485             mDisconnectParams = null;
2486             mDcFailCause = cause;
2487         }
2488 
2489         @Override
enter()2490         public void enter() {
2491             mTag += 1;
2492             if (DBG) log("DcInactiveState: enter() mTag=" + mTag);
2493             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
2494                     TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__INACTIVE,
2495                     mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault());
2496             mDataCallSessionStats.onDataCallDisconnected(mDcFailCause);
2497             if (mHandoverState == HANDOVER_STATE_BEING_TRANSFERRED) {
2498                 // This is from source data connection to set itself's state
2499                 setHandoverState(HANDOVER_STATE_COMPLETED);
2500             }
2501 
2502             // Check for dangling agent. Ideally the handover source agent should be null if
2503             // handover process is smooth. When it's not null, that means handover failed. The
2504             // agent was not successfully transferred to the new data connection. We should
2505             // gracefully notify connectivity service the network was disconnected.
2506             if (mHandoverSourceNetworkAgent != null) {
2507                 DataConnection sourceDc = mHandoverSourceNetworkAgent.getDataConnection();
2508                 if (sourceDc != null) {
2509                     // If the source data connection still owns this agent, then just reset the
2510                     // handover state back to idle because handover is already failed.
2511                     mHandoverLocalLog.log(
2512                             "Handover failed. Reset the source dc " + sourceDc.getName()
2513                                     + " state to idle");
2514                     sourceDc.cancelHandover();
2515                 } else {
2516                     // The agent is now a dangling agent. No data connection owns this agent.
2517                     // Gracefully notify connectivity service disconnected.
2518                     mHandoverLocalLog.log(
2519                             "Handover failed and dangling agent found.");
2520                     mHandoverSourceNetworkAgent.acquireOwnership(
2521                             DataConnection.this, mTransportType);
2522                     log("Cleared dangling network agent. " + mHandoverSourceNetworkAgent);
2523                     mHandoverSourceNetworkAgent.unregister(DataConnection.this);
2524                     mHandoverSourceNetworkAgent.releaseOwnership(DataConnection.this);
2525                 }
2526                 mHandoverSourceNetworkAgent = null;
2527             }
2528 
2529             if (mConnectionParams != null) {
2530                 if (DBG) {
2531                     log("DcInactiveState: enter notifyConnectCompleted +ALL failCause="
2532                             + DataFailCause.toString(mDcFailCause));
2533                 }
2534                 notifyConnectCompleted(mConnectionParams, mDcFailCause, mHandoverFailureMode,
2535                         true);
2536             }
2537             if (mDisconnectParams != null) {
2538                 if (DBG) {
2539                     log("DcInactiveState: enter notifyDisconnectCompleted +ALL failCause="
2540                             + DataFailCause.toString(mDcFailCause));
2541                 }
2542                 notifyDisconnectCompleted(mDisconnectParams, true);
2543             }
2544             if (mDisconnectParams == null && mConnectionParams == null
2545                     && mDcFailCause != DataFailCause.NONE) {
2546                 if (DBG) {
2547                     log("DcInactiveState: enter notifyAllDisconnectCompleted failCause="
2548                             + DataFailCause.toString(mDcFailCause));
2549                 }
2550                 notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE,
2551                         DataFailCause.toString(mDcFailCause));
2552             }
2553 
2554             // Remove ourselves from cid mapping, before clearSettings
2555             mDcController.removeActiveDcByCid(DataConnection.this);
2556 
2557             // For the first time entering here (idle state before setup), do not notify
2558             // disconnected state. Only notify data connection disconnected for data that is
2559             // actually moving from disconnecting to disconnected, or setup failed. In both cases,
2560             // APN setting will not be null.
2561             if (mApnSetting != null) {
2562                 notifyDataConnectionState();
2563             }
2564             clearSettings();
2565         }
2566 
2567         @Override
exit()2568         public void exit() {
2569         }
2570 
2571         @Override
processMessage(Message msg)2572         public boolean processMessage(Message msg) {
2573             switch (msg.what) {
2574                 case EVENT_RESET:
2575                 case EVENT_REEVALUATE_RESTRICTED_STATE:
2576                     if (DBG) {
2577                         log("DcInactiveState: msg.what=" + getWhatToString(msg.what)
2578                                 + ", ignore we're already done");
2579                     }
2580                     return HANDLED;
2581                 case EVENT_CONNECT:
2582                     if (DBG) log("DcInactiveState: mag.what=EVENT_CONNECT");
2583                     ConnectionParams cp = (ConnectionParams) msg.obj;
2584 
2585                     if (!initConnection(cp)) {
2586                         log("DcInactiveState: msg.what=EVENT_CONNECT initConnection failed");
2587                         notifyConnectCompleted(cp, DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER,
2588                                 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
2589                         transitionTo(mInactiveState);
2590                         return HANDLED;
2591                     }
2592 
2593                     int cause = connect(cp);
2594                     if (cause != DataFailCause.NONE) {
2595                         log("DcInactiveState: msg.what=EVENT_CONNECT connect failed");
2596                         notifyConnectCompleted(cp, cause,
2597                                 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
2598                         transitionTo(mInactiveState);
2599                         return HANDLED;
2600                     }
2601 
2602                     if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2603                         mSubId = cp.mSubId;
2604                     }
2605 
2606                     transitionTo(mActivatingState);
2607                     return HANDLED;
2608                 case EVENT_DISCONNECT:
2609                     if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT");
2610                     notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
2611                     return HANDLED;
2612                 case EVENT_DISCONNECT_ALL:
2613                     if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL");
2614                     notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
2615                     return HANDLED;
2616                 default:
2617                     if (VDBG) {
2618                         log("DcInactiveState not handled msg.what=" + getWhatToString(msg.what));
2619                     }
2620                     return NOT_HANDLED;
2621             }
2622         }
2623     }
2624     private DcInactiveState mInactiveState = new DcInactiveState();
2625 
2626     /**
2627      * The state machine is activating a connection.
2628      */
2629     private class DcActivatingState extends State {
2630         @Override
enter()2631         public void enter() {
2632             int apnTypeBitmask = getApnTypeBitmask();
2633             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
2634                     TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVATING,
2635                     mPhone.getPhoneId(), mId, apnTypeBitmask, canHandleDefault());
2636             setHandoverState(HANDOVER_STATE_IDLE);
2637             // restricted evaluation depends on network requests from apnContext. The evaluation
2638             // should happen once entering connecting state rather than active state because it's
2639             // possible that restricted network request can be released during the connecting window
2640             // and if we wait for connection established, then we might mistakenly
2641             // consider it as un-restricted. ConnectivityService then will immediately
2642             // tear down the connection through networkAgent unwanted callback if all requests for
2643             // this connection are going away.
2644             mRestrictedNetworkOverride = shouldRestrictNetwork();
2645 
2646             mPhone.getCarrierPrivilegesTracker()
2647                     .registerCarrierPrivilegesListener(
2648                             getHandler(), EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null);
2649             notifyDataConnectionState();
2650             mDataCallSessionStats.onSetupDataCall(apnTypeBitmask);
2651         }
2652         @Override
processMessage(Message msg)2653         public boolean processMessage(Message msg) {
2654             boolean retVal;
2655             AsyncResult ar;
2656             ConnectionParams cp;
2657 
2658             if (DBG) log("DcActivatingState: msg=" + msgToString(msg));
2659             switch (msg.what) {
2660                 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED:
2661                 case EVENT_CONNECT:
2662                     // Activating can't process until we're done.
2663                     deferMessage(msg);
2664                     retVal = HANDLED;
2665                     break;
2666 
2667                 case EVENT_SETUP_DATA_CONNECTION_DONE:
2668                     cp = (ConnectionParams) msg.obj;
2669 
2670                     DataCallResponse dataCallResponse =
2671                             msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
2672                     SetupResult result = onSetupConnectionCompleted(msg.arg1, dataCallResponse, cp);
2673                     if (result != SetupResult.ERROR_STALE) {
2674                         if (mConnectionParams != cp) {
2675                             loge("DcActivatingState: WEIRD mConnectionsParams:"+ mConnectionParams
2676                                     + " != cp:" + cp);
2677                         }
2678                     }
2679                     if (DBG) {
2680                         log("DcActivatingState onSetupConnectionCompleted result=" + result
2681                                 + " dc=" + DataConnection.this);
2682                     }
2683                     if (cp.mApnContext != null) {
2684                         cp.mApnContext.requestLog("onSetupConnectionCompleted result=" + result);
2685                     }
2686                     switch (result) {
2687                         case SUCCESS:
2688                             // All is well
2689                             mDcFailCause = DataFailCause.NONE;
2690                             transitionTo(mActiveState);
2691                             break;
2692                         case ERROR_RADIO_NOT_AVAILABLE:
2693                             // Vendor ril rejected the command and didn't connect.
2694                             // Transition to inactive but send notifications after
2695                             // we've entered the mInactive state.
2696                             mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
2697                                     DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
2698                             transitionTo(mInactiveState);
2699                             break;
2700                         case ERROR_DUPLICATE_CID:
2701                             // TODO (b/180988471): Properly handle the case when an existing cid is
2702                             // returned by tearing down the network agent if enterprise changed.
2703                             long retry = RetryManager.NO_SUGGESTED_RETRY_DELAY;
2704                             if (cp.mApnContext != null) {
2705                                 retry = RetryManager.NO_RETRY;
2706                                 mDct.getDataThrottler().setRetryTime(
2707                                         cp.mApnContext.getApnTypeBitmask(),
2708                                         retry, DcTracker.REQUEST_TYPE_NORMAL);
2709                             }
2710                             String logStr = "DcActivatingState: "
2711                                     + DataFailCause.toString(result.mFailCause)
2712                                     + " retry=" + retry;
2713                             if (DBG) log(logStr);
2714                             if (cp.mApnContext != null) cp.mApnContext.requestLog(logStr);
2715                             mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
2716                                     DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
2717                             transitionTo(mInactiveState);
2718                             break;
2719                         case ERROR_NO_DEFAULT_CONNECTION:
2720                             // TODO (b/180988471): Properly handle the case when a default data
2721                             // connection doesn't exist (tear down connection and retry).
2722                             // Currently, this just tears down the connection without retry.
2723                             if (DBG) log("DcActivatingState: NO_DEFAULT_DATA");
2724                         case ERROR_INVALID_ARG:
2725                             // The addresses given from the RIL are bad
2726                             tearDownData(cp);
2727                             transitionTo(mDisconnectingErrorCreatingConnection);
2728                             break;
2729                         case ERROR_DATA_SERVICE_SPECIFIC_ERROR:
2730 
2731                             // Retrieve the suggested retry delay from the modem and save it.
2732                             // If the modem want us to retry the current APN again, it will
2733                             // suggest a positive delay value (in milliseconds). Otherwise we'll get
2734                             // NO_SUGGESTED_RETRY_DELAY here.
2735 
2736                             long delay = getSuggestedRetryDelay(dataCallResponse);
2737                             long retryTime = RetryManager.NO_SUGGESTED_RETRY_DELAY;
2738                             if (delay == RetryManager.NO_RETRY) {
2739                                 retryTime = RetryManager.NO_RETRY;
2740                             } else if (delay >= 0) {
2741                                 retryTime = SystemClock.elapsedRealtime() + delay;
2742                             }
2743                             int newRequestType = DcTracker.calculateNewRetryRequestType(
2744                                     mHandoverFailureMode, cp.mRequestType, mDcFailCause);
2745                             mDct.getDataThrottler().setRetryTime(getApnTypeBitmask(),
2746                                     retryTime, newRequestType);
2747 
2748                             String str = "DcActivatingState: ERROR_DATA_SERVICE_SPECIFIC_ERROR "
2749                                     + " delay=" + delay
2750                                     + " result=" + result
2751                                     + " result.isRadioRestartFailure="
2752                                     + DataFailCause.isRadioRestartFailure(mPhone.getContext(),
2753                                     result.mFailCause, mPhone.getSubId())
2754                                     + " isPermanentFailure=" +
2755                                     mDct.isPermanentFailure(result.mFailCause);
2756                             if (DBG) log(str);
2757                             if (cp.mApnContext != null) cp.mApnContext.requestLog(str);
2758 
2759                             // Save the cause. DcTracker.onDataSetupComplete will check this
2760                             // failure cause and determine if we need to retry this APN later
2761                             // or not.
2762                             mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
2763                                     dataCallResponse != null
2764                                             ? dataCallResponse.getHandoverFailureMode()
2765                                             : DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
2766                             transitionTo(mInactiveState);
2767                             break;
2768                         case ERROR_STALE:
2769                             loge("DcActivatingState: stale EVENT_SETUP_DATA_CONNECTION_DONE"
2770                                     + " tag:" + cp.mTag + " != mTag:" + mTag);
2771                             break;
2772                         default:
2773                             throw new RuntimeException("Unknown SetupResult, should not happen");
2774                     }
2775                     retVal = HANDLED;
2776                     mDataCallSessionStats
2777                             .onSetupDataCallResponse(dataCallResponse, cp.mRilRat,
2778                                     getApnTypeBitmask(), mApnSetting.getProtocol(),
2779                                     result.mFailCause);
2780                     break;
2781                 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
2782                     AsyncResult asyncResult = (AsyncResult) msg.obj;
2783                     int[] administratorUids = (int[]) asyncResult.result;
2784                     mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
2785                     retVal = HANDLED;
2786                     break;
2787                 case EVENT_START_HANDOVER_ON_TARGET:
2788                     //called after startHandover on target transport
2789                     ((Consumer<Boolean>) msg.obj).accept(true /* is in correct state*/);
2790                     retVal = HANDLED;
2791                     break;
2792                 case EVENT_CANCEL_HANDOVER:
2793                     transitionTo(mInactiveState);
2794                     retVal = HANDLED;
2795                     break;
2796                 default:
2797                     if (VDBG) {
2798                         log("DcActivatingState not handled msg.what=" +
2799                                 getWhatToString(msg.what) + " RefCount=" + mApnContexts.size());
2800                     }
2801                     retVal = NOT_HANDLED;
2802                     break;
2803             }
2804             return retVal;
2805         }
2806     }
2807     private DcActivatingState mActivatingState = new DcActivatingState();
2808 
2809     /**
2810      * The state machine is connected, expecting an EVENT_DISCONNECT.
2811      */
2812     private class DcActiveState extends State {
2813 
enter()2814         @Override public void enter() {
2815             if (DBG) log("DcActiveState: enter dc=" + DataConnection.this);
2816             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
2817                     TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVE,
2818                     mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault());
2819             // If we were retrying there maybe more than one, otherwise they'll only be one.
2820             notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE,
2821                     Phone.REASON_CONNECTED);
2822 
2823             mPhone.getCallTracker().registerForVoiceCallStarted(getHandler(),
2824                     DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED, null);
2825             mPhone.getCallTracker().registerForVoiceCallEnded(getHandler(),
2826                     DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED, null);
2827 
2828             // If the EVENT_CONNECT set the current max retry restore it here
2829             // if it didn't then this is effectively a NOP.
2830             mDcController.addActiveDcByCid(DataConnection.this);
2831 
2832             updateTcpBufferSizes(mRilRat);
2833             updateLinkBandwidthsFromCarrierConfig(mRilRat);
2834 
2835             final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder();
2836             configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE);
2837             configBuilder.setLegacyTypeName(NETWORK_TYPE);
2838             int networkType = getNetworkType();
2839             configBuilder.setLegacySubType(networkType);
2840             configBuilder.setLegacySubTypeName(TelephonyManager.getNetworkTypeName(networkType));
2841             configBuilder.setLegacyExtraInfo(mApnSetting.getApnName());
2842             final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent();
2843             if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager
2844                     .ACTION_CARRIER_SIGNAL_REDIRECTED)) {
2845                 // carrierSignal Receivers will place the carrier-specific provisioning notification
2846                 configBuilder.setProvisioningNotificationEnabled(false);
2847             }
2848 
2849             final String subscriberId = mPhone.getSubscriberId();
2850             if (!TextUtils.isEmpty(subscriberId)) {
2851                 configBuilder.setSubscriberId(subscriberId);
2852             }
2853 
2854             // set skip464xlat if it is not default otherwise
2855             if (shouldSkip464Xlat()) {
2856                 configBuilder.setNat64DetectionEnabled(false);
2857             }
2858 
2859             mUnmeteredUseOnly = isUnmeteredUseOnly();
2860             mMmsUseOnly = isMmsUseOnly();
2861             mEnterpriseUse = isEnterpriseUse();
2862 
2863             if (DBG) {
2864                 log("mRestrictedNetworkOverride = " + mRestrictedNetworkOverride
2865                         + ", mUnmeteredUseOnly = " + mUnmeteredUseOnly
2866                         + ", mMmsUseOnly = " + mMmsUseOnly
2867                         + ", mEnterpriseUse = " + mEnterpriseUse);
2868             }
2869 
2870             // Always register a VcnNetworkPolicyChangeListener, regardless of whether this is a
2871             // handover
2872             // or new Network.
2873             mVcnManager.addVcnNetworkPolicyChangeListener(
2874                     new HandlerExecutor(getHandler()), mVcnPolicyChangeListener);
2875 
2876             if (mConnectionParams != null
2877                     && mConnectionParams.mRequestType == REQUEST_TYPE_HANDOVER) {
2878                 // If this is a data setup for handover, we need to reuse the existing network agent
2879                 // instead of creating a new one. This should be transparent to connectivity
2880                 // service.
2881                 DcTracker dcTracker = mPhone.getDcTracker(getHandoverSourceTransport());
2882                 DataConnection dc = dcTracker.getDataConnectionByApnType(
2883                         mConnectionParams.mApnContext.getApnType());
2884                 // It's possible that the source data connection has been disconnected by the modem
2885                 // already. If not, set its handover state to completed.
2886                 if (dc != null) {
2887                     // Transfer network agent from the original data connection as soon as the
2888                     // new handover data connection is connected.
2889                     dc.setHandoverState(HANDOVER_STATE_COMPLETED);
2890                 }
2891 
2892                 if (mHandoverSourceNetworkAgent != null) {
2893                     String logStr = "Transfer network agent " + mHandoverSourceNetworkAgent.getTag()
2894                             + " successfully.";
2895                     log(logStr);
2896                     mHandoverLocalLog.log(logStr);
2897                     mNetworkAgent = mHandoverSourceNetworkAgent;
2898                     mNetworkAgent.acquireOwnership(DataConnection.this, mTransportType);
2899 
2900                     // TODO: Should evaluate mDisabledApnTypeBitMask again after handover. We don't
2901                     // do it now because connectivity service does not support dynamically removing
2902                     // immutable capabilities.
2903 
2904                     mNetworkAgent.updateLegacySubtype(DataConnection.this);
2905                     // Update the capability after handover
2906                     mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2907                             DataConnection.this);
2908                     mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
2909                     mHandoverSourceNetworkAgent = null;
2910                 } else {
2911                     String logStr = "Failed to get network agent from original data connection";
2912                     loge(logStr);
2913                     mHandoverLocalLog.log(logStr);
2914                     return;
2915                 }
2916             } else {
2917                 mScore = calculateScore();
2918                 final NetworkFactory factory = PhoneFactory.getNetworkFactory(
2919                         mPhone.getPhoneId());
2920                 final NetworkProvider provider = (null == factory) ? null : factory.getProvider();
2921 
2922                 mDisabledApnTypeBitMask |= getDisallowedApnTypes();
2923                 updateLinkPropertiesHttpProxy();
2924                 mNetworkAgent = new DcNetworkAgent(DataConnection.this, mPhone, mScore,
2925                         configBuilder.build(), provider, mTransportType);
2926 
2927                 VcnNetworkPolicyResult policyResult =
2928                         mVcnManager.applyVcnNetworkPolicy(
2929                                 getNetworkCapabilities(), getLinkProperties());
2930                 if (policyResult.isTeardownRequested()) {
2931                     tearDownAll(
2932                             Phone.REASON_VCN_REQUESTED_TEARDOWN,
2933                             DcTracker.RELEASE_TYPE_DETACH,
2934                             null /* onCompletedMsg */);
2935                 } else {
2936                     // All network agents start out in CONNECTING mode, but DcNetworkAgents are
2937                     // created when the network is already connected. Hence, send the connected
2938                     // notification immediately.
2939                     mNetworkAgent.markConnected();
2940                 }
2941 
2942                 // The network agent is always created with NOT_SUSPENDED capability, but the
2943                 // network might be already out of service (or voice call is ongoing) just right
2944                 // before data connection is created. Connectivity service would not allow a network
2945                 // created with suspended state, so we create a non-suspended network first, and
2946                 // then immediately evaluate the suspended state.
2947                 sendMessage(obtainMessage(EVENT_UPDATE_SUSPENDED_STATE));
2948             }
2949 
2950             // The qos parameters are set when the call is connected
2951             syncQosToNetworkAgent();
2952 
2953             if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
2954                 mPhone.mCi.registerForNattKeepaliveStatus(
2955                         getHandler(), DataConnection.EVENT_KEEPALIVE_STATUS, null);
2956                 mPhone.mCi.registerForLceInfo(
2957                         getHandler(), DataConnection.EVENT_LINK_CAPACITY_CHANGED, null);
2958             }
2959             notifyDataConnectionState();
2960             TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
2961                     mCid, getApnTypeBitmask(), RilDataCall.State.CONNECTED);
2962         }
2963 
2964         @Override
exit()2965         public void exit() {
2966             if (DBG) log("DcActiveState: exit dc=" + this);
2967             mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler());
2968             mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler());
2969 
2970             if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
2971                 mPhone.mCi.unregisterForNattKeepaliveStatus(getHandler());
2972                 mPhone.mCi.unregisterForLceInfo(getHandler());
2973             }
2974 
2975             // If we are still owning this agent, then we should inform connectivity service the
2976             // data connection is disconnected. There is one exception that we shouldn't unregister,
2977             // which is when IWLAN handover is ongoing. Instead of unregistering, the agent will
2978             // be transferred to the new data connection on the other transport.
2979             if (mNetworkAgent != null) {
2980                 syncQosToNetworkAgent();
2981                 if (mHandoverState == HANDOVER_STATE_IDLE) {
2982                     mNetworkAgent.unregister(DataConnection.this);
2983                 }
2984                 mNetworkAgent.releaseOwnership(DataConnection.this);
2985             }
2986             mNetworkAgent = null;
2987 
2988             TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
2989                     mCid, getApnTypeBitmask(), RilDataCall.State.DISCONNECTED);
2990 
2991             mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener);
2992 
2993             mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler());
2994         }
2995 
2996         @Override
processMessage(Message msg)2997         public boolean processMessage(Message msg) {
2998             boolean retVal;
2999 
3000             switch (msg.what) {
3001                 case EVENT_CONNECT: {
3002                     ConnectionParams cp = (ConnectionParams) msg.obj;
3003                     // either add this new apn context to our set or
3004                     // update the existing cp with the latest connection generation number
3005                     mApnContexts.put(cp.mApnContext, cp);
3006                     // TODO (b/118347948): evaluate if it's still needed after assigning
3007                     // different scores to different Cellular network.
3008                     mDisabledApnTypeBitMask &= ~cp.mApnContext.getApnTypeBitmask();
3009                     mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3010                             DataConnection.this);
3011                     if (DBG) {
3012                         log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this);
3013                     }
3014                     notifyConnectCompleted(cp, DataFailCause.NONE,
3015                             DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
3016                     retVal = HANDLED;
3017                     break;
3018                 }
3019                 case EVENT_DISCONNECT: {
3020                     DisconnectParams dp = (DisconnectParams) msg.obj;
3021                     if (DBG) {
3022                         log("DcActiveState: EVENT_DISCONNECT dp=" + dp
3023                                 + " dc=" + DataConnection.this);
3024                     }
3025                     if (mApnContexts.containsKey(dp.mApnContext)) {
3026                         if (DBG) {
3027                             log("DcActiveState msg.what=EVENT_DISCONNECT RefCount="
3028                                     + mApnContexts.size());
3029                         }
3030 
3031                         if (mApnContexts.size() == 1) {
3032                             mApnContexts.clear();
3033                             mDisconnectParams = dp;
3034                             mConnectionParams = null;
3035                             dp.mTag = mTag;
3036                             tearDownData(dp);
3037                             transitionTo(mDisconnectingState);
3038                         } else {
3039                             mApnContexts.remove(dp.mApnContext);
3040                             // TODO (b/118347948): evaluate if it's still needed after assigning
3041                             // different scores to different Cellular network.
3042                             mDisabledApnTypeBitMask |= dp.mApnContext.getApnTypeBitmask();
3043                             mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3044                                     DataConnection.this);
3045                             notifyDisconnectCompleted(dp, false);
3046                         }
3047                     } else {
3048                         log("DcActiveState ERROR no such apnContext=" + dp.mApnContext
3049                                 + " in this dc=" + DataConnection.this);
3050                         notifyDisconnectCompleted(dp, false);
3051                     }
3052                     retVal = HANDLED;
3053                     break;
3054                 }
3055                 case EVENT_DISCONNECT_ALL: {
3056                     if (DBG) {
3057                         log("DcActiveState EVENT_DISCONNECT clearing apn contexts,"
3058                                 + " dc=" + DataConnection.this);
3059                     }
3060                     DisconnectParams dp = (DisconnectParams) msg.obj;
3061                     mDisconnectParams = dp;
3062                     mConnectionParams = null;
3063                     dp.mTag = mTag;
3064                     tearDownData(dp);
3065                     transitionTo(mDisconnectingState);
3066                     retVal = HANDLED;
3067                     break;
3068                 }
3069                 case EVENT_LOST_CONNECTION: {
3070                     if (DBG) {
3071                         log("DcActiveState EVENT_LOST_CONNECTION dc=" + DataConnection.this);
3072                     }
3073 
3074                     mInactiveState.setEnterNotificationParams(DataFailCause.LOST_CONNECTION);
3075                     transitionTo(mInactiveState);
3076                     retVal = HANDLED;
3077                     break;
3078                 }
3079                 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: {
3080                     AsyncResult ar = (AsyncResult) msg.obj;
3081                     Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>) ar.result;
3082                     mDataRegState = drsRatPair.first;
3083                     updateTcpBufferSizes(drsRatPair.second);
3084                     if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
3085                         updateLinkBandwidthsFromCarrierConfig(drsRatPair.second);
3086                     }
3087                     mRilRat = drsRatPair.second;
3088                     if (DBG) {
3089                         log("DcActiveState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"
3090                                 + " drs=" + mDataRegState
3091                                 + " mRilRat=" + mRilRat);
3092                     }
3093                     updateSuspendState();
3094                     if (mNetworkAgent != null) {
3095                         mNetworkAgent.updateLegacySubtype(DataConnection.this);
3096                         // The new suspended state will be passed through connectivity service
3097                         // through NET_CAPABILITY_NOT_SUSPENDED.
3098                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3099                                 DataConnection.this);
3100                         mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
3101                     }
3102                     retVal = HANDLED;
3103                     mDataCallSessionStats.onDrsOrRatChanged(mRilRat);
3104                     break;
3105                 }
3106                 case EVENT_NR_FREQUENCY_CHANGED:
3107                     // fallthrough
3108                 case EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED:
3109                     if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
3110                         updateLinkBandwidthsFromCarrierConfig(mRilRat);
3111                     }
3112                     if (mNetworkAgent != null) {
3113                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3114                                 DataConnection.this);
3115                     }
3116                     retVal = HANDLED;
3117                     break;
3118                 case EVENT_DATA_CONNECTION_METEREDNESS_CHANGED:
3119                     boolean isUnmetered = (boolean) msg.obj;
3120                     if (isUnmetered == mUnmeteredOverride) {
3121                         retVal = HANDLED;
3122                         break;
3123                     }
3124                     mUnmeteredOverride = isUnmetered;
3125                     if (mNetworkAgent != null) {
3126                         mNetworkAgent.updateLegacySubtype(DataConnection.this);
3127                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3128                                 DataConnection.this);
3129                     }
3130                     retVal = HANDLED;
3131                     break;
3132                 case EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED:
3133                     boolean isCongested = (boolean) msg.obj;
3134                     if (isCongested == mCongestedOverride) {
3135                         retVal = HANDLED;
3136                         break;
3137                     }
3138                     mCongestedOverride = isCongested;
3139                     if (mNetworkAgent != null) {
3140                         mNetworkAgent.updateLegacySubtype(DataConnection.this);
3141                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3142                                 DataConnection.this);
3143                     }
3144                     retVal = HANDLED;
3145                     break;
3146                 case EVENT_DATA_CONNECTION_ROAM_ON:
3147                 case EVENT_DATA_CONNECTION_ROAM_OFF: {
3148                     if (mNetworkAgent != null) {
3149                         mNetworkAgent.updateLegacySubtype(DataConnection.this);
3150                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3151                                 DataConnection.this);
3152                     }
3153                     retVal = HANDLED;
3154                     break;
3155                 }
3156                 case EVENT_DATA_CONNECTION_VOICE_CALL_STARTED:
3157                 case EVENT_DATA_CONNECTION_VOICE_CALL_ENDED:
3158                 case EVENT_CSS_INDICATOR_CHANGED:
3159                 case EVENT_UPDATE_SUSPENDED_STATE: {
3160                     updateSuspendState();
3161                     if (mNetworkAgent != null) {
3162                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3163                                 DataConnection.this);
3164                     }
3165                     retVal = HANDLED;
3166                     break;
3167                 }
3168                 case EVENT_BW_REFRESH_RESPONSE: {
3169                     AsyncResult ar = (AsyncResult)msg.obj;
3170                     if (ar.exception != null) {
3171                         log("EVENT_BW_REFRESH_RESPONSE: error ignoring, e=" + ar.exception);
3172                     } else {
3173                         if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) {
3174                             updateLinkBandwidthsFromModem((List<LinkCapacityEstimate>) ar.result);
3175                         }
3176                     }
3177                     retVal = HANDLED;
3178                     break;
3179                 }
3180                 case EVENT_KEEPALIVE_START_REQUEST: {
3181                     KeepalivePacketData pkt = (KeepalivePacketData) msg.obj;
3182                     int slotId = msg.arg1;
3183                     int intervalMillis = msg.arg2 * 1000;
3184                     if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
3185                         mPhone.mCi.startNattKeepalive(
3186                                 DataConnection.this.mCid, pkt, intervalMillis,
3187                                 DataConnection.this.obtainMessage(
3188                                         EVENT_KEEPALIVE_STARTED, slotId, 0, null));
3189                     } else {
3190                         // We currently do not support NATT Keepalive requests using the
3191                         // DataService API, so unless the request is WWAN (always bound via
3192                         // the CommandsInterface), the request cannot be honored.
3193                         //
3194                         // TODO: b/72331356 to add support for Keepalive to the DataService
3195                         // so that keepalive requests can be handled (if supported) by the
3196                         // underlying transport.
3197                         if (mNetworkAgent != null) {
3198                             mNetworkAgent.sendSocketKeepaliveEvent(
3199                                     msg.arg1, SocketKeepalive.ERROR_INVALID_NETWORK);
3200                         }
3201                     }
3202                     retVal = HANDLED;
3203                     break;
3204                 }
3205                 case EVENT_KEEPALIVE_STOP_REQUEST: {
3206                     int slotId = msg.arg1;
3207                     int handle = mNetworkAgent.keepaliveTracker.getHandleForSlot(slotId);
3208                     if (handle < 0) {
3209                         loge("No slot found for stopSocketKeepalive! " + slotId);
3210                         mNetworkAgent.sendSocketKeepaliveEvent(
3211                                 slotId, SocketKeepalive.ERROR_NO_SUCH_SLOT);
3212                         retVal = HANDLED;
3213                         break;
3214                     } else {
3215                         logd("Stopping keepalive with handle: " + handle);
3216                     }
3217 
3218                     mPhone.mCi.stopNattKeepalive(
3219                             handle, DataConnection.this.obtainMessage(
3220                                     EVENT_KEEPALIVE_STOPPED, handle, slotId, null));
3221                     retVal = HANDLED;
3222                     break;
3223                 }
3224                 case EVENT_KEEPALIVE_STARTED: {
3225                     AsyncResult ar = (AsyncResult) msg.obj;
3226                     final int slot = msg.arg1;
3227                     if (ar.exception != null || ar.result == null) {
3228                         loge("EVENT_KEEPALIVE_STARTED: error starting keepalive, e="
3229                                 + ar.exception);
3230                         mNetworkAgent.sendSocketKeepaliveEvent(
3231                                 slot, SocketKeepalive.ERROR_HARDWARE_ERROR);
3232                     } else {
3233                         KeepaliveStatus ks = (KeepaliveStatus) ar.result;
3234                         if (ks == null) {
3235                             loge("Null KeepaliveStatus received!");
3236                         } else {
3237                             mNetworkAgent.keepaliveTracker.handleKeepaliveStarted(slot, ks);
3238                         }
3239                     }
3240                     retVal = HANDLED;
3241                     break;
3242                 }
3243                 case EVENT_KEEPALIVE_STATUS: {
3244                     AsyncResult ar = (AsyncResult) msg.obj;
3245                     if (ar.exception != null) {
3246                         loge("EVENT_KEEPALIVE_STATUS: error in keepalive, e=" + ar.exception);
3247                         // We have no way to notify connectivity in this case.
3248                     }
3249                     if (ar.result != null) {
3250                         KeepaliveStatus ks = (KeepaliveStatus) ar.result;
3251                         mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(ks);
3252                     }
3253 
3254                     retVal = HANDLED;
3255                     break;
3256                 }
3257                 case EVENT_KEEPALIVE_STOPPED: {
3258                     AsyncResult ar = (AsyncResult) msg.obj;
3259                     final int handle = msg.arg1;
3260                     final int slotId = msg.arg2;
3261 
3262                     if (ar.exception != null) {
3263                         loge("EVENT_KEEPALIVE_STOPPED: error stopping keepalive for handle="
3264                                 + handle + " e=" + ar.exception);
3265                         mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(
3266                                 new KeepaliveStatus(KeepaliveStatus.ERROR_UNKNOWN));
3267                     } else {
3268                         log("Keepalive Stop Requested for handle=" + handle);
3269                         mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(
3270                                 new KeepaliveStatus(handle, KeepaliveStatus.STATUS_INACTIVE));
3271                     }
3272                     retVal = HANDLED;
3273                     break;
3274                 }
3275                 case EVENT_LINK_CAPACITY_CHANGED: {
3276                     AsyncResult ar = (AsyncResult) msg.obj;
3277                     if (ar.exception != null) {
3278                         loge("EVENT_LINK_CAPACITY_CHANGED e=" + ar.exception);
3279                     } else {
3280                         if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) {
3281                             updateLinkBandwidthsFromModem((List<LinkCapacityEstimate>) ar.result);
3282                         }
3283                     }
3284                     retVal = HANDLED;
3285                     break;
3286                 }
3287                 case EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE: {
3288                     AsyncResult ar = (AsyncResult) msg.obj;
3289                     if (ar.exception != null) {
3290                         loge("EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE e=" + ar.exception);
3291                     } else {
3292                         Pair<Integer, Integer> pair = (Pair<Integer, Integer>) ar.result;
3293                         if (isBandwidthSourceKey(
3294                                 DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
3295                             updateLinkBandwidthsFromBandwidthEstimator(pair.first, pair.second);
3296                         }
3297                     }
3298                     retVal = HANDLED;
3299                     break;
3300                 }
3301                 case EVENT_REEVALUATE_RESTRICTED_STATE: {
3302                     // If the network was restricted, and now it does not need to be restricted
3303                     // anymore, we should add the NET_CAPABILITY_NOT_RESTRICTED capability.
3304                     if (mRestrictedNetworkOverride && !shouldRestrictNetwork()) {
3305                         if (DBG) {
3306                             log("Data connection becomes not-restricted. dc=" + this);
3307                         }
3308                         // Note we only do this when network becomes non-restricted. When a
3309                         // non-restricted becomes restricted (e.g. users disable data, or turn off
3310                         // data roaming), DCT will explicitly tear down the networks (because
3311                         // connectivity service does not support force-close TCP connections today).
3312                         // Also note that NET_CAPABILITY_NOT_RESTRICTED is an immutable capability
3313                         // (see {@link NetworkCapabilities}) once we add it to the network, we can't
3314                         // remove it through the entire life cycle of the connection.
3315                         mRestrictedNetworkOverride = false;
3316                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3317                                 DataConnection.this);
3318                     }
3319 
3320                     // If the data does need to be unmetered use only (e.g. users turn on data, or
3321                     // device is not roaming anymore assuming data roaming is off), then we can
3322                     // dynamically add those metered APN type capabilities back. (But not the
3323                     // other way around because most of the APN-type capabilities are immutable
3324                     // capabilities.)
3325                     if (mUnmeteredUseOnly && !isUnmeteredUseOnly()) {
3326                         mUnmeteredUseOnly = false;
3327                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3328                                 DataConnection.this);
3329                     }
3330 
3331                     mMmsUseOnly = isMmsUseOnly();
3332 
3333                     retVal = HANDLED;
3334                     break;
3335                 }
3336                 case EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES: {
3337                     // Update other properties like link properties if needed in future.
3338                     updateScore();
3339                     retVal = HANDLED;
3340                     break;
3341                 }
3342                 case EVENT_NR_STATE_CHANGED: {
3343                     updateTcpBufferSizes(mRilRat);
3344                     if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
3345                         updateLinkBandwidthsFromCarrierConfig(mRilRat);
3346                     }
3347                     if (mNetworkAgent != null) {
3348                         mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
3349                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
3350                                 DataConnection.this);
3351                     }
3352                     retVal = HANDLED;
3353                     break;
3354                 }
3355                 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
3356                     AsyncResult asyncResult = (AsyncResult) msg.obj;
3357                     int[] administratorUids = (int[]) asyncResult.result;
3358                     mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
3359 
3360                     // Administrator UIDs changed, so update NetworkAgent with new
3361                     // NetworkCapabilities
3362                     if (mNetworkAgent != null) {
3363                         mNetworkAgent.sendNetworkCapabilities(
3364                                 getNetworkCapabilities(), DataConnection.this);
3365                     }
3366                     retVal = HANDLED;
3367                     break;
3368                 case EVENT_START_HANDOVER:  //calls startHandover()
3369                     Consumer<Integer> r = (Consumer<Integer>) msg.obj;
3370                     r.accept(msg.arg1);
3371                     retVal = HANDLED;
3372                     break;
3373 
3374                 default:
3375                     if (VDBG) {
3376                         log("DcActiveState not handled msg.what=" + getWhatToString(msg.what));
3377                     }
3378                     retVal = NOT_HANDLED;
3379                     break;
3380             }
3381             return retVal;
3382         }
3383     }
3384     private DcActiveState mActiveState = new DcActiveState();
3385 
3386     /**
3387      * The state machine is disconnecting.
3388      */
3389     private class DcDisconnectingState extends State {
3390         @Override
enter()3391         public void enter() {
3392             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
3393                     TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTING,
3394                     mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault());
3395             notifyDataConnectionState();
3396         }
3397         @Override
processMessage(Message msg)3398         public boolean processMessage(Message msg) {
3399             boolean retVal;
3400 
3401             switch (msg.what) {
3402                 case EVENT_CONNECT:
3403                     if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = "
3404                             + mApnContexts.size());
3405                     deferMessage(msg);
3406                     retVal = HANDLED;
3407                     break;
3408 
3409                 case EVENT_DEACTIVATE_DONE:
3410                     DisconnectParams dp = (DisconnectParams) msg.obj;
3411 
3412                     String str = "DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE RefCount="
3413                             + mApnContexts.size();
3414 
3415                     if (DBG) log(str);
3416                     if (dp.mApnContext != null) dp.mApnContext.requestLog(str);
3417 
3418                     // Clear out existing qos sessions
3419                     updateQosParameters(null);
3420 
3421                     if (dp.mTag == mTag) {
3422                         // Transition to inactive but send notifications after
3423                         // we've entered the mInactive state.
3424                         mInactiveState.setEnterNotificationParams(dp);
3425                         transitionTo(mInactiveState);
3426                     } else {
3427                         if (DBG) log("DcDisconnectState stale EVENT_DEACTIVATE_DONE"
3428                                 + " dp.tag=" + dp.mTag + " mTag=" + mTag);
3429                     }
3430                     retVal = HANDLED;
3431                     break;
3432 
3433                 default:
3434                     if (VDBG) {
3435                         log("DcDisconnectingState not handled msg.what="
3436                                 + getWhatToString(msg.what));
3437                     }
3438                     retVal = NOT_HANDLED;
3439                     break;
3440             }
3441             return retVal;
3442         }
3443     }
3444     private DcDisconnectingState mDisconnectingState = new DcDisconnectingState();
3445 
3446     /**
3447      * The state machine is disconnecting after an creating a connection.
3448      */
3449     private class DcDisconnectionErrorCreatingConnection extends State {
3450         @Override
enter()3451         public void enter() {
3452             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
3453                     TelephonyStatsLog
3454                             .MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTION_ERROR_CREATING_CONNECTION,
3455                     mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault());
3456             notifyDataConnectionState();
3457         }
3458         @Override
processMessage(Message msg)3459         public boolean processMessage(Message msg) {
3460             boolean retVal;
3461 
3462             switch (msg.what) {
3463                 case EVENT_DEACTIVATE_DONE:
3464                     ConnectionParams cp = (ConnectionParams) msg.obj;
3465                     if (cp.mTag == mTag) {
3466                         String str = "DcDisconnectionErrorCreatingConnection" +
3467                                 " msg.what=EVENT_DEACTIVATE_DONE";
3468                         if (DBG) log(str);
3469                         if (cp.mApnContext != null) cp.mApnContext.requestLog(str);
3470 
3471                         // Transition to inactive but send notifications after
3472                         // we've entered the mInactive state.
3473                         mInactiveState.setEnterNotificationParams(cp,
3474                                 DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER,
3475                                 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
3476                         transitionTo(mInactiveState);
3477                     } else {
3478                         if (DBG) {
3479                             log("DcDisconnectionErrorCreatingConnection stale EVENT_DEACTIVATE_DONE"
3480                                     + " dp.tag=" + cp.mTag + ", mTag=" + mTag);
3481                         }
3482                     }
3483                     retVal = HANDLED;
3484                     break;
3485 
3486                 default:
3487                     if (VDBG) {
3488                         log("DcDisconnectionErrorCreatingConnection not handled msg.what="
3489                                 + getWhatToString(msg.what));
3490                     }
3491                     retVal = NOT_HANDLED;
3492                     break;
3493             }
3494             return retVal;
3495         }
3496     }
3497     private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection =
3498                 new DcDisconnectionErrorCreatingConnection();
3499 
3500     /**
3501      * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg.
3502      * Used for cellular networks that use Access Point Names (APN) such
3503      * as GSM networks.
3504      *
3505      * @param apnContext is the Access Point Name to bring up a connection to
3506      * @param profileId for the connection
3507      * @param rilRadioTechnology Radio technology for the data connection
3508      * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
3509      *                       With AsyncResult.userObj set to the original msg.obj,
3510      *                       AsyncResult.result = FailCause and AsyncResult.exception = Exception().
3511      * @param connectionGeneration used to track a single connection request so disconnects can get
3512      *                             ignored if obsolete.
3513      * @param requestType Data request type
3514      * @param subId the subscription id associated with this data connection.
3515      * @param isApnPreferred whether or not the apn is preferred.
3516      */
bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isApnPreferred)3517     public void bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology,
3518                         Message onCompletedMsg, int connectionGeneration,
3519                         @RequestNetworkType int requestType, int subId, boolean isApnPreferred) {
3520         if (DBG) {
3521             log("bringUp: apnContext=" + apnContext + " onCompletedMsg=" + onCompletedMsg);
3522         }
3523 
3524         if (mApnSetting == null) {
3525             mApnSetting = apnContext.getApnSetting();
3526         }
3527 
3528         sendMessage(DataConnection.EVENT_CONNECT,
3529                 new ConnectionParams(apnContext, profileId, rilRadioTechnology, onCompletedMsg,
3530                         connectionGeneration, requestType, subId, isApnPreferred));
3531     }
3532 
3533     /**
3534      * Tear down the connection through the apn on the network.
3535      *
3536      * @param apnContext APN context
3537      * @param reason reason to tear down
3538      * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
3539      *        With AsyncResult.userObj set to the original msg.obj.
3540      */
tearDown(ApnContext apnContext, String reason, Message onCompletedMsg)3541     public void tearDown(ApnContext apnContext, String reason, Message onCompletedMsg) {
3542         if (DBG) {
3543             log("tearDown: apnContext=" + apnContext + " reason=" + reason + " onCompletedMsg="
3544                     + onCompletedMsg);
3545         }
3546         sendMessage(DataConnection.EVENT_DISCONNECT,
3547                 new DisconnectParams(apnContext, reason, DcTracker.RELEASE_TYPE_DETACH,
3548                         onCompletedMsg));
3549     }
3550 
3551     // ******* "public" interface
3552 
3553     /**
3554      * Used for testing purposes.
3555      */
tearDownNow()3556     void tearDownNow() {
3557         if (DBG) log("tearDownNow()");
3558         sendMessage(obtainMessage(EVENT_TEAR_DOWN_NOW));
3559     }
3560 
3561     /**
3562      * Tear down the connection through the apn on the network.  Ignores reference count and
3563      * and always tears down.
3564      *
3565      * @param releaseType Data release type
3566      * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
3567      *        With AsyncResult.userObj set to the original msg.obj.
3568      */
tearDownAll(String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)3569     public void tearDownAll(String reason, @ReleaseNetworkType int releaseType,
3570                             Message onCompletedMsg) {
3571         if (DBG) {
3572             log("tearDownAll: reason=" + reason + ", releaseType="
3573                     + DcTracker.releaseTypeToString(releaseType));
3574         }
3575         sendMessage(DataConnection.EVENT_DISCONNECT_ALL,
3576                 new DisconnectParams(null, reason, releaseType, onCompletedMsg));
3577     }
3578 
3579     /**
3580      * Reset the data connection to inactive state.
3581      */
reset()3582     public void reset() {
3583         sendMessage(EVENT_RESET);
3584         if (DBG) log("reset");
3585     }
3586 
3587     /**
3588      * Re-evaluate the restricted state. If the restricted data connection does not need to be
3589      * restricted anymore, we need to dynamically change the network's capability.
3590      */
reevaluateRestrictedState()3591     void reevaluateRestrictedState() {
3592         sendMessage(EVENT_REEVALUATE_RESTRICTED_STATE);
3593         if (DBG) log("reevaluate restricted state");
3594     }
3595 
3596     /**
3597      * Re-evaluate the data connection properties. For example, it will recalculate data connection
3598      * score and update through network agent it if changed.
3599      */
reevaluateDataConnectionProperties()3600     void reevaluateDataConnectionProperties() {
3601         sendMessage(EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES);
3602         if (DBG) log("reevaluate data connection properties");
3603     }
3604 
3605     /**
3606      * @return The parameters used for initiating a data connection.
3607      */
getConnectionParams()3608     public ConnectionParams getConnectionParams() {
3609         return mConnectionParams;
3610     }
3611 
3612     /**
3613      * Update PCSCF addresses
3614      *
3615      * @param response
3616      */
updatePcscfAddr(DataCallResponse response)3617     public void updatePcscfAddr(DataCallResponse response) {
3618         mPcscfAddr = response.getPcscfAddresses().stream()
3619                 .map(InetAddress::getHostAddress).toArray(String[]::new);
3620     }
3621 
3622     /**
3623      * @return The list of PCSCF addresses
3624      */
getPcscfAddresses()3625     public String[] getPcscfAddresses() {
3626         return mPcscfAddr;
3627     }
3628 
3629     /**
3630      * Using the result of the SETUP_DATA_CALL determine the retry delay.
3631      *
3632      * @param response The response from setup data call
3633      * @return {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} if not suggested.
3634      * {@link RetryManager#NO_RETRY} if retry should not happen. Otherwise the delay in milliseconds
3635      * to the next SETUP_DATA_CALL.
3636      */
getSuggestedRetryDelay(DataCallResponse response)3637     private long getSuggestedRetryDelay(DataCallResponse response) {
3638         /** According to ril.h
3639          * The value < 0 means no value is suggested
3640          * The value 0 means retry should be done ASAP.
3641          * The value of Long.MAX_VALUE(0x7fffffffffffffff) means no retry.
3642          */
3643         if (response == null) {
3644             return RetryManager.NO_SUGGESTED_RETRY_DELAY;
3645         }
3646 
3647         long suggestedRetryTime = response.getRetryDurationMillis();
3648 
3649         // The value < 0 means no value is suggested
3650         if (suggestedRetryTime < 0) {
3651             if (DBG) log("No suggested retry delay.");
3652             return RetryManager.NO_SUGGESTED_RETRY_DELAY;
3653         } else if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)
3654                 && suggestedRetryTime == Long.MAX_VALUE) {
3655             if (DBG) log("Network suggested not retrying.");
3656             return RetryManager.NO_RETRY;
3657         } else if (mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_6)
3658                 && suggestedRetryTime == Integer.MAX_VALUE) {
3659             if (DBG) log("Network suggested not retrying.");
3660             return RetryManager.NO_RETRY;
3661         }
3662 
3663         return suggestedRetryTime;
3664     }
3665 
getApnContexts()3666     public List<ApnContext> getApnContexts() {
3667         return new ArrayList<>(mApnContexts.keySet());
3668     }
3669 
3670     /**
3671      * Return whether there is an ApnContext for the given type in this DataConnection.
3672      * @param type APN type to check
3673      * @param exclusive true if the given APN type should be the only APN type that exists
3674      * @return True if there is an ApnContext for the given type
3675      */
isApnContextAttached(@pnType int type, boolean exclusive)3676     private boolean isApnContextAttached(@ApnType int type, boolean exclusive) {
3677         boolean attached = mApnContexts.keySet().stream()
3678                 .map(ApnContext::getApnTypeBitmask)
3679                 .anyMatch(bitmask -> bitmask == type);
3680         if (exclusive) {
3681             attached &= mApnContexts.size() == 1;
3682         }
3683         return attached;
3684     }
3685 
3686     /** Get the network agent of the data connection */
3687     @Nullable
getNetworkAgent()3688     DcNetworkAgent getNetworkAgent() {
3689         return mNetworkAgent;
3690     }
3691 
setHandoverState(@andoverState int state)3692     void setHandoverState(@HandoverState int state) {
3693         if (mHandoverState != state) {
3694             String logStr = "State changed from " + handoverStateToString(mHandoverState)
3695                     + " to " + handoverStateToString(state);
3696             mHandoverLocalLog.log(logStr);
3697             logd(logStr);
3698             mHandoverState = state;
3699         }
3700     }
3701 
3702     /** Sets the {@link DataCallSessionStats} mock for this phone ID during unit testing. */
3703     @VisibleForTesting
setDataCallSessionStats(DataCallSessionStats dataCallSessionStats)3704     public void setDataCallSessionStats(DataCallSessionStats dataCallSessionStats) {
3705         mDataCallSessionStats = dataCallSessionStats;
3706     }
3707 
3708     /**
3709      * @return the string for msg.what as our info.
3710      */
3711     @Override
getWhatToString(int what)3712     protected String getWhatToString(int what) {
3713         return cmdToString(what);
3714     }
3715 
msgToString(Message msg)3716     private static String msgToString(Message msg) {
3717         String retVal;
3718         if (msg == null) {
3719             retVal = "null";
3720         } else {
3721             StringBuilder   b = new StringBuilder();
3722 
3723             b.append("{what=");
3724             b.append(cmdToString(msg.what));
3725 
3726             b.append(" when=");
3727             TimeUtils.formatDuration(msg.getWhen() - SystemClock.uptimeMillis(), b);
3728 
3729             if (msg.arg1 != 0) {
3730                 b.append(" arg1=");
3731                 b.append(msg.arg1);
3732             }
3733 
3734             if (msg.arg2 != 0) {
3735                 b.append(" arg2=");
3736                 b.append(msg.arg2);
3737             }
3738 
3739             if (msg.obj != null) {
3740                 b.append(" obj=");
3741                 b.append(msg.obj);
3742             }
3743 
3744             b.append(" target=");
3745             b.append(msg.getTarget());
3746 
3747             b.append(" replyTo=");
3748             b.append(msg.replyTo);
3749 
3750             b.append("}");
3751 
3752             retVal = b.toString();
3753         }
3754         return retVal;
3755     }
3756 
slog(String s)3757     static void slog(String s) {
3758         Rlog.d("DC", s);
3759     }
3760 
3761     /**
3762      * Log with debug
3763      *
3764      * @param s is string log
3765      */
3766     @Override
log(String s)3767     protected void log(String s) {
3768         Rlog.d(getName(), s);
3769     }
3770 
3771     /**
3772      * Log with debug attribute
3773      *
3774      * @param s is string log
3775      */
3776     @Override
logd(String s)3777     protected void logd(String s) {
3778         Rlog.d(getName(), s);
3779     }
3780 
3781     /**
3782      * Log with verbose attribute
3783      *
3784      * @param s is string log
3785      */
3786     @Override
logv(String s)3787     protected void logv(String s) {
3788         Rlog.v(getName(), s);
3789     }
3790 
3791     /**
3792      * Log with info attribute
3793      *
3794      * @param s is string log
3795      */
3796     @Override
logi(String s)3797     protected void logi(String s) {
3798         Rlog.i(getName(), s);
3799     }
3800 
3801     /**
3802      * Log with warning attribute
3803      *
3804      * @param s is string log
3805      */
3806     @Override
logw(String s)3807     protected void logw(String s) {
3808         Rlog.w(getName(), s);
3809     }
3810 
3811     /**
3812      * Log with error attribute
3813      *
3814      * @param s is string log
3815      */
3816     @Override
loge(String s)3817     protected void loge(String s) {
3818         Rlog.e(getName(), s);
3819     }
3820 
3821     /**
3822      * Log with error attribute
3823      *
3824      * @param s is string log
3825      * @param e is a Throwable which logs additional information.
3826      */
3827     @Override
loge(String s, Throwable e)3828     protected void loge(String s, Throwable e) {
3829         Rlog.e(getName(), s, e);
3830     }
3831 
3832     /** Doesn't print mApnList of ApnContext's which would be recursive */
toStringSimple()3833     public String toStringSimple() {
3834         return getName() + ": State=" + getCurrentState().getName()
3835                 + " mApnSetting=" + mApnSetting + " RefCount=" + mApnContexts.size()
3836                 + " mCid=" + mCid + " mCreateTime=" + mCreateTime
3837                 + " mLastastFailTime=" + mLastFailTime
3838                 + " mLastFailCause=" + DataFailCause.toString(mLastFailCause)
3839                 + " mTag=" + mTag
3840                 + " mLinkProperties=" + mLinkProperties
3841                 + " linkCapabilities=" + getNetworkCapabilities()
3842                 + " mRestrictedNetworkOverride=" + mRestrictedNetworkOverride;
3843     }
3844 
3845     @Override
toString()3846     public String toString() {
3847         return "{" + toStringSimple() + " mApnContexts=" + mApnContexts + "}";
3848     }
3849 
3850     /** Check if the device is connected to NR 5G Non-Standalone network. */
isNRConnected()3851     private boolean isNRConnected() {
3852         return mPhone.getServiceState().getNrState()
3853                 == NetworkRegistrationInfo.NR_STATE_CONNECTED;
3854     }
3855 
3856     /**
3857      * @return The disallowed APN types bitmask
3858      */
getDisallowedApnTypes()3859     private @ApnType int getDisallowedApnTypes() {
3860         CarrierConfigManager configManager = (CarrierConfigManager)
3861                 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
3862         int apnTypesBitmask = 0;
3863         if (configManager != null) {
3864             PersistableBundle bundle = configManager.getConfigForSubId(mSubId);
3865             if (bundle != null) {
3866                 String key = (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
3867                         ? CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY
3868                         : CarrierConfigManager.KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY;
3869                 if (bundle.getStringArray(key) != null) {
3870                     String disallowedApnTypesString =
3871                             TextUtils.join(",", bundle.getStringArray(key));
3872                     if (!TextUtils.isEmpty(disallowedApnTypesString)) {
3873                         apnTypesBitmask = ApnSetting.getApnTypesBitmaskFromString(
3874                                 disallowedApnTypesString);
3875                     }
3876                 }
3877             }
3878         }
3879 
3880         return apnTypesBitmask;
3881     }
3882 
dumpToLog()3883     private void dumpToLog() {
3884         dump(null, new PrintWriter(new StringWriter(0)) {
3885             @Override
3886             public void println(String s) {
3887                 DataConnection.this.logd(s);
3888             }
3889 
3890             @Override
3891             public void flush() {
3892             }
3893         }, null);
3894     }
3895 
3896     /**
3897      *  Re-calculate score and update through network agent if it changes.
3898      */
updateScore()3899     private void updateScore() {
3900         int oldScore = mScore;
3901         mScore = calculateScore();
3902         if (oldScore != mScore && mNetworkAgent != null) {
3903             log("Updating score from " + oldScore + " to " + mScore);
3904             mNetworkAgent.sendNetworkScore(mScore, this);
3905         }
3906     }
3907 
calculateScore()3908     private int calculateScore() {
3909         int score = OTHER_CONNECTION_SCORE;
3910 
3911         // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have
3912         // specify a subId, this dataConnection is considered to be default Internet data
3913         // connection. In this case we assign a slightly higher score of 50. The intention is
3914         // it will not be replaced by other data connections accidentally in DSDS usecase.
3915         for (ApnContext apnContext : mApnContexts.keySet()) {
3916             for (NetworkRequest networkRequest : apnContext.getNetworkRequests()) {
3917                 if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
3918                         && networkRequest.getNetworkSpecifier() == null) {
3919                     score = DEFAULT_INTERNET_CONNECTION_SCORE;
3920                     break;
3921                 }
3922             }
3923         }
3924 
3925         return score;
3926     }
3927 
handoverStateToString(@andoverState int state)3928     private String handoverStateToString(@HandoverState int state) {
3929         switch (state) {
3930             case HANDOVER_STATE_IDLE: return "IDLE";
3931             case HANDOVER_STATE_BEING_TRANSFERRED: return "BEING_TRANSFERRED";
3932             case HANDOVER_STATE_COMPLETED: return "COMPLETED";
3933             default: return "UNKNOWN";
3934         }
3935     }
3936 
getState()3937     private @DataState int getState() {
3938         if (isInactive()) {
3939             return TelephonyManager.DATA_DISCONNECTED;
3940         } else if (isActivating()) {
3941             return TelephonyManager.DATA_CONNECTING;
3942         } else if (isActive()) {
3943             // The data connection can only be suspended when it's in active state.
3944             if (mIsSuspended) {
3945                 return TelephonyManager.DATA_SUSPENDED;
3946             }
3947             return TelephonyManager.DATA_CONNECTED;
3948         } else if (isDisconnecting()) {
3949             return TelephonyManager.DATA_DISCONNECTING;
3950         }
3951 
3952         return TelephonyManager.DATA_UNKNOWN;
3953     }
3954 
3955     /**
3956      * Get precise data connection state
3957      *
3958      * @return The {@link PreciseDataConnectionState}
3959      */
getPreciseDataConnectionState()3960     public PreciseDataConnectionState getPreciseDataConnectionState() {
3961         return new PreciseDataConnectionState.Builder()
3962                 .setTransportType(mTransportType)
3963                 .setId(mCid)
3964                 .setState(getState())
3965                 .setApnSetting(mApnSetting)
3966                 .setLinkProperties(mLinkProperties)
3967                 .setNetworkType(getNetworkType())
3968                 .setFailCause(mDcFailCause)
3969                 .build();
3970     }
3971 
3972     /**
3973      * Dump the current state.
3974      *
3975      * @param fd
3976      * @param printWriter
3977      * @param args
3978      */
3979     @Override
dump(FileDescriptor fd, PrintWriter printWriter, String[] args)3980     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
3981         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
3982         pw.print("DataConnection ");
3983         super.dump(fd, pw, args);
3984         pw.flush();
3985         pw.increaseIndent();
3986         pw.println("transport type="
3987                 + AccessNetworkConstants.transportTypeToString(mTransportType));
3988         pw.println("mApnContexts.size=" + mApnContexts.size());
3989         pw.println("mApnContexts=" + mApnContexts);
3990         pw.println("mApnSetting=" + mApnSetting);
3991         pw.println("mTag=" + mTag);
3992         pw.println("mCid=" + mCid);
3993         pw.println("mConnectionParams=" + mConnectionParams);
3994         pw.println("mDisconnectParams=" + mDisconnectParams);
3995         pw.println("mDcFailCause=" + DataFailCause.toString(mDcFailCause));
3996         pw.println("mPhone=" + mPhone);
3997         pw.println("mSubId=" + mSubId);
3998         pw.println("mLinkProperties=" + mLinkProperties);
3999         pw.flush();
4000         pw.println("mDataRegState=" + mDataRegState);
4001         pw.println("mHandoverState=" + handoverStateToString(mHandoverState));
4002         pw.println("mRilRat=" + mRilRat);
4003         pw.println("mNetworkCapabilities=" + getNetworkCapabilities());
4004         pw.println("mCreateTime=" + TimeUtils.logTimeOfDay(mCreateTime));
4005         pw.println("mLastFailTime=" + TimeUtils.logTimeOfDay(mLastFailTime));
4006         pw.println("mLastFailCause=" + DataFailCause.toString(mLastFailCause));
4007         pw.println("mUserData=" + mUserData);
4008         pw.println("mRestrictedNetworkOverride=" + mRestrictedNetworkOverride);
4009         pw.println("mUnmeteredUseOnly=" + mUnmeteredUseOnly);
4010         pw.println("mMmsUseOnly=" + mMmsUseOnly);
4011         pw.println("mEnterpriseUse=" + mEnterpriseUse);
4012         pw.println("mUnmeteredOverride=" + mUnmeteredOverride);
4013         pw.println("mCongestedOverride=" + mCongestedOverride);
4014         pw.println("mDownlinkBandwidth" + mDownlinkBandwidth);
4015         pw.println("mUplinkBandwidth=" + mUplinkBandwidth);
4016         pw.println("mDefaultQos=" + mDefaultQos);
4017         pw.println("mQosBearerSessions=" + mQosBearerSessions);
4018         pw.println("disallowedApnTypes="
4019                 + ApnSetting.getApnTypesStringFromBitmask(getDisallowedApnTypes()));
4020         pw.println("mInstanceNumber=" + mInstanceNumber);
4021         pw.println("mAc=" + mAc);
4022         pw.println("mScore=" + mScore);
4023         if (mNetworkAgent != null) {
4024             mNetworkAgent.dump(fd, pw, args);
4025         }
4026         pw.println("handover local log:");
4027         pw.increaseIndent();
4028         mHandoverLocalLog.dump(fd, pw, args);
4029         pw.decreaseIndent();
4030         pw.decreaseIndent();
4031         pw.println();
4032         pw.flush();
4033     }
4034 
4035     /**
4036      * Class used to track VCN-defined Network policies for this DataConnection.
4037      *
4038      * <p>MUST be registered with the associated DataConnection's Handler.
4039      */
4040     private class DataConnectionVcnNetworkPolicyChangeListener
4041             implements VcnNetworkPolicyChangeListener {
4042         @Override
onPolicyChanged()4043         public void onPolicyChanged() {
4044             // Poll the current underlying Network policy from VcnManager and send to NetworkAgent.
4045             final NetworkCapabilities networkCapabilities = getNetworkCapabilities();
4046             VcnNetworkPolicyResult policyResult =
4047                     mVcnManager.applyVcnNetworkPolicy(
4048                             networkCapabilities, getLinkProperties());
4049             if (policyResult.isTeardownRequested()) {
4050                 tearDownAll(
4051                         Phone.REASON_VCN_REQUESTED_TEARDOWN,
4052                         DcTracker.RELEASE_TYPE_DETACH,
4053                         null /* onCompletedMsg */);
4054             }
4055 
4056             if (mNetworkAgent != null) {
4057                 mNetworkAgent.sendNetworkCapabilities(networkCapabilities, DataConnection.this);
4058             }
4059         }
4060     }
4061 }
4062 
4063