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