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