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.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED;
20 import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED;
21 
22 import android.annotation.IntDef;
23 import android.annotation.Nullable;
24 import android.app.PendingIntent;
25 import android.content.Context;
26 import android.net.ConnectivityManager;
27 import android.net.InetAddresses;
28 import android.net.KeepalivePacketData;
29 import android.net.LinkAddress;
30 import android.net.LinkProperties;
31 import android.net.NetworkAgentConfig;
32 import android.net.NetworkCapabilities;
33 import android.net.NetworkFactory;
34 import android.net.NetworkInfo;
35 import android.net.NetworkProvider;
36 import android.net.NetworkRequest;
37 import android.net.ProxyInfo;
38 import android.net.RouteInfo;
39 import android.net.SocketKeepalive;
40 import android.net.TelephonyNetworkSpecifier;
41 import android.os.AsyncResult;
42 import android.os.Message;
43 import android.os.PersistableBundle;
44 import android.os.SystemClock;
45 import android.os.SystemProperties;
46 import android.provider.Telephony;
47 import android.telephony.AccessNetworkConstants;
48 import android.telephony.AccessNetworkConstants.TransportType;
49 import android.telephony.Annotation.ApnType;
50 import android.telephony.Annotation.DataFailureCause;
51 import android.telephony.CarrierConfigManager;
52 import android.telephony.DataFailCause;
53 import android.telephony.NetworkRegistrationInfo;
54 import android.telephony.ServiceState;
55 import android.telephony.SubscriptionManager;
56 import android.telephony.TelephonyManager;
57 import android.telephony.data.ApnSetting;
58 import android.telephony.data.DataCallResponse;
59 import android.telephony.data.DataProfile;
60 import android.telephony.data.DataService;
61 import android.telephony.data.DataServiceCallback;
62 import android.text.TextUtils;
63 import android.util.LocalLog;
64 import android.util.Pair;
65 import android.util.TimeUtils;
66 
67 import com.android.internal.annotations.VisibleForTesting;
68 import com.android.internal.telephony.CallTracker;
69 import com.android.internal.telephony.CarrierSignalAgent;
70 import com.android.internal.telephony.DctConstants;
71 import com.android.internal.telephony.LinkCapacityEstimate;
72 import com.android.internal.telephony.Phone;
73 import com.android.internal.telephony.PhoneConstants;
74 import com.android.internal.telephony.PhoneFactory;
75 import com.android.internal.telephony.RIL;
76 import com.android.internal.telephony.RILConstants;
77 import com.android.internal.telephony.RetryManager;
78 import com.android.internal.telephony.ServiceStateTracker;
79 import com.android.internal.telephony.TelephonyStatsLog;
80 import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
81 import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
82 import com.android.internal.telephony.metrics.TelephonyMetrics;
83 import com.android.internal.telephony.nano.TelephonyProto.RilDataCall;
84 import com.android.internal.util.AsyncChannel;
85 import com.android.internal.util.IndentingPrintWriter;
86 import com.android.internal.util.Protocol;
87 import com.android.internal.util.State;
88 import com.android.internal.util.StateMachine;
89 import com.android.telephony.Rlog;
90 
91 import java.io.FileDescriptor;
92 import java.io.PrintWriter;
93 import java.io.StringWriter;
94 import java.lang.annotation.Retention;
95 import java.lang.annotation.RetentionPolicy;
96 import java.net.InetAddress;
97 import java.net.UnknownHostException;
98 import java.util.ArrayList;
99 import java.util.Arrays;
100 import java.util.Collection;
101 import java.util.List;
102 import java.util.Locale;
103 import java.util.Map;
104 import java.util.concurrent.ConcurrentHashMap;
105 import java.util.concurrent.atomic.AtomicInteger;
106 
107 /**
108  * {@hide}
109  *
110  * DataConnection StateMachine.
111  *
112  * This a class for representing a single data connection, with instances of this
113  * class representing a connection via the cellular network. There may be multiple
114  * data connections and all of them are managed by the <code>DataConnectionTracker</code>.
115  *
116  * NOTE: All DataConnection objects must be running on the same looper, which is the default
117  * as the coordinator has members which are used without synchronization.
118  */
119 public class DataConnection extends StateMachine {
120     private static final boolean DBG = true;
121     private static final boolean VDBG = true;
122 
123     private static final String NETWORK_TYPE = "MOBILE";
124 
125     private static final String RAT_NAME_5G = "nr";
126     private static final String RAT_NAME_EVDO = "evdo";
127 
128     /**
129      * The data connection is not being or been handovered. Note this is the state for the source
130      * data connection, not destination data connection
131      */
132     private static final int HANDOVER_STATE_IDLE = 1;
133 
134     /**
135      * The data connection is being handovered. Note this is the state for the source
136      * data connection, not destination data connection.
137      */
138     private static final int HANDOVER_STATE_BEING_TRANSFERRED = 2;
139 
140     /**
141      * The data connection is already handovered. Note this is the state for the source
142      * data connection, not destination data connection.
143      */
144     private static final int HANDOVER_STATE_COMPLETED = 3;
145 
146     /** @hide */
147     @Retention(RetentionPolicy.SOURCE)
148     @IntDef(prefix = {"HANDOVER_STATE_"}, value = {
149             HANDOVER_STATE_IDLE,
150             HANDOVER_STATE_BEING_TRANSFERRED,
151             HANDOVER_STATE_COMPLETED})
152     public @interface HandoverState {}
153 
154     // The data connection providing default Internet connection will have a higher score of 50.
155     // Other connections will have a slightly lower score of 45. The intention is other connections
156     // will not cause ConnectivityService to tear down default internet connection. For example,
157     // to validate Internet connection on non-default data SIM, we'll set up a temporary Internet
158     // connection on that data SIM. In this case, score of 45 is assigned so ConnectivityService
159     // will not replace the default Internet connection with it.
160     private static final int DEFAULT_INTERNET_CONNECTION_SCORE = 50;
161     private static final int OTHER_CONNECTION_SCORE = 45;
162 
163     // The score we report to connectivity service
164     private int mScore;
165 
166     // The subscription id associated with this data connection.
167     private int mSubId;
168 
169     // The data connection controller
170     private DcController mDcController;
171 
172     // The Tester for failing all bringup's
173     private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
174 
175     private static AtomicInteger mInstanceNumber = new AtomicInteger(0);
176     private AsyncChannel mAc;
177 
178     // The DCT that's talking to us, we only support one!
179     private DcTracker mDct = null;
180 
181     private String[] mPcscfAddr;
182 
183     private final String mTagSuffix;
184 
185     private final LocalLog mHandoverLocalLog = new LocalLog(100);
186 
187     private int[] mAdministratorUids = new int[0];
188 
189     /**
190      * Used internally for saving connecting parameters.
191      */
192     public static class ConnectionParams {
193         int mTag;
194         ApnContext mApnContext;
195         int mProfileId;
196         int mRilRat;
197         Message mOnCompletedMsg;
198         final int mConnectionGeneration;
199         @RequestNetworkType
200         final int mRequestType;
201         final int mSubId;
202         final boolean mIsPreferredApn;
203 
ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isPreferredApn)204         ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology,
205                          Message onCompletedMsg, int connectionGeneration,
206                          @RequestNetworkType int requestType, int subId,
207                          boolean isPreferredApn) {
208             mApnContext = apnContext;
209             mProfileId = profileId;
210             mRilRat = rilRadioTechnology;
211             mOnCompletedMsg = onCompletedMsg;
212             mConnectionGeneration = connectionGeneration;
213             mRequestType = requestType;
214             mSubId = subId;
215             mIsPreferredApn = isPreferredApn;
216         }
217 
218         @Override
toString()219         public String toString() {
220             return "{mTag=" + mTag + " mApnContext=" + mApnContext
221                     + " mProfileId=" + mProfileId
222                     + " mRat=" + mRilRat
223                     + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg)
224                     + " mRequestType=" + DcTracker.requestTypeToString(mRequestType)
225                     + " mSubId=" + mSubId
226                     + " mIsPreferredApn=" + mIsPreferredApn
227                     + "}";
228         }
229     }
230 
231     /**
232      * Used internally for saving disconnecting parameters.
233      */
234     public static class DisconnectParams {
235         int mTag;
236         public ApnContext mApnContext;
237         String mReason;
238         @ReleaseNetworkType
239         final int mReleaseType;
240         Message mOnCompletedMsg;
241 
DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)242         DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType,
243                          Message onCompletedMsg) {
244             mApnContext = apnContext;
245             mReason = reason;
246             mReleaseType = releaseType;
247             mOnCompletedMsg = onCompletedMsg;
248         }
249 
250         @Override
toString()251         public String toString() {
252             return "{mTag=" + mTag + " mApnContext=" + mApnContext
253                     + " mReason=" + mReason
254                     + " mReleaseType=" + DcTracker.releaseTypeToString(mReleaseType)
255                     + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) + "}";
256         }
257     }
258 
259     private ApnSetting mApnSetting;
260     private ConnectionParams mConnectionParams;
261     private DisconnectParams mDisconnectParams;
262     @DataFailureCause
263     private int mDcFailCause;
264 
265     private Phone mPhone;
266     private DataServiceManager mDataServiceManager;
267     private final int mTransportType;
268     private LinkProperties mLinkProperties = new LinkProperties();
269     private long mCreateTime;
270     private long mLastFailTime;
271     @DataFailureCause
272     private int mLastFailCause;
273     private static final String NULL_IP = "0.0.0.0";
274     private Object mUserData;
275     private int mSubscriptionOverride;
276     private boolean mUnmeteredOverride;
277     private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
278     private int mDataRegState = Integer.MAX_VALUE;
279     private NetworkInfo mNetworkInfo;
280     private int mDownlinkBandwidth = 14;
281     private int mUplinkBandwidth = 14;
282 
283     /** The corresponding network agent for this data connection. */
284     private DcNetworkAgent mNetworkAgent;
285 
286     /**
287      * The network agent from handover source data connection. This is the potential network agent
288      * that will be transferred here after handover completed.
289      */
290     private DcNetworkAgent mHandoverSourceNetworkAgent;
291 
292     private int mDisabledApnTypeBitMask = 0;
293 
294     int mTag;
295 
296     /** Data connection id assigned by the modem. This is unique across transports */
297     public int mCid;
298 
299     @HandoverState
300     private int mHandoverState;
301     private final Map<ApnContext, ConnectionParams> mApnContexts = new ConcurrentHashMap<>();
302     PendingIntent mReconnectIntent = null;
303 
304 
305     // ***** Event codes for driving the state machine, package visible for Dcc
306     static final int BASE = Protocol.BASE_DATA_CONNECTION;
307     static final int EVENT_CONNECT = BASE + 0;
308     static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1;
309     static final int EVENT_DEACTIVATE_DONE = BASE + 3;
310     static final int EVENT_DISCONNECT = BASE + 4;
311     static final int EVENT_RIL_CONNECTED = BASE + 5;
312     static final int EVENT_DISCONNECT_ALL = BASE + 6;
313     static final int EVENT_DATA_STATE_CHANGED = BASE + 7;
314     static final int EVENT_TEAR_DOWN_NOW = BASE + 8;
315     static final int EVENT_LOST_CONNECTION = BASE + 9;
316     static final int EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED = BASE + 11;
317     static final int EVENT_DATA_CONNECTION_ROAM_ON = BASE + 12;
318     static final int EVENT_DATA_CONNECTION_ROAM_OFF = BASE + 13;
319     static final int EVENT_BW_REFRESH_RESPONSE = BASE + 14;
320     static final int EVENT_DATA_CONNECTION_VOICE_CALL_STARTED = BASE + 15;
321     static final int EVENT_DATA_CONNECTION_VOICE_CALL_ENDED = BASE + 16;
322     static final int EVENT_DATA_CONNECTION_OVERRIDE_CHANGED = BASE + 17;
323     static final int EVENT_KEEPALIVE_STATUS = BASE + 18;
324     static final int EVENT_KEEPALIVE_STARTED = BASE + 19;
325     static final int EVENT_KEEPALIVE_STOPPED = BASE + 20;
326     static final int EVENT_KEEPALIVE_START_REQUEST = BASE + 21;
327     static final int EVENT_KEEPALIVE_STOP_REQUEST = BASE + 22;
328     static final int EVENT_LINK_CAPACITY_CHANGED = BASE + 23;
329     static final int EVENT_RESET = BASE + 24;
330     static final int EVENT_REEVALUATE_RESTRICTED_STATE = BASE + 25;
331     static final int EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES = BASE + 26;
332     static final int EVENT_NR_STATE_CHANGED = BASE + 27;
333     static final int EVENT_DATA_CONNECTION_METEREDNESS_CHANGED = BASE + 28;
334     static final int EVENT_NR_FREQUENCY_CHANGED = BASE + 29;
335     static final int EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED = BASE + 30;
336     static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = BASE + 31;
337     private static final int CMD_TO_STRING_COUNT = EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED - BASE + 1;
338 
339     private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
340     static {
341         sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT";
342         sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] =
343                 "EVENT_SETUP_DATA_CONNECTION_DONE";
344         sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE";
345         sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT";
346         sCmdToString[EVENT_RIL_CONNECTED - BASE] = "EVENT_RIL_CONNECTED";
347         sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL";
348         sCmdToString[EVENT_DATA_STATE_CHANGED - BASE] = "EVENT_DATA_STATE_CHANGED";
349         sCmdToString[EVENT_TEAR_DOWN_NOW - BASE] = "EVENT_TEAR_DOWN_NOW";
350         sCmdToString[EVENT_LOST_CONNECTION - BASE] = "EVENT_LOST_CONNECTION";
351         sCmdToString[EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED - BASE] =
352                 "EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED";
353         sCmdToString[EVENT_DATA_CONNECTION_ROAM_ON - BASE] = "EVENT_DATA_CONNECTION_ROAM_ON";
354         sCmdToString[EVENT_DATA_CONNECTION_ROAM_OFF - BASE] = "EVENT_DATA_CONNECTION_ROAM_OFF";
355         sCmdToString[EVENT_BW_REFRESH_RESPONSE - BASE] = "EVENT_BW_REFRESH_RESPONSE";
356         sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_STARTED - BASE] =
357                 "EVENT_DATA_CONNECTION_VOICE_CALL_STARTED";
358         sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_ENDED - BASE] =
359                 "EVENT_DATA_CONNECTION_VOICE_CALL_ENDED";
360         sCmdToString[EVENT_DATA_CONNECTION_OVERRIDE_CHANGED - BASE] =
361                 "EVENT_DATA_CONNECTION_OVERRIDE_CHANGED";
362         sCmdToString[EVENT_KEEPALIVE_STATUS - BASE] = "EVENT_KEEPALIVE_STATUS";
363         sCmdToString[EVENT_KEEPALIVE_STARTED - BASE] = "EVENT_KEEPALIVE_STARTED";
364         sCmdToString[EVENT_KEEPALIVE_STOPPED - BASE] = "EVENT_KEEPALIVE_STOPPED";
365         sCmdToString[EVENT_KEEPALIVE_START_REQUEST - BASE] = "EVENT_KEEPALIVE_START_REQUEST";
366         sCmdToString[EVENT_KEEPALIVE_STOP_REQUEST - BASE] = "EVENT_KEEPALIVE_STOP_REQUEST";
367         sCmdToString[EVENT_LINK_CAPACITY_CHANGED - BASE] = "EVENT_LINK_CAPACITY_CHANGED";
368         sCmdToString[EVENT_RESET - BASE] = "EVENT_RESET";
369         sCmdToString[EVENT_REEVALUATE_RESTRICTED_STATE - BASE] =
370                 "EVENT_REEVALUATE_RESTRICTED_STATE";
371         sCmdToString[EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES - BASE] =
372                 "EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES";
373         sCmdToString[EVENT_NR_STATE_CHANGED - BASE] = "EVENT_NR_STATE_CHANGED";
374         sCmdToString[EVENT_DATA_CONNECTION_METEREDNESS_CHANGED - BASE] =
375                 "EVENT_DATA_CONNECTION_METEREDNESS_CHANGED";
376         sCmdToString[EVENT_NR_FREQUENCY_CHANGED - BASE] = "EVENT_NR_FREQUENCY_CHANGED";
377         sCmdToString[EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED - BASE] =
378                 "EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED";
379         sCmdToString[EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED - BASE] =
380                 "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED";
381     }
382     // Convert cmd to string or null if unknown
cmdToString(int cmd)383     static String cmdToString(int cmd) {
384         String value = null;
385         cmd -= BASE;
386         if ((cmd >= 0) && (cmd < sCmdToString.length)) {
387             value = sCmdToString[cmd];
388         }
389         if (value == null) {
390             value = "0x" + Integer.toHexString(cmd + BASE);
391         }
392         return value;
393     }
394 
395     /**
396      * Create the connection object
397      *
398      * @param phone the Phone
399      * @param id the connection id
400      * @return DataConnection that was created.
401      */
makeDataConnection(Phone phone, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc)402     public static DataConnection makeDataConnection(Phone phone, int id, DcTracker dct,
403                                                     DataServiceManager dataServiceManager,
404                                                     DcTesterFailBringUpAll failBringUpAll,
405                                                     DcController dcc) {
406         String transportType = (dataServiceManager.getTransportType()
407                 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
408                 ? "C"   // Cellular
409                 : "I";  // IWLAN
410         DataConnection dc = new DataConnection(phone, transportType + "-"
411                 + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll,
412                 dcc);
413         dc.start();
414         if (DBG) dc.log("Made " + dc.getName());
415         return dc;
416     }
417 
dispose()418     void dispose() {
419         log("dispose: call quiteNow()");
420         quitNow();
421     }
422 
423     /* Getter functions */
424 
getLinkProperties()425     LinkProperties getLinkProperties() {
426         return new LinkProperties(mLinkProperties);
427     }
428 
isInactive()429     boolean isInactive() {
430         return getCurrentState() == mInactiveState;
431     }
432 
isDisconnecting()433     boolean isDisconnecting() {
434         return getCurrentState() == mDisconnectingState;
435     }
436 
437     @VisibleForTesting
isActive()438     public boolean isActive() {
439         return getCurrentState() == mActiveState;
440     }
441 
isActivating()442     boolean isActivating() {
443         return getCurrentState() == mActivatingState;
444     }
445 
hasBeenTransferred()446     boolean hasBeenTransferred() {
447         return mHandoverState == HANDOVER_STATE_COMPLETED;
448     }
449 
getCid()450     int getCid() {
451         return mCid;
452     }
453 
getApnSetting()454     ApnSetting getApnSetting() {
455         return mApnSetting;
456     }
457 
setLinkPropertiesHttpProxy(ProxyInfo proxy)458     void setLinkPropertiesHttpProxy(ProxyInfo proxy) {
459         mLinkProperties.setHttpProxy(proxy);
460     }
461 
462     public static class UpdateLinkPropertyResult {
463         public SetupResult setupResult = SetupResult.SUCCESS;
464         public LinkProperties oldLp;
465         public LinkProperties newLp;
UpdateLinkPropertyResult(LinkProperties curLp)466         public UpdateLinkPropertyResult(LinkProperties curLp) {
467             oldLp = curLp;
468             newLp = curLp;
469         }
470     }
471 
472     /**
473      * Class returned by onSetupConnectionCompleted.
474      */
475     public enum SetupResult {
476         SUCCESS,
477         ERROR_RADIO_NOT_AVAILABLE,
478         ERROR_INVALID_ARG,
479         ERROR_STALE,
480         ERROR_DATA_SERVICE_SPECIFIC_ERROR;
481 
482         public int mFailCause;
483 
SetupResult()484         SetupResult() {
485             mFailCause = DataFailCause.getFailCause(0);
486         }
487 
488         @Override
toString()489         public String toString() {
490             return name() + "  SetupResult.mFailCause=" + mFailCause;
491         }
492     }
493 
isIpv4Connected()494     public boolean isIpv4Connected() {
495         boolean ret = false;
496         Collection <InetAddress> addresses = mLinkProperties.getAddresses();
497 
498         for (InetAddress addr: addresses) {
499             if (addr instanceof java.net.Inet4Address) {
500                 java.net.Inet4Address i4addr = (java.net.Inet4Address) addr;
501                 if (!i4addr.isAnyLocalAddress() && !i4addr.isLinkLocalAddress() &&
502                         !i4addr.isLoopbackAddress() && !i4addr.isMulticastAddress()) {
503                     ret = true;
504                     break;
505                 }
506             }
507         }
508         return ret;
509     }
510 
isIpv6Connected()511     public boolean isIpv6Connected() {
512         boolean ret = false;
513         Collection <InetAddress> addresses = mLinkProperties.getAddresses();
514 
515         for (InetAddress addr: addresses) {
516             if (addr instanceof java.net.Inet6Address) {
517                 java.net.Inet6Address i6addr = (java.net.Inet6Address) addr;
518                 if (!i6addr.isAnyLocalAddress() && !i6addr.isLinkLocalAddress() &&
519                         !i6addr.isLoopbackAddress() && !i6addr.isMulticastAddress()) {
520                     ret = true;
521                     break;
522                 }
523             }
524         }
525         return ret;
526     }
527 
528     @VisibleForTesting
updateLinkProperty(DataCallResponse newState)529     public UpdateLinkPropertyResult updateLinkProperty(DataCallResponse newState) {
530         UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties);
531 
532         if (newState == null) return result;
533 
534         result.newLp = new LinkProperties();
535 
536         // set link properties based on data call response
537         result.setupResult = setLinkProperties(newState, result.newLp);
538         if (result.setupResult != SetupResult.SUCCESS) {
539             if (DBG) log("updateLinkProperty failed : " + result.setupResult);
540             return result;
541         }
542         // copy HTTP proxy as it is not part DataCallResponse.
543         result.newLp.setHttpProxy(mLinkProperties.getHttpProxy());
544 
545         checkSetMtu(mApnSetting, result.newLp);
546 
547         mLinkProperties = result.newLp;
548 
549         updateTcpBufferSizes(mRilRat);
550 
551         if (DBG && (! result.oldLp.equals(result.newLp))) {
552             log("updateLinkProperty old LP=" + result.oldLp);
553             log("updateLinkProperty new LP=" + result.newLp);
554         }
555 
556         if (result.newLp.equals(result.oldLp) == false &&
557                 mNetworkAgent != null) {
558             mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
559         }
560 
561         return result;
562     }
563 
564     /**
565      * Read the MTU value from link properties where it can be set from network. In case
566      * not set by the network, set it again using the mtu szie value defined in the APN
567      * database for the connected APN
568      */
checkSetMtu(ApnSetting apn, LinkProperties lp)569     private void checkSetMtu(ApnSetting apn, LinkProperties lp) {
570         if (lp == null) return;
571 
572         if (apn == null || lp == null) return;
573 
574         if (lp.getMtu() != PhoneConstants.UNSET_MTU) {
575             if (DBG) log("MTU set by call response to: " + lp.getMtu());
576             return;
577         }
578 
579         if (apn != null && apn.getMtu() != PhoneConstants.UNSET_MTU) {
580             lp.setMtu(apn.getMtu());
581             if (DBG) log("MTU set by APN to: " + apn.getMtu());
582             return;
583         }
584 
585         int mtu = mPhone.getContext().getResources().getInteger(
586                 com.android.internal.R.integer.config_mobile_mtu);
587         if (mtu != PhoneConstants.UNSET_MTU) {
588             lp.setMtu(mtu);
589             if (DBG) log("MTU set by config resource to: " + mtu);
590         }
591     }
592 
593     //***** Constructor (NOTE: uses dcc.getHandler() as its Handler)
DataConnection(Phone phone, String tagSuffix, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc)594     private DataConnection(Phone phone, String tagSuffix, int id,
595                            DcTracker dct, DataServiceManager dataServiceManager,
596                            DcTesterFailBringUpAll failBringUpAll, DcController dcc) {
597         super("DC-" + tagSuffix, dcc.getHandler());
598         mTagSuffix = tagSuffix;
599         setLogRecSize(300);
600         setLogOnlyTransitions(true);
601         if (DBG) log("DataConnection created");
602 
603         mPhone = phone;
604         mDct = dct;
605         mDataServiceManager = dataServiceManager;
606         mTransportType = dataServiceManager.getTransportType();
607         mDcTesterFailBringUpAll = failBringUpAll;
608         mDcController = dcc;
609         mId = id;
610         mCid = -1;
611         ServiceState ss = mPhone.getServiceState();
612         mDataRegState = mPhone.getServiceState().getDataRegistrationState();
613         int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
614 
615         NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
616                 NetworkRegistrationInfo.DOMAIN_PS, mTransportType);
617         if (nri != null) {
618             networkType = nri.getAccessNetworkTechnology();
619             mRilRat = ServiceState.networkTypeToRilRadioTechnology(networkType);
620             updateLinkBandwidthsFromCarrierConfig(mRilRat);
621         }
622 
623         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_MOBILE,
624                 networkType, NETWORK_TYPE, TelephonyManager.getNetworkTypeName(networkType));
625 
626         addState(mDefaultState);
627             addState(mInactiveState, mDefaultState);
628             addState(mActivatingState, mDefaultState);
629             addState(mActiveState, mDefaultState);
630             addState(mDisconnectingState, mDefaultState);
631             addState(mDisconnectingErrorCreatingConnection, mDefaultState);
632         setInitialState(mInactiveState);
633     }
634 
635     /**
636      * Get the source transport for handover. For example, handover from WWAN to WLAN, WWAN is the
637      * source transport, and vice versa.
638      */
getHandoverSourceTransport()639     private @TransportType int getHandoverSourceTransport() {
640         return mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
641                 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
642                 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
643     }
644 
645     /**
646      * Begin setting up a data connection, calls setupDataCall
647      * and the ConnectionParams will be returned with the
648      * EVENT_SETUP_DATA_CONNECTION_DONE
649      *
650      * @param cp is the connection parameters
651      *
652      * @return Fail cause if failed to setup data connection. {@link DataFailCause#NONE} if success.
653      */
connect(ConnectionParams cp)654     private @DataFailureCause int connect(ConnectionParams cp) {
655         log("connect: carrier='" + mApnSetting.getEntryName()
656                 + "' APN='" + mApnSetting.getApnName()
657                 + "' proxy='" + mApnSetting.getProxyAddressAsString()
658                 + "' port='" + mApnSetting.getProxyPort() + "'");
659         if (cp.mApnContext != null) cp.mApnContext.requestLog("DataConnection.connect");
660 
661         // Check if we should fake an error.
662         if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter  > 0) {
663             DataCallResponse response = new DataCallResponse.Builder()
664                     .setCause(mDcTesterFailBringUpAll.getDcFailBringUp().mFailCause)
665                     .setSuggestedRetryTime(
666                             mDcTesterFailBringUpAll.getDcFailBringUp().mSuggestedRetryTime)
667                     .setMtuV4(PhoneConstants.UNSET_MTU)
668                     .setMtuV6(PhoneConstants.UNSET_MTU)
669                     .build();
670 
671             Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
672             AsyncResult.forMessage(msg, response, null);
673             sendMessage(msg);
674             if (DBG) {
675                 log("connect: FailBringUpAll=" + mDcTesterFailBringUpAll.getDcFailBringUp()
676                         + " send error response=" + response);
677             }
678             mDcTesterFailBringUpAll.getDcFailBringUp().mCounter -= 1;
679             return DataFailCause.NONE;
680         }
681 
682         mCreateTime = -1;
683         mLastFailTime = -1;
684         mLastFailCause = DataFailCause.NONE;
685 
686         Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
687         msg.obj = cp;
688 
689         DataProfile dp = DcTracker.createDataProfile(mApnSetting, cp.mProfileId,
690                 cp.mIsPreferredApn);
691 
692         // We need to use the actual modem roaming state instead of the framework roaming state
693         // here. This flag is only passed down to ril_service for picking the correct protocol (for
694         // old modem backward compatibility).
695         boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration();
696 
697         // If the apn is NOT metered, we will allow data roaming regardless of the setting.
698         boolean isUnmeteredApnType = !ApnSettingUtils.isMeteredApnType(
699                 cp.mApnContext.getApnTypeBitmask(), mPhone);
700 
701         // Set this flag to true if the user turns on data roaming. Or if we override the roaming
702         // state in framework, we should set this flag to true as well so the modem will not reject
703         // the data call setup (because the modem actually thinks the device is roaming).
704         boolean allowRoaming = mPhone.getDataRoamingEnabled()
705                 || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()
706                 || isUnmeteredApnType));
707 
708         if (DBG) {
709             log("allowRoaming=" + allowRoaming
710                     + ", mPhone.getDataRoamingEnabled()=" + mPhone.getDataRoamingEnabled()
711                     + ", isModemRoaming=" + isModemRoaming
712                     + ", mPhone.getServiceState().getDataRoaming()="
713                     + mPhone.getServiceState().getDataRoaming()
714                     + ", isUnmeteredApnType=" + isUnmeteredApnType
715             );
716         }
717 
718         // Check if this data setup is a handover.
719         LinkProperties linkProperties = null;
720         int reason = DataService.REQUEST_REASON_NORMAL;
721         if (cp.mRequestType == DcTracker.REQUEST_TYPE_HANDOVER) {
722             // If this is a data setup for handover, we need to pass the link properties
723             // of the existing data connection to the modem.
724             DcTracker dcTracker = mPhone.getDcTracker(getHandoverSourceTransport());
725             if (dcTracker == null || cp.mApnContext == null) {
726                 loge("connect: Handover failed. dcTracker=" + dcTracker + ", apnContext="
727                         + cp.mApnContext);
728                 return DataFailCause.HANDOVER_FAILED;
729             }
730 
731             DataConnection dc = dcTracker.getDataConnectionByApnType(cp.mApnContext.getApnType());
732             if (dc == null) {
733                 loge("connect: Can't find data connection for handover.");
734                 return DataFailCause.HANDOVER_FAILED;
735             }
736 
737             // Preserve the potential network agent from the source data connection. The ownership
738             // is not transferred at this moment.
739             mHandoverSourceNetworkAgent = dc.getNetworkAgent();
740             if (mHandoverSourceNetworkAgent == null) {
741                 loge("Cannot get network agent from the source dc " + dc.getName());
742                 return DataFailCause.HANDOVER_FAILED;
743             }
744 
745             linkProperties = dc.getLinkProperties();
746             if (linkProperties == null || linkProperties.getLinkAddresses().isEmpty()) {
747                 loge("connect: Can't find link properties of handover data connection. dc="
748                         + dc);
749                 return DataFailCause.HANDOVER_FAILED;
750             }
751 
752             mHandoverLocalLog.log("Handover started. Preserved the agent.");
753             log("Get the handover source network agent: " + mHandoverSourceNetworkAgent);
754 
755             dc.setHandoverState(HANDOVER_STATE_BEING_TRANSFERRED);
756             reason = DataService.REQUEST_REASON_HANDOVER;
757         }
758 
759         mDataServiceManager.setupDataCall(
760                 ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat),
761                 dp,
762                 isModemRoaming,
763                 allowRoaming,
764                 reason,
765                 linkProperties,
766                 msg);
767         TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat,
768                 dp.getProfileId(), dp.getApn(), dp.getProtocolType());
769         return DataFailCause.NONE;
770     }
771 
onSubscriptionOverride(int overrideMask, int overrideValue)772     public void onSubscriptionOverride(int overrideMask, int overrideValue) {
773         mSubscriptionOverride = (mSubscriptionOverride & ~overrideMask)
774                 | (overrideValue & overrideMask);
775         sendMessage(obtainMessage(EVENT_DATA_CONNECTION_OVERRIDE_CHANGED));
776     }
777 
778     /**
779      * Update NetworkCapabilities.NET_CAPABILITY_NOT_METERED based on meteredness
780      * @param isUnmetered whether this DC should be set to unmetered or not
781      */
onMeterednessChanged(boolean isUnmetered)782     public void onMeterednessChanged(boolean isUnmetered) {
783         sendMessage(obtainMessage(EVENT_DATA_CONNECTION_METEREDNESS_CHANGED, isUnmetered));
784     }
785 
786     /**
787      * TearDown the data connection when the deactivation is complete a Message with
788      * msg.what == EVENT_DEACTIVATE_DONE
789      *
790      * @param o is the object returned in the AsyncResult.obj.
791      */
tearDownData(Object o)792     private void tearDownData(Object o) {
793         int discReason = DataService.REQUEST_REASON_NORMAL;
794         ApnContext apnContext = null;
795         if ((o != null) && (o instanceof DisconnectParams)) {
796             DisconnectParams dp = (DisconnectParams) o;
797             apnContext = dp.mApnContext;
798             if (TextUtils.equals(dp.mReason, Phone.REASON_RADIO_TURNED_OFF)
799                     || TextUtils.equals(dp.mReason, Phone.REASON_PDP_RESET)) {
800                 discReason = DataService.REQUEST_REASON_SHUTDOWN;
801             } else if (dp.mReleaseType == DcTracker.RELEASE_TYPE_HANDOVER) {
802                 discReason = DataService.REQUEST_REASON_HANDOVER;
803             }
804         }
805 
806         String str = "tearDownData. mCid=" + mCid + ", reason=" + discReason;
807         if (DBG) log(str);
808         if (apnContext != null) apnContext.requestLog(str);
809         mDataServiceManager.deactivateDataCall(mCid, discReason,
810                 obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, o));
811     }
812 
notifyAllWithEvent(ApnContext alreadySent, int event, String reason)813     private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) {
814         mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason,
815                 mNetworkInfo.getExtraInfo());
816         for (ConnectionParams cp : mApnContexts.values()) {
817             ApnContext apnContext = cp.mApnContext;
818             if (apnContext == alreadySent) continue;
819             if (reason != null) apnContext.setReason(reason);
820             Pair<ApnContext, Integer> pair = new Pair<>(apnContext, cp.mConnectionGeneration);
821             Message msg = mDct.obtainMessage(event, mCid, cp.mRequestType, pair);
822             AsyncResult.forMessage(msg);
823             msg.sendToTarget();
824         }
825     }
826 
827     /**
828      * Send the connectionCompletedMsg.
829      *
830      * @param cp is the ConnectionParams
831      * @param cause and if no error the cause is DataFailCause.NONE
832      * @param sendAll is true if all contexts are to be notified
833      */
notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause, boolean sendAll)834     private void notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause,
835                                         boolean sendAll) {
836         ApnContext alreadySent = null;
837 
838         if (cp != null && cp.mOnCompletedMsg != null) {
839             // Get the completed message but only use it once
840             Message connectionCompletedMsg = cp.mOnCompletedMsg;
841             cp.mOnCompletedMsg = null;
842             alreadySent = cp.mApnContext;
843 
844             long timeStamp = System.currentTimeMillis();
845             connectionCompletedMsg.arg1 = mCid;
846             connectionCompletedMsg.arg2 = cp.mRequestType;
847 
848             if (cause == DataFailCause.NONE) {
849                 mCreateTime = timeStamp;
850                 AsyncResult.forMessage(connectionCompletedMsg);
851             } else {
852                 mLastFailCause = cause;
853                 mLastFailTime = timeStamp;
854 
855                 // Return message with a Throwable exception to signify an error.
856                 if (cause == DataFailCause.NONE) cause = DataFailCause.UNKNOWN;
857                 AsyncResult.forMessage(connectionCompletedMsg, cause,
858                         new Throwable(DataFailCause.toString(cause)));
859             }
860             if (DBG) {
861                 log("notifyConnectCompleted at " + timeStamp + " cause=" + cause
862                         + " connectionCompletedMsg=" + msgToString(connectionCompletedMsg));
863             }
864 
865             connectionCompletedMsg.sendToTarget();
866         }
867         if (sendAll) {
868             log("Send to all. " + alreadySent + " " + DataFailCause.toString(cause));
869             notifyAllWithEvent(alreadySent, DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR,
870                     DataFailCause.toString(cause));
871         }
872     }
873 
874     /**
875      * Send ar.userObj if its a message, which is should be back to originator.
876      *
877      * @param dp is the DisconnectParams.
878      */
notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll)879     private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) {
880         if (VDBG) log("NotifyDisconnectCompleted");
881 
882         ApnContext alreadySent = null;
883         String reason = null;
884 
885         if (dp != null && dp.mOnCompletedMsg != null) {
886             // Get the completed message but only use it once
887             Message msg = dp.mOnCompletedMsg;
888             dp.mOnCompletedMsg = null;
889             if (msg.obj instanceof ApnContext) {
890                 alreadySent = (ApnContext)msg.obj;
891             }
892             reason = dp.mReason;
893             if (VDBG) {
894                 log(String.format("msg=%s msg.obj=%s", msg.toString(),
895                     ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
896             }
897             AsyncResult.forMessage(msg);
898             msg.sendToTarget();
899         }
900         if (sendAll) {
901             if (reason == null) {
902                 reason = DataFailCause.toString(DataFailCause.UNKNOWN);
903             }
904             notifyAllWithEvent(alreadySent, DctConstants.EVENT_DISCONNECT_DONE, reason);
905         }
906         if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
907     }
908 
909     /*
910      * **************************************************************************
911      * Begin Members and methods owned by DataConnectionTracker but stored
912      * in a DataConnection because there is one per connection.
913      * **************************************************************************
914      */
915 
916     /*
917      * The id is owned by DataConnectionTracker.
918      */
919     private int mId;
920 
921     /**
922      * Get the DataConnection ID
923      */
getDataConnectionId()924     public int getDataConnectionId() {
925         return mId;
926     }
927 
928     /*
929      * **************************************************************************
930      * End members owned by DataConnectionTracker
931      * **************************************************************************
932      */
933 
934     /**
935      * Clear all settings called when entering mInactiveState.
936      */
clearSettings()937     private void clearSettings() {
938         if (DBG) log("clearSettings");
939 
940         mCreateTime = -1;
941         mLastFailTime = -1;
942         mLastFailCause = DataFailCause.NONE;
943         mCid = -1;
944 
945         mPcscfAddr = new String[5];
946 
947         mLinkProperties = new LinkProperties();
948         mApnContexts.clear();
949         mApnSetting = null;
950         mUnmeteredUseOnly = false;
951         mRestrictedNetworkOverride = false;
952         mDcFailCause = DataFailCause.NONE;
953         mDisabledApnTypeBitMask = 0;
954         mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
955         mSubscriptionOverride = 0;
956         mUnmeteredOverride = false;
957         mDownlinkBandwidth = 14;
958         mUplinkBandwidth = 14;
959     }
960 
961     /**
962      * Process setup data completion result from data service
963      *
964      * @param resultCode The result code returned by data service
965      * @param response Data call setup response from data service
966      * @param cp The original connection params used for data call setup
967      * @return Setup result
968      */
onSetupConnectionCompleted(@ataServiceCallback.ResultCode int resultCode, DataCallResponse response, ConnectionParams cp)969     private SetupResult onSetupConnectionCompleted(@DataServiceCallback.ResultCode int resultCode,
970                                                    DataCallResponse response,
971                                                    ConnectionParams cp) {
972         SetupResult result;
973 
974         log("onSetupConnectionCompleted: resultCode=" + resultCode + ", response=" + response);
975         if (cp.mTag != mTag) {
976             if (DBG) {
977                 log("onSetupConnectionCompleted stale cp.tag=" + cp.mTag + ", mtag=" + mTag);
978             }
979             result = SetupResult.ERROR_STALE;
980         } else if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) {
981             result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
982             result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
983         } else if (response.getCause() != 0) {
984             if (response.getCause() == DataFailCause.RADIO_NOT_AVAILABLE) {
985                 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
986                 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
987             } else {
988                 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
989                 result.mFailCause = DataFailCause.getFailCause(response.getCause());
990             }
991         } else {
992             if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse");
993             mCid = response.getId();
994 
995             mPcscfAddr = response.getPcscfAddresses().stream()
996                     .map(InetAddress::getHostAddress).toArray(String[]::new);
997 
998             result = updateLinkProperty(response).setupResult;
999         }
1000 
1001         return result;
1002     }
1003 
isDnsOk(String[] domainNameServers)1004     private boolean isDnsOk(String[] domainNameServers) {
1005         if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1])
1006                 && !mPhone.isDnsCheckDisabled()) {
1007             // Work around a race condition where QMI does not fill in DNS:
1008             // Deactivate PDP and let DataConnectionTracker retry.
1009             // Do not apply the race condition workaround for MMS APN
1010             // if Proxy is an IP-address.
1011             // Otherwise, the default APN will not be restored anymore.
1012             if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) {
1013                 log(String.format(
1014                         "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s",
1015                         mApnSetting.getApnTypeBitmask(), PhoneConstants.APN_TYPE_MMS,
1016                         mApnSetting.getMmsProxyAddressAsString(),
1017                         isIpAddress(mApnSetting.getMmsProxyAddressAsString())));
1018                 return false;
1019             }
1020         }
1021         return true;
1022     }
1023 
1024     /**
1025      * TCP buffer size config based on the ril technology. There are 6 parameters
1026      * read_min, read_default, read_max, write_min, write_default, write_max in the TCP buffer
1027      * config string and they are separated by a comma. The unit of these parameters is byte.
1028      */
1029     private static final String TCP_BUFFER_SIZES_GPRS = "4092,8760,48000,4096,8760,48000";
1030     private static final String TCP_BUFFER_SIZES_EDGE = "4093,26280,70800,4096,16384,70800";
1031     private static final String TCP_BUFFER_SIZES_UMTS = "58254,349525,1048576,58254,349525,1048576";
1032     private static final String TCP_BUFFER_SIZES_1XRTT = "16384,32768,131072,4096,16384,102400";
1033     private static final String TCP_BUFFER_SIZES_EVDO = "4094,87380,262144,4096,16384,262144";
1034     private static final String TCP_BUFFER_SIZES_EHRPD = "131072,262144,1048576,4096,16384,524288";
1035     private static final String TCP_BUFFER_SIZES_HSDPA = "61167,367002,1101005,8738,52429,262114";
1036     private static final String TCP_BUFFER_SIZES_HSPA = "40778,244668,734003,16777,100663,301990";
1037     private static final String TCP_BUFFER_SIZES_LTE =
1038             "524288,1048576,2097152,262144,524288,1048576";
1039     private static final String TCP_BUFFER_SIZES_HSPAP =
1040             "122334,734003,2202010,32040,192239,576717";
1041     private static final String TCP_BUFFER_SIZES_NR =
1042             "2097152,6291456,16777216,512000,2097152,8388608";
1043     private static final String TCP_BUFFER_SIZES_LTE_CA =
1044             "4096,6291456,12582912,4096,1048576,2097152";
1045 
updateTcpBufferSizes(int rilRat)1046     private void updateTcpBufferSizes(int rilRat) {
1047         String sizes = null;
1048         ServiceState ss = mPhone.getServiceState();
1049         if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && ss.isUsingCarrierAggregation()) {
1050             rilRat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
1051         }
1052         String ratName = ServiceState.rilRadioTechnologyToString(rilRat).toLowerCase(Locale.ROOT);
1053         // ServiceState gives slightly different names for EVDO tech ("evdo-rev.0" for ex)
1054         // - patch it up:
1055         if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 ||
1056                 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A ||
1057                 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B) {
1058             ratName = RAT_NAME_EVDO;
1059         }
1060 
1061         // NR 5G Non-Standalone use LTE cell as the primary cell, the ril technology is LTE in this
1062         // case. We use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
1063         if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
1064                 && ((rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE
1065                 || rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) && isNRConnected())
1066                 && mPhone.getServiceStateTracker().getNrContextIds().contains(mCid)) {
1067             ratName = RAT_NAME_5G;
1068         }
1069 
1070         log("updateTcpBufferSizes: " + ratName);
1071 
1072         // in the form: "ratname:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
1073         String[] configOverride = mPhone.getContext().getResources().getStringArray(
1074                 com.android.internal.R.array.config_mobile_tcp_buffers);
1075         for (int i = 0; i < configOverride.length; i++) {
1076             String[] split = configOverride[i].split(":");
1077             if (ratName.equals(split[0]) && split.length == 2) {
1078                 sizes = split[1];
1079                 break;
1080             }
1081         }
1082 
1083         if (sizes == null) {
1084             // no override - use telephony defaults
1085             // doing it this way allows device or carrier to just override the types they
1086             // care about and inherit the defaults for the others.
1087             switch (rilRat) {
1088                 case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS:
1089                     sizes = TCP_BUFFER_SIZES_GPRS;
1090                     break;
1091                 case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE:
1092                     sizes = TCP_BUFFER_SIZES_EDGE;
1093                     break;
1094                 case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS:
1095                     sizes = TCP_BUFFER_SIZES_UMTS;
1096                     break;
1097                 case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT:
1098                     sizes = TCP_BUFFER_SIZES_1XRTT;
1099                     break;
1100                 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0:
1101                 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A:
1102                 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B:
1103                     sizes = TCP_BUFFER_SIZES_EVDO;
1104                     break;
1105                 case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD:
1106                     sizes = TCP_BUFFER_SIZES_EHRPD;
1107                     break;
1108                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA:
1109                     sizes = TCP_BUFFER_SIZES_HSDPA;
1110                     break;
1111                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA:
1112                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA:
1113                     sizes = TCP_BUFFER_SIZES_HSPA;
1114                     break;
1115                 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
1116                     // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
1117                     if (RAT_NAME_5G.equals(ratName)) {
1118                         sizes = TCP_BUFFER_SIZES_NR;
1119                     } else {
1120                         sizes = TCP_BUFFER_SIZES_LTE;
1121                     }
1122                     break;
1123                 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA:
1124                     // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
1125                     if (RAT_NAME_5G.equals(ratName)) {
1126                         sizes = TCP_BUFFER_SIZES_NR;
1127                     } else {
1128                         sizes = TCP_BUFFER_SIZES_LTE_CA;
1129                     }
1130                     break;
1131                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
1132                     sizes = TCP_BUFFER_SIZES_HSPAP;
1133                     break;
1134                 case ServiceState.RIL_RADIO_TECHNOLOGY_NR:
1135                     sizes = TCP_BUFFER_SIZES_NR;
1136                     break;
1137                 default:
1138                     // Leave empty - this will let ConnectivityService use the system default.
1139                     break;
1140             }
1141         }
1142         mLinkProperties.setTcpBufferSizes(sizes);
1143     }
1144 
updateLinkBandwidthsFromCarrierConfig(int rilRat)1145     private void updateLinkBandwidthsFromCarrierConfig(int rilRat) {
1146         String ratName = ServiceState.rilRadioTechnologyToString(rilRat);
1147         if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) {
1148             ratName = mPhone.getServiceState().getNrFrequencyRange()
1149                     == ServiceState.FREQUENCY_RANGE_MMWAVE
1150                     ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA;
1151         }
1152 
1153         if (DBG) log("updateLinkBandwidthsFromCarrierConfig: " + ratName);
1154 
1155         Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName);
1156         if (values == null) {
1157             values = new Pair<>(14, 14);
1158         }
1159         mDownlinkBandwidth = values.first;
1160         mUplinkBandwidth = values.second;
1161     }
1162 
1163 
updateLinkBandwidthsFromModem(LinkCapacityEstimate lce)1164     private void updateLinkBandwidthsFromModem(LinkCapacityEstimate lce) {
1165         if (DBG) log("updateLinkBandwidthsFromModem: lce=" + lce);
1166         boolean downlinkUpdated = false;
1167         boolean uplinkUpdated = false;
1168         // LCE status deprecated in IRadio 1.2, so only check for IRadio < 1.2
1169         if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2)
1170                 || mPhone.getLceStatus() == RILConstants.LCE_ACTIVE) {
1171             if (lce.downlinkCapacityKbps != LinkCapacityEstimate.INVALID) {
1172                 mDownlinkBandwidth = lce.downlinkCapacityKbps;
1173                 downlinkUpdated = true;
1174             }
1175             if (lce.uplinkCapacityKbps != LinkCapacityEstimate.INVALID) {
1176                 mUplinkBandwidth = lce.uplinkCapacityKbps;
1177                 uplinkUpdated = true;
1178             }
1179         }
1180         if (!downlinkUpdated || !uplinkUpdated) {
1181             String ratName = ServiceState.rilRadioTechnologyToString(mRilRat);
1182             if (mRilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) {
1183                 ratName = mPhone.getServiceState().getNrFrequencyRange()
1184                         == ServiceState.FREQUENCY_RANGE_MMWAVE
1185                         ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA;
1186             }
1187             Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName);
1188             if (values != null) {
1189                 if (!downlinkUpdated) {
1190                     mDownlinkBandwidth = values.first;
1191                 }
1192                 if (!uplinkUpdated) {
1193                     mUplinkBandwidth = values.second;
1194                 }
1195             }
1196         }
1197         if (mNetworkAgent != null) {
1198             mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this);
1199         }
1200     }
1201 
isBandwidthSourceKey(String source)1202     private boolean isBandwidthSourceKey(String source) {
1203         return source.equals(mPhone.getContext().getResources().getString(
1204                 com.android.internal.R.string.config_bandwidthEstimateSource));
1205     }
1206 
1207     /**
1208      * Indicates if this data connection was established for unmetered use only. Note that this
1209      * flag should be populated when data becomes active. And if it is set to true, it can be set to
1210      * false later when we are reevaluating the data connection. But if it is set to false, it
1211      * can never become true later because setting it to true will cause this data connection
1212      * losing some immutable network capabilities, which can cause issues in connectivity service.
1213      */
1214     private boolean mUnmeteredUseOnly = false;
1215 
1216     /**
1217      * Indicates if when this connection was established we had a restricted/privileged
1218      * NetworkRequest and needed it to overcome data-enabled limitations.
1219      *
1220      * This flag overrides the APN-based restriction capability, restricting the network
1221      * based on both having a NetworkRequest with restricted AND needing a restricted
1222      * bit to overcome user-disabled status.  This allows us to handle the common case
1223      * of having both restricted requests and unrestricted requests for the same apn:
1224      * if conditions require a restricted network to overcome user-disabled then it must
1225      * be restricted, otherwise it is unrestricted (or restricted based on APN type).
1226      *
1227      * This supports a privileged app bringing up a network without general apps having access
1228      * to it when the network is otherwise unavailable (hipri).  The first use case is
1229      * pre-paid SIM reprovisioning over internet, where the carrier insists on no traffic
1230      * other than from the privileged carrier-app.
1231      *
1232      * Note that the data connection cannot go from unrestricted to restricted because the
1233      * connectivity service does not support dynamically closing TCP connections at this point.
1234      */
1235     private boolean mRestrictedNetworkOverride = false;
1236 
1237     /**
1238      * Check if this data connection should be restricted. We should call this when data connection
1239      * becomes active, or when we want to re-evaluate the conditions to decide if we need to
1240      * unstrict the data connection.
1241      *
1242      * @return True if this data connection needs to be restricted.
1243      */
1244 
shouldRestrictNetwork()1245     private boolean shouldRestrictNetwork() {
1246         // first, check if there is any network request that containing restricted capability
1247         // (i.e. Do not have NET_CAPABILITY_NOT_RESTRICTED in the request)
1248         boolean isAnyRestrictedRequest = false;
1249         for (ApnContext apnContext : mApnContexts.keySet()) {
1250             if (apnContext.hasRestrictedRequests(true /* exclude DUN */)) {
1251                 isAnyRestrictedRequest = true;
1252                 break;
1253             }
1254         }
1255 
1256         // If all of the network requests are non-restricted, then we don't need to restrict
1257         // the network.
1258         if (!isAnyRestrictedRequest) {
1259             return false;
1260         }
1261 
1262         // If the network is unmetered, then we don't need to restrict the network because users
1263         // won't be charged anyway.
1264         if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
1265             return false;
1266         }
1267 
1268         // If the data is disabled, then we need to restrict the network so only privileged apps can
1269         // use the restricted network while data is disabled.
1270         if (!mPhone.getDataEnabledSettings().isDataEnabled()) {
1271             return true;
1272         }
1273 
1274         // If the device is roaming, and the user does not turn on data roaming, then we need to
1275         // restrict the network so only privileged apps can use it.
1276         if (!mDct.getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
1277             return true;
1278         }
1279 
1280         // Otherwise we should not restrict the network so anyone who requests can use it.
1281         return false;
1282     }
1283 
1284     /**
1285      * @return True if this data connection should only be used for unmetered purposes.
1286      */
isUnmeteredUseOnly()1287     private boolean isUnmeteredUseOnly() {
1288         // If this data connection is on IWLAN, then it's unmetered and can be used by everyone.
1289         // Should not be for unmetered used only.
1290         if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
1291             return false;
1292         }
1293 
1294         // If data is enabled, this data connection can't be for unmetered used only because
1295         // everyone should be able to use it if:
1296         // 1. Device is not roaming, or
1297         // 2. Device is roaming and data roaming is turned on
1298         if (mPhone.getDataEnabledSettings().isDataEnabled()) {
1299             if (!mPhone.getServiceState().getDataRoaming() || mDct.getDataRoamingEnabled()) {
1300                 return false;
1301             }
1302         }
1303 
1304         // The data connection can only be unmetered used only if all attached APN contexts
1305         // attached to this data connection are unmetered.
1306         for (ApnContext apnContext : mApnContexts.keySet()) {
1307             if (ApnSettingUtils.isMeteredApnType(apnContext.getApnTypeBitmask(), mPhone)) {
1308                 return false;
1309             }
1310         }
1311         return true;
1312     }
1313 
1314     /**
1315      * Get the network capabilities for this data connection.
1316      *
1317      * Note that this method reads fields from mNetworkInfo, so its output is only as fresh
1318      * as mNetworkInfo. Call updateNetworkInfoSuspendState before calling this.
1319      *
1320      * @return the {@link NetworkCapabilities} of this data connection.
1321      */
getNetworkCapabilities()1322     public NetworkCapabilities getNetworkCapabilities() {
1323         NetworkCapabilities result = new NetworkCapabilities();
1324         result.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
1325 
1326         if (mApnSetting != null) {
1327             final String[] types = ApnSetting.getApnTypesStringFromBitmask(
1328                 mApnSetting.getApnTypeBitmask() & ~mDisabledApnTypeBitMask).split(",");
1329             for (String type : types) {
1330                 if (!mRestrictedNetworkOverride && mUnmeteredUseOnly
1331                         && ApnSettingUtils.isMeteredApnType(
1332                                 ApnSetting.getApnTypesBitmaskFromString(type), mPhone)) {
1333                     log("Dropped the metered " + type + " for the unmetered data call.");
1334                     continue;
1335                 }
1336                 switch (type) {
1337                     case PhoneConstants.APN_TYPE_ALL: {
1338                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
1339                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1340                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
1341                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
1342                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
1343                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
1344                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
1345                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
1346                         break;
1347                     }
1348                     case PhoneConstants.APN_TYPE_DEFAULT: {
1349                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
1350                         break;
1351                     }
1352                     case PhoneConstants.APN_TYPE_MMS: {
1353                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1354                         break;
1355                     }
1356                     case PhoneConstants.APN_TYPE_SUPL: {
1357                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
1358                         break;
1359                     }
1360                     case PhoneConstants.APN_TYPE_DUN: {
1361                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
1362                         break;
1363                     }
1364                     case PhoneConstants.APN_TYPE_FOTA: {
1365                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
1366                         break;
1367                     }
1368                     case PhoneConstants.APN_TYPE_IMS: {
1369                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
1370                         break;
1371                     }
1372                     case PhoneConstants.APN_TYPE_CBS: {
1373                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
1374                         break;
1375                     }
1376                     case PhoneConstants.APN_TYPE_IA: {
1377                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
1378                         break;
1379                     }
1380                     case PhoneConstants.APN_TYPE_EMERGENCY: {
1381                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
1382                         break;
1383                     }
1384                     case PhoneConstants.APN_TYPE_MCX: {
1385                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX);
1386                         break;
1387                     }
1388                     case PhoneConstants.APN_TYPE_XCAP: {
1389                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
1390                         break;
1391                     }
1392                     default:
1393                 }
1394             }
1395 
1396             // DataConnection has the immutable NOT_METERED capability only if all APNs in the
1397             // APN setting are unmetered according to carrier config METERED_APN_TYPES_STRINGS.
1398             // All other cases should use the dynamic TEMPORARILY_NOT_METERED capability instead.
1399             result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED,
1400                     !ApnSettingUtils.isMetered(mApnSetting, mPhone));
1401 
1402             if (result.deduceRestrictedCapability()) {
1403                 result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
1404             }
1405         }
1406 
1407         if (mRestrictedNetworkOverride) {
1408             result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
1409             // don't use dun on restriction-overriden networks.
1410             result.removeCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
1411         }
1412 
1413         result.setLinkDownstreamBandwidthKbps(mDownlinkBandwidth);
1414         result.setLinkUpstreamBandwidthKbps(mUplinkBandwidth);
1415 
1416         result.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
1417                 .setSubscriptionId(mSubId).build());
1418 
1419         result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
1420                 !mPhone.getServiceState().getDataRoaming());
1421 
1422         if ((mSubscriptionOverride & SUBSCRIPTION_OVERRIDE_CONGESTED) == 0) {
1423             result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
1424         }
1425 
1426         // Mark TEMPORARILY_NOT_METERED in the following cases:
1427         // 1. The non-restricted data is intended for unmetered use only.
1428         // 2. DcTracker set an unmetered override due to network/location (eg. 5G).
1429         // 3. SubscriptionManager set an unmetered override as requested by policy.
1430         if ((mUnmeteredUseOnly && !mRestrictedNetworkOverride) || mUnmeteredOverride
1431                 || (mSubscriptionOverride & SUBSCRIPTION_OVERRIDE_UNMETERED) != 0) {
1432             result.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
1433         } else {
1434             result.removeCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
1435         }
1436 
1437         final boolean suspended =
1438                 mNetworkInfo.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED;
1439         result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED, !suspended);
1440 
1441         result.setAdministratorUids(mAdministratorUids);
1442 
1443         return result;
1444     }
1445 
1446     /** @return {@code true} if validation is required, {@code false} otherwise. */
isValidationRequired()1447     public boolean isValidationRequired() {
1448         final NetworkCapabilities nc = getNetworkCapabilities();
1449         return nc != null
1450                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
1451                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
1452                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
1453                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
1454     }
1455 
1456     /**
1457      * @return {@code True} if 464xlat should be skipped.
1458      */
1459     @VisibleForTesting
shouldSkip464Xlat()1460     public boolean shouldSkip464Xlat() {
1461         switch (mApnSetting.getSkip464Xlat()) {
1462             case Telephony.Carriers.SKIP_464XLAT_ENABLE:
1463                 return true;
1464             case Telephony.Carriers.SKIP_464XLAT_DISABLE:
1465                 return false;
1466             case Telephony.Carriers.SKIP_464XLAT_DEFAULT:
1467             default:
1468                 break;
1469         }
1470 
1471         // As default, return true if ims and no internet
1472         final NetworkCapabilities nc = getNetworkCapabilities();
1473         return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
1474                 && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
1475     }
1476 
1477     /**
1478      * @return {@code} true iff. {@code address} is a literal IPv4 or IPv6 address.
1479      */
1480     @VisibleForTesting
isIpAddress(String address)1481     public static boolean isIpAddress(String address) {
1482         if (address == null) return false;
1483 
1484         // Accept IPv6 addresses (only) in square brackets for compatibility.
1485         if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {
1486             address = address.substring(1, address.length() - 1);
1487         }
1488         return InetAddresses.isNumericAddress(address);
1489     }
1490 
setLinkProperties(DataCallResponse response, LinkProperties linkProperties)1491     private SetupResult setLinkProperties(DataCallResponse response,
1492             LinkProperties linkProperties) {
1493         // Check if system property dns usable
1494         String propertyPrefix = "net." + response.getInterfaceName() + ".";
1495         String dnsServers[] = new String[2];
1496         dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
1497         dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
1498         boolean okToUseSystemPropertyDns = isDnsOk(dnsServers);
1499 
1500         SetupResult result;
1501 
1502         // Start with clean network properties and if we have
1503         // a failure we'll clear again at the bottom of this code.
1504         linkProperties.clear();
1505 
1506         if (response.getCause() == DataFailCause.NONE) {
1507             try {
1508                 // set interface name
1509                 linkProperties.setInterfaceName(response.getInterfaceName());
1510 
1511                 // set link addresses
1512                 if (response.getAddresses().size() > 0) {
1513                     for (LinkAddress la : response.getAddresses()) {
1514                         if (!la.getAddress().isAnyLocalAddress()) {
1515                             if (DBG) {
1516                                 log("addr/pl=" + la.getAddress() + "/"
1517                                         + la.getPrefixLength());
1518                             }
1519                             linkProperties.addLinkAddress(la);
1520                         }
1521                     }
1522                 } else {
1523                     throw new UnknownHostException("no address for ifname="
1524                             + response.getInterfaceName());
1525                 }
1526 
1527                 // set dns servers
1528                 if (response.getDnsAddresses().size() > 0) {
1529                     for (InetAddress dns : response.getDnsAddresses()) {
1530                         if (!dns.isAnyLocalAddress()) {
1531                             linkProperties.addDnsServer(dns);
1532                         }
1533                     }
1534                 } else if (okToUseSystemPropertyDns) {
1535                     for (String dnsAddr : dnsServers) {
1536                         dnsAddr = dnsAddr.trim();
1537                         if (dnsAddr.isEmpty()) continue;
1538                         InetAddress ia;
1539                         try {
1540                             ia = InetAddresses.parseNumericAddress(dnsAddr);
1541                         } catch (IllegalArgumentException e) {
1542                             throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr);
1543                         }
1544                         if (!ia.isAnyLocalAddress()) {
1545                             linkProperties.addDnsServer(ia);
1546                         }
1547                     }
1548                 } else {
1549                     throw new UnknownHostException("Empty dns response and no system default dns");
1550                 }
1551 
1552                 // set pcscf
1553                 if (response.getPcscfAddresses().size() > 0) {
1554                     for (InetAddress pcscf : response.getPcscfAddresses()) {
1555                         linkProperties.addPcscfServer(pcscf);
1556                     }
1557                 }
1558 
1559                 for (InetAddress gateway : response.getGatewayAddresses()) {
1560                     int mtu = gateway instanceof java.net.Inet6Address ? response.getMtuV6()
1561                             : response.getMtuV4();
1562                     // Allow 0.0.0.0 or :: as a gateway;
1563                     // this indicates a point-to-point interface.
1564                     linkProperties.addRoute(new RouteInfo(null, gateway, null,
1565                             RouteInfo.RTN_UNICAST, mtu));
1566                 }
1567 
1568                 // set interface MTU
1569                 // this may clobber the setting read from the APN db, but that's ok
1570                 // TODO: remove once LinkProperties#setMtu is deprecated
1571                 linkProperties.setMtu(response.getMtu());
1572 
1573                 result = SetupResult.SUCCESS;
1574             } catch (UnknownHostException e) {
1575                 log("setLinkProperties: UnknownHostException " + e);
1576                 result = SetupResult.ERROR_INVALID_ARG;
1577             }
1578         } else {
1579             result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
1580         }
1581 
1582         // An error occurred so clear properties
1583         if (result != SetupResult.SUCCESS) {
1584             if (DBG) {
1585                 log("setLinkProperties: error clearing LinkProperties status="
1586                         + response.getCause() + " result=" + result);
1587             }
1588             linkProperties.clear();
1589         }
1590 
1591         return result;
1592     }
1593 
1594     /**
1595      * Initialize connection, this will fail if the
1596      * apnSettings are not compatible.
1597      *
1598      * @param cp the Connection parameters
1599      * @return true if initialization was successful.
1600      */
initConnection(ConnectionParams cp)1601     private boolean initConnection(ConnectionParams cp) {
1602         ApnContext apnContext = cp.mApnContext;
1603         if (mApnSetting == null) {
1604             // Only change apn setting if it isn't set, it will
1605             // only NOT be set only if we're in DcInactiveState.
1606             mApnSetting = apnContext.getApnSetting();
1607         }
1608         if (mApnSetting == null || !mApnSetting.canHandleType(apnContext.getApnTypeBitmask())) {
1609             if (DBG) {
1610                 log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp
1611                         + " dc=" + DataConnection.this);
1612             }
1613             return false;
1614         }
1615         mTag += 1;
1616         mConnectionParams = cp;
1617         mConnectionParams.mTag = mTag;
1618 
1619         // always update the ConnectionParams with the latest or the
1620         // connectionGeneration gets stale
1621         mApnContexts.put(apnContext, cp);
1622 
1623         if (DBG) {
1624             log("initConnection: "
1625                     + " RefCount=" + mApnContexts.size()
1626                     + " mApnList=" + mApnContexts
1627                     + " mConnectionParams=" + mConnectionParams);
1628         }
1629         return true;
1630     }
1631 
1632     /**
1633      * The parent state for all other states.
1634      */
1635     private class DcDefaultState extends State {
1636         @Override
enter()1637         public void enter() {
1638             if (DBG) log("DcDefaultState: enter");
1639 
1640             // Register for DRS or RAT change
1641             mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
1642                     mTransportType, getHandler(),
1643                     DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null);
1644 
1645             mPhone.getServiceStateTracker().registerForDataRoamingOn(getHandler(),
1646                     DataConnection.EVENT_DATA_CONNECTION_ROAM_ON, null);
1647             mPhone.getServiceStateTracker().registerForDataRoamingOff(getHandler(),
1648                     DataConnection.EVENT_DATA_CONNECTION_ROAM_OFF, null, true);
1649             mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(),
1650                     DataConnection.EVENT_NR_STATE_CHANGED, null);
1651             mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(),
1652                     DataConnection.EVENT_NR_FREQUENCY_CHANGED, null);
1653 
1654             // Add ourselves to the list of data connections
1655             mDcController.addDc(DataConnection.this);
1656         }
1657         @Override
exit()1658         public void exit() {
1659             if (DBG) log("DcDefaultState: exit");
1660 
1661             // Unregister for DRS or RAT change.
1662             mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(
1663                     mTransportType, getHandler());
1664 
1665             mPhone.getServiceStateTracker().unregisterForDataRoamingOn(getHandler());
1666             mPhone.getServiceStateTracker().unregisterForDataRoamingOff(getHandler());
1667             mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler());
1668             mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler());
1669 
1670             // Remove ourselves from the DC lists
1671             mDcController.removeDc(DataConnection.this);
1672 
1673             if (mAc != null) {
1674                 mAc.disconnected();
1675                 mAc = null;
1676             }
1677             mApnContexts.clear();
1678             mReconnectIntent = null;
1679             mDct = null;
1680             mApnSetting = null;
1681             mPhone = null;
1682             mDataServiceManager = null;
1683             mLinkProperties = null;
1684             mLastFailCause = DataFailCause.NONE;
1685             mUserData = null;
1686             mDcController = null;
1687             mDcTesterFailBringUpAll = null;
1688         }
1689 
1690         @Override
processMessage(Message msg)1691         public boolean processMessage(Message msg) {
1692             boolean retVal = HANDLED;
1693 
1694             if (VDBG) {
1695                 log("DcDefault msg=" + getWhatToString(msg.what)
1696                         + " RefCount=" + mApnContexts.size());
1697             }
1698             switch (msg.what) {
1699                 case EVENT_RESET:
1700                     if (VDBG) log("DcDefaultState: msg.what=REQ_RESET");
1701                     transitionTo(mInactiveState);
1702                     break;
1703                 case EVENT_CONNECT:
1704                     if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected");
1705                     ConnectionParams cp = (ConnectionParams) msg.obj;
1706                     notifyConnectCompleted(cp, DataFailCause.UNKNOWN, false);
1707                     break;
1708 
1709                 case EVENT_DISCONNECT:
1710                 case EVENT_DISCONNECT_ALL:
1711                 case EVENT_REEVALUATE_RESTRICTED_STATE:
1712                     if (DBG) {
1713                         log("DcDefaultState deferring msg.what=" + getWhatToString(msg.what)
1714                                 + " RefCount=" + mApnContexts.size());
1715                     }
1716                     deferMessage(msg);
1717                     break;
1718                 case EVENT_TEAR_DOWN_NOW:
1719                     if (DBG) log("DcDefaultState EVENT_TEAR_DOWN_NOW");
1720                     mDataServiceManager.deactivateDataCall(mCid, DataService.REQUEST_REASON_NORMAL,
1721                             null);
1722                     break;
1723                 case EVENT_LOST_CONNECTION:
1724                     if (DBG) {
1725                         String s = "DcDefaultState ignore EVENT_LOST_CONNECTION"
1726                                 + " tag=" + msg.arg1 + ":mTag=" + mTag;
1727                         logAndAddLogRec(s);
1728                     }
1729                     break;
1730                 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED:
1731                     AsyncResult ar = (AsyncResult)msg.obj;
1732                     Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>)ar.result;
1733                     mDataRegState = drsRatPair.first;
1734                     updateTcpBufferSizes(drsRatPair.second);
1735                     if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
1736                         updateLinkBandwidthsFromCarrierConfig(drsRatPair.second);
1737                     }
1738                     mRilRat = drsRatPair.second;
1739                     if (DBG) {
1740                         log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"
1741                                 + " drs=" + mDataRegState
1742                                 + " mRilRat=" + mRilRat);
1743                     }
1744                     updateNetworkInfo();
1745                     break;
1746                 default:
1747                     if (DBG) {
1748                         log("DcDefaultState: ignore msg.what=" + getWhatToString(msg.what));
1749                     }
1750                     break;
1751             }
1752 
1753             return retVal;
1754         }
1755     }
1756 
updateNetworkInfo()1757     private void updateNetworkInfo() {
1758         final ServiceState state = mPhone.getServiceState();
1759 
1760         NetworkRegistrationInfo nri = state.getNetworkRegistrationInfo(
1761                 NetworkRegistrationInfo.DOMAIN_PS, mTransportType);
1762         int subtype = TelephonyManager.NETWORK_TYPE_UNKNOWN;
1763         if (nri != null) {
1764             subtype = nri.getAccessNetworkTechnology();
1765         }
1766 
1767         mNetworkInfo.setSubtype(subtype, TelephonyManager.getNetworkTypeName(subtype));
1768     }
1769 
updateNetworkInfoSuspendState()1770     private void updateNetworkInfoSuspendState() {
1771         // this is only called when we are either connected or suspended.  Decide which.
1772         if (mNetworkAgent == null) {
1773             Rlog.e(getName(), "Setting suspend state without a NetworkAgent");
1774         }
1775 
1776         // if we are not in-service change to SUSPENDED
1777         final ServiceStateTracker sst = mPhone.getServiceStateTracker();
1778         if (sst.getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
1779             mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, null,
1780                     mNetworkInfo.getExtraInfo());
1781         } else {
1782             // check for voice call and concurrency issues
1783             if (sst.isConcurrentVoiceAndDataAllowed() == false) {
1784                 final CallTracker ct = mPhone.getCallTracker();
1785                 if (ct.getState() != PhoneConstants.State.IDLE) {
1786                     mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, null,
1787                             mNetworkInfo.getExtraInfo());
1788                     return;
1789                 }
1790             }
1791             mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null,
1792                     mNetworkInfo.getExtraInfo());
1793         }
1794     }
1795 
1796     private DcDefaultState mDefaultState = new DcDefaultState();
1797 
1798     /**
1799      * The state machine is inactive and expects a EVENT_CONNECT.
1800      */
1801     private class DcInactiveState extends State {
1802         // Inform all contexts we've failed connecting
setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause)1803         public void setEnterNotificationParams(ConnectionParams cp,
1804                                                @DataFailureCause int cause) {
1805             if (VDBG) log("DcInactiveState: setEnterNotificationParams cp,cause");
1806             mConnectionParams = cp;
1807             mDisconnectParams = null;
1808             mDcFailCause = cause;
1809         }
1810 
1811         // Inform all contexts we've failed disconnected
setEnterNotificationParams(DisconnectParams dp)1812         public void setEnterNotificationParams(DisconnectParams dp) {
1813             if (VDBG) log("DcInactiveState: setEnterNotificationParams dp");
1814             mConnectionParams = null;
1815             mDisconnectParams = dp;
1816             mDcFailCause = DataFailCause.NONE;
1817         }
1818 
1819         // Inform all contexts of the failure cause
setEnterNotificationParams(@ataFailureCause int cause)1820         public void setEnterNotificationParams(@DataFailureCause int cause) {
1821             mConnectionParams = null;
1822             mDisconnectParams = null;
1823             mDcFailCause = cause;
1824         }
1825 
1826         @Override
enter()1827         public void enter() {
1828             mTag += 1;
1829             if (DBG) log("DcInactiveState: enter() mTag=" + mTag);
1830             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
1831                     TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__INACTIVE,
1832                     mPhone.getPhoneId(), mId,
1833                     mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L,
1834                     mApnSetting != null
1835                         ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false);
1836             if (mHandoverState == HANDOVER_STATE_BEING_TRANSFERRED) {
1837                 setHandoverState(HANDOVER_STATE_COMPLETED);
1838             }
1839 
1840             // Check for dangling agent. Ideally the handover source agent should be null if
1841             // handover process is smooth. When it's not null, that means handover failed. The
1842             // agent was not successfully transferred to the new data connection. We should
1843             // gracefully notify connectivity service the network was disconnected.
1844             if (mHandoverSourceNetworkAgent != null) {
1845                 DataConnection sourceDc = mHandoverSourceNetworkAgent.getDataConnection();
1846                 if (sourceDc != null) {
1847                     // If the source data connection still owns this agent, then just reset the
1848                     // handover state back to idle because handover is already failed.
1849                     mHandoverLocalLog.log(
1850                             "Handover failed. Reset the source dc " + sourceDc.getName()
1851                                     + " state to idle");
1852                     sourceDc.setHandoverState(HANDOVER_STATE_IDLE);
1853                 } else {
1854                     // The agent is now a dangling agent. No data connection owns this agent.
1855                     // Gracefully notify connectivity service disconnected.
1856                     mHandoverLocalLog.log(
1857                             "Handover failed and dangling agent found.");
1858                     mHandoverSourceNetworkAgent.acquireOwnership(
1859                             DataConnection.this, mTransportType);
1860                     NetworkInfo networkInfo = mHandoverSourceNetworkAgent.getNetworkInfo();
1861                     if (networkInfo != null) {
1862                         log("Cleared dangling network agent. " + mHandoverSourceNetworkAgent);
1863                         mHandoverSourceNetworkAgent.unregister(DataConnection.this);
1864                     } else {
1865                         String str = "Failed to get network info.";
1866                         loge(str);
1867                         mHandoverLocalLog.log(str);
1868                     }
1869                     mHandoverSourceNetworkAgent.releaseOwnership(DataConnection.this);
1870                 }
1871                 mHandoverSourceNetworkAgent = null;
1872             }
1873 
1874             if (mConnectionParams != null) {
1875                 if (DBG) {
1876                     log("DcInactiveState: enter notifyConnectCompleted +ALL failCause="
1877                             + mDcFailCause);
1878                 }
1879                 notifyConnectCompleted(mConnectionParams, mDcFailCause, true);
1880             }
1881             if (mDisconnectParams != null) {
1882                 if (DBG) {
1883                     log("DcInactiveState: enter notifyDisconnectCompleted +ALL failCause="
1884                             + mDcFailCause);
1885                 }
1886                 notifyDisconnectCompleted(mDisconnectParams, true);
1887             }
1888             if (mDisconnectParams == null && mConnectionParams == null
1889                     && mDcFailCause != DataFailCause.NONE) {
1890                 if (DBG) {
1891                     log("DcInactiveState: enter notifyAllDisconnectCompleted failCause="
1892                             + mDcFailCause);
1893                 }
1894                 notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE,
1895                         DataFailCause.toString(mDcFailCause));
1896             }
1897 
1898             // Remove ourselves from cid mapping, before clearSettings
1899             mDcController.removeActiveDcByCid(DataConnection.this);
1900 
1901             clearSettings();
1902         }
1903 
1904         @Override
exit()1905         public void exit() {
1906         }
1907 
1908         @Override
processMessage(Message msg)1909         public boolean processMessage(Message msg) {
1910             switch (msg.what) {
1911                 case EVENT_RESET:
1912                 case EVENT_REEVALUATE_RESTRICTED_STATE:
1913                     if (DBG) {
1914                         log("DcInactiveState: msg.what=" + getWhatToString(msg.what)
1915                                 + ", ignore we're already done");
1916                     }
1917                     return HANDLED;
1918                 case EVENT_CONNECT:
1919                     if (DBG) log("DcInactiveState: mag.what=EVENT_CONNECT");
1920                     ConnectionParams cp = (ConnectionParams) msg.obj;
1921 
1922                     if (!initConnection(cp)) {
1923                         log("DcInactiveState: msg.what=EVENT_CONNECT initConnection failed");
1924                         notifyConnectCompleted(cp, DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER,
1925                                 false);
1926                         transitionTo(mInactiveState);
1927                         return HANDLED;
1928                     }
1929 
1930                     int cause = connect(cp);
1931                     if (cause != DataFailCause.NONE) {
1932                         log("DcInactiveState: msg.what=EVENT_CONNECT connect failed");
1933                         notifyConnectCompleted(cp, cause, false);
1934                         transitionTo(mInactiveState);
1935                         return HANDLED;
1936                     }
1937 
1938                     if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1939                         mSubId = cp.mSubId;
1940                     }
1941 
1942                     transitionTo(mActivatingState);
1943                     return HANDLED;
1944                 case EVENT_DISCONNECT:
1945                     if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT");
1946                     notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
1947                     return HANDLED;
1948                 case EVENT_DISCONNECT_ALL:
1949                     if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL");
1950                     notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
1951                     return HANDLED;
1952                 default:
1953                     if (VDBG) {
1954                         log("DcInactiveState not handled msg.what=" + getWhatToString(msg.what));
1955                     }
1956                     return NOT_HANDLED;
1957             }
1958         }
1959     }
1960     private DcInactiveState mInactiveState = new DcInactiveState();
1961 
1962     /**
1963      * The state machine is activating a connection.
1964      */
1965     private class DcActivatingState extends State {
1966         @Override
enter()1967         public void enter() {
1968             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
1969                     TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVATING,
1970                     mPhone.getPhoneId(), mId,
1971                     mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L,
1972                     mApnSetting != null
1973                         ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false);
1974             setHandoverState(HANDOVER_STATE_IDLE);
1975             // restricted evaluation depends on network requests from apnContext. The evaluation
1976             // should happen once entering connecting state rather than active state because it's
1977             // possible that restricted network request can be released during the connecting window
1978             // and if we wait for connection established, then we might mistakenly
1979             // consider it as un-restricted. ConnectivityService then will immediately
1980             // tear down the connection through networkAgent unwanted callback if all requests for
1981             // this connection are going away.
1982             mRestrictedNetworkOverride = shouldRestrictNetwork();
1983 
1984             mPhone.getCarrierPrivilegesTracker()
1985                     .registerCarrierPrivilegesListener(
1986                             getHandler(), EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null);
1987         }
1988         @Override
processMessage(Message msg)1989         public boolean processMessage(Message msg) {
1990             boolean retVal;
1991             AsyncResult ar;
1992             ConnectionParams cp;
1993 
1994             if (DBG) log("DcActivatingState: msg=" + msgToString(msg));
1995             switch (msg.what) {
1996                 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED:
1997                 case EVENT_CONNECT:
1998                     // Activating can't process until we're done.
1999                     deferMessage(msg);
2000                     retVal = HANDLED;
2001                     break;
2002 
2003                 case EVENT_SETUP_DATA_CONNECTION_DONE:
2004                     cp = (ConnectionParams) msg.obj;
2005 
2006                     DataCallResponse dataCallResponse =
2007                             msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
2008                     SetupResult result = onSetupConnectionCompleted(msg.arg1, dataCallResponse, cp);
2009                     if (result != SetupResult.ERROR_STALE) {
2010                         if (mConnectionParams != cp) {
2011                             loge("DcActivatingState: WEIRD mConnectionsParams:"+ mConnectionParams
2012                                     + " != cp:" + cp);
2013                         }
2014                     }
2015                     if (DBG) {
2016                         log("DcActivatingState onSetupConnectionCompleted result=" + result
2017                                 + " dc=" + DataConnection.this);
2018                     }
2019                     if (cp.mApnContext != null) {
2020                         cp.mApnContext.requestLog("onSetupConnectionCompleted result=" + result);
2021                     }
2022                     switch (result) {
2023                         case SUCCESS:
2024                             // All is well
2025                             mDcFailCause = DataFailCause.NONE;
2026                             transitionTo(mActiveState);
2027                             break;
2028                         case ERROR_RADIO_NOT_AVAILABLE:
2029                             // Vendor ril rejected the command and didn't connect.
2030                             // Transition to inactive but send notifications after
2031                             // we've entered the mInactive state.
2032                             mInactiveState.setEnterNotificationParams(cp, result.mFailCause);
2033                             transitionTo(mInactiveState);
2034                             break;
2035                         case ERROR_INVALID_ARG:
2036                             // The addresses given from the RIL are bad
2037                             tearDownData(cp);
2038                             transitionTo(mDisconnectingErrorCreatingConnection);
2039                             break;
2040                         case ERROR_DATA_SERVICE_SPECIFIC_ERROR:
2041 
2042                             // Retrieve the suggested retry delay from the modem and save it.
2043                             // If the modem want us to retry the current APN again, it will
2044                             // suggest a positive delay value (in milliseconds). Otherwise we'll get
2045                             // NO_SUGGESTED_RETRY_DELAY here.
2046 
2047                             long delay = getSuggestedRetryDelay(dataCallResponse);
2048                             cp.mApnContext.setModemSuggestedDelay(delay);
2049 
2050                             String str = "DcActivatingState: ERROR_DATA_SERVICE_SPECIFIC_ERROR "
2051                                     + " delay=" + delay
2052                                     + " result=" + result
2053                                     + " result.isRadioRestartFailure="
2054                                     + DataFailCause.isRadioRestartFailure(mPhone.getContext(),
2055                                     result.mFailCause, mPhone.getSubId())
2056                                     + " isPermanentFailure=" +
2057                                     mDct.isPermanentFailure(result.mFailCause);
2058                             if (DBG) log(str);
2059                             if (cp.mApnContext != null) cp.mApnContext.requestLog(str);
2060 
2061                             // Save the cause. DcTracker.onDataSetupComplete will check this
2062                             // failure cause and determine if we need to retry this APN later
2063                             // or not.
2064                             mInactiveState.setEnterNotificationParams(cp, result.mFailCause);
2065                             transitionTo(mInactiveState);
2066                             break;
2067                         case ERROR_STALE:
2068                             loge("DcActivatingState: stale EVENT_SETUP_DATA_CONNECTION_DONE"
2069                                     + " tag:" + cp.mTag + " != mTag:" + mTag);
2070                             break;
2071                         default:
2072                             throw new RuntimeException("Unknown SetupResult, should not happen");
2073                     }
2074                     retVal = HANDLED;
2075                     break;
2076                 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
2077                     AsyncResult asyncResult = (AsyncResult) msg.obj;
2078                     int[] administratorUids = (int[]) asyncResult.result;
2079                     mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
2080                     retVal = HANDLED;
2081                     break;
2082                 default:
2083                     if (VDBG) {
2084                         log("DcActivatingState not handled msg.what=" +
2085                                 getWhatToString(msg.what) + " RefCount=" + mApnContexts.size());
2086                     }
2087                     retVal = NOT_HANDLED;
2088                     break;
2089             }
2090             return retVal;
2091         }
2092     }
2093     private DcActivatingState mActivatingState = new DcActivatingState();
2094 
2095     /**
2096      * The state machine is connected, expecting an EVENT_DISCONNECT.
2097      */
2098     private class DcActiveState extends State {
2099 
enter()2100         @Override public void enter() {
2101             if (DBG) log("DcActiveState: enter dc=" + DataConnection.this);
2102             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
2103                     TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVE,
2104                     mPhone.getPhoneId(), mId,
2105                     mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L,
2106                     mApnSetting != null
2107                         ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false);
2108 
2109             updateNetworkInfo();
2110 
2111             // If we were retrying there maybe more than one, otherwise they'll only be one.
2112             notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE,
2113                     Phone.REASON_CONNECTED);
2114 
2115             mPhone.getCallTracker().registerForVoiceCallStarted(getHandler(),
2116                     DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED, null);
2117             mPhone.getCallTracker().registerForVoiceCallEnded(getHandler(),
2118                     DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED, null);
2119 
2120             // If the EVENT_CONNECT set the current max retry restore it here
2121             // if it didn't then this is effectively a NOP.
2122             mDcController.addActiveDcByCid(DataConnection.this);
2123 
2124             mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED,
2125                     mNetworkInfo.getReason(), null);
2126             mNetworkInfo.setExtraInfo(mApnSetting.getApnName());
2127             updateTcpBufferSizes(mRilRat);
2128             updateLinkBandwidthsFromCarrierConfig(mRilRat);
2129 
2130             final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder();
2131             configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE);
2132             configBuilder.setLegacyTypeName(NETWORK_TYPE);
2133             configBuilder.setLegacyExtraInfo(mApnSetting.getApnName());
2134             final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent();
2135             if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager
2136                     .ACTION_CARRIER_SIGNAL_REDIRECTED)) {
2137                 // carrierSignal Receivers will place the carrier-specific provisioning notification
2138                 configBuilder.disableProvisioningNotification();
2139             }
2140 
2141             final String subscriberId = mPhone.getSubscriberId();
2142             if (!TextUtils.isEmpty(subscriberId)) {
2143                 configBuilder.setSubscriberId(subscriberId);
2144             }
2145 
2146             // set skip464xlat if it is not default otherwise
2147             if (shouldSkip464Xlat()) {
2148                 configBuilder.disableNat64Detection();
2149             }
2150 
2151             mUnmeteredUseOnly = isUnmeteredUseOnly();
2152 
2153             if (DBG) {
2154                 log("mRestrictedNetworkOverride = " + mRestrictedNetworkOverride
2155                         + ", mUnmeteredUseOnly = " + mUnmeteredUseOnly);
2156             }
2157 
2158             if (mConnectionParams != null
2159                     && mConnectionParams.mRequestType == DcTracker.REQUEST_TYPE_HANDOVER) {
2160                 // If this is a data setup for handover, we need to reuse the existing network agent
2161                 // instead of creating a new one. This should be transparent to connectivity
2162                 // service.
2163                 DcTracker dcTracker = mPhone.getDcTracker(getHandoverSourceTransport());
2164                 DataConnection dc = dcTracker.getDataConnectionByApnType(
2165                         mConnectionParams.mApnContext.getApnType());
2166                 // It's possible that the source data connection has been disconnected by the modem
2167                 // already. If not, set its handover state to completed.
2168                 if (dc != null) {
2169                     // Transfer network agent from the original data connection as soon as the
2170                     // new handover data connection is connected.
2171                     dc.setHandoverState(HANDOVER_STATE_COMPLETED);
2172                 }
2173 
2174                 if (mHandoverSourceNetworkAgent != null) {
2175                     String logStr = "Transfer network agent " + mHandoverSourceNetworkAgent.getTag()
2176                             + " successfully.";
2177                     log(logStr);
2178                     mHandoverLocalLog.log(logStr);
2179                     mNetworkAgent = mHandoverSourceNetworkAgent;
2180                     mNetworkAgent.acquireOwnership(DataConnection.this, mTransportType);
2181 
2182                     // TODO: Should evaluate mDisabledApnTypeBitMask again after handover. We don't
2183                     // do it now because connectivity service does not support dynamically removing
2184                     // immutable capabilities.
2185 
2186                     // Update the capability after handover
2187                     mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2188                             DataConnection.this);
2189                     mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
2190                     mHandoverSourceNetworkAgent = null;
2191                 } else {
2192                     String logStr = "Failed to get network agent from original data connection";
2193                     loge(logStr);
2194                     mHandoverLocalLog.log(logStr);
2195                     return;
2196                 }
2197             } else {
2198                 mScore = calculateScore();
2199                 final NetworkFactory factory = PhoneFactory.getNetworkFactory(
2200                         mPhone.getPhoneId());
2201                 final NetworkProvider provider = (null == factory) ? null : factory.getProvider();
2202 
2203                 mDisabledApnTypeBitMask |= getDisallowedApnTypes();
2204 
2205                 mNetworkAgent = new DcNetworkAgent(DataConnection.this,
2206                         mPhone, mNetworkInfo, mScore, configBuilder.build(), provider,
2207                         mTransportType);
2208                 // All network agents start out in CONNECTING mode, but DcNetworkAgents are
2209                 // created when the network is already connected. Hence, send the connected
2210                 // notification immediately.
2211                 mNetworkAgent.markConnected();
2212             }
2213 
2214             if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
2215                 mPhone.mCi.registerForNattKeepaliveStatus(
2216                         getHandler(), DataConnection.EVENT_KEEPALIVE_STATUS, null);
2217                 mPhone.mCi.registerForLceInfo(
2218                         getHandler(), DataConnection.EVENT_LINK_CAPACITY_CHANGED, null);
2219             }
2220             TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
2221                     mCid, mApnSetting.getApnTypeBitmask(), RilDataCall.State.CONNECTED);
2222         }
2223 
2224         @Override
exit()2225         public void exit() {
2226             if (DBG) log("DcActiveState: exit dc=" + this);
2227             String reason = mNetworkInfo.getReason();
2228             if(mDcController.isExecutingCarrierChange()) {
2229                 reason = Phone.REASON_CARRIER_CHANGE;
2230             } else if (mDisconnectParams != null && mDisconnectParams.mReason != null) {
2231                 reason = mDisconnectParams.mReason;
2232             } else {
2233                 reason = DataFailCause.toString(mDcFailCause);
2234             }
2235             mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler());
2236             mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler());
2237 
2238             // If the data connection is being handover to other transport, we should not notify
2239             // disconnected to connectivity service.
2240             if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED) {
2241                 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
2242                         reason, mNetworkInfo.getExtraInfo());
2243             }
2244 
2245             if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
2246                 mPhone.mCi.unregisterForNattKeepaliveStatus(getHandler());
2247                 mPhone.mCi.unregisterForLceInfo(getHandler());
2248             }
2249 
2250             // If we are still owning this agent, then we should inform connectivity service the
2251             // data connection is disconnected. If we don't own this agent at this point, that means
2252             // it has been transferred to the new data connection for IWLAN data handover case.
2253             if (mNetworkAgent != null) {
2254                 mNetworkAgent.sendNetworkInfo(mNetworkInfo, DataConnection.this);
2255                 mNetworkAgent.releaseOwnership(DataConnection.this);
2256             }
2257             mNetworkAgent = null;
2258 
2259             TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
2260                     mCid, mApnSetting.getApnTypeBitmask(), RilDataCall.State.DISCONNECTED);
2261 
2262             mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler());
2263         }
2264 
2265         @Override
processMessage(Message msg)2266         public boolean processMessage(Message msg) {
2267             boolean retVal;
2268 
2269             switch (msg.what) {
2270                 case EVENT_CONNECT: {
2271                     ConnectionParams cp = (ConnectionParams) msg.obj;
2272                     // either add this new apn context to our set or
2273                     // update the existing cp with the latest connection generation number
2274                     mApnContexts.put(cp.mApnContext, cp);
2275                     // TODO (b/118347948): evaluate if it's still needed after assigning
2276                     // different scores to different Cellular network.
2277                     mDisabledApnTypeBitMask &= ~cp.mApnContext.getApnTypeBitmask();
2278                     mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2279                             DataConnection.this);
2280                     if (DBG) {
2281                         log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this);
2282                     }
2283                     notifyConnectCompleted(cp, DataFailCause.NONE, false);
2284                     retVal = HANDLED;
2285                     break;
2286                 }
2287                 case EVENT_DISCONNECT: {
2288                     DisconnectParams dp = (DisconnectParams) msg.obj;
2289                     if (DBG) {
2290                         log("DcActiveState: EVENT_DISCONNECT dp=" + dp
2291                                 + " dc=" + DataConnection.this);
2292                     }
2293                     if (mApnContexts.containsKey(dp.mApnContext)) {
2294                         if (DBG) {
2295                             log("DcActiveState msg.what=EVENT_DISCONNECT RefCount="
2296                                     + mApnContexts.size());
2297                         }
2298 
2299                         if (mApnContexts.size() == 1) {
2300                             mApnContexts.clear();
2301                             mDisconnectParams = dp;
2302                             mConnectionParams = null;
2303                             dp.mTag = mTag;
2304                             tearDownData(dp);
2305                             transitionTo(mDisconnectingState);
2306                         } else {
2307                             mApnContexts.remove(dp.mApnContext);
2308                             // TODO (b/118347948): evaluate if it's still needed after assigning
2309                             // different scores to different Cellular network.
2310                             mDisabledApnTypeBitMask |= dp.mApnContext.getApnTypeBitmask();
2311                             mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2312                                     DataConnection.this);
2313                             notifyDisconnectCompleted(dp, false);
2314                         }
2315                     } else {
2316                         log("DcActiveState ERROR no such apnContext=" + dp.mApnContext
2317                                 + " in this dc=" + DataConnection.this);
2318                         notifyDisconnectCompleted(dp, false);
2319                     }
2320                     retVal = HANDLED;
2321                     break;
2322                 }
2323                 case EVENT_DISCONNECT_ALL: {
2324                     if (DBG) {
2325                         log("DcActiveState EVENT_DISCONNECT clearing apn contexts,"
2326                                 + " dc=" + DataConnection.this);
2327                     }
2328                     DisconnectParams dp = (DisconnectParams) msg.obj;
2329                     mDisconnectParams = dp;
2330                     mConnectionParams = null;
2331                     dp.mTag = mTag;
2332                     tearDownData(dp);
2333                     transitionTo(mDisconnectingState);
2334                     retVal = HANDLED;
2335                     break;
2336                 }
2337                 case EVENT_LOST_CONNECTION: {
2338                     if (DBG) {
2339                         log("DcActiveState EVENT_LOST_CONNECTION dc=" + DataConnection.this);
2340                     }
2341 
2342                     mInactiveState.setEnterNotificationParams(DataFailCause.LOST_CONNECTION);
2343                     transitionTo(mInactiveState);
2344                     retVal = HANDLED;
2345                     break;
2346                 }
2347                 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: {
2348                     AsyncResult ar = (AsyncResult) msg.obj;
2349                     Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>) ar.result;
2350                     mDataRegState = drsRatPair.first;
2351                     updateTcpBufferSizes(drsRatPair.second);
2352                     if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
2353                         updateLinkBandwidthsFromCarrierConfig(drsRatPair.second);
2354                     }
2355                     mRilRat = drsRatPair.second;
2356                     if (DBG) {
2357                         log("DcActiveState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"
2358                                 + " drs=" + mDataRegState
2359                                 + " mRilRat=" + mRilRat);
2360                     }
2361                     updateNetworkInfoSuspendState();
2362                     if (mNetworkAgent != null) {
2363                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2364                                 DataConnection.this);
2365                         mNetworkAgent.sendNetworkInfo(mNetworkInfo, DataConnection.this);
2366                         mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
2367                     }
2368                     retVal = HANDLED;
2369                     break;
2370                 }
2371                 case EVENT_NR_FREQUENCY_CHANGED:
2372                     // fallthrough
2373                 case EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED:
2374                     if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
2375                         updateLinkBandwidthsFromCarrierConfig(mRilRat);
2376                     }
2377                     if (mNetworkAgent != null) {
2378                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2379                                 DataConnection.this);
2380                     }
2381                     retVal = HANDLED;
2382                     break;
2383                 case EVENT_DATA_CONNECTION_METEREDNESS_CHANGED:
2384                     boolean isUnmetered = (boolean) msg.obj;
2385                     if (isUnmetered == mUnmeteredOverride) {
2386                         retVal = HANDLED;
2387                         break;
2388                     }
2389                     mUnmeteredOverride = isUnmetered;
2390                     // fallthrough
2391                 case EVENT_DATA_CONNECTION_ROAM_ON:
2392                 case EVENT_DATA_CONNECTION_ROAM_OFF:
2393                 case EVENT_DATA_CONNECTION_OVERRIDE_CHANGED: {
2394                     updateNetworkInfo();
2395                     if (mNetworkAgent != null) {
2396                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2397                                 DataConnection.this);
2398                     }
2399                     retVal = HANDLED;
2400                     break;
2401                 }
2402                 case EVENT_BW_REFRESH_RESPONSE: {
2403                     AsyncResult ar = (AsyncResult)msg.obj;
2404                     if (ar.exception != null) {
2405                         log("EVENT_BW_REFRESH_RESPONSE: error ignoring, e=" + ar.exception);
2406                     } else {
2407                         if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) {
2408                             updateLinkBandwidthsFromModem((LinkCapacityEstimate) ar.result);
2409                         }
2410                     }
2411                     retVal = HANDLED;
2412                     break;
2413                 }
2414                 case EVENT_DATA_CONNECTION_VOICE_CALL_STARTED:
2415                 case EVENT_DATA_CONNECTION_VOICE_CALL_ENDED: {
2416                     updateNetworkInfo();
2417                     updateNetworkInfoSuspendState();
2418                     if (mNetworkAgent != null) {
2419                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2420                                 DataConnection.this);
2421                         mNetworkAgent.sendNetworkInfo(mNetworkInfo, DataConnection.this);
2422                     }
2423                     retVal = HANDLED;
2424                     break;
2425                 }
2426                 case EVENT_KEEPALIVE_START_REQUEST: {
2427                     KeepalivePacketData pkt = (KeepalivePacketData) msg.obj;
2428                     int slotId = msg.arg1;
2429                     int intervalMillis = msg.arg2 * 1000;
2430                     if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
2431                         mPhone.mCi.startNattKeepalive(
2432                                 DataConnection.this.mCid, pkt, intervalMillis,
2433                                 DataConnection.this.obtainMessage(
2434                                         EVENT_KEEPALIVE_STARTED, slotId, 0, null));
2435                     } else {
2436                         // We currently do not support NATT Keepalive requests using the
2437                         // DataService API, so unless the request is WWAN (always bound via
2438                         // the CommandsInterface), the request cannot be honored.
2439                         //
2440                         // TODO: b/72331356 to add support for Keepalive to the DataService
2441                         // so that keepalive requests can be handled (if supported) by the
2442                         // underlying transport.
2443                         if (mNetworkAgent != null) {
2444                             mNetworkAgent.sendSocketKeepaliveEvent(
2445                                     msg.arg1, SocketKeepalive.ERROR_INVALID_NETWORK);
2446                         }
2447                     }
2448                     retVal = HANDLED;
2449                     break;
2450                 }
2451                 case EVENT_KEEPALIVE_STOP_REQUEST: {
2452                     int slotId = msg.arg1;
2453                     int handle = mNetworkAgent.keepaliveTracker.getHandleForSlot(slotId);
2454                     if (handle < 0) {
2455                         loge("No slot found for stopSocketKeepalive! " + slotId);
2456                         mNetworkAgent.sendSocketKeepaliveEvent(
2457                                 slotId, SocketKeepalive.NO_KEEPALIVE);
2458                         retVal = HANDLED;
2459                         break;
2460                     } else {
2461                         logd("Stopping keepalive with handle: " + handle);
2462                     }
2463 
2464                     mPhone.mCi.stopNattKeepalive(
2465                             handle, DataConnection.this.obtainMessage(
2466                                     EVENT_KEEPALIVE_STOPPED, handle, slotId, null));
2467                     retVal = HANDLED;
2468                     break;
2469                 }
2470                 case EVENT_KEEPALIVE_STARTED: {
2471                     AsyncResult ar = (AsyncResult) msg.obj;
2472                     final int slot = msg.arg1;
2473                     if (ar.exception != null || ar.result == null) {
2474                         loge("EVENT_KEEPALIVE_STARTED: error starting keepalive, e="
2475                                 + ar.exception);
2476                         mNetworkAgent.sendSocketKeepaliveEvent(
2477                                 slot, SocketKeepalive.ERROR_HARDWARE_ERROR);
2478                     } else {
2479                         KeepaliveStatus ks = (KeepaliveStatus) ar.result;
2480                         if (ks == null) {
2481                             loge("Null KeepaliveStatus received!");
2482                         } else {
2483                             mNetworkAgent.keepaliveTracker.handleKeepaliveStarted(slot, ks);
2484                         }
2485                     }
2486                     retVal = HANDLED;
2487                     break;
2488                 }
2489                 case EVENT_KEEPALIVE_STATUS: {
2490                     AsyncResult ar = (AsyncResult) msg.obj;
2491                     if (ar.exception != null) {
2492                         loge("EVENT_KEEPALIVE_STATUS: error in keepalive, e=" + ar.exception);
2493                         // We have no way to notify connectivity in this case.
2494                     }
2495                     if (ar.result != null) {
2496                         KeepaliveStatus ks = (KeepaliveStatus) ar.result;
2497                         mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(ks);
2498                     }
2499 
2500                     retVal = HANDLED;
2501                     break;
2502                 }
2503                 case EVENT_KEEPALIVE_STOPPED: {
2504                     AsyncResult ar = (AsyncResult) msg.obj;
2505                     final int handle = msg.arg1;
2506                     final int slotId = msg.arg2;
2507 
2508                     if (ar.exception != null) {
2509                         loge("EVENT_KEEPALIVE_STOPPED: error stopping keepalive for handle="
2510                                 + handle + " e=" + ar.exception);
2511                         mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(
2512                                 new KeepaliveStatus(KeepaliveStatus.ERROR_UNKNOWN));
2513                     } else {
2514                         log("Keepalive Stop Requested for handle=" + handle);
2515                         mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(
2516                                 new KeepaliveStatus(handle, KeepaliveStatus.STATUS_INACTIVE));
2517                     }
2518                     retVal = HANDLED;
2519                     break;
2520                 }
2521                 case EVENT_LINK_CAPACITY_CHANGED: {
2522                     AsyncResult ar = (AsyncResult) msg.obj;
2523                     if (ar.exception != null) {
2524                         loge("EVENT_LINK_CAPACITY_CHANGED e=" + ar.exception);
2525                     } else {
2526                         if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) {
2527                             updateLinkBandwidthsFromModem((LinkCapacityEstimate) ar.result);
2528                         }
2529                     }
2530                     retVal = HANDLED;
2531                     break;
2532                 }
2533                 case EVENT_REEVALUATE_RESTRICTED_STATE: {
2534                     // If the network was restricted, and now it does not need to be restricted
2535                     // anymore, we should add the NET_CAPABILITY_NOT_RESTRICTED capability.
2536                     if (mRestrictedNetworkOverride && !shouldRestrictNetwork()) {
2537                         if (DBG) {
2538                             log("Data connection becomes not-restricted. dc=" + this);
2539                         }
2540                         // Note we only do this when network becomes non-restricted. When a
2541                         // non-restricted becomes restricted (e.g. users disable data, or turn off
2542                         // data roaming), DCT will explicitly tear down the networks (because
2543                         // connectivity service does not support force-close TCP connections today).
2544                         // Also note that NET_CAPABILITY_NOT_RESTRICTED is an immutable capability
2545                         // (see {@link NetworkCapabilities}) once we add it to the network, we can't
2546                         // remove it through the entire life cycle of the connection.
2547                         mRestrictedNetworkOverride = false;
2548                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2549                                 DataConnection.this);
2550                     }
2551 
2552                     // If the data does need to be unmetered use only (e.g. users turn on data, or
2553                     // device is not roaming anymore assuming data roaming is off), then we can
2554                     // dynamically add those metered APN type capabilities back. (But not the
2555                     // other way around because most of the APN-type capabilities are immutable
2556                     // capabilities.)
2557                     if (mUnmeteredUseOnly && !isUnmeteredUseOnly()) {
2558                         mUnmeteredUseOnly = false;
2559                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2560                                 DataConnection.this);
2561                     }
2562 
2563                     retVal = HANDLED;
2564                     break;
2565                 }
2566                 case EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES: {
2567                     // Update other properties like link properties if needed in future.
2568                     updateScore();
2569                     retVal = HANDLED;
2570                     break;
2571                 }
2572                 case EVENT_NR_STATE_CHANGED: {
2573                     updateTcpBufferSizes(mRilRat);
2574                     if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
2575                         updateLinkBandwidthsFromCarrierConfig(mRilRat);
2576                     }
2577                     if (mNetworkAgent != null) {
2578                         mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
2579                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
2580                                 DataConnection.this);
2581                     }
2582                     retVal = HANDLED;
2583                     break;
2584                 }
2585                 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
2586                     AsyncResult asyncResult = (AsyncResult) msg.obj;
2587                     int[] administratorUids = (int[]) asyncResult.result;
2588                     mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
2589 
2590                     // Administrator UIDs changed, so update NetworkAgent with new
2591                     // NetworkCapabilities
2592                     if (mNetworkAgent != null) {
2593                         mNetworkAgent.sendNetworkCapabilities(
2594                                 getNetworkCapabilities(), DataConnection.this);
2595                     }
2596                     retVal = HANDLED;
2597                     break;
2598                 default:
2599                     if (VDBG) {
2600                         log("DcActiveState not handled msg.what=" + getWhatToString(msg.what));
2601                     }
2602                     retVal = NOT_HANDLED;
2603                     break;
2604             }
2605             return retVal;
2606         }
2607     }
2608     private DcActiveState mActiveState = new DcActiveState();
2609 
2610     /**
2611      * The state machine is disconnecting.
2612      */
2613     private class DcDisconnectingState extends State {
2614         @Override
enter()2615         public void enter() {
2616             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
2617                     TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTING,
2618                     mPhone.getPhoneId(), mId,
2619                     mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L,
2620                     mApnSetting != null
2621                         ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false);
2622         }
2623         @Override
processMessage(Message msg)2624         public boolean processMessage(Message msg) {
2625             boolean retVal;
2626 
2627             switch (msg.what) {
2628                 case EVENT_CONNECT:
2629                     if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = "
2630                             + mApnContexts.size());
2631                     deferMessage(msg);
2632                     retVal = HANDLED;
2633                     break;
2634 
2635                 case EVENT_DEACTIVATE_DONE:
2636                     DisconnectParams dp = (DisconnectParams) msg.obj;
2637 
2638                     String str = "DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE RefCount="
2639                             + mApnContexts.size();
2640                     if (DBG) log(str);
2641                     if (dp.mApnContext != null) dp.mApnContext.requestLog(str);
2642 
2643                     if (dp.mTag == mTag) {
2644                         // Transition to inactive but send notifications after
2645                         // we've entered the mInactive state.
2646                         mInactiveState.setEnterNotificationParams(dp);
2647                         transitionTo(mInactiveState);
2648                     } else {
2649                         if (DBG) log("DcDisconnectState stale EVENT_DEACTIVATE_DONE"
2650                                 + " dp.tag=" + dp.mTag + " mTag=" + mTag);
2651                     }
2652                     retVal = HANDLED;
2653                     break;
2654 
2655                 default:
2656                     if (VDBG) {
2657                         log("DcDisconnectingState not handled msg.what="
2658                                 + getWhatToString(msg.what));
2659                     }
2660                     retVal = NOT_HANDLED;
2661                     break;
2662             }
2663             return retVal;
2664         }
2665     }
2666     private DcDisconnectingState mDisconnectingState = new DcDisconnectingState();
2667 
2668     /**
2669      * The state machine is disconnecting after an creating a connection.
2670      */
2671     private class DcDisconnectionErrorCreatingConnection extends State {
2672         @Override
enter()2673         public void enter() {
2674             TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
2675                     TelephonyStatsLog
2676                             .MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTION_ERROR_CREATING_CONNECTION,
2677                     mPhone.getPhoneId(), mId,
2678                     mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L,
2679                     mApnSetting != null
2680                         ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false);
2681         }
2682         @Override
processMessage(Message msg)2683         public boolean processMessage(Message msg) {
2684             boolean retVal;
2685 
2686             switch (msg.what) {
2687                 case EVENT_DEACTIVATE_DONE:
2688                     ConnectionParams cp = (ConnectionParams) msg.obj;
2689                     if (cp.mTag == mTag) {
2690                         String str = "DcDisconnectionErrorCreatingConnection" +
2691                                 " msg.what=EVENT_DEACTIVATE_DONE";
2692                         if (DBG) log(str);
2693                         if (cp.mApnContext != null) cp.mApnContext.requestLog(str);
2694 
2695                         // Transition to inactive but send notifications after
2696                         // we've entered the mInactive state.
2697                         mInactiveState.setEnterNotificationParams(cp,
2698                                 DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER);
2699                         transitionTo(mInactiveState);
2700                     } else {
2701                         if (DBG) {
2702                             log("DcDisconnectionErrorCreatingConnection stale EVENT_DEACTIVATE_DONE"
2703                                     + " dp.tag=" + cp.mTag + ", mTag=" + mTag);
2704                         }
2705                     }
2706                     retVal = HANDLED;
2707                     break;
2708 
2709                 default:
2710                     if (VDBG) {
2711                         log("DcDisconnectionErrorCreatingConnection not handled msg.what="
2712                                 + getWhatToString(msg.what));
2713                     }
2714                     retVal = NOT_HANDLED;
2715                     break;
2716             }
2717             return retVal;
2718         }
2719     }
2720     private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection =
2721                 new DcDisconnectionErrorCreatingConnection();
2722 
2723     /**
2724      * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg.
2725      * Used for cellular networks that use Access Point Names (APN) such
2726      * as GSM networks.
2727      *
2728      * @param apnContext is the Access Point Name to bring up a connection to
2729      * @param profileId for the connection
2730      * @param rilRadioTechnology Radio technology for the data connection
2731      * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
2732      *                       With AsyncResult.userObj set to the original msg.obj,
2733      *                       AsyncResult.result = FailCause and AsyncResult.exception = Exception().
2734      * @param connectionGeneration used to track a single connection request so disconnects can get
2735      *                             ignored if obsolete.
2736      * @param requestType Data request type
2737      * @param subId the subscription id associated with this data connection.
2738      * @param isApnPreferred whether or not the apn is preferred.
2739      */
bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isApnPreferred)2740     public void bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology,
2741                         Message onCompletedMsg, int connectionGeneration,
2742                         @RequestNetworkType int requestType, int subId, boolean isApnPreferred) {
2743         if (DBG) {
2744             log("bringUp: apnContext=" + apnContext + " onCompletedMsg=" + onCompletedMsg);
2745         }
2746         sendMessage(DataConnection.EVENT_CONNECT,
2747                 new ConnectionParams(apnContext, profileId, rilRadioTechnology, onCompletedMsg,
2748                         connectionGeneration, requestType, subId, isApnPreferred));
2749     }
2750 
2751     /**
2752      * Tear down the connection through the apn on the network.
2753      *
2754      * @param apnContext APN context
2755      * @param reason reason to tear down
2756      * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
2757      *        With AsyncResult.userObj set to the original msg.obj.
2758      */
tearDown(ApnContext apnContext, String reason, Message onCompletedMsg)2759     public void tearDown(ApnContext apnContext, String reason, Message onCompletedMsg) {
2760         if (DBG) {
2761             log("tearDown: apnContext=" + apnContext + " reason=" + reason + " onCompletedMsg="
2762                     + onCompletedMsg);
2763         }
2764         sendMessage(DataConnection.EVENT_DISCONNECT,
2765                 new DisconnectParams(apnContext, reason, DcTracker.RELEASE_TYPE_DETACH,
2766                         onCompletedMsg));
2767     }
2768 
2769     // ******* "public" interface
2770 
2771     /**
2772      * Used for testing purposes.
2773      */
tearDownNow()2774     void tearDownNow() {
2775         if (DBG) log("tearDownNow()");
2776         sendMessage(obtainMessage(EVENT_TEAR_DOWN_NOW));
2777     }
2778 
2779     /**
2780      * Tear down the connection through the apn on the network.  Ignores reference count and
2781      * and always tears down.
2782      *
2783      * @param releaseType Data release type
2784      * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
2785      *        With AsyncResult.userObj set to the original msg.obj.
2786      */
tearDownAll(String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)2787     public void tearDownAll(String reason, @ReleaseNetworkType int releaseType,
2788                             Message onCompletedMsg) {
2789         if (DBG) log("tearDownAll: reason=" + reason + ", releaseType=" + releaseType);
2790         sendMessage(DataConnection.EVENT_DISCONNECT_ALL,
2791                 new DisconnectParams(null, reason, releaseType, onCompletedMsg));
2792     }
2793 
2794     /**
2795      * Reset the data connection to inactive state.
2796      */
reset()2797     public void reset() {
2798         sendMessage(EVENT_RESET);
2799         if (DBG) log("reset");
2800     }
2801 
2802     /**
2803      * Re-evaluate the restricted state. If the restricted data connection does not need to be
2804      * restricted anymore, we need to dynamically change the network's capability.
2805      */
reevaluateRestrictedState()2806     void reevaluateRestrictedState() {
2807         sendMessage(EVENT_REEVALUATE_RESTRICTED_STATE);
2808         if (DBG) log("reevaluate restricted state");
2809     }
2810 
2811     /**
2812      * Re-evaluate the data connection properties. For example, it will recalculate data connection
2813      * score and update through network agent it if changed.
2814      */
reevaluateDataConnectionProperties()2815     void reevaluateDataConnectionProperties() {
2816         sendMessage(EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES);
2817         if (DBG) log("reevaluate data connection properties");
2818     }
2819 
2820     /**
2821      * @return The parameters used for initiating a data connection.
2822      */
getConnectionParams()2823     public ConnectionParams getConnectionParams() {
2824         return mConnectionParams;
2825     }
2826 
2827     /**
2828      * @return The list of PCSCF addresses
2829      */
getPcscfAddresses()2830     public String[] getPcscfAddresses() {
2831         return mPcscfAddr;
2832     }
2833 
2834     /**
2835      * Using the result of the SETUP_DATA_CALL determine the retry delay.
2836      *
2837      * @param response The response from setup data call
2838      * @return NO_SUGGESTED_RETRY_DELAY if no retry is needed otherwise the delay to the
2839      *         next SETUP_DATA_CALL
2840      */
getSuggestedRetryDelay(DataCallResponse response)2841     private long getSuggestedRetryDelay(DataCallResponse response) {
2842         /** According to ril.h
2843          * The value < 0 means no value is suggested
2844          * The value 0 means retry should be done ASAP.
2845          * The value of Integer.MAX_VALUE(0x7fffffff) means no retry.
2846          */
2847 
2848         // The value < 0 means no value is suggested
2849         if (response.getSuggestedRetryTime() < 0) {
2850             if (DBG) log("No suggested retry delay.");
2851             return RetryManager.NO_SUGGESTED_RETRY_DELAY;
2852         }
2853         // The value of Integer.MAX_VALUE(0x7fffffff) means no retry.
2854         else if (response.getSuggestedRetryTime() == Integer.MAX_VALUE) {
2855             if (DBG) log("Modem suggested not retrying.");
2856             return RetryManager.NO_RETRY;
2857         }
2858 
2859         // We need to cast it to long because the value returned from RIL is a 32-bit integer,
2860         // but the time values used in AlarmManager are all 64-bit long.
2861         return (long) response.getSuggestedRetryTime();
2862     }
2863 
getApnContexts()2864     public List<ApnContext> getApnContexts() {
2865         return new ArrayList<>(mApnContexts.keySet());
2866     }
2867 
2868     /** Get the network agent of the data connection */
2869     @Nullable
getNetworkAgent()2870     DcNetworkAgent getNetworkAgent() {
2871         return mNetworkAgent;
2872     }
2873 
setHandoverState(@andoverState int state)2874     void setHandoverState(@HandoverState int state) {
2875         if (mHandoverState != state) {
2876             mHandoverLocalLog.log("State changed from " + handoverStateToString(mHandoverState)
2877                     + " to " + handoverStateToString(state));
2878             mHandoverState = state;
2879         }
2880     }
2881 
2882     /**
2883      * @return the string for msg.what as our info.
2884      */
2885     @Override
getWhatToString(int what)2886     protected String getWhatToString(int what) {
2887         return cmdToString(what);
2888     }
2889 
msgToString(Message msg)2890     private static String msgToString(Message msg) {
2891         String retVal;
2892         if (msg == null) {
2893             retVal = "null";
2894         } else {
2895             StringBuilder   b = new StringBuilder();
2896 
2897             b.append("{what=");
2898             b.append(cmdToString(msg.what));
2899 
2900             b.append(" when=");
2901             TimeUtils.formatDuration(msg.getWhen() - SystemClock.uptimeMillis(), b);
2902 
2903             if (msg.arg1 != 0) {
2904                 b.append(" arg1=");
2905                 b.append(msg.arg1);
2906             }
2907 
2908             if (msg.arg2 != 0) {
2909                 b.append(" arg2=");
2910                 b.append(msg.arg2);
2911             }
2912 
2913             if (msg.obj != null) {
2914                 b.append(" obj=");
2915                 b.append(msg.obj);
2916             }
2917 
2918             b.append(" target=");
2919             b.append(msg.getTarget());
2920 
2921             b.append(" replyTo=");
2922             b.append(msg.replyTo);
2923 
2924             b.append("}");
2925 
2926             retVal = b.toString();
2927         }
2928         return retVal;
2929     }
2930 
slog(String s)2931     static void slog(String s) {
2932         Rlog.d("DC", s);
2933     }
2934 
2935     /**
2936      * Log with debug
2937      *
2938      * @param s is string log
2939      */
2940     @Override
log(String s)2941     protected void log(String s) {
2942         Rlog.d(getName(), s);
2943     }
2944 
2945     /**
2946      * Log with debug attribute
2947      *
2948      * @param s is string log
2949      */
2950     @Override
logd(String s)2951     protected void logd(String s) {
2952         Rlog.d(getName(), s);
2953     }
2954 
2955     /**
2956      * Log with verbose attribute
2957      *
2958      * @param s is string log
2959      */
2960     @Override
logv(String s)2961     protected void logv(String s) {
2962         Rlog.v(getName(), s);
2963     }
2964 
2965     /**
2966      * Log with info attribute
2967      *
2968      * @param s is string log
2969      */
2970     @Override
logi(String s)2971     protected void logi(String s) {
2972         Rlog.i(getName(), s);
2973     }
2974 
2975     /**
2976      * Log with warning attribute
2977      *
2978      * @param s is string log
2979      */
2980     @Override
logw(String s)2981     protected void logw(String s) {
2982         Rlog.w(getName(), s);
2983     }
2984 
2985     /**
2986      * Log with error attribute
2987      *
2988      * @param s is string log
2989      */
2990     @Override
loge(String s)2991     protected void loge(String s) {
2992         Rlog.e(getName(), s);
2993     }
2994 
2995     /**
2996      * Log with error attribute
2997      *
2998      * @param s is string log
2999      * @param e is a Throwable which logs additional information.
3000      */
3001     @Override
loge(String s, Throwable e)3002     protected void loge(String s, Throwable e) {
3003         Rlog.e(getName(), s, e);
3004     }
3005 
3006     /** Doesn't print mApnList of ApnContext's which would be recursive */
toStringSimple()3007     public String toStringSimple() {
3008         return getName() + ": State=" + getCurrentState().getName()
3009                 + " mApnSetting=" + mApnSetting + " RefCount=" + mApnContexts.size()
3010                 + " mCid=" + mCid + " mCreateTime=" + mCreateTime
3011                 + " mLastastFailTime=" + mLastFailTime
3012                 + " mLastFailCause=" + mLastFailCause
3013                 + " mTag=" + mTag
3014                 + " mLinkProperties=" + mLinkProperties
3015                 + " linkCapabilities=" + getNetworkCapabilities()
3016                 + " mRestrictedNetworkOverride=" + mRestrictedNetworkOverride;
3017     }
3018 
3019     @Override
toString()3020     public String toString() {
3021         return "{" + toStringSimple() + " mApnContexts=" + mApnContexts + "}";
3022     }
3023 
3024     /** Check if the device is connected to NR 5G Non-Standalone network. */
isNRConnected()3025     private boolean isNRConnected() {
3026         return mPhone.getServiceState().getNrState()
3027                 == NetworkRegistrationInfo.NR_STATE_CONNECTED;
3028     }
3029 
3030     /**
3031      * @return The disallowed APN types bitmask
3032      */
getDisallowedApnTypes()3033     private @ApnType int getDisallowedApnTypes() {
3034         CarrierConfigManager configManager = (CarrierConfigManager)
3035                 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
3036         int apnTypesBitmask = 0;
3037         if (configManager != null) {
3038             PersistableBundle bundle = configManager.getConfigForSubId(mSubId);
3039             if (bundle != null) {
3040                 String key = (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
3041                         ? CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY
3042                         : CarrierConfigManager.KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY;
3043                 if (bundle.getStringArray(key) != null) {
3044                     String disallowedApnTypesString =
3045                             TextUtils.join(",", bundle.getStringArray(key));
3046                     if (!TextUtils.isEmpty(disallowedApnTypesString)) {
3047                         apnTypesBitmask = ApnSetting.getApnTypesBitmaskFromString(
3048                                 disallowedApnTypesString);
3049                     }
3050                 }
3051             }
3052         }
3053 
3054         return apnTypesBitmask;
3055     }
3056 
dumpToLog()3057     private void dumpToLog() {
3058         dump(null, new PrintWriter(new StringWriter(0)) {
3059             @Override
3060             public void println(String s) {
3061                 DataConnection.this.logd(s);
3062             }
3063 
3064             @Override
3065             public void flush() {
3066             }
3067         }, null);
3068     }
3069 
3070     /**
3071      *  Re-calculate score and update through network agent if it changes.
3072      */
updateScore()3073     private void updateScore() {
3074         int oldScore = mScore;
3075         mScore = calculateScore();
3076         if (oldScore != mScore && mNetworkAgent != null) {
3077             log("Updating score from " + oldScore + " to " + mScore);
3078             mNetworkAgent.sendNetworkScore(mScore, this);
3079         }
3080     }
3081 
calculateScore()3082     private int calculateScore() {
3083         int score = OTHER_CONNECTION_SCORE;
3084 
3085         // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have
3086         // specify a subId, this dataConnection is considered to be default Internet data
3087         // connection. In this case we assign a slightly higher score of 50. The intention is
3088         // it will not be replaced by other data connections accidentally in DSDS usecase.
3089         for (ApnContext apnContext : mApnContexts.keySet()) {
3090             for (NetworkRequest networkRequest : apnContext.getNetworkRequests()) {
3091                 if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
3092                         && networkRequest.getNetworkSpecifier() == null) {
3093                     score = DEFAULT_INTERNET_CONNECTION_SCORE;
3094                     break;
3095                 }
3096             }
3097         }
3098 
3099         return score;
3100     }
3101 
handoverStateToString(@andoverState int state)3102     private String handoverStateToString(@HandoverState int state) {
3103         switch (state) {
3104             case HANDOVER_STATE_IDLE: return "IDLE";
3105             case HANDOVER_STATE_BEING_TRANSFERRED: return "BEING_TRANSFERRED";
3106             case HANDOVER_STATE_COMPLETED: return "COMPLETED";
3107             default: return "UNKNOWN";
3108         }
3109     }
3110 
3111     /**
3112      * Dump the current state.
3113      *
3114      * @param fd
3115      * @param pw
3116      * @param args
3117      */
3118     @Override
dump(FileDescriptor fd, PrintWriter printWriter, String[] args)3119     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
3120         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
3121         pw.print("DataConnection ");
3122         super.dump(fd, pw, args);
3123         pw.flush();
3124         pw.increaseIndent();
3125         pw.println("transport type="
3126                 + AccessNetworkConstants.transportTypeToString(mTransportType));
3127         pw.println("mApnContexts.size=" + mApnContexts.size());
3128         pw.println("mApnContexts=" + mApnContexts);
3129         pw.println("mApnSetting=" + mApnSetting);
3130         pw.println("mTag=" + mTag);
3131         pw.println("mCid=" + mCid);
3132         pw.println("mConnectionParams=" + mConnectionParams);
3133         pw.println("mDisconnectParams=" + mDisconnectParams);
3134         pw.println("mDcFailCause=" + mDcFailCause);
3135         pw.println("mPhone=" + mPhone);
3136         pw.println("mSubId=" + mSubId);
3137         pw.println("mLinkProperties=" + mLinkProperties);
3138         pw.flush();
3139         pw.println("mDataRegState=" + mDataRegState);
3140         pw.println("mHandoverState=" + handoverStateToString(mHandoverState));
3141         pw.println("mRilRat=" + mRilRat);
3142         pw.println("mNetworkCapabilities=" + getNetworkCapabilities());
3143         pw.println("mCreateTime=" + TimeUtils.logTimeOfDay(mCreateTime));
3144         pw.println("mLastFailTime=" + TimeUtils.logTimeOfDay(mLastFailTime));
3145         pw.println("mLastFailCause=" + mLastFailCause);
3146         pw.println("mUserData=" + mUserData);
3147         pw.println("mSubscriptionOverride=" + Integer.toHexString(mSubscriptionOverride));
3148         pw.println("mRestrictedNetworkOverride=" + mRestrictedNetworkOverride);
3149         pw.println("mUnmeteredUseOnly=" + mUnmeteredUseOnly);
3150         pw.println("mUnmeteredOverride=" + mUnmeteredOverride);
3151         pw.println("mDownlinkBandwidth" + mDownlinkBandwidth);
3152         pw.println("mUplinkBandwidth=" + mUplinkBandwidth);
3153         pw.println("disallowedApnTypes="
3154                 + ApnSetting.getApnTypesStringFromBitmask(getDisallowedApnTypes()));
3155         pw.println("mInstanceNumber=" + mInstanceNumber);
3156         pw.println("mAc=" + mAc);
3157         pw.println("mScore=" + mScore);
3158         if (mNetworkAgent != null) {
3159             mNetworkAgent.dump(fd, pw, args);
3160         }
3161         pw.println("handover local log:");
3162         pw.increaseIndent();
3163         mHandoverLocalLog.dump(fd, pw, args);
3164         pw.decreaseIndent();
3165         pw.decreaseIndent();
3166         pw.println();
3167         pw.flush();
3168     }
3169 }
3170 
3171