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