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