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