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