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.telephony.data.DataCallResponse.PDU_SESSION_ID_NOT_SET; 20 21 import static com.android.internal.telephony.dataconnection.DcTracker.REQUEST_TYPE_HANDOVER; 22 23 import android.annotation.IntDef; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.app.PendingIntent; 27 import android.content.Context; 28 import android.content.pm.PackageManager; 29 import android.content.pm.PackageManager.NameNotFoundException; 30 import android.content.pm.UserInfo; 31 import android.net.ConnectivityManager; 32 import android.net.InetAddresses; 33 import android.net.KeepalivePacketData; 34 import android.net.LinkAddress; 35 import android.net.LinkProperties; 36 import android.net.NetworkAgentConfig; 37 import android.net.NetworkCapabilities; 38 import android.net.NetworkFactory; 39 import android.net.NetworkProvider; 40 import android.net.NetworkRequest; 41 import android.net.ProxyInfo; 42 import android.net.RouteInfo; 43 import android.net.SocketKeepalive; 44 import android.net.TelephonyNetworkSpecifier; 45 import android.net.vcn.VcnManager; 46 import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener; 47 import android.net.vcn.VcnNetworkPolicyResult; 48 import android.os.AsyncResult; 49 import android.os.HandlerExecutor; 50 import android.os.Message; 51 import android.os.PersistableBundle; 52 import android.os.Process; 53 import android.os.SystemClock; 54 import android.os.SystemProperties; 55 import android.os.UserManager; 56 import android.provider.Telephony; 57 import android.telephony.AccessNetworkConstants; 58 import android.telephony.AccessNetworkConstants.TransportType; 59 import android.telephony.Annotation.ApnType; 60 import android.telephony.Annotation.DataFailureCause; 61 import android.telephony.Annotation.DataState; 62 import android.telephony.Annotation.NetworkType; 63 import android.telephony.CarrierConfigManager; 64 import android.telephony.DataFailCause; 65 import android.telephony.LinkCapacityEstimate; 66 import android.telephony.NetworkRegistrationInfo; 67 import android.telephony.PreciseDataConnectionState; 68 import android.telephony.ServiceState; 69 import android.telephony.SubscriptionManager; 70 import android.telephony.TelephonyManager; 71 import android.telephony.data.ApnSetting; 72 import android.telephony.data.DataCallResponse; 73 import android.telephony.data.DataCallResponse.HandoverFailureMode; 74 import android.telephony.data.DataProfile; 75 import android.telephony.data.DataService; 76 import android.telephony.data.DataServiceCallback; 77 import android.telephony.data.NetworkSliceInfo; 78 import android.telephony.data.Qos; 79 import android.telephony.data.QosBearerSession; 80 import android.telephony.data.TrafficDescriptor; 81 import android.text.TextUtils; 82 import android.util.LocalLog; 83 import android.util.Pair; 84 import android.util.TimeUtils; 85 86 import com.android.internal.annotations.VisibleForTesting; 87 import com.android.internal.telephony.CarrierPrivilegesTracker; 88 import com.android.internal.telephony.CarrierSignalAgent; 89 import com.android.internal.telephony.DctConstants; 90 import com.android.internal.telephony.Phone; 91 import com.android.internal.telephony.PhoneConstants; 92 import com.android.internal.telephony.PhoneFactory; 93 import com.android.internal.telephony.RIL; 94 import com.android.internal.telephony.RILConstants; 95 import com.android.internal.telephony.RetryManager; 96 import com.android.internal.telephony.TelephonyStatsLog; 97 import com.android.internal.telephony.data.DataConfigManager; 98 import com.android.internal.telephony.data.KeepaliveStatus; 99 import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType; 100 import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType; 101 import com.android.internal.telephony.metrics.DataCallSessionStats; 102 import com.android.internal.telephony.metrics.TelephonyMetrics; 103 import com.android.internal.telephony.nano.TelephonyProto.RilDataCall; 104 import com.android.internal.telephony.uicc.IccUtils; 105 import com.android.internal.telephony.util.ArrayUtils; 106 import com.android.internal.util.AsyncChannel; 107 import com.android.internal.util.IndentingPrintWriter; 108 import com.android.internal.util.Protocol; 109 import com.android.internal.util.State; 110 import com.android.internal.util.StateMachine; 111 import com.android.net.module.util.NetworkCapabilitiesUtils; 112 import com.android.telephony.Rlog; 113 114 import java.io.FileDescriptor; 115 import java.io.PrintWriter; 116 import java.io.StringWriter; 117 import java.lang.annotation.Retention; 118 import java.lang.annotation.RetentionPolicy; 119 import java.net.InetAddress; 120 import java.net.UnknownHostException; 121 import java.nio.ByteBuffer; 122 import java.util.ArrayList; 123 import java.util.Arrays; 124 import java.util.Collection; 125 import java.util.Collections; 126 import java.util.List; 127 import java.util.Locale; 128 import java.util.Map; 129 import java.util.UUID; 130 import java.util.concurrent.ConcurrentHashMap; 131 import java.util.concurrent.atomic.AtomicInteger; 132 import java.util.function.Consumer; 133 134 /** 135 * {@hide} 136 * 137 * DataConnection StateMachine. 138 * 139 * This a class for representing a single data connection, with instances of this 140 * class representing a connection via the cellular network. There may be multiple 141 * data connections and all of them are managed by the <code>DataConnectionTracker</code>. 142 * 143 * NOTE: All DataConnection objects must be running on the same looper, which is the default 144 * as the coordinator has members which are used without synchronization. 145 */ 146 public class DataConnection extends StateMachine { 147 private static final boolean DBG = true; 148 private static final boolean VDBG = true; 149 150 private static final String NETWORK_TYPE = "MOBILE"; 151 152 private static final String RAT_NAME_5G = "nr"; 153 private static final String RAT_NAME_EVDO = "evdo"; 154 155 /** 156 * OSId for "Android", using UUID version 5 with namespace ISO OSI. 157 * Prepended to the OsAppId in TrafficDescriptor to use for URSP matching. 158 */ 159 private static final UUID OS_ID = UUID.fromString("97a498e3-fc92-5c94-8986-0333d06e4e47"); 160 161 /** 162 * The data connection is not being or been handovered. Note this is the state for the source 163 * data connection, not destination data connection 164 */ 165 private static final int HANDOVER_STATE_IDLE = 1; 166 167 /** 168 * The data connection is being handovered. Note this is the state for the source 169 * data connection, not destination data connection. 170 */ 171 private static final int HANDOVER_STATE_BEING_TRANSFERRED = 2; 172 173 /** 174 * The data connection is already handovered. Note this is the state for the source 175 * data connection, not destination data connection. 176 */ 177 private static final int HANDOVER_STATE_COMPLETED = 3; 178 179 180 /** @hide */ 181 @Retention(RetentionPolicy.SOURCE) 182 @IntDef(prefix = {"HANDOVER_STATE_"}, value = { 183 HANDOVER_STATE_IDLE, 184 HANDOVER_STATE_BEING_TRANSFERRED, 185 HANDOVER_STATE_COMPLETED}) 186 public @interface HandoverState {} 187 188 // The data connection providing default Internet connection will have a higher score of 50. 189 // Other connections will have a slightly lower score of 45. The intention is other connections 190 // will not cause ConnectivityService to tear down default internet connection. For example, 191 // to validate Internet connection on non-default data SIM, we'll set up a temporary Internet 192 // connection on that data SIM. In this case, score of 45 is assigned so ConnectivityService 193 // will not replace the default Internet connection with it. 194 private static final int DEFAULT_INTERNET_CONNECTION_SCORE = 50; 195 private static final int OTHER_CONNECTION_SCORE = 45; 196 197 // The score we report to connectivity service 198 private int mScore; 199 200 // The subscription id associated with this data connection. 201 private int mSubId; 202 203 // The data connection controller 204 private DcController mDcController; 205 206 // The Tester for failing all bringup's 207 private DcTesterFailBringUpAll mDcTesterFailBringUpAll; 208 209 // Whether or not the data connection should allocate its own pdu session id 210 private boolean mDoAllocatePduSessionId; 211 212 private static AtomicInteger mInstanceNumber = new AtomicInteger(0); 213 private AsyncChannel mAc; 214 215 // The DCT that's talking to us, we only support one! 216 private DcTracker mDct = null; 217 218 private String[] mPcscfAddr; 219 220 private final String mTagSuffix; 221 222 private final LocalLog mHandoverLocalLog = new LocalLog(64); 223 224 private int[] mAdministratorUids = new int[0]; 225 226 // stats per data call 227 private DataCallSessionStats mDataCallSessionStats; 228 229 /** 230 * Used internally for saving connecting parameters. 231 */ 232 public static class ConnectionParams { 233 int mTag; 234 ApnContext mApnContext; 235 int mProfileId; 236 int mRilRat; 237 Message mOnCompletedMsg; 238 final int mConnectionGeneration; 239 @RequestNetworkType 240 final int mRequestType; 241 final int mSubId; 242 final boolean mIsPreferredApn; 243 ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isPreferredApn)244 ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology, 245 Message onCompletedMsg, int connectionGeneration, 246 @RequestNetworkType int requestType, int subId, 247 boolean isPreferredApn) { 248 mApnContext = apnContext; 249 mProfileId = profileId; 250 mRilRat = rilRadioTechnology; 251 mOnCompletedMsg = onCompletedMsg; 252 mConnectionGeneration = connectionGeneration; 253 mRequestType = requestType; 254 mSubId = subId; 255 mIsPreferredApn = isPreferredApn; 256 } 257 258 @Override toString()259 public String toString() { 260 return "{mTag=" + mTag + " mApnContext=" + mApnContext 261 + " mProfileId=" + mProfileId 262 + " mRat=" + mRilRat 263 + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) 264 + " mRequestType=" + DcTracker.requestTypeToString(mRequestType) 265 + " mSubId=" + mSubId 266 + " mIsPreferredApn=" + mIsPreferredApn 267 + "}"; 268 } 269 } 270 271 /** 272 * Used internally for saving disconnecting parameters. 273 */ 274 public static class DisconnectParams { 275 int mTag; 276 public ApnContext mApnContext; 277 String mReason; 278 @ReleaseNetworkType 279 final int mReleaseType; 280 Message mOnCompletedMsg; 281 DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)282 DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType, 283 Message onCompletedMsg) { 284 mApnContext = apnContext; 285 mReason = reason; 286 mReleaseType = releaseType; 287 mOnCompletedMsg = onCompletedMsg; 288 } 289 290 @Override toString()291 public String toString() { 292 return "{mTag=" + mTag + " mApnContext=" + mApnContext 293 + " mReason=" + mReason 294 + " mReleaseType=" + DcTracker.releaseTypeToString(mReleaseType) 295 + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) + "}"; 296 } 297 } 298 299 private volatile ApnSetting mApnSetting; 300 private ConnectionParams mConnectionParams; 301 private DisconnectParams mDisconnectParams; 302 @DataFailureCause 303 private int mDcFailCause; 304 305 @HandoverFailureMode 306 private int mHandoverFailureMode; 307 308 private Phone mPhone; 309 private DataServiceManager mDataServiceManager; 310 private VcnManager mVcnManager; 311 private final int mTransportType; 312 private LinkProperties mLinkProperties = new LinkProperties(); 313 private int mPduSessionId; 314 private long mCreateTime; 315 private long mLastFailTime; 316 @DataFailureCause 317 private int mLastFailCause; 318 private static final String NULL_IP = "0.0.0.0"; 319 private Object mUserData; 320 private boolean mCongestedOverride; 321 private boolean mUnmeteredOverride; 322 private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; 323 private int mDataRegState = Integer.MAX_VALUE; 324 // Indicating data connection is suspended due to temporary reasons, for example, out of 325 // service, concurrency voice/data not supported, etc.. Note this flag is only meaningful when 326 // data is in active state. When data is in inactive, connecting, or disconnecting, this flag 327 // is unmeaningful. 328 private boolean mIsSuspended; 329 private int mDownlinkBandwidth = 14; 330 private int mUplinkBandwidth = 14; 331 private Qos mDefaultQos = null; 332 private List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); 333 private NetworkSliceInfo mSliceInfo; 334 private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>(); 335 336 /** The corresponding network agent for this data connection. */ 337 private DcNetworkAgent mNetworkAgent; 338 339 /** 340 * The network agent from handover source data connection. This is the potential network agent 341 * that will be transferred here after handover completed. 342 */ 343 private DcNetworkAgent mHandoverSourceNetworkAgent; 344 345 private int mDisabledApnTypeBitMask = 0; 346 347 int mTag; 348 349 /** Data connection id assigned by the modem. This is unique across transports */ 350 public int mCid; 351 352 @HandoverState 353 private int mHandoverState = HANDOVER_STATE_IDLE; 354 private final Map<ApnContext, ConnectionParams> mApnContexts = new ConcurrentHashMap<>(); 355 PendingIntent mReconnectIntent = null; 356 357 /** Class used to track VCN-defined Network policies for this DcNetworkAgent. */ 358 private final VcnNetworkPolicyChangeListener mVcnPolicyChangeListener = 359 new DataConnectionVcnNetworkPolicyChangeListener(); 360 361 // ***** Event codes for driving the state machine, package visible for Dcc 362 static final int BASE = Protocol.BASE_DATA_CONNECTION; 363 static final int EVENT_CONNECT = BASE + 0; 364 static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1; 365 static final int EVENT_DEACTIVATE_DONE = BASE + 3; 366 static final int EVENT_DISCONNECT = BASE + 4; 367 static final int EVENT_DISCONNECT_ALL = BASE + 6; 368 static final int EVENT_DATA_STATE_CHANGED = BASE + 7; 369 static final int EVENT_TEAR_DOWN_NOW = BASE + 8; 370 static final int EVENT_LOST_CONNECTION = BASE + 9; 371 static final int EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED = BASE + 11; 372 static final int EVENT_DATA_CONNECTION_ROAM_ON = BASE + 12; 373 static final int EVENT_DATA_CONNECTION_ROAM_OFF = BASE + 13; 374 static final int EVENT_BW_REFRESH_RESPONSE = BASE + 14; 375 static final int EVENT_DATA_CONNECTION_VOICE_CALL_STARTED = BASE + 15; 376 static final int EVENT_DATA_CONNECTION_VOICE_CALL_ENDED = BASE + 16; 377 static final int EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED = BASE + 17; 378 static final int EVENT_KEEPALIVE_STATUS = BASE + 18; 379 static final int EVENT_KEEPALIVE_STARTED = BASE + 19; 380 static final int EVENT_KEEPALIVE_STOPPED = BASE + 20; 381 static final int EVENT_KEEPALIVE_START_REQUEST = BASE + 21; 382 static final int EVENT_KEEPALIVE_STOP_REQUEST = BASE + 22; 383 static final int EVENT_LINK_CAPACITY_CHANGED = BASE + 23; 384 static final int EVENT_RESET = BASE + 24; 385 static final int EVENT_REEVALUATE_RESTRICTED_STATE = BASE + 25; 386 static final int EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES = BASE + 26; 387 static final int EVENT_NR_STATE_CHANGED = BASE + 27; 388 static final int EVENT_DATA_CONNECTION_METEREDNESS_CHANGED = BASE + 28; 389 static final int EVENT_NR_FREQUENCY_CHANGED = BASE + 29; 390 static final int EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED = BASE + 30; 391 static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = BASE + 31; 392 static final int EVENT_CSS_INDICATOR_CHANGED = BASE + 32; 393 static final int EVENT_UPDATE_SUSPENDED_STATE = BASE + 33; 394 static final int EVENT_START_HANDOVER = BASE + 34; 395 static final int EVENT_CANCEL_HANDOVER = BASE + 35; 396 static final int EVENT_START_HANDOVER_ON_TARGET = BASE + 36; 397 static final int EVENT_ALLOCATE_PDU_SESSION_ID = BASE + 37; 398 static final int EVENT_RELEASE_PDU_SESSION_ID = BASE + 38; 399 static final int EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE = BASE + 39; 400 private static final int CMD_TO_STRING_COUNT = EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE - BASE + 1; 401 402 private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT]; 403 static { 404 sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT"; 405 sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] = 406 "EVENT_SETUP_DATA_CONNECTION_DONE"; 407 sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE"; 408 sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT"; 409 sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL"; 410 sCmdToString[EVENT_DATA_STATE_CHANGED - BASE] = "EVENT_DATA_STATE_CHANGED"; 411 sCmdToString[EVENT_TEAR_DOWN_NOW - BASE] = "EVENT_TEAR_DOWN_NOW"; 412 sCmdToString[EVENT_LOST_CONNECTION - BASE] = "EVENT_LOST_CONNECTION"; 413 sCmdToString[EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED - BASE] = 414 "EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"; 415 sCmdToString[EVENT_DATA_CONNECTION_ROAM_ON - BASE] = "EVENT_DATA_CONNECTION_ROAM_ON"; 416 sCmdToString[EVENT_DATA_CONNECTION_ROAM_OFF - BASE] = "EVENT_DATA_CONNECTION_ROAM_OFF"; 417 sCmdToString[EVENT_BW_REFRESH_RESPONSE - BASE] = "EVENT_BW_REFRESH_RESPONSE"; 418 sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_STARTED - BASE] = 419 "EVENT_DATA_CONNECTION_VOICE_CALL_STARTED"; 420 sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_ENDED - BASE] = 421 "EVENT_DATA_CONNECTION_VOICE_CALL_ENDED"; 422 sCmdToString[EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED - BASE] = 423 "EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED"; 424 sCmdToString[EVENT_KEEPALIVE_STATUS - BASE] = "EVENT_KEEPALIVE_STATUS"; 425 sCmdToString[EVENT_KEEPALIVE_STARTED - BASE] = "EVENT_KEEPALIVE_STARTED"; 426 sCmdToString[EVENT_KEEPALIVE_STOPPED - BASE] = "EVENT_KEEPALIVE_STOPPED"; 427 sCmdToString[EVENT_KEEPALIVE_START_REQUEST - BASE] = "EVENT_KEEPALIVE_START_REQUEST"; 428 sCmdToString[EVENT_KEEPALIVE_STOP_REQUEST - BASE] = "EVENT_KEEPALIVE_STOP_REQUEST"; 429 sCmdToString[EVENT_LINK_CAPACITY_CHANGED - BASE] = "EVENT_LINK_CAPACITY_CHANGED"; 430 sCmdToString[EVENT_RESET - BASE] = "EVENT_RESET"; 431 sCmdToString[EVENT_REEVALUATE_RESTRICTED_STATE - BASE] = 432 "EVENT_REEVALUATE_RESTRICTED_STATE"; 433 sCmdToString[EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES - BASE] = 434 "EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES"; 435 sCmdToString[EVENT_NR_STATE_CHANGED - BASE] = "EVENT_NR_STATE_CHANGED"; 436 sCmdToString[EVENT_DATA_CONNECTION_METEREDNESS_CHANGED - BASE] = 437 "EVENT_DATA_CONNECTION_METEREDNESS_CHANGED"; 438 sCmdToString[EVENT_NR_FREQUENCY_CHANGED - BASE] = "EVENT_NR_FREQUENCY_CHANGED"; 439 sCmdToString[EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED - BASE] = 440 "EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED"; 441 sCmdToString[EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED - BASE] = 442 "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED"; 443 sCmdToString[EVENT_CSS_INDICATOR_CHANGED - BASE] = "EVENT_CSS_INDICATOR_CHANGED"; 444 sCmdToString[EVENT_UPDATE_SUSPENDED_STATE - BASE] = "EVENT_UPDATE_SUSPENDED_STATE"; 445 sCmdToString[EVENT_START_HANDOVER - BASE] = "EVENT_START_HANDOVER"; 446 sCmdToString[EVENT_CANCEL_HANDOVER - BASE] = "EVENT_CANCEL_HANDOVER"; 447 sCmdToString[EVENT_START_HANDOVER_ON_TARGET - BASE] = "EVENT_START_HANDOVER_ON_TARGET"; 448 sCmdToString[EVENT_ALLOCATE_PDU_SESSION_ID - BASE] = "EVENT_ALLOCATE_PDU_SESSION_ID"; 449 sCmdToString[EVENT_RELEASE_PDU_SESSION_ID - BASE] = "EVENT_RELEASE_PDU_SESSION_ID"; 450 sCmdToString[EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE - BASE] = 451 "EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE"; 452 } 453 // Convert cmd to string or null if unknown cmdToString(int cmd)454 static String cmdToString(int cmd) { 455 String value = null; 456 cmd -= BASE; 457 if ((cmd >= 0) && (cmd < sCmdToString.length)) { 458 value = sCmdToString[cmd]; 459 } 460 if (value == null) { 461 value = "0x" + Integer.toHexString(cmd + BASE); 462 } 463 return value; 464 } 465 466 /** 467 * Create the connection object 468 * 469 * @param phone the Phone 470 * @param id the connection id 471 * @return DataConnection that was created. 472 */ makeDataConnection(Phone phone, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc)473 public static DataConnection makeDataConnection(Phone phone, int id, DcTracker dct, 474 DataServiceManager dataServiceManager, 475 DcTesterFailBringUpAll failBringUpAll, 476 DcController dcc) { 477 String transportType = (dataServiceManager.getTransportType() 478 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 479 ? "C" // Cellular 480 : "I"; // IWLAN 481 DataConnection dc = new DataConnection(phone, transportType + "-" 482 + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll, 483 dcc); 484 dc.start(); 485 if (DBG) dc.log("Made " + dc.getName()); 486 return dc; 487 } 488 dispose()489 void dispose() { 490 log("dispose: call quiteNow()"); 491 quitNow(); 492 } 493 494 /* Getter functions */ 495 getLinkProperties()496 LinkProperties getLinkProperties() { 497 return new LinkProperties(mLinkProperties); 498 } 499 isDisconnecting()500 boolean isDisconnecting() { 501 return getCurrentState() == mDisconnectingState 502 || getCurrentState() == mDisconnectingErrorCreatingConnection; 503 } 504 505 @VisibleForTesting isActive()506 public boolean isActive() { 507 return getCurrentState() == mActiveState; 508 } 509 510 @VisibleForTesting isInactive()511 public boolean isInactive() { 512 return getCurrentState() == mInactiveState; 513 } 514 isActivating()515 boolean isActivating() { 516 return getCurrentState() == mActivatingState; 517 } 518 hasBeenTransferred()519 boolean hasBeenTransferred() { 520 return mHandoverState == HANDOVER_STATE_COMPLETED; 521 } 522 getCid()523 int getCid() { 524 return mCid; 525 } 526 527 /** 528 * @return DataConnection's ApnSetting. 529 */ getApnSetting()530 public ApnSetting getApnSetting() { 531 return mApnSetting; 532 } 533 534 /** 535 * Update http proxy of link properties based on current apn setting 536 */ updateLinkPropertiesHttpProxy()537 private void updateLinkPropertiesHttpProxy() { 538 if (mApnSetting == null 539 || TextUtils.isEmpty(mApnSetting.getProxyAddressAsString())) { 540 return; 541 } 542 try { 543 int port = mApnSetting.getProxyPort(); 544 if (port == -1) { 545 port = 8080; 546 } 547 ProxyInfo proxy = ProxyInfo.buildDirectProxy( 548 mApnSetting.getProxyAddressAsString(), port); 549 mLinkProperties.setHttpProxy(proxy); 550 } catch (NumberFormatException e) { 551 loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" 552 + mApnSetting.getProxyPort() + "): " + e); 553 } 554 } 555 556 public static class UpdateLinkPropertyResult { 557 public SetupResult setupResult = SetupResult.SUCCESS; 558 public LinkProperties oldLp; 559 public LinkProperties newLp; UpdateLinkPropertyResult(LinkProperties curLp)560 public UpdateLinkPropertyResult(LinkProperties curLp) { 561 oldLp = curLp; 562 newLp = curLp; 563 } 564 } 565 566 /** 567 * Class returned by onSetupConnectionCompleted. 568 */ 569 public enum SetupResult { 570 SUCCESS, 571 ERROR_RADIO_NOT_AVAILABLE, 572 ERROR_INVALID_ARG, 573 ERROR_STALE, 574 ERROR_DATA_SERVICE_SPECIFIC_ERROR, 575 ERROR_DUPLICATE_CID, 576 ERROR_NO_DEFAULT_CONNECTION; 577 578 public int mFailCause; 579 SetupResult()580 SetupResult() { 581 mFailCause = DataFailCause.getFailCause(0); 582 } 583 584 @Override toString()585 public String toString() { 586 return name() + " SetupResult.mFailCause=" + DataFailCause.toString(mFailCause); 587 } 588 } 589 isIpv4Connected()590 public boolean isIpv4Connected() { 591 boolean ret = false; 592 Collection <InetAddress> addresses = mLinkProperties.getAddresses(); 593 594 for (InetAddress addr: addresses) { 595 if (addr instanceof java.net.Inet4Address) { 596 java.net.Inet4Address i4addr = (java.net.Inet4Address) addr; 597 if (!i4addr.isAnyLocalAddress() && !i4addr.isLinkLocalAddress() && 598 !i4addr.isLoopbackAddress() && !i4addr.isMulticastAddress()) { 599 ret = true; 600 break; 601 } 602 } 603 } 604 return ret; 605 } 606 isIpv6Connected()607 public boolean isIpv6Connected() { 608 boolean ret = false; 609 Collection <InetAddress> addresses = mLinkProperties.getAddresses(); 610 611 for (InetAddress addr: addresses) { 612 if (addr instanceof java.net.Inet6Address) { 613 java.net.Inet6Address i6addr = (java.net.Inet6Address) addr; 614 if (!i6addr.isAnyLocalAddress() && !i6addr.isLinkLocalAddress() && 615 !i6addr.isLoopbackAddress() && !i6addr.isMulticastAddress()) { 616 ret = true; 617 break; 618 } 619 } 620 } 621 return ret; 622 } 623 getPduSessionId()624 public int getPduSessionId() { 625 return mPduSessionId; 626 } 627 getSliceInfo()628 public NetworkSliceInfo getSliceInfo() { 629 return mSliceInfo; 630 } 631 getTrafficDescriptors()632 public List<TrafficDescriptor> getTrafficDescriptors() { 633 return mTrafficDescriptors; 634 } 635 636 /** 637 * Update DC fields based on a new DataCallResponse 638 * @param response the response to use to update DC fields 639 */ updateResponseFields(DataCallResponse response)640 public void updateResponseFields(DataCallResponse response) { 641 updateQosParameters(response); 642 updateSliceInfo(response); 643 updateTrafficDescriptors(response); 644 } 645 updateQosParameters(final @Nullable DataCallResponse response)646 public void updateQosParameters(final @Nullable DataCallResponse response) { 647 if (response == null) { 648 mDefaultQos = null; 649 mQosBearerSessions.clear(); 650 return; 651 } 652 653 mDefaultQos = response.getDefaultQos(); 654 mQosBearerSessions = response.getQosBearerSessions(); 655 656 if (mNetworkAgent != null) { 657 syncQosToNetworkAgent(); 658 } 659 } 660 syncQosToNetworkAgent()661 private void syncQosToNetworkAgent() { 662 final DcNetworkAgent networkAgent = mNetworkAgent; 663 final List<QosBearerSession> qosBearerSessions = mQosBearerSessions; 664 if (qosBearerSessions == null) { 665 networkAgent.updateQosBearerSessions(new ArrayList<>()); 666 return; 667 } 668 networkAgent.updateQosBearerSessions(qosBearerSessions); 669 } 670 671 /** 672 * Update the latest slice info on this data connection with 673 * {@link DataCallResponse#getSliceInfo}. 674 */ updateSliceInfo(DataCallResponse response)675 public void updateSliceInfo(DataCallResponse response) { 676 mSliceInfo = response.getSliceInfo(); 677 } 678 679 /** 680 * Update the latest traffic descriptor on this data connection with 681 * {@link DataCallResponse#getTrafficDescriptors}. 682 */ updateTrafficDescriptors(DataCallResponse response)683 public void updateTrafficDescriptors(DataCallResponse response) { 684 mTrafficDescriptors = response.getTrafficDescriptors(); 685 mDcController.updateTrafficDescriptorsForCid(response.getId(), 686 response.getTrafficDescriptors()); 687 } 688 689 @VisibleForTesting updateLinkProperty(DataCallResponse newState)690 public UpdateLinkPropertyResult updateLinkProperty(DataCallResponse newState) { 691 UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties); 692 693 if (newState == null) return result; 694 695 result.newLp = new LinkProperties(); 696 697 // set link properties based on data call response 698 result.setupResult = setLinkProperties(newState, result.newLp); 699 if (result.setupResult != SetupResult.SUCCESS) { 700 if (DBG) log("updateLinkProperty failed : " + result.setupResult); 701 return result; 702 } 703 // copy HTTP proxy as it is not part DataCallResponse. 704 result.newLp.setHttpProxy(mLinkProperties.getHttpProxy()); 705 706 checkSetMtu(mApnSetting, result.newLp); 707 708 mLinkProperties = result.newLp; 709 710 updateTcpBufferSizes(mRilRat); 711 712 if (DBG && (! result.oldLp.equals(result.newLp))) { 713 log("updateLinkProperty old LP=" + result.oldLp); 714 log("updateLinkProperty new LP=" + result.newLp); 715 } 716 717 if (result.newLp.equals(result.oldLp) == false && 718 mNetworkAgent != null) { 719 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 720 } 721 722 return result; 723 } 724 725 /** 726 * Sets the pdu session id of the data connection 727 * @param pduSessionId pdu session id to set 728 */ 729 @VisibleForTesting setPduSessionId(int pduSessionId)730 public void setPduSessionId(int pduSessionId) { 731 if (mPduSessionId != pduSessionId) { 732 logd("Changing pdu session id from: " + mPduSessionId + " to: " + pduSessionId + ", " 733 + "Handover state: " + handoverStateToString(this.mHandoverState)); 734 mPduSessionId = pduSessionId; 735 } 736 } 737 738 /** 739 * Read the MTU value from link properties where it can be set from network. In case 740 * not set by the network, set it again using the mtu szie value defined in the APN 741 * database for the connected APN 742 */ checkSetMtu(ApnSetting apn, LinkProperties lp)743 private void checkSetMtu(ApnSetting apn, LinkProperties lp) { 744 if (lp == null) return; 745 746 if (apn == null || lp == null) return; 747 748 if (lp.getMtu() != PhoneConstants.UNSET_MTU) { 749 if (DBG) log("MTU set by call response to: " + lp.getMtu()); 750 return; 751 } 752 753 if (apn != null && apn.getMtuV4() != PhoneConstants.UNSET_MTU) { 754 lp.setMtu(apn.getMtuV4()); 755 if (DBG) log("MTU set by APN to: " + apn.getMtuV4()); 756 return; 757 } 758 759 int mtu = mPhone.getContext().getResources().getInteger( 760 com.android.internal.R.integer.config_mobile_mtu); 761 if (mtu != PhoneConstants.UNSET_MTU) { 762 lp.setMtu(mtu); 763 if (DBG) log("MTU set by config resource to: " + mtu); 764 } 765 } 766 767 //***** Constructor (NOTE: uses dcc.getHandler() as its Handler) DataConnection(Phone phone, String tagSuffix, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc)768 private DataConnection(Phone phone, String tagSuffix, int id, 769 DcTracker dct, DataServiceManager dataServiceManager, 770 DcTesterFailBringUpAll failBringUpAll, DcController dcc) { 771 super("DC-" + tagSuffix, dcc); 772 mTagSuffix = tagSuffix; 773 setLogRecSize(300); 774 setLogOnlyTransitions(true); 775 if (DBG) log("DataConnection created"); 776 777 mPhone = phone; 778 mDct = dct; 779 mDataServiceManager = dataServiceManager; 780 mVcnManager = mPhone.getContext().getSystemService(VcnManager.class); 781 mTransportType = dataServiceManager.getTransportType(); 782 mDcTesterFailBringUpAll = failBringUpAll; 783 mDcController = dcc; 784 mId = id; 785 mCid = -1; 786 mDataRegState = mPhone.getServiceState().getDataRegistrationState(); 787 mIsSuspended = false; 788 mDataCallSessionStats = new DataCallSessionStats(mPhone); 789 mDoAllocatePduSessionId = false; 790 791 int networkType = getNetworkType(); 792 mRilRat = ServiceState.networkTypeToRilRadioTechnology(networkType); 793 updateLinkBandwidthsFromCarrierConfig(mRilRat); 794 795 addState(mDefaultState); 796 addState(mInactiveState, mDefaultState); 797 addState(mActivatingState, mDefaultState); 798 addState(mActiveState, mDefaultState); 799 addState(mDisconnectingState, mDefaultState); 800 addState(mDisconnectingErrorCreatingConnection, mDefaultState); 801 setInitialState(mInactiveState); 802 } 803 getNetworkType()804 private @NetworkType int getNetworkType() { 805 ServiceState ss = mPhone.getServiceState(); 806 int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 807 808 NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo( 809 NetworkRegistrationInfo.DOMAIN_PS, mTransportType); 810 if (nri != null) { 811 networkType = nri.getAccessNetworkTechnology(); 812 } 813 814 return networkType; 815 } 816 817 /** 818 * Get the source transport for handover. For example, handover from WWAN to WLAN, WWAN is the 819 * source transport, and vice versa. 820 */ getHandoverSourceTransport()821 private @TransportType int getHandoverSourceTransport() { 822 return mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 823 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN 824 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN; 825 } 826 827 /** 828 * API to generate the OsAppId for enterprise traffic category. 829 * @return byte[] representing OsId + length of OsAppId + OsAppId 830 */ 831 @VisibleForTesting getEnterpriseOsAppId()832 public static byte[] getEnterpriseOsAppId() { 833 byte[] osAppId = NetworkCapabilities.getCapabilityCarrierName( 834 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE).getBytes(); 835 // 16 bytes for UUID, 1 byte for length of osAppId, and up to 255 bytes for osAppId 836 ByteBuffer bb = ByteBuffer.allocate(16 + 1 + osAppId.length); 837 bb.putLong(OS_ID.getMostSignificantBits()); 838 bb.putLong(OS_ID.getLeastSignificantBits()); 839 bb.put((byte) osAppId.length); 840 bb.put(osAppId); 841 if (VDBG) { 842 Rlog.d("DataConnection", "getEnterpriseOsAppId: " 843 + IccUtils.bytesToHexString(bb.array())); 844 } 845 return bb.array(); 846 } 847 848 /** 849 * Begin setting up a data connection, calls setupDataCall 850 * and the ConnectionParams will be returned with the 851 * EVENT_SETUP_DATA_CONNECTION_DONE 852 * 853 * @param cp is the connection parameters 854 * 855 * @return Fail cause if failed to setup data connection. {@link DataFailCause#NONE} if success. 856 */ connect(ConnectionParams cp)857 private @DataFailureCause int connect(ConnectionParams cp) { 858 log("connect: carrier='" + mApnSetting.getEntryName() 859 + "' APN='" + mApnSetting.getApnName() 860 + "' proxy='" + mApnSetting.getProxyAddressAsString() 861 + "' port='" + mApnSetting.getProxyPort() + "'"); 862 ApnContext.requestLog(cp.mApnContext, "DataConnection.connect"); 863 864 // Check if we should fake an error. 865 if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter > 0) { 866 DataCallResponse response = new DataCallResponse.Builder() 867 .setCause(mDcTesterFailBringUpAll.getDcFailBringUp().mFailCause) 868 .setRetryDurationMillis( 869 mDcTesterFailBringUpAll.getDcFailBringUp().mSuggestedRetryTime) 870 .setMtuV4(PhoneConstants.UNSET_MTU) 871 .setMtuV6(PhoneConstants.UNSET_MTU) 872 .build(); 873 874 Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp); 875 AsyncResult.forMessage(msg, response, null); 876 sendMessage(msg); 877 if (DBG) { 878 log("connect: FailBringUpAll=" + mDcTesterFailBringUpAll.getDcFailBringUp() 879 + " send error response=" + response); 880 } 881 mDcTesterFailBringUpAll.getDcFailBringUp().mCounter -= 1; 882 return DataFailCause.NONE; 883 } 884 885 mCreateTime = -1; 886 mLastFailTime = -1; 887 mLastFailCause = DataFailCause.NONE; 888 889 Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp); 890 msg.obj = cp; 891 892 DataProfile dp = new DataProfile.Builder() 893 .setApnSetting(mApnSetting) 894 .setPreferred(cp.mIsPreferredApn) 895 .build(); 896 897 // We need to use the actual modem roaming state instead of the framework roaming state 898 // here. This flag is only passed down to ril_service for picking the correct protocol (for 899 // old modem backward compatibility). 900 boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration(); 901 902 // If the apn is NOT metered, we will allow data roaming regardless of the setting. 903 boolean isUnmeteredApnType = !ApnSettingUtils.isMeteredApnType( 904 cp.mApnContext.getApnTypeBitmask(), mPhone); 905 906 // Set this flag to true if the user turns on data roaming. Or if we override the roaming 907 // state in framework, we should set this flag to true as well so the modem will not reject 908 // the data call setup (because the modem actually thinks the device is roaming). 909 boolean allowRoaming = mPhone.getDataRoamingEnabled() 910 || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming() 911 || isUnmeteredApnType)); 912 913 String dnn = null; 914 byte[] osAppId = null; 915 if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) { 916 osAppId = getEnterpriseOsAppId(); 917 } else { 918 dnn = mApnSetting.getApnName(); 919 } 920 final TrafficDescriptor td = osAppId == null && dnn == null ? null 921 : new TrafficDescriptor(dnn, osAppId); 922 final boolean matchAllRuleAllowed = td == null || td.getOsAppId() == null; 923 924 if (DBG) { 925 log("allowRoaming=" + allowRoaming 926 + ", mPhone.getDataRoamingEnabled()=" + mPhone.getDataRoamingEnabled() 927 + ", isModemRoaming=" + isModemRoaming 928 + ", mPhone.getServiceState().getDataRoaming()=" 929 + mPhone.getServiceState().getDataRoaming() 930 + ", isUnmeteredApnType=" + isUnmeteredApnType 931 + ", trafficDescriptor=" + td 932 + ", matchAllRuleAllowed=" + matchAllRuleAllowed 933 ); 934 } 935 936 // Check if this data setup is a handover. 937 LinkProperties linkProperties = null; 938 int reason = DataService.REQUEST_REASON_NORMAL; 939 if (cp.mRequestType == REQUEST_TYPE_HANDOVER) { 940 // If this is a data setup for handover, we need to pass the link properties 941 // of the existing data connection to the modem. 942 DcTracker srcDcTracker = mPhone.getDcTracker(getHandoverSourceTransport()); 943 if (srcDcTracker == null || cp.mApnContext == null) { 944 loge("connect: Handover failed. dcTracker=" + srcDcTracker + ", apnContext=" 945 + cp.mApnContext); 946 return DataFailCause.HANDOVER_FAILED; 947 } 948 949 950 // srcDc is the source data connection while the current instance is the target 951 DataConnection srcDc = 952 srcDcTracker.getDataConnectionByApnType(cp.mApnContext.getApnType()); 953 if (srcDc == null) { 954 loge("connect: Can't find data connection for handover."); 955 return DataFailCause.HANDOVER_FAILED; 956 } 957 958 // Helpful for logging purposes 959 DataServiceManager srcDsm = srcDc.mDataServiceManager; 960 String srcDsmTag = (srcDsm == null ? "(null)" : srcDsm.getTag()); 961 logd("connect: REQUEST_TYPE_HANDOVER - Request handover from " + srcDc.getName() 962 + ", targetDsm=" + mDataServiceManager.getTag() 963 + ", sourceDsm=" + srcDsmTag); 964 965 966 /* startHandover is called on the source data connection, and if successful, 967 we ask the target data connection (which is the current instance) to call 968 #setupDataCall with request type handover. 969 */ 970 Consumer<Integer> onCompleted = (dataServiceCallbackResultCode) -> 971 /* startHandover is called on the srcDc handler, but the callback needs to 972 be called on the current (which is the targetDc) handler which is why we 973 call sendRunnableMessage. */ 974 sendRunnableMessage(EVENT_START_HANDOVER_ON_TARGET, 975 (inCorrectState) -> requestHandover(inCorrectState, srcDc, 976 dataServiceCallbackResultCode, 977 cp, msg, dp, isModemRoaming, allowRoaming)); 978 srcDc.startHandover(onCompleted); 979 return DataFailCause.NONE; 980 } 981 982 // setup data call for REQUEST_TYPE_NORMAL 983 mDoAllocatePduSessionId = mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN; 984 allocatePduSessionId(psi -> { 985 this.setPduSessionId(psi); 986 mDataServiceManager.setupDataCall( 987 ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat), 988 dp, 989 isModemRoaming, 990 allowRoaming, 991 reason, 992 linkProperties, 993 psi, 994 null, //slice info is null since this is not a handover 995 td, 996 matchAllRuleAllowed, 997 msg); 998 TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat, 999 dp.getProfileId(), dp.getApn(), dp.getProtocolType()); 1000 }); 1001 return DataFailCause.NONE; 1002 } 1003 allocatePduSessionId(Consumer<Integer> allocateCallback)1004 private void allocatePduSessionId(Consumer<Integer> allocateCallback) { 1005 if (mDoAllocatePduSessionId) { 1006 Message msg = this.obtainMessage(EVENT_ALLOCATE_PDU_SESSION_ID); 1007 msg.obj = allocateCallback; 1008 mPhone.mCi.allocatePduSessionId(msg); 1009 } else { 1010 allocateCallback.accept(PDU_SESSION_ID_NOT_SET); 1011 } 1012 } 1013 onRquestHandoverFailed(ConnectionParams cp)1014 private void onRquestHandoverFailed(ConnectionParams cp) { 1015 sendMessage(obtainMessage(EVENT_CANCEL_HANDOVER)); 1016 notifyConnectCompleted(cp, DataFailCause.UNKNOWN, 1017 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 1018 } 1019 requestHandover(boolean inCorrectState, DataConnection srcDc, @DataServiceCallback.ResultCode int resultCode, ConnectionParams cp, Message msg, DataProfile dp, boolean isModemRoaming, boolean allowRoaming)1020 private void requestHandover(boolean inCorrectState, DataConnection srcDc, 1021 @DataServiceCallback.ResultCode int resultCode, 1022 ConnectionParams cp, Message msg, DataProfile dp, boolean isModemRoaming, 1023 boolean allowRoaming) { 1024 1025 if (!inCorrectState) { 1026 logd("requestHandover: Not in correct state"); 1027 if (isResultCodeSuccess(resultCode)) { 1028 if (srcDc != null) { 1029 logd("requestHandover: Not in correct state - Success result code"); 1030 // We need to cancel the handover on source if we ended up in the wrong state. 1031 srcDc.cancelHandover(); 1032 } else { 1033 logd("requestHandover: Not in correct state - Success result code - " 1034 + "srcdc = null"); 1035 } 1036 } 1037 onRquestHandoverFailed(cp); 1038 return; 1039 } else if (!isResultCodeSuccess(resultCode)) { 1040 if (DBG) { 1041 logd("requestHandover: Non success result code from DataService, " 1042 + "setupDataCall will not be called, result code = " 1043 + DataServiceCallback.resultCodeToString(resultCode)); 1044 } 1045 onRquestHandoverFailed(cp); 1046 return; 1047 } 1048 1049 if (srcDc == null) { 1050 loge("requestHandover: Cannot find source data connection."); 1051 onRquestHandoverFailed(cp); 1052 return; 1053 } 1054 1055 LinkProperties linkProperties; 1056 int reason; 1057 1058 // Preserve the potential network agent from the source data connection. The ownership 1059 // is not transferred at this moment. 1060 mHandoverSourceNetworkAgent = srcDc.getNetworkAgent(); 1061 if (mHandoverSourceNetworkAgent == null) { 1062 loge("requestHandover: Cannot get network agent from the source dc " + srcDc.getName()); 1063 onRquestHandoverFailed(cp); 1064 return; 1065 } 1066 1067 linkProperties = srcDc.getLinkProperties(); 1068 if (linkProperties == null || linkProperties.getLinkAddresses().isEmpty()) { 1069 loge("requestHandover: Can't find link properties of handover data connection. dc=" 1070 + srcDc); 1071 onRquestHandoverFailed(cp); 1072 return; 1073 } 1074 1075 mHandoverLocalLog.log("Handover started. Preserved the agent."); 1076 log("Get the handover source network agent: " + mHandoverSourceNetworkAgent); 1077 1078 reason = DataService.REQUEST_REASON_HANDOVER; 1079 1080 TrafficDescriptor td = dp.getApn() == null ? null 1081 : new TrafficDescriptor(dp.getApn(), null); 1082 boolean matchAllRuleAllowed = true; 1083 1084 mDataServiceManager.setupDataCall( 1085 ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat), 1086 dp, 1087 isModemRoaming, 1088 allowRoaming, 1089 reason, 1090 linkProperties, 1091 srcDc.getPduSessionId(), 1092 srcDc.getSliceInfo(), 1093 td, 1094 matchAllRuleAllowed, 1095 msg); 1096 TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat, 1097 dp.getProfileId(), dp.getApn(), dp.getProtocolType()); 1098 } 1099 1100 /** 1101 * Called on the source data connection from the target data connection. 1102 */ 1103 @VisibleForTesting startHandover(Consumer<Integer> onTargetDcComplete)1104 public void startHandover(Consumer<Integer> onTargetDcComplete) { 1105 logd("startHandover: " + toStringSimple()); 1106 // Set the handover state to being transferred on "this" data connection which is the src. 1107 setHandoverState(HANDOVER_STATE_BEING_TRANSFERRED); 1108 1109 Consumer<Integer> onSrcDcComplete = 1110 resultCode -> onHandoverStarted(resultCode, onTargetDcComplete); 1111 /* 1112 The flow here is: 1113 srcDc#startHandover -> dataService#startHandover -> (onHandoverStarted) -> 1114 onSrcDcComplete -> onTargetDcComplete 1115 */ 1116 mDataServiceManager.startHandover(mCid, 1117 this.obtainMessage(EVENT_START_HANDOVER, 1118 onSrcDcComplete)); 1119 } 1120 1121 /** 1122 * Called on the source data connection when the async call to start handover is complete 1123 */ onHandoverStarted(@ataServiceCallback.ResultCode int resultCode, Consumer<Integer> onTargetDcComplete)1124 private void onHandoverStarted(@DataServiceCallback.ResultCode int resultCode, 1125 Consumer<Integer> onTargetDcComplete) { 1126 logd("onHandoverStarted: " + toStringSimple()); 1127 if (!isResultCodeSuccess(resultCode)) { 1128 setHandoverState(HANDOVER_STATE_IDLE); 1129 } 1130 onTargetDcComplete.accept(resultCode); 1131 } 1132 cancelHandover()1133 private void cancelHandover() { 1134 if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED) { 1135 logd("cancelHandover: handover state is " + handoverStateToString(mHandoverState) 1136 + ", expecting HANDOVER_STATE_BEING_TRANSFERRED"); 1137 } 1138 mDataServiceManager.cancelHandover(mCid, this.obtainMessage(EVENT_CANCEL_HANDOVER)); 1139 setHandoverState(HANDOVER_STATE_IDLE); 1140 } 1141 1142 /** 1143 * Update NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED based on congested override 1144 * @param isCongested whether this DC should be set to congested or not 1145 */ onCongestednessChanged(boolean isCongested)1146 public void onCongestednessChanged(boolean isCongested) { 1147 sendMessage(obtainMessage(EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED, isCongested)); 1148 } 1149 1150 /** 1151 * Update NetworkCapabilities.NET_CAPABILITY_NOT_METERED based on metered override 1152 * @param isUnmetered whether this DC should be set to unmetered or not 1153 */ onMeterednessChanged(boolean isUnmetered)1154 public void onMeterednessChanged(boolean isUnmetered) { 1155 sendMessage(obtainMessage(EVENT_DATA_CONNECTION_METEREDNESS_CHANGED, isUnmetered)); 1156 } 1157 1158 /** 1159 * TearDown the data connection when the deactivation is complete a Message with 1160 * msg.what == EVENT_DEACTIVATE_DONE 1161 * 1162 * @param o is the object returned in the AsyncResult.obj. 1163 */ tearDownData(Object o)1164 private void tearDownData(Object o) { 1165 int discReason = DataService.REQUEST_REASON_NORMAL; 1166 ApnContext apnContext = null; 1167 if ((o != null) && (o instanceof DisconnectParams)) { 1168 DisconnectParams dp = (DisconnectParams) o; 1169 apnContext = dp.mApnContext; 1170 if (TextUtils.equals(dp.mReason, Phone.REASON_RADIO_TURNED_OFF) 1171 || TextUtils.equals(dp.mReason, Phone.REASON_PDP_RESET)) { 1172 discReason = DataService.REQUEST_REASON_SHUTDOWN; 1173 } else if (dp.mReleaseType == DcTracker.RELEASE_TYPE_HANDOVER) { 1174 discReason = DataService.REQUEST_REASON_HANDOVER; 1175 } 1176 } 1177 1178 String str = "tearDownData. mCid=" + mCid + ", reason=" + discReason; 1179 if (DBG) log(str); 1180 ApnContext.requestLog(apnContext, str); 1181 1182 1183 //Needed to be final to work in a closure 1184 final int fDiscReason = discReason; 1185 releasePduSessionId(() -> { 1186 // This is run after release pdu session id is complete 1187 this.setPduSessionId(PDU_SESSION_ID_NOT_SET); 1188 mDataServiceManager.deactivateDataCall(mCid, fDiscReason, 1189 obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, o)); 1190 mDataCallSessionStats.setDeactivateDataCallReason(fDiscReason); 1191 }); 1192 } 1193 releasePduSessionId(Runnable releaseCallback)1194 private void releasePduSessionId(Runnable releaseCallback) { 1195 // If the transport is IWLAN, and there is a valid PDU session id, also the data connection 1196 // is not being handovered, we should release the pdu session id. 1197 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1198 && mHandoverState == HANDOVER_STATE_IDLE 1199 && this.getPduSessionId() != PDU_SESSION_ID_NOT_SET) { 1200 Message msg = this.obtainMessage(EVENT_RELEASE_PDU_SESSION_ID); 1201 msg.obj = releaseCallback; 1202 mPhone.mCi.releasePduSessionId(msg, this.getPduSessionId()); 1203 } else { 1204 // Just go and run the callback since we either have no pdu session id to release 1205 // or we are in the middle of a handover 1206 releaseCallback.run(); 1207 } 1208 } 1209 notifyAllWithEvent(ApnContext alreadySent, int event, String reason)1210 private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) { 1211 for (ConnectionParams cp : mApnContexts.values()) { 1212 ApnContext apnContext = cp.mApnContext; 1213 if (apnContext == alreadySent) continue; 1214 if (reason != null) apnContext.setReason(reason); 1215 Pair<ApnContext, Integer> pair = new Pair<>(apnContext, cp.mConnectionGeneration); 1216 Message msg = mDct.obtainMessage(event, cp.mRequestType, 1217 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, pair); 1218 AsyncResult.forMessage(msg); 1219 msg.sendToTarget(); 1220 } 1221 } 1222 1223 /** 1224 * Send the connectionCompletedMsg. 1225 * 1226 * @param cp is the ConnectionParams 1227 * @param cause and if no error the cause is DataFailCause.NONE 1228 * @param handoverFailureMode The action on handover failure 1229 * @param sendAll is true if all contexts are to be notified 1230 */ notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause, @HandoverFailureMode int handoverFailureMode, boolean sendAll)1231 private void notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause, 1232 @HandoverFailureMode int handoverFailureMode, boolean sendAll) { 1233 ApnContext alreadySent = null; 1234 1235 if (cp != null && cp.mOnCompletedMsg != null) { 1236 // Get the completed message but only use it once 1237 Message connectionCompletedMsg = cp.mOnCompletedMsg; 1238 cp.mOnCompletedMsg = null; 1239 alreadySent = cp.mApnContext; 1240 1241 long timeStamp = System.currentTimeMillis(); 1242 connectionCompletedMsg.arg1 = cp.mRequestType; 1243 connectionCompletedMsg.arg2 = handoverFailureMode; 1244 1245 if (cause == DataFailCause.NONE) { 1246 mCreateTime = timeStamp; 1247 AsyncResult.forMessage(connectionCompletedMsg); 1248 } else { 1249 mLastFailCause = cause; 1250 mLastFailTime = timeStamp; 1251 1252 // Return message with a Throwable exception to signify an error. 1253 if (cause == DataFailCause.NONE) cause = DataFailCause.UNKNOWN; 1254 AsyncResult.forMessage(connectionCompletedMsg, cause, 1255 new Throwable(DataFailCause.toString(cause))); 1256 } 1257 if (DBG) { 1258 log("notifyConnectCompleted at " + timeStamp + " cause=" 1259 + DataFailCause.toString(cause) + " connectionCompletedMsg=" 1260 + msgToString(connectionCompletedMsg)); 1261 } 1262 1263 connectionCompletedMsg.sendToTarget(); 1264 } 1265 if (sendAll) { 1266 log("Send to all. " + alreadySent + " " + DataFailCause.toString(cause)); 1267 notifyAllWithEvent(alreadySent, DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR, 1268 DataFailCause.toString(cause)); 1269 } 1270 } 1271 1272 /** 1273 * Send ar.userObj if its a message, which is should be back to originator. 1274 * 1275 * @param dp is the DisconnectParams. 1276 */ notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll)1277 private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) { 1278 if (VDBG) log("NotifyDisconnectCompleted"); 1279 1280 ApnContext alreadySent = null; 1281 String reason = null; 1282 1283 if (dp != null && dp.mOnCompletedMsg != null) { 1284 // Get the completed message but only use it once 1285 Message msg = dp.mOnCompletedMsg; 1286 dp.mOnCompletedMsg = null; 1287 if (msg.obj instanceof ApnContext) { 1288 alreadySent = (ApnContext)msg.obj; 1289 } 1290 reason = dp.mReason; 1291 if (VDBG) { 1292 log(String.format("msg=%s msg.obj=%s", msg.toString(), 1293 ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>"))); 1294 } 1295 AsyncResult.forMessage(msg); 1296 msg.sendToTarget(); 1297 } 1298 if (sendAll) { 1299 if (reason == null) { 1300 reason = DataFailCause.toString(DataFailCause.UNKNOWN); 1301 } 1302 notifyAllWithEvent(alreadySent, DctConstants.EVENT_DISCONNECT_DONE, reason); 1303 } 1304 if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp); 1305 } 1306 sendRunnableMessage(int eventCode, @NonNull final Consumer<Boolean> r)1307 private void sendRunnableMessage(int eventCode, @NonNull final Consumer<Boolean> r) { 1308 sendMessage(eventCode, r); 1309 } 1310 1311 /* 1312 * ************************************************************************** 1313 * Begin Members and methods owned by DataConnectionTracker but stored 1314 * in a DataConnection because there is one per connection. 1315 * ************************************************************************** 1316 */ 1317 1318 /* 1319 * The id is owned by DataConnectionTracker. 1320 */ 1321 private int mId; 1322 1323 /** 1324 * Get the DataConnection ID 1325 */ getDataConnectionId()1326 public int getDataConnectionId() { 1327 return mId; 1328 } 1329 1330 /* 1331 * ************************************************************************** 1332 * End members owned by DataConnectionTracker 1333 * ************************************************************************** 1334 */ 1335 1336 /** 1337 * Clear all settings called when entering mInactiveState. 1338 */ clearSettings()1339 private synchronized void clearSettings() { 1340 if (DBG) log("clearSettings"); 1341 1342 mCreateTime = -1; 1343 mLastFailTime = -1; 1344 mLastFailCause = DataFailCause.NONE; 1345 mCid = -1; 1346 1347 mPcscfAddr = new String[5]; 1348 1349 mLinkProperties = new LinkProperties(); 1350 mApnContexts.clear(); 1351 mApnSetting = null; 1352 mUnmeteredUseOnly = false; 1353 mMmsUseOnly = false; 1354 mEnterpriseUse = false; 1355 mRestrictedNetworkOverride = false; 1356 mDcFailCause = DataFailCause.NONE; 1357 mDisabledApnTypeBitMask = 0; 1358 mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1359 mCongestedOverride = false; 1360 mUnmeteredOverride = false; 1361 mDownlinkBandwidth = 14; 1362 mUplinkBandwidth = 14; 1363 mIsSuspended = false; 1364 mHandoverState = HANDOVER_STATE_IDLE; 1365 mHandoverFailureMode = DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN; 1366 mSliceInfo = null; 1367 mDefaultQos = null; 1368 mDoAllocatePduSessionId = false; 1369 mQosBearerSessions.clear(); 1370 mTrafficDescriptors.clear(); 1371 } 1372 1373 /** 1374 * Process setup data completion result from data service 1375 * 1376 * @param resultCode The result code returned by data service 1377 * @param response Data call setup response from data service 1378 * @param cp The original connection params used for data call setup 1379 * @return Setup result 1380 */ onSetupConnectionCompleted(@ataServiceCallback.ResultCode int resultCode, DataCallResponse response, ConnectionParams cp)1381 private SetupResult onSetupConnectionCompleted(@DataServiceCallback.ResultCode int resultCode, 1382 DataCallResponse response, 1383 ConnectionParams cp) { 1384 SetupResult result; 1385 1386 log("onSetupConnectionCompleted: resultCode=" + resultCode + ", response=" + response); 1387 if (cp.mTag != mTag) { 1388 if (DBG) { 1389 log("onSetupConnectionCompleted stale cp.tag=" + cp.mTag + ", mtag=" + mTag); 1390 } 1391 result = SetupResult.ERROR_STALE; 1392 } else if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) { 1393 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE; 1394 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE; 1395 } else if (resultCode == DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE) { 1396 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR; 1397 result.mFailCause = DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE; 1398 } else if (resultCode == DataServiceCallback.RESULT_ERROR_INVALID_ARG) { 1399 result = SetupResult.ERROR_INVALID_ARG; 1400 result.mFailCause = DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER; 1401 } else if (response.getCause() != 0) { 1402 if (response.getCause() == DataFailCause.RADIO_NOT_AVAILABLE) { 1403 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE; 1404 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE; 1405 } else { 1406 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR; 1407 result.mFailCause = DataFailCause.getFailCause(response.getCause()); 1408 } 1409 } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE 1410 && mDcController.getActiveDcByCid(response.getId()) != null) { 1411 if (!mDcController.getTrafficDescriptorsForCid(response.getId()) 1412 .equals(response.getTrafficDescriptors())) { 1413 if (DBG) log("Updating traffic descriptors: " + response.getTrafficDescriptors()); 1414 mDcController.getActiveDcByCid(response.getId()).updateTrafficDescriptors(response); 1415 mDct.obtainMessage(DctConstants.EVENT_TRAFFIC_DESCRIPTORS_UPDATED).sendToTarget(); 1416 } 1417 if (DBG) log("DataConnection already exists for cid: " + response.getId()); 1418 result = SetupResult.ERROR_DUPLICATE_CID; 1419 result.mFailCause = DataFailCause.DUPLICATE_CID; 1420 } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE 1421 && !mDcController.isDefaultDataActive()) { 1422 if (DBG) log("No default data connection currently active"); 1423 mCid = response.getId(); 1424 result = SetupResult.ERROR_NO_DEFAULT_CONNECTION; 1425 result.mFailCause = DataFailCause.NO_DEFAULT_DATA; 1426 } else { 1427 if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse"); 1428 mCid = response.getId(); 1429 setPduSessionId(response.getPduSessionId()); 1430 updatePcscfAddr(response); 1431 updateResponseFields(response); 1432 result = updateLinkProperty(response).setupResult; 1433 } 1434 1435 return result; 1436 } 1437 isResultCodeSuccess(int resultCode)1438 private static boolean isResultCodeSuccess(int resultCode) { 1439 return resultCode == DataServiceCallback.RESULT_SUCCESS 1440 || resultCode == DataServiceCallback.RESULT_ERROR_UNSUPPORTED; 1441 } 1442 isDnsOk(String[] domainNameServers)1443 private boolean isDnsOk(String[] domainNameServers) { 1444 if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1]) 1445 && !mPhone.isDnsCheckDisabled()) { 1446 // Work around a race condition where QMI does not fill in DNS: 1447 // Deactivate PDP and let DataConnectionTracker retry. 1448 // Do not apply the race condition workaround for MMS APN 1449 // if Proxy is an IP-address. 1450 // Otherwise, the default APN will not be restored anymore. 1451 if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) { 1452 log(String.format( 1453 "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s", 1454 mApnSetting.getApnTypeBitmask(), ApnSetting.TYPE_MMS_STRING, 1455 mApnSetting.getMmsProxyAddressAsString(), 1456 isIpAddress(mApnSetting.getMmsProxyAddressAsString()))); 1457 return false; 1458 } 1459 } 1460 return true; 1461 } 1462 1463 /** 1464 * TCP buffer size config based on the ril technology. There are 6 parameters 1465 * read_min, read_default, read_max, write_min, write_default, write_max in the TCP buffer 1466 * config string and they are separated by a comma. The unit of these parameters is byte. 1467 */ 1468 private static final String TCP_BUFFER_SIZES_GPRS = "4092,8760,48000,4096,8760,48000"; 1469 private static final String TCP_BUFFER_SIZES_EDGE = "4093,26280,70800,4096,16384,70800"; 1470 private static final String TCP_BUFFER_SIZES_UMTS = "58254,349525,1048576,58254,349525,1048576"; 1471 private static final String TCP_BUFFER_SIZES_1XRTT = "16384,32768,131072,4096,16384,102400"; 1472 private static final String TCP_BUFFER_SIZES_EVDO = "4094,87380,262144,4096,16384,262144"; 1473 private static final String TCP_BUFFER_SIZES_EHRPD = "131072,262144,1048576,4096,16384,524288"; 1474 private static final String TCP_BUFFER_SIZES_HSDPA = "61167,367002,1101005,8738,52429,262114"; 1475 private static final String TCP_BUFFER_SIZES_HSPA = "40778,244668,734003,16777,100663,301990"; 1476 private static final String TCP_BUFFER_SIZES_LTE = 1477 "524288,1048576,2097152,262144,524288,1048576"; 1478 private static final String TCP_BUFFER_SIZES_HSPAP = 1479 "122334,734003,2202010,32040,192239,576717"; 1480 private static final String TCP_BUFFER_SIZES_NR = 1481 "2097152,6291456,16777216,512000,2097152,8388608"; 1482 private static final String TCP_BUFFER_SIZES_LTE_CA = 1483 "4096,6291456,12582912,4096,1048576,2097152"; 1484 updateTcpBufferSizes(int rilRat)1485 private void updateTcpBufferSizes(int rilRat) { 1486 String sizes = null; 1487 ServiceState ss = mPhone.getServiceState(); 1488 if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && 1489 ss.isUsingCarrierAggregation()) { 1490 rilRat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA; 1491 } 1492 String ratName = ServiceState.rilRadioTechnologyToString(rilRat).toLowerCase(Locale.ROOT); 1493 // ServiceState gives slightly different names for EVDO tech ("evdo-rev.0" for ex) 1494 // - patch it up: 1495 if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 || 1496 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A || 1497 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B) { 1498 ratName = RAT_NAME_EVDO; 1499 } 1500 1501 // NR 5G Non-Standalone use LTE cell as the primary cell, the ril technology is LTE in this 1502 // case. We use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1503 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1504 && ((rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE || 1505 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) && isNRConnected()) 1506 && mPhone.getServiceStateTracker().getNrContextIds().contains(mCid)) { 1507 ratName = RAT_NAME_5G; 1508 } 1509 1510 log("updateTcpBufferSizes: " + ratName); 1511 1512 // in the form: "ratname:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max" 1513 String[] configOverride = mPhone.getContext().getResources().getStringArray( 1514 com.android.internal.R.array.config_mobile_tcp_buffers); 1515 for (int i = 0; i < configOverride.length; i++) { 1516 String[] split = configOverride[i].split(":"); 1517 if (ratName.equals(split[0]) && split.length == 2) { 1518 sizes = split[1]; 1519 break; 1520 } 1521 } 1522 1523 if (sizes == null) { 1524 // no override - use telephony defaults 1525 // doing it this way allows device or carrier to just override the types they 1526 // care about and inherit the defaults for the others. 1527 switch (rilRat) { 1528 case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS: 1529 sizes = TCP_BUFFER_SIZES_GPRS; 1530 break; 1531 case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE: 1532 sizes = TCP_BUFFER_SIZES_EDGE; 1533 break; 1534 case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS: 1535 sizes = TCP_BUFFER_SIZES_UMTS; 1536 break; 1537 case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT: 1538 sizes = TCP_BUFFER_SIZES_1XRTT; 1539 break; 1540 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0: 1541 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A: 1542 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B: 1543 sizes = TCP_BUFFER_SIZES_EVDO; 1544 break; 1545 case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD: 1546 sizes = TCP_BUFFER_SIZES_EHRPD; 1547 break; 1548 case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA: 1549 sizes = TCP_BUFFER_SIZES_HSDPA; 1550 break; 1551 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA: 1552 case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA: 1553 sizes = TCP_BUFFER_SIZES_HSPA; 1554 break; 1555 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE: 1556 // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1557 if (RAT_NAME_5G.equals(ratName)) { 1558 sizes = TCP_BUFFER_SIZES_NR; 1559 } else { 1560 sizes = TCP_BUFFER_SIZES_LTE; 1561 } 1562 break; 1563 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA: 1564 // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1565 if (RAT_NAME_5G.equals(ratName)) { 1566 sizes = TCP_BUFFER_SIZES_NR; 1567 } else { 1568 sizes = TCP_BUFFER_SIZES_LTE_CA; 1569 } 1570 break; 1571 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP: 1572 sizes = TCP_BUFFER_SIZES_HSPAP; 1573 break; 1574 case ServiceState.RIL_RADIO_TECHNOLOGY_NR: 1575 sizes = TCP_BUFFER_SIZES_NR; 1576 break; 1577 default: 1578 // Leave empty - this will let ConnectivityService use the system default. 1579 break; 1580 } 1581 } 1582 mLinkProperties.setTcpBufferSizes(sizes); 1583 } 1584 updateLinkBandwidthsFromCarrierConfig(int rilRat)1585 private void updateLinkBandwidthsFromCarrierConfig(int rilRat) { 1586 String ratName = DataConfigManager.getDataConfigNetworkType( 1587 mPhone.getDisplayInfoController().getTelephonyDisplayInfo()); 1588 1589 if (DBG) log("updateLinkBandwidthsFromCarrierConfig: " + ratName); 1590 1591 Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName); 1592 if (values == null) { 1593 values = new Pair<>(14, 14); 1594 } 1595 mDownlinkBandwidth = values.first; 1596 mUplinkBandwidth = values.second; 1597 } 1598 1599 updateLinkBandwidthsFromModem(List<LinkCapacityEstimate> lceList)1600 private void updateLinkBandwidthsFromModem(List<LinkCapacityEstimate> lceList) { 1601 if (DBG) log("updateLinkBandwidthsFromModem: lceList=" + lceList); 1602 boolean downlinkUpdated = false; 1603 boolean uplinkUpdated = false; 1604 LinkCapacityEstimate lce = lceList.get(0); 1605 // LCE status deprecated in IRadio 1.2, so only check for IRadio < 1.2 1606 if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2) 1607 || mPhone.getLceStatus() == RILConstants.LCE_ACTIVE) { 1608 if (lce.getDownlinkCapacityKbps() != LinkCapacityEstimate.INVALID) { 1609 mDownlinkBandwidth = lce.getDownlinkCapacityKbps(); 1610 downlinkUpdated = true; 1611 } 1612 if (lce.getUplinkCapacityKbps() != LinkCapacityEstimate.INVALID) { 1613 mUplinkBandwidth = lce.getUplinkCapacityKbps(); 1614 uplinkUpdated = true; 1615 } 1616 } 1617 1618 if (!downlinkUpdated || !uplinkUpdated) { 1619 fallBackToCarrierConfigValues(downlinkUpdated, uplinkUpdated); 1620 } 1621 1622 if (mNetworkAgent != null) { 1623 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this); 1624 } 1625 } 1626 updateLinkBandwidthsFromBandwidthEstimator(int uplinkBandwidthKbps, int downlinkBandwidthKbps)1627 private void updateLinkBandwidthsFromBandwidthEstimator(int uplinkBandwidthKbps, 1628 int downlinkBandwidthKbps) { 1629 if (DBG) { 1630 log("updateLinkBandwidthsFromBandwidthEstimator, UL= " 1631 + uplinkBandwidthKbps + " DL= " + downlinkBandwidthKbps); 1632 } 1633 boolean downlinkUpdated = false; 1634 boolean uplinkUpdated = false; 1635 if (downlinkBandwidthKbps > 0) { 1636 mDownlinkBandwidth = downlinkBandwidthKbps; 1637 downlinkUpdated = true; 1638 } 1639 if (uplinkBandwidthKbps > 0) { 1640 mUplinkBandwidth = uplinkBandwidthKbps; 1641 uplinkUpdated = true; 1642 } 1643 1644 if (!downlinkUpdated || !uplinkUpdated) { 1645 fallBackToCarrierConfigValues(downlinkUpdated, uplinkUpdated); 1646 } 1647 if (mNetworkAgent != null) { 1648 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this); 1649 } 1650 } 1651 fallBackToCarrierConfigValues(boolean downlinkUpdated, boolean uplinkUpdated)1652 private void fallBackToCarrierConfigValues(boolean downlinkUpdated, boolean uplinkUpdated) { 1653 String ratName = ServiceState.rilRadioTechnologyToString(mRilRat); 1654 if (mRilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) { 1655 ratName = mPhone.getServiceState().getNrFrequencyRange() 1656 == ServiceState.FREQUENCY_RANGE_MMWAVE 1657 ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA; 1658 } 1659 Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName); 1660 if (values != null) { 1661 if (!downlinkUpdated) { 1662 mDownlinkBandwidth = values.first; 1663 } 1664 if (!uplinkUpdated) { 1665 mUplinkBandwidth = values.second; 1666 } 1667 mUplinkBandwidth = Math.min(mUplinkBandwidth, mDownlinkBandwidth); 1668 } 1669 } 1670 isBandwidthSourceKey(String source)1671 private boolean isBandwidthSourceKey(String source) { 1672 return source.equals(mPhone.getContext().getResources().getString( 1673 com.android.internal.R.string.config_bandwidthEstimateSource)); 1674 } 1675 1676 /** 1677 * Indicates if this data connection was established for unmetered use only. Note that this 1678 * flag should be populated when data becomes active. And if it is set to true, it can be set to 1679 * false later when we are reevaluating the data connection. But if it is set to false, it 1680 * can never become true later because setting it to true will cause this data connection 1681 * losing some immutable network capabilities, which can cause issues in connectivity service. 1682 */ 1683 private boolean mUnmeteredUseOnly = false; 1684 1685 /** 1686 * Indicates if this data connection was established for MMS use only. This is true only when 1687 * mobile data is disabled but the user allows sending and receiving MMS messages. If the data 1688 * enabled settings indicate that MMS data is allowed unconditionally, MMS can be sent when data 1689 * is disabled even if it is a metered APN type. 1690 */ 1691 private boolean mMmsUseOnly = false; 1692 1693 /** 1694 * Indicates if when this connection was established we had a restricted/privileged 1695 * NetworkRequest and needed it to overcome data-enabled limitations. 1696 * 1697 * This flag overrides the APN-based restriction capability, restricting the network 1698 * based on both having a NetworkRequest with restricted AND needing a restricted 1699 * bit to overcome user-disabled status. This allows us to handle the common case 1700 * of having both restricted requests and unrestricted requests for the same apn: 1701 * if conditions require a restricted network to overcome user-disabled then it must 1702 * be restricted, otherwise it is unrestricted (or restricted based on APN type). 1703 * 1704 * This supports a privileged app bringing up a network without general apps having access 1705 * to it when the network is otherwise unavailable (hipri). The first use case is 1706 * pre-paid SIM reprovisioning over internet, where the carrier insists on no traffic 1707 * other than from the privileged carrier-app. 1708 * 1709 * Note that the data connection cannot go from unrestricted to restricted because the 1710 * connectivity service does not support dynamically closing TCP connections at this point. 1711 */ 1712 private boolean mRestrictedNetworkOverride = false; 1713 1714 /** 1715 * Indicates if this data connection supports enterprise use. Note that this flag should be 1716 * populated when data becomes active. Once it is set, the value cannot be changed because 1717 * setting it will cause this data connection to lose immutable network capabilities, which can 1718 * cause issues in connectivity service. 1719 */ 1720 private boolean mEnterpriseUse = false; 1721 1722 /** 1723 * Check if this data connection should be restricted. We should call this when data connection 1724 * becomes active, or when we want to re-evaluate the conditions to decide if we need to 1725 * unstrict the data connection. 1726 * 1727 * @return True if this data connection needs to be restricted. 1728 */ shouldRestrictNetwork()1729 private boolean shouldRestrictNetwork() { 1730 // first, check if there is any network request that containing restricted capability 1731 // (i.e. Do not have NET_CAPABILITY_NOT_RESTRICTED in the request) 1732 boolean isAnyRestrictedRequest = false; 1733 for (ApnContext apnContext : mApnContexts.keySet()) { 1734 if (apnContext.hasRestrictedRequests(true /* exclude DUN */)) { 1735 isAnyRestrictedRequest = true; 1736 break; 1737 } 1738 } 1739 1740 // If all of the network requests are non-restricted, then we don't need to restrict 1741 // the network. 1742 if (!isAnyRestrictedRequest) { 1743 return false; 1744 } 1745 1746 // If the network is unmetered, then we don't need to restrict the network because users 1747 // won't be charged anyway. 1748 if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) { 1749 return false; 1750 } 1751 1752 // If the data is disabled, then we need to restrict the network so only privileged apps can 1753 // use the restricted network while data is disabled. 1754 if (!mPhone.getDataEnabledSettings().isDataEnabled()) { 1755 return true; 1756 } 1757 1758 // If the device is roaming, and the user does not turn on data roaming, then we need to 1759 // restrict the network so only privileged apps can use it. 1760 if (!mDct.getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) { 1761 return true; 1762 } 1763 1764 // Otherwise we should not restrict the network so anyone who requests can use it. 1765 return false; 1766 } 1767 1768 /** 1769 * @return True if this data connection should only be used for unmetered purposes. 1770 */ isUnmeteredUseOnly()1771 private boolean isUnmeteredUseOnly() { 1772 // If this data connection is on IWLAN, then it's unmetered and can be used by everyone. 1773 // Should not be for unmetered used only. 1774 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1775 return false; 1776 } 1777 1778 // If data is enabled, this data connection can't be for unmetered used only because 1779 // everyone should be able to use it if: 1780 // 1. Device is not roaming, or 1781 // 2. Device is roaming and data roaming is turned on 1782 if (mPhone.getDataEnabledSettings().isDataEnabled()) { 1783 if (!mPhone.getServiceState().getDataRoaming() || mDct.getDataRoamingEnabled()) { 1784 return false; 1785 } 1786 } 1787 1788 // The data connection can only be unmetered used only if all attached APN contexts 1789 // attached to this data connection are unmetered. 1790 for (ApnContext apnContext : mApnContexts.keySet()) { 1791 if (ApnSettingUtils.isMeteredApnType(apnContext.getApnTypeBitmask(), mPhone)) { 1792 return false; 1793 } 1794 } 1795 return true; 1796 } 1797 1798 /** 1799 * @return True if this data connection should only be used for MMS purposes. 1800 */ isMmsUseOnly()1801 private boolean isMmsUseOnly() { 1802 // MMS use only if data is disabled, MMS is allowed unconditionally, and MMS is the only 1803 // APN type for this data connection. 1804 DataEnabledSettings des = mPhone.getDataEnabledSettings(); 1805 boolean mmsAllowedUnconditionally = !des.isDataEnabled() && des.isMmsAlwaysAllowed(); 1806 boolean mmsApnOnly = isApnContextAttached(ApnSetting.TYPE_MMS, true); 1807 return mmsAllowedUnconditionally && mmsApnOnly; 1808 } 1809 1810 /** 1811 * Check if this data connection supports enterprise use. We call this when the data connection 1812 * becomes active or when we want to reevaluate the conditions to decide if we need to update 1813 * the network agent capabilities. 1814 * 1815 * @return True if this data connection supports enterprise use. 1816 */ isEnterpriseUse()1817 private boolean isEnterpriseUse() { 1818 return mApnContexts.keySet().stream().anyMatch( 1819 ac -> ac.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE); 1820 } 1821 1822 /** 1823 * Get the network capabilities for this data connection. 1824 * 1825 * @return the {@link NetworkCapabilities} of this data connection. 1826 */ getNetworkCapabilities()1827 public NetworkCapabilities getNetworkCapabilities() { 1828 final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder() 1829 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); 1830 boolean unmeteredApns = false; 1831 1832 if (mApnSetting != null && !mEnterpriseUse && !mMmsUseOnly) { 1833 final int[] types = ApnSetting.getApnTypesFromBitmask( 1834 mApnSetting.getApnTypeBitmask() & ~mDisabledApnTypeBitMask); 1835 for (int type : types) { 1836 if ((!mRestrictedNetworkOverride && mUnmeteredUseOnly) 1837 && ApnSettingUtils.isMeteredApnType(type, mPhone)) { 1838 log("Dropped the metered " + ApnSetting.getApnTypeString(type) 1839 + " type for the unmetered data call."); 1840 continue; 1841 } 1842 switch (type) { 1843 case ApnSetting.TYPE_ALL: { 1844 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1845 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1846 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL); 1847 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA); 1848 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); 1849 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS); 1850 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IA); 1851 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1852 break; 1853 } 1854 case ApnSetting.TYPE_DEFAULT: { 1855 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1856 break; 1857 } 1858 case ApnSetting.TYPE_MMS: { 1859 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1860 break; 1861 } 1862 case ApnSetting.TYPE_SUPL: { 1863 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL); 1864 break; 1865 } 1866 case ApnSetting.TYPE_DUN: { 1867 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1868 break; 1869 } 1870 case ApnSetting.TYPE_FOTA: { 1871 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA); 1872 break; 1873 } 1874 case ApnSetting.TYPE_IMS: { 1875 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); 1876 break; 1877 } 1878 case ApnSetting.TYPE_CBS: { 1879 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS); 1880 break; 1881 } 1882 case ApnSetting.TYPE_IA: { 1883 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IA); 1884 break; 1885 } 1886 case ApnSetting.TYPE_EMERGENCY: { 1887 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS); 1888 break; 1889 } 1890 case ApnSetting.TYPE_MCX: { 1891 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX); 1892 break; 1893 } 1894 case ApnSetting.TYPE_XCAP: { 1895 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP); 1896 break; 1897 } 1898 default: 1899 } 1900 } 1901 1902 if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) { 1903 unmeteredApns = true; 1904 } 1905 } 1906 1907 // Mark NOT_METERED in the following cases: 1908 // 1. All APNs in the APN settings are unmetered. 1909 // 2. The non-restricted data is intended for unmetered use only. 1910 if (unmeteredApns || (mUnmeteredUseOnly && !mRestrictedNetworkOverride)) { 1911 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1912 } else { 1913 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1914 } 1915 1916 if (mEnterpriseUse) { 1917 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE); 1918 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1919 } 1920 1921 if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())) { 1922 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1923 } 1924 1925 if (mMmsUseOnly) { 1926 if (ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_MMS, mPhone)) { 1927 log("Adding unmetered capability for the unmetered MMS-only data connection"); 1928 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1929 } 1930 log("Adding MMS capability for the MMS-only data connection"); 1931 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1932 } 1933 1934 if (mRestrictedNetworkOverride) { 1935 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1936 // don't use dun on restriction-overriden networks. 1937 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1938 } 1939 1940 builder.setLinkDownstreamBandwidthKbps(mDownlinkBandwidth); 1941 builder.setLinkUpstreamBandwidthKbps(mUplinkBandwidth); 1942 1943 builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 1944 .setSubscriptionId(mSubId).build()); 1945 builder.setSubscriptionIds(Collections.singleton(mSubId)); 1946 1947 if (!mPhone.getServiceState().getDataRoaming()) { 1948 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 1949 } 1950 1951 if (!mCongestedOverride) { 1952 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); 1953 } 1954 1955 if (mUnmeteredOverride) { 1956 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED); 1957 } 1958 1959 if (!mIsSuspended) { 1960 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED); 1961 } 1962 1963 final int carrierServicePackageUid = getCarrierServicePackageUid(); 1964 1965 // TODO(b/205736323): Owner and Admin UIDs currently come from separate data sources. Unify 1966 // them, and remove ArrayUtils.contains() check. 1967 if (carrierServicePackageUid != Process.INVALID_UID 1968 && ArrayUtils.contains(mAdministratorUids, carrierServicePackageUid)) { 1969 builder.setOwnerUid(carrierServicePackageUid); 1970 builder.setAllowedUids(Collections.singleton(carrierServicePackageUid)); 1971 } 1972 builder.setAdministratorUids(mAdministratorUids); 1973 1974 // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a 1975 // VCN. 1976 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 1977 final VcnNetworkPolicyResult vcnPolicy = getVcnPolicy(builder.build()); 1978 if (!vcnPolicy.getNetworkCapabilities() 1979 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)) { 1980 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 1981 } 1982 if (!vcnPolicy.getNetworkCapabilities() 1983 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) { 1984 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1985 } 1986 1987 return builder.build(); 1988 } 1989 1990 // TODO(b/205736323): Once TelephonyManager#getCarrierServicePackageNameForLogicalSlot() is 1991 // plumbed to CarrierPrivilegesTracker's cache, query the cached UIDs. getFirstUidForPackage(String pkgName)1992 private int getFirstUidForPackage(String pkgName) { 1993 if (pkgName == null) { 1994 return Process.INVALID_UID; 1995 } 1996 1997 List<UserInfo> users = mPhone.getContext().getSystemService(UserManager.class).getUsers(); 1998 for (UserInfo user : users) { 1999 int userId = user.getUserHandle().getIdentifier(); 2000 try { 2001 PackageManager pm = mPhone.getContext().getPackageManager(); 2002 2003 if (pm != null) { 2004 return pm.getPackageUidAsUser(pkgName, userId); 2005 } 2006 } catch (NameNotFoundException exception) { 2007 // Didn't find package. Try other users 2008 Rlog.i( 2009 "DataConnection", 2010 "Unable to find uid for package " + pkgName + " and user " + userId); 2011 } 2012 } 2013 return Process.INVALID_UID; 2014 } 2015 getCarrierServicePackageUid()2016 private int getCarrierServicePackageUid() { 2017 String pkgName = 2018 mPhone.getContext() 2019 .getSystemService(TelephonyManager.class) 2020 .getCarrierServicePackageNameForLogicalSlot(mPhone.getPhoneId()); 2021 2022 return getFirstUidForPackage(pkgName); 2023 } 2024 2025 /** 2026 * Check if the this data network is VCN-managed. 2027 * 2028 * @param networkCapabilities The network capabilities of this data network. 2029 * @return The VCN's policy for this DataNetwork. 2030 */ getVcnPolicy(NetworkCapabilities networkCapabilities)2031 private VcnNetworkPolicyResult getVcnPolicy(NetworkCapabilities networkCapabilities) { 2032 return mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties()); 2033 } 2034 2035 /** @return {@code true} if validation is required, {@code false} otherwise. */ isValidationRequired()2036 public boolean isValidationRequired() { 2037 final NetworkCapabilities nc = getNetworkCapabilities(); 2038 return nc != null 2039 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 2040 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 2041 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) 2042 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN); 2043 } 2044 2045 /** 2046 * @return {@code True} if 464xlat should be skipped. 2047 */ 2048 @VisibleForTesting shouldSkip464Xlat()2049 public boolean shouldSkip464Xlat() { 2050 switch (mApnSetting.getSkip464Xlat()) { 2051 case Telephony.Carriers.SKIP_464XLAT_ENABLE: 2052 return true; 2053 case Telephony.Carriers.SKIP_464XLAT_DISABLE: 2054 return false; 2055 case Telephony.Carriers.SKIP_464XLAT_DEFAULT: 2056 default: 2057 break; 2058 } 2059 2060 // As default, return true if ims and no internet 2061 final NetworkCapabilities nc = getNetworkCapabilities(); 2062 return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS) 2063 && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 2064 } 2065 2066 /** 2067 * @return {@code} true iff. {@code address} is a literal IPv4 or IPv6 address. 2068 */ 2069 @VisibleForTesting isIpAddress(String address)2070 public static boolean isIpAddress(String address) { 2071 if (address == null) return false; 2072 2073 // Accept IPv6 addresses (only) in square brackets for compatibility. 2074 if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) { 2075 address = address.substring(1, address.length() - 1); 2076 } 2077 return InetAddresses.isNumericAddress(address); 2078 } 2079 setLinkProperties(DataCallResponse response, LinkProperties linkProperties)2080 private SetupResult setLinkProperties(DataCallResponse response, 2081 LinkProperties linkProperties) { 2082 // Check if system property dns usable 2083 String propertyPrefix = "net." + response.getInterfaceName() + "."; 2084 String dnsServers[] = new String[2]; 2085 dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1"); 2086 dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2"); 2087 boolean okToUseSystemPropertyDns = isDnsOk(dnsServers); 2088 2089 SetupResult result; 2090 2091 // Start with clean network properties and if we have 2092 // a failure we'll clear again at the bottom of this code. 2093 linkProperties.clear(); 2094 2095 if (response.getCause() == DataFailCause.NONE) { 2096 try { 2097 // set interface name 2098 linkProperties.setInterfaceName(response.getInterfaceName()); 2099 2100 // set link addresses 2101 if (response.getAddresses().size() > 0) { 2102 for (LinkAddress la : response.getAddresses()) { 2103 if (!la.getAddress().isAnyLocalAddress()) { 2104 if (DBG) { 2105 log("addr/pl=" + la.getAddress() + "/" 2106 + la.getPrefixLength()); 2107 } 2108 linkProperties.addLinkAddress(la); 2109 } 2110 } 2111 } else { 2112 throw new UnknownHostException("no address for ifname=" 2113 + response.getInterfaceName()); 2114 } 2115 2116 // set dns servers 2117 if (response.getDnsAddresses().size() > 0) { 2118 for (InetAddress dns : response.getDnsAddresses()) { 2119 if (!dns.isAnyLocalAddress()) { 2120 linkProperties.addDnsServer(dns); 2121 } 2122 } 2123 } else if (okToUseSystemPropertyDns) { 2124 for (String dnsAddr : dnsServers) { 2125 dnsAddr = dnsAddr.trim(); 2126 if (dnsAddr.isEmpty()) continue; 2127 InetAddress ia; 2128 try { 2129 ia = InetAddresses.parseNumericAddress(dnsAddr); 2130 } catch (IllegalArgumentException e) { 2131 throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr); 2132 } 2133 if (!ia.isAnyLocalAddress()) { 2134 linkProperties.addDnsServer(ia); 2135 } 2136 } 2137 } else { 2138 throw new UnknownHostException("Empty dns response and no system default dns"); 2139 } 2140 2141 // set pcscf 2142 if (response.getPcscfAddresses().size() > 0) { 2143 for (InetAddress pcscf : response.getPcscfAddresses()) { 2144 linkProperties.addPcscfServer(pcscf); 2145 } 2146 } 2147 2148 for (InetAddress gateway : response.getGatewayAddresses()) { 2149 int mtu = gateway instanceof java.net.Inet6Address ? response.getMtuV6() 2150 : response.getMtuV4(); 2151 // Allow 0.0.0.0 or :: as a gateway; 2152 // this indicates a point-to-point interface. 2153 linkProperties.addRoute(new RouteInfo(null, gateway, null, 2154 RouteInfo.RTN_UNICAST, mtu)); 2155 } 2156 2157 // set interface MTU 2158 // this may clobber the setting read from the APN db, but that's ok 2159 // TODO: remove once LinkProperties#setMtu is deprecated 2160 linkProperties.setMtu(response.getMtu()); 2161 2162 result = SetupResult.SUCCESS; 2163 } catch (UnknownHostException e) { 2164 log("setLinkProperties: UnknownHostException " + e); 2165 result = SetupResult.ERROR_INVALID_ARG; 2166 } 2167 } else { 2168 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR; 2169 } 2170 2171 // An error occurred so clear properties 2172 if (result != SetupResult.SUCCESS) { 2173 if (DBG) { 2174 log("setLinkProperties: error clearing LinkProperties status=" 2175 + response.getCause() + " result=" + result); 2176 } 2177 linkProperties.clear(); 2178 } 2179 2180 return result; 2181 } 2182 2183 /** 2184 * Initialize connection, this will fail if the 2185 * apnSettings are not compatible. 2186 * 2187 * @param cp the Connection parameters 2188 * @return true if initialization was successful. 2189 */ initConnection(ConnectionParams cp)2190 private boolean initConnection(ConnectionParams cp) { 2191 ApnContext apnContext = cp.mApnContext; 2192 if (mApnSetting == null) { 2193 // Only change apn setting if it isn't set, it will 2194 // only NOT be set only if we're in DcInactiveState. 2195 mApnSetting = apnContext.getApnSetting(); 2196 } 2197 if (mApnSetting == null || (!mApnSetting.canHandleType(apnContext.getApnTypeBitmask()) 2198 && apnContext.getApnTypeBitmask() != ApnSetting.TYPE_ENTERPRISE)) { 2199 if (DBG) { 2200 log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp 2201 + " dc=" + DataConnection.this); 2202 } 2203 return false; 2204 } 2205 mTag += 1; 2206 mConnectionParams = cp; 2207 mConnectionParams.mTag = mTag; 2208 2209 // always update the ConnectionParams with the latest or the 2210 // connectionGeneration gets stale 2211 mApnContexts.put(apnContext, cp); 2212 2213 if (DBG) { 2214 log("initConnection: " 2215 + " RefCount=" + mApnContexts.size() 2216 + " mApnList=" + mApnContexts 2217 + " mConnectionParams=" + mConnectionParams); 2218 } 2219 return true; 2220 } 2221 2222 /** 2223 * The parent state for all other states. 2224 */ 2225 private class DcDefaultState extends State { 2226 @Override enter()2227 public void enter() { 2228 if (DBG) log("DcDefaultState: enter"); 2229 2230 // Register for DRS or RAT change 2231 mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged( 2232 mTransportType, getHandler(), 2233 DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null); 2234 2235 mPhone.getServiceStateTracker().registerForDataRoamingOn(getHandler(), 2236 DataConnection.EVENT_DATA_CONNECTION_ROAM_ON, null); 2237 mPhone.getServiceStateTracker().registerForDataRoamingOff(getHandler(), 2238 DataConnection.EVENT_DATA_CONNECTION_ROAM_OFF, null, true); 2239 mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(), 2240 DataConnection.EVENT_NR_STATE_CHANGED, null); 2241 mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(), 2242 DataConnection.EVENT_NR_FREQUENCY_CHANGED, null); 2243 mPhone.getServiceStateTracker().registerForCssIndicatorChanged(getHandler(), 2244 DataConnection.EVENT_CSS_INDICATOR_CHANGED, null); 2245 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) { 2246 mPhone.getLinkBandwidthEstimator().registerForBandwidthChanged(getHandler(), 2247 DataConnection.EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE, null); 2248 } 2249 2250 // Add ourselves to the list of data connections 2251 mDcController.addDc(DataConnection.this); 2252 } 2253 @Override exit()2254 public void exit() { 2255 if (DBG) log("DcDefaultState: exit"); 2256 2257 // Unregister for DRS or RAT change. 2258 mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged( 2259 mTransportType, getHandler()); 2260 2261 mPhone.getServiceStateTracker().unregisterForDataRoamingOn(getHandler()); 2262 mPhone.getServiceStateTracker().unregisterForDataRoamingOff(getHandler()); 2263 mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler()); 2264 mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler()); 2265 mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler()); 2266 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) { 2267 mPhone.getLinkBandwidthEstimator().unregisterForBandwidthChanged(getHandler()); 2268 } 2269 2270 // Remove ourselves from the DC lists 2271 mDcController.removeDc(DataConnection.this); 2272 2273 if (mAc != null) { 2274 mAc.disconnected(); 2275 mAc = null; 2276 } 2277 mApnContexts.clear(); 2278 mReconnectIntent = null; 2279 mDct = null; 2280 mApnSetting = null; 2281 mPhone = null; 2282 mDataServiceManager = null; 2283 mLinkProperties = null; 2284 mLastFailCause = DataFailCause.NONE; 2285 mUserData = null; 2286 mDcController = null; 2287 mDcTesterFailBringUpAll = null; 2288 } 2289 2290 @Override processMessage(Message msg)2291 public boolean processMessage(Message msg) { 2292 boolean retVal = HANDLED; 2293 2294 if (VDBG) { 2295 log("DcDefault msg=" + getWhatToString(msg.what) 2296 + " RefCount=" + mApnContexts.size()); 2297 } 2298 switch (msg.what) { 2299 case EVENT_RESET: 2300 if (VDBG) log("DcDefaultState: msg.what=REQ_RESET"); 2301 transitionTo(mInactiveState); 2302 break; 2303 case EVENT_CONNECT: 2304 if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected"); 2305 ConnectionParams cp = (ConnectionParams) msg.obj; 2306 notifyConnectCompleted(cp, DataFailCause.UNKNOWN, 2307 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 2308 break; 2309 2310 case EVENT_DISCONNECT: 2311 case EVENT_DISCONNECT_ALL: 2312 case EVENT_REEVALUATE_RESTRICTED_STATE: 2313 if (DBG) { 2314 log("DcDefaultState deferring msg.what=" + getWhatToString(msg.what) 2315 + " RefCount=" + mApnContexts.size()); 2316 } 2317 deferMessage(msg); 2318 break; 2319 case EVENT_TEAR_DOWN_NOW: 2320 if (DBG) log("DcDefaultState EVENT_TEAR_DOWN_NOW"); 2321 mDataServiceManager.deactivateDataCall(mCid, DataService.REQUEST_REASON_NORMAL, 2322 null); 2323 mDataCallSessionStats.setDeactivateDataCallReason( 2324 DataService.REQUEST_REASON_NORMAL); 2325 break; 2326 case EVENT_LOST_CONNECTION: 2327 if (DBG) { 2328 String s = "DcDefaultState ignore EVENT_LOST_CONNECTION" 2329 + " tag=" + msg.arg1 + ":mTag=" + mTag; 2330 logAndAddLogRec(s); 2331 } 2332 break; 2333 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: 2334 AsyncResult ar = (AsyncResult)msg.obj; 2335 Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>)ar.result; 2336 mDataRegState = drsRatPair.first; 2337 updateTcpBufferSizes(drsRatPair.second); 2338 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 2339 updateLinkBandwidthsFromCarrierConfig(drsRatPair.second); 2340 } 2341 mRilRat = drsRatPair.second; 2342 if (DBG) { 2343 log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED" 2344 + " regState=" + ServiceState.rilServiceStateToString(mDataRegState) 2345 + " RAT=" + ServiceState.rilRadioTechnologyToString(mRilRat)); 2346 } 2347 mDataCallSessionStats.onDrsOrRatChanged( 2348 ServiceState.rilRadioTechnologyToNetworkType(mRilRat)); 2349 break; 2350 2351 case EVENT_START_HANDOVER: //calls startHandover() 2352 if (DBG) { 2353 log("DcDefaultState: EVENT_START_HANDOVER not expected."); 2354 } 2355 Consumer<Integer> r = (Consumer<Integer>) msg.obj; 2356 r.accept(DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 2357 break; 2358 case EVENT_START_HANDOVER_ON_TARGET: 2359 if (DBG) { 2360 log("DcDefaultState: EVENT_START_HANDOVER not expected, but will " 2361 + "clean up, result code: " 2362 + DataServiceCallback.resultCodeToString(msg.arg1)); 2363 } 2364 ((Consumer<Boolean>) msg.obj).accept(false /* is in correct state*/); 2365 break; 2366 case EVENT_CANCEL_HANDOVER: 2367 // We don't need to do anything in this case 2368 if (DBG) { 2369 log("DcDefaultState: EVENT_CANCEL_HANDOVER resultCode=" 2370 + DataServiceCallback.resultCodeToString(msg.arg1)); 2371 } 2372 break; 2373 case EVENT_RELEASE_PDU_SESSION_ID: { 2374 // We do the same thing in all state in order to preserve the existing workflow 2375 final AsyncResult asyncResult = (AsyncResult) msg.obj; 2376 if (asyncResult == null) { 2377 loge("EVENT_RELEASE_PDU_SESSION_ID: asyncResult is null!"); 2378 } else { 2379 if (msg.obj != null) { 2380 if (DBG) logd("EVENT_RELEASE_PDU_SESSION_ID: id released"); 2381 Runnable runnable = (Runnable) asyncResult.userObj; 2382 runnable.run(); 2383 } else { 2384 loge("EVENT_RELEASE_PDU_SESSION_ID: no runnable set"); 2385 } 2386 } 2387 retVal = HANDLED; 2388 break; 2389 } 2390 case EVENT_ALLOCATE_PDU_SESSION_ID: { 2391 // We do the same thing in all state in order to preserve the existing workflow 2392 final AsyncResult asyncResult = (AsyncResult) msg.obj; 2393 if (asyncResult == null) { 2394 loge("EVENT_ALLOCATE_PDU_SESSION_ID: asyncResult is null!"); 2395 } else { 2396 Consumer<Integer> onAllocated = (Consumer<Integer>) asyncResult.userObj; 2397 if (asyncResult.exception != null) { 2398 loge("EVENT_ALLOCATE_PDU_SESSION_ID: exception", 2399 asyncResult.exception); 2400 onAllocated.accept(PDU_SESSION_ID_NOT_SET); 2401 } else if (asyncResult.result == null) { 2402 loge("EVENT_ALLOCATE_PDU_SESSION_ID: result null, no id"); 2403 onAllocated.accept(PDU_SESSION_ID_NOT_SET); 2404 } else { 2405 int psi = (int) asyncResult.result; 2406 if (DBG) logd("EVENT_ALLOCATE_PDU_SESSION_ID: psi=" + psi); 2407 onAllocated.accept(psi); 2408 } 2409 } 2410 retVal = HANDLED; 2411 break; 2412 } 2413 default: 2414 if (DBG) { 2415 log("DcDefaultState: ignore msg.what=" + getWhatToString(msg.what)); 2416 } 2417 break; 2418 } 2419 2420 return retVal; 2421 } 2422 } 2423 updateSuspendState()2424 private void updateSuspendState() { 2425 if (mNetworkAgent == null) { 2426 Rlog.d(getName(), "Setting suspend state without a NetworkAgent"); 2427 } 2428 2429 boolean newSuspendedState = false; 2430 // Data can only be (temporarily) suspended while data is in active state 2431 if (getCurrentState() == mActiveState) { 2432 // Never set suspended for emergency apn. Emergency data connection 2433 // can work while device is not in service. 2434 if (mApnSetting != null && mApnSetting.isEmergencyApn()) { 2435 newSuspendedState = false; 2436 // If we are not in service, change to suspended. 2437 } else if (mDataRegState != ServiceState.STATE_IN_SERVICE) { 2438 newSuspendedState = true; 2439 // Check voice/data concurrency. 2440 } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { 2441 newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE; 2442 } 2443 } 2444 2445 // Only notify when there is a change. 2446 if (mIsSuspended != newSuspendedState) { 2447 mIsSuspended = newSuspendedState; 2448 2449 // If data connection is active, we need to notify the new data connection state 2450 // changed event reflecting the latest suspended state. 2451 if (isActive()) { 2452 notifyDataConnectionState(); 2453 } 2454 } 2455 } 2456 notifyDataConnectionState()2457 private void notifyDataConnectionState() { 2458 // The receivers of this have no way to differentiate between default and enterprise 2459 // connections. Do not notify for enterprise. 2460 if (!isEnterpriseUse()) { 2461 mPhone.notifyDataConnection(getPreciseDataConnectionState()); 2462 } else { 2463 log("notifyDataConnectionState: Skipping for enterprise; state=" + getState()); 2464 } 2465 } 2466 2467 private DcDefaultState mDefaultState = new DcDefaultState(); 2468 getApnTypeBitmask()2469 private int getApnTypeBitmask() { 2470 return isEnterpriseUse() ? ApnSetting.TYPE_ENTERPRISE : 2471 mApnSetting != null ? mApnSetting.getApnTypeBitmask() : 0; 2472 } 2473 canHandleDefault()2474 private boolean canHandleDefault() { 2475 return !isEnterpriseUse() && mApnSetting != null 2476 ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false; 2477 } 2478 2479 /** 2480 * The state machine is inactive and expects a EVENT_CONNECT. 2481 */ 2482 private class DcInactiveState extends State { 2483 // Inform all contexts we've failed connecting setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause, @HandoverFailureMode int handoverFailureMode)2484 public void setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause, 2485 @HandoverFailureMode int handoverFailureMode) { 2486 if (VDBG) log("DcInactiveState: setEnterNotificationParams cp,cause"); 2487 mConnectionParams = cp; 2488 mDisconnectParams = null; 2489 mDcFailCause = cause; 2490 mHandoverFailureMode = handoverFailureMode; 2491 } 2492 2493 // Inform all contexts we've failed disconnected setEnterNotificationParams(DisconnectParams dp)2494 public void setEnterNotificationParams(DisconnectParams dp) { 2495 if (VDBG) log("DcInactiveState: setEnterNotificationParams dp"); 2496 mConnectionParams = null; 2497 mDisconnectParams = dp; 2498 mDcFailCause = DataFailCause.NONE; 2499 } 2500 2501 // Inform all contexts of the failure cause setEnterNotificationParams(@ataFailureCause int cause)2502 public void setEnterNotificationParams(@DataFailureCause int cause) { 2503 mConnectionParams = null; 2504 mDisconnectParams = null; 2505 mDcFailCause = cause; 2506 } 2507 2508 @Override enter()2509 public void enter() { 2510 mTag += 1; 2511 if (DBG) log("DcInactiveState: enter() mTag=" + mTag); 2512 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2513 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__INACTIVE, 2514 mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault()); 2515 mDataCallSessionStats.onDataCallDisconnected(mDcFailCause); 2516 if (mHandoverState == HANDOVER_STATE_BEING_TRANSFERRED) { 2517 // This is from source data connection to set itself's state 2518 setHandoverState(HANDOVER_STATE_COMPLETED); 2519 } 2520 2521 // Check for dangling agent. Ideally the handover source agent should be null if 2522 // handover process is smooth. When it's not null, that means handover failed. The 2523 // agent was not successfully transferred to the new data connection. We should 2524 // gracefully notify connectivity service the network was disconnected. 2525 if (mHandoverSourceNetworkAgent != null) { 2526 DataConnection sourceDc = mHandoverSourceNetworkAgent.getDataConnection(); 2527 if (sourceDc != null) { 2528 // If the source data connection still owns this agent, then just reset the 2529 // handover state back to idle because handover is already failed. 2530 mHandoverLocalLog.log( 2531 "Handover failed. Reset the source dc " + sourceDc.getName() 2532 + " state to idle"); 2533 sourceDc.cancelHandover(); 2534 } else { 2535 // The agent is now a dangling agent. No data connection owns this agent. 2536 // Gracefully notify connectivity service disconnected. 2537 mHandoverLocalLog.log( 2538 "Handover failed and dangling agent found."); 2539 mHandoverSourceNetworkAgent.acquireOwnership( 2540 DataConnection.this, mTransportType); 2541 log("Cleared dangling network agent. " + mHandoverSourceNetworkAgent); 2542 mHandoverSourceNetworkAgent.unregister(DataConnection.this); 2543 mHandoverSourceNetworkAgent.releaseOwnership(DataConnection.this); 2544 } 2545 mHandoverSourceNetworkAgent = null; 2546 } 2547 2548 if (mConnectionParams != null) { 2549 if (DBG) { 2550 log("DcInactiveState: enter notifyConnectCompleted +ALL failCause=" 2551 + DataFailCause.toString(mDcFailCause)); 2552 } 2553 notifyConnectCompleted(mConnectionParams, mDcFailCause, mHandoverFailureMode, 2554 true); 2555 } 2556 if (mDisconnectParams != null) { 2557 if (DBG) { 2558 log("DcInactiveState: enter notifyDisconnectCompleted +ALL failCause=" 2559 + DataFailCause.toString(mDcFailCause)); 2560 } 2561 notifyDisconnectCompleted(mDisconnectParams, true); 2562 } 2563 if (mDisconnectParams == null && mConnectionParams == null 2564 && mDcFailCause != DataFailCause.NONE) { 2565 if (DBG) { 2566 log("DcInactiveState: enter notifyAllDisconnectCompleted failCause=" 2567 + DataFailCause.toString(mDcFailCause)); 2568 } 2569 notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE, 2570 DataFailCause.toString(mDcFailCause)); 2571 } 2572 2573 // Remove ourselves from cid mapping, before clearSettings 2574 mDcController.removeActiveDcByCid(DataConnection.this); 2575 2576 // For the first time entering here (idle state before setup), do not notify 2577 // disconnected state. Only notify data connection disconnected for data that is 2578 // actually moving from disconnecting to disconnected, or setup failed. In both cases, 2579 // APN setting will not be null. 2580 if (mApnSetting != null) { 2581 notifyDataConnectionState(); 2582 } 2583 clearSettings(); 2584 } 2585 2586 @Override exit()2587 public void exit() { 2588 } 2589 2590 @Override processMessage(Message msg)2591 public boolean processMessage(Message msg) { 2592 switch (msg.what) { 2593 case EVENT_RESET: 2594 case EVENT_REEVALUATE_RESTRICTED_STATE: 2595 if (DBG) { 2596 log("DcInactiveState: msg.what=" + getWhatToString(msg.what) 2597 + ", ignore we're already done"); 2598 } 2599 return HANDLED; 2600 case EVENT_CONNECT: 2601 if (DBG) log("DcInactiveState: mag.what=EVENT_CONNECT"); 2602 ConnectionParams cp = (ConnectionParams) msg.obj; 2603 2604 if (!initConnection(cp)) { 2605 log("DcInactiveState: msg.what=EVENT_CONNECT initConnection failed"); 2606 notifyConnectCompleted(cp, DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER, 2607 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 2608 transitionTo(mInactiveState); 2609 return HANDLED; 2610 } 2611 2612 int cause = connect(cp); 2613 if (cause != DataFailCause.NONE) { 2614 log("DcInactiveState: msg.what=EVENT_CONNECT connect failed"); 2615 notifyConnectCompleted(cp, cause, 2616 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 2617 transitionTo(mInactiveState); 2618 return HANDLED; 2619 } 2620 2621 if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2622 mSubId = cp.mSubId; 2623 } 2624 2625 transitionTo(mActivatingState); 2626 return HANDLED; 2627 case EVENT_DISCONNECT: 2628 if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT"); 2629 notifyDisconnectCompleted((DisconnectParams)msg.obj, false); 2630 return HANDLED; 2631 case EVENT_DISCONNECT_ALL: 2632 if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL"); 2633 notifyDisconnectCompleted((DisconnectParams)msg.obj, false); 2634 return HANDLED; 2635 default: 2636 if (VDBG) { 2637 log("DcInactiveState not handled msg.what=" + getWhatToString(msg.what)); 2638 } 2639 return NOT_HANDLED; 2640 } 2641 } 2642 } 2643 private DcInactiveState mInactiveState = new DcInactiveState(); 2644 2645 /** 2646 * The state machine is activating a connection. 2647 */ 2648 private class DcActivatingState extends State { 2649 @Override enter()2650 public void enter() { 2651 int apnTypeBitmask = getApnTypeBitmask(); 2652 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2653 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVATING, 2654 mPhone.getPhoneId(), mId, apnTypeBitmask, canHandleDefault()); 2655 setHandoverState(HANDOVER_STATE_IDLE); 2656 // restricted evaluation depends on network requests from apnContext. The evaluation 2657 // should happen once entering connecting state rather than active state because it's 2658 // possible that restricted network request can be released during the connecting window 2659 // and if we wait for connection established, then we might mistakenly 2660 // consider it as un-restricted. ConnectivityService then will immediately 2661 // tear down the connection through networkAgent unwanted callback if all requests for 2662 // this connection are going away. 2663 mRestrictedNetworkOverride = shouldRestrictNetwork(); 2664 2665 CarrierPrivilegesTracker carrierPrivTracker = mPhone.getCarrierPrivilegesTracker(); 2666 if (carrierPrivTracker != null) { 2667 carrierPrivTracker.registerCarrierPrivilegesListener( 2668 getHandler(), EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null); 2669 } 2670 notifyDataConnectionState(); 2671 mDataCallSessionStats.onSetupDataCall(apnTypeBitmask); 2672 } 2673 @Override processMessage(Message msg)2674 public boolean processMessage(Message msg) { 2675 boolean retVal; 2676 AsyncResult ar; 2677 ConnectionParams cp; 2678 2679 if (DBG) log("DcActivatingState: msg=" + msgToString(msg)); 2680 switch (msg.what) { 2681 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: 2682 case EVENT_CONNECT: 2683 // Activating can't process until we're done. 2684 deferMessage(msg); 2685 retVal = HANDLED; 2686 break; 2687 2688 case EVENT_SETUP_DATA_CONNECTION_DONE: 2689 cp = (ConnectionParams) msg.obj; 2690 2691 DataCallResponse dataCallResponse = 2692 msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE); 2693 SetupResult result = onSetupConnectionCompleted(msg.arg1, dataCallResponse, cp); 2694 if (result != SetupResult.ERROR_STALE) { 2695 if (mConnectionParams != cp) { 2696 loge("DcActivatingState: WEIRD mConnectionsParams:"+ mConnectionParams 2697 + " != cp:" + cp); 2698 } 2699 } 2700 if (DBG) { 2701 log("DcActivatingState onSetupConnectionCompleted result=" + result 2702 + " dc=" + DataConnection.this); 2703 } 2704 ApnContext.requestLog( 2705 cp.mApnContext, "onSetupConnectionCompleted result=" + result); 2706 switch (result) { 2707 case SUCCESS: 2708 // All is well 2709 mDcFailCause = DataFailCause.NONE; 2710 transitionTo(mActiveState); 2711 break; 2712 case ERROR_RADIO_NOT_AVAILABLE: 2713 // Vendor ril rejected the command and didn't connect. 2714 // Transition to inactive but send notifications after 2715 // we've entered the mInactive state. 2716 mInactiveState.setEnterNotificationParams(cp, result.mFailCause, 2717 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN); 2718 transitionTo(mInactiveState); 2719 break; 2720 case ERROR_DUPLICATE_CID: 2721 // TODO (b/180988471): Properly handle the case when an existing cid is 2722 // returned by tearing down the network agent if enterprise changed. 2723 long retry = RetryManager.NO_SUGGESTED_RETRY_DELAY; 2724 if (cp.mApnContext != null) { 2725 retry = RetryManager.NO_RETRY; 2726 mDct.getDataThrottler().setRetryTime( 2727 cp.mApnContext.getApnTypeBitmask(), 2728 retry, DcTracker.REQUEST_TYPE_NORMAL); 2729 } 2730 String logStr = "DcActivatingState: " 2731 + DataFailCause.toString(result.mFailCause) 2732 + " retry=" + retry; 2733 if (DBG) log(logStr); 2734 ApnContext.requestLog(cp.mApnContext, logStr); 2735 mInactiveState.setEnterNotificationParams(cp, result.mFailCause, 2736 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN); 2737 transitionTo(mInactiveState); 2738 break; 2739 case ERROR_NO_DEFAULT_CONNECTION: 2740 // TODO (b/180988471): Properly handle the case when a default data 2741 // connection doesn't exist (tear down connection and retry). 2742 // Currently, this just tears down the connection without retry. 2743 if (DBG) log("DcActivatingState: NO_DEFAULT_DATA"); 2744 case ERROR_INVALID_ARG: 2745 // The addresses given from the RIL are bad 2746 tearDownData(cp); 2747 transitionTo(mDisconnectingErrorCreatingConnection); 2748 break; 2749 case ERROR_DATA_SERVICE_SPECIFIC_ERROR: 2750 2751 // Retrieve the suggested retry delay from the modem and save it. 2752 // If the modem want us to retry the current APN again, it will 2753 // suggest a positive delay value (in milliseconds). Otherwise we'll get 2754 // NO_SUGGESTED_RETRY_DELAY here. 2755 2756 long delay = getSuggestedRetryDelay(dataCallResponse); 2757 long retryTime = RetryManager.NO_SUGGESTED_RETRY_DELAY; 2758 if (delay == RetryManager.NO_RETRY) { 2759 retryTime = RetryManager.NO_RETRY; 2760 } else if (delay >= 0) { 2761 retryTime = SystemClock.elapsedRealtime() + delay; 2762 } 2763 int newRequestType = DcTracker.calculateNewRetryRequestType( 2764 mHandoverFailureMode, cp.mRequestType, mDcFailCause); 2765 mDct.getDataThrottler().setRetryTime(getApnTypeBitmask(), 2766 retryTime, newRequestType); 2767 2768 String str = "DcActivatingState: ERROR_DATA_SERVICE_SPECIFIC_ERROR " 2769 + " delay=" + delay 2770 + " result=" + result 2771 + " result.isRadioRestartFailure=" 2772 + DataFailCause.isRadioRestartFailure(mPhone.getContext(), 2773 result.mFailCause, mPhone.getSubId()) 2774 + " isPermanentFailure=" + 2775 mDct.isPermanentFailure(result.mFailCause); 2776 if (DBG) log(str); 2777 ApnContext.requestLog(cp.mApnContext, str); 2778 2779 // Save the cause. DcTracker.onDataSetupComplete will check this 2780 // failure cause and determine if we need to retry this APN later 2781 // or not. 2782 mInactiveState.setEnterNotificationParams(cp, result.mFailCause, 2783 dataCallResponse != null 2784 ? dataCallResponse.getHandoverFailureMode() 2785 : DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN); 2786 transitionTo(mInactiveState); 2787 break; 2788 case ERROR_STALE: 2789 loge("DcActivatingState: stale EVENT_SETUP_DATA_CONNECTION_DONE" 2790 + " tag:" + cp.mTag + " != mTag:" + mTag); 2791 break; 2792 default: 2793 throw new RuntimeException("Unknown SetupResult, should not happen"); 2794 } 2795 retVal = HANDLED; 2796 mDataCallSessionStats 2797 .onSetupDataCallResponse(dataCallResponse, 2798 ServiceState.rilRadioTechnologyToNetworkType(cp.mRilRat), 2799 getApnTypeBitmask(), mApnSetting.getProtocol(), 2800 result.mFailCause); 2801 break; 2802 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: 2803 AsyncResult asyncResult = (AsyncResult) msg.obj; 2804 int[] administratorUids = (int[]) asyncResult.result; 2805 mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); 2806 retVal = HANDLED; 2807 break; 2808 case EVENT_START_HANDOVER_ON_TARGET: 2809 //called after startHandover on target transport 2810 ((Consumer<Boolean>) msg.obj).accept(true /* is in correct state*/); 2811 retVal = HANDLED; 2812 break; 2813 case EVENT_CANCEL_HANDOVER: 2814 transitionTo(mInactiveState); 2815 retVal = HANDLED; 2816 break; 2817 default: 2818 if (VDBG) { 2819 log("DcActivatingState not handled msg.what=" + 2820 getWhatToString(msg.what) + " RefCount=" + mApnContexts.size()); 2821 } 2822 retVal = NOT_HANDLED; 2823 break; 2824 } 2825 return retVal; 2826 } 2827 } 2828 private DcActivatingState mActivatingState = new DcActivatingState(); 2829 2830 /** 2831 * The state machine is connected, expecting an EVENT_DISCONNECT. 2832 */ 2833 private class DcActiveState extends State { 2834 enter()2835 @Override public void enter() { 2836 if (DBG) log("DcActiveState: enter dc=" + DataConnection.this); 2837 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2838 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVE, 2839 mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault()); 2840 // If we were retrying there maybe more than one, otherwise they'll only be one. 2841 notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE, 2842 Phone.REASON_CONNECTED); 2843 2844 mPhone.getCallTracker().registerForVoiceCallStarted(getHandler(), 2845 DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED, null); 2846 mPhone.getCallTracker().registerForVoiceCallEnded(getHandler(), 2847 DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED, null); 2848 2849 // If the EVENT_CONNECT set the current max retry restore it here 2850 // if it didn't then this is effectively a NOP. 2851 mDcController.addActiveDcByCid(DataConnection.this); 2852 2853 updateTcpBufferSizes(mRilRat); 2854 updateLinkBandwidthsFromCarrierConfig(mRilRat); 2855 2856 final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder(); 2857 configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE); 2858 configBuilder.setLegacyTypeName(NETWORK_TYPE); 2859 int networkType = getNetworkType(); 2860 configBuilder.setLegacySubType(networkType); 2861 configBuilder.setLegacySubTypeName(TelephonyManager.getNetworkTypeName(networkType)); 2862 configBuilder.setLegacyExtraInfo(mApnSetting.getApnName()); 2863 final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent(); 2864 if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager 2865 .ACTION_CARRIER_SIGNAL_REDIRECTED)) { 2866 // carrierSignal Receivers will place the carrier-specific provisioning notification 2867 configBuilder.setProvisioningNotificationEnabled(false); 2868 } 2869 2870 final String subscriberId = mPhone.getSubscriberId(); 2871 if (!TextUtils.isEmpty(subscriberId)) { 2872 configBuilder.setSubscriberId(subscriberId); 2873 } 2874 2875 // set skip464xlat if it is not default otherwise 2876 if (shouldSkip464Xlat()) { 2877 configBuilder.setNat64DetectionEnabled(false); 2878 } 2879 2880 mUnmeteredUseOnly = isUnmeteredUseOnly(); 2881 mMmsUseOnly = isMmsUseOnly(); 2882 mEnterpriseUse = isEnterpriseUse(); 2883 2884 if (DBG) { 2885 log("mRestrictedNetworkOverride = " + mRestrictedNetworkOverride 2886 + ", mUnmeteredUseOnly = " + mUnmeteredUseOnly 2887 + ", mMmsUseOnly = " + mMmsUseOnly 2888 + ", mEnterpriseUse = " + mEnterpriseUse); 2889 } 2890 2891 // Always register a VcnNetworkPolicyChangeListener, regardless of whether this is a 2892 // handover 2893 // or new Network. 2894 mVcnManager.addVcnNetworkPolicyChangeListener( 2895 new HandlerExecutor(getHandler()), mVcnPolicyChangeListener); 2896 2897 if (mConnectionParams != null 2898 && mConnectionParams.mRequestType == REQUEST_TYPE_HANDOVER) { 2899 // If this is a data setup for handover, we need to reuse the existing network agent 2900 // instead of creating a new one. This should be transparent to connectivity 2901 // service. 2902 DcTracker dcTracker = mPhone.getDcTracker(getHandoverSourceTransport()); 2903 DataConnection dc = dcTracker.getDataConnectionByApnType( 2904 mConnectionParams.mApnContext.getApnType()); 2905 // It's possible that the source data connection has been disconnected by the modem 2906 // already. If not, set its handover state to completed. 2907 if (dc != null) { 2908 // Transfer network agent from the original data connection as soon as the 2909 // new handover data connection is connected. 2910 dc.setHandoverState(HANDOVER_STATE_COMPLETED); 2911 } 2912 2913 if (mHandoverSourceNetworkAgent != null) { 2914 String logStr = "Transfer network agent " + mHandoverSourceNetworkAgent.getTag() 2915 + " successfully."; 2916 log(logStr); 2917 mHandoverLocalLog.log(logStr); 2918 mNetworkAgent = mHandoverSourceNetworkAgent; 2919 mNetworkAgent.acquireOwnership(DataConnection.this, mTransportType); 2920 2921 // TODO: Should evaluate mDisabledApnTypeBitMask again after handover. We don't 2922 // do it now because connectivity service does not support dynamically removing 2923 // immutable capabilities. 2924 2925 mNetworkAgent.updateLegacySubtype(DataConnection.this); 2926 // Update the capability after handover 2927 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2928 DataConnection.this); 2929 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 2930 mHandoverSourceNetworkAgent = null; 2931 } else { 2932 String logStr = "Failed to get network agent from original data connection"; 2933 loge(logStr); 2934 mHandoverLocalLog.log(logStr); 2935 return; 2936 } 2937 } else { 2938 mScore = calculateScore(); 2939 final NetworkFactory factory = PhoneFactory.getNetworkFactory( 2940 mPhone.getPhoneId()); 2941 final NetworkProvider provider = (null == factory) ? null : factory.getProvider(); 2942 2943 mDisabledApnTypeBitMask |= getDisallowedApnTypes(); 2944 updateLinkPropertiesHttpProxy(); 2945 mNetworkAgent = new DcNetworkAgent(DataConnection.this, mPhone, mScore, 2946 configBuilder.build(), provider, mTransportType); 2947 2948 VcnNetworkPolicyResult policyResult = 2949 mVcnManager.applyVcnNetworkPolicy( 2950 getNetworkCapabilities(), getLinkProperties()); 2951 if (policyResult.isTeardownRequested()) { 2952 tearDownAll( 2953 Phone.REASON_VCN_REQUESTED_TEARDOWN, 2954 DcTracker.RELEASE_TYPE_DETACH, 2955 null /* onCompletedMsg */); 2956 } else { 2957 // All network agents start out in CONNECTING mode, but DcNetworkAgents are 2958 // created when the network is already connected. Hence, send the connected 2959 // notification immediately. 2960 mNetworkAgent.markConnected(); 2961 } 2962 2963 // The network agent is always created with NOT_SUSPENDED capability, but the 2964 // network might be already out of service (or voice call is ongoing) just right 2965 // before data connection is created. Connectivity service would not allow a network 2966 // created with suspended state, so we create a non-suspended network first, and 2967 // then immediately evaluate the suspended state. 2968 sendMessage(obtainMessage(EVENT_UPDATE_SUSPENDED_STATE)); 2969 } 2970 2971 // The qos parameters are set when the call is connected 2972 syncQosToNetworkAgent(); 2973 2974 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 2975 mPhone.mCi.registerForNattKeepaliveStatus( 2976 getHandler(), DataConnection.EVENT_KEEPALIVE_STATUS, null); 2977 mPhone.mCi.registerForLceInfo( 2978 getHandler(), DataConnection.EVENT_LINK_CAPACITY_CHANGED, null); 2979 } 2980 notifyDataConnectionState(); 2981 TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(), 2982 mCid, getApnTypeBitmask(), RilDataCall.State.CONNECTED); 2983 } 2984 2985 @Override exit()2986 public void exit() { 2987 if (DBG) log("DcActiveState: exit dc=" + this); 2988 mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler()); 2989 mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler()); 2990 2991 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 2992 mPhone.mCi.unregisterForNattKeepaliveStatus(getHandler()); 2993 mPhone.mCi.unregisterForLceInfo(getHandler()); 2994 } 2995 2996 // If we are still owning this agent, then we should inform connectivity service the 2997 // data connection is disconnected. There is one exception that we shouldn't unregister, 2998 // which is when IWLAN handover is ongoing. Instead of unregistering, the agent will 2999 // be transferred to the new data connection on the other transport. 3000 if (mNetworkAgent != null) { 3001 syncQosToNetworkAgent(); 3002 if (mHandoverState == HANDOVER_STATE_IDLE) { 3003 mNetworkAgent.unregister(DataConnection.this); 3004 } 3005 mNetworkAgent.releaseOwnership(DataConnection.this); 3006 } 3007 mNetworkAgent = null; 3008 3009 TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(), 3010 mCid, getApnTypeBitmask(), RilDataCall.State.DISCONNECTED); 3011 3012 mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener); 3013 3014 CarrierPrivilegesTracker carrierPrivTracker = mPhone.getCarrierPrivilegesTracker(); 3015 if (carrierPrivTracker != null) { 3016 carrierPrivTracker.unregisterCarrierPrivilegesListener(getHandler()); 3017 } 3018 } 3019 3020 @Override processMessage(Message msg)3021 public boolean processMessage(Message msg) { 3022 boolean retVal; 3023 3024 switch (msg.what) { 3025 case EVENT_CONNECT: { 3026 ConnectionParams cp = (ConnectionParams) msg.obj; 3027 // either add this new apn context to our set or 3028 // update the existing cp with the latest connection generation number 3029 mApnContexts.put(cp.mApnContext, cp); 3030 // TODO (b/118347948): evaluate if it's still needed after assigning 3031 // different scores to different Cellular network. 3032 mDisabledApnTypeBitMask &= ~cp.mApnContext.getApnTypeBitmask(); 3033 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3034 DataConnection.this); 3035 if (DBG) { 3036 log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this); 3037 } 3038 notifyConnectCompleted(cp, DataFailCause.NONE, 3039 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 3040 retVal = HANDLED; 3041 break; 3042 } 3043 case EVENT_DISCONNECT: { 3044 DisconnectParams dp = (DisconnectParams) msg.obj; 3045 if (DBG) { 3046 log("DcActiveState: EVENT_DISCONNECT dp=" + dp 3047 + " dc=" + DataConnection.this); 3048 } 3049 if (mApnContexts.containsKey(dp.mApnContext)) { 3050 if (DBG) { 3051 log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" 3052 + mApnContexts.size()); 3053 } 3054 3055 if (mApnContexts.size() == 1) { 3056 mApnContexts.clear(); 3057 mDisconnectParams = dp; 3058 mConnectionParams = null; 3059 dp.mTag = mTag; 3060 tearDownData(dp); 3061 transitionTo(mDisconnectingState); 3062 } else { 3063 mApnContexts.remove(dp.mApnContext); 3064 // TODO (b/118347948): evaluate if it's still needed after assigning 3065 // different scores to different Cellular network. 3066 mDisabledApnTypeBitMask |= dp.mApnContext.getApnTypeBitmask(); 3067 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3068 DataConnection.this); 3069 notifyDisconnectCompleted(dp, false); 3070 } 3071 } else { 3072 log("DcActiveState ERROR no such apnContext=" + dp.mApnContext 3073 + " in this dc=" + DataConnection.this); 3074 notifyDisconnectCompleted(dp, false); 3075 } 3076 retVal = HANDLED; 3077 break; 3078 } 3079 case EVENT_DISCONNECT_ALL: { 3080 if (DBG) { 3081 log("DcActiveState EVENT_DISCONNECT clearing apn contexts," 3082 + " dc=" + DataConnection.this); 3083 } 3084 DisconnectParams dp = (DisconnectParams) msg.obj; 3085 mDisconnectParams = dp; 3086 mConnectionParams = null; 3087 dp.mTag = mTag; 3088 tearDownData(dp); 3089 transitionTo(mDisconnectingState); 3090 retVal = HANDLED; 3091 break; 3092 } 3093 case EVENT_LOST_CONNECTION: { 3094 if (DBG) { 3095 log("DcActiveState EVENT_LOST_CONNECTION dc=" + DataConnection.this); 3096 } 3097 3098 mInactiveState.setEnterNotificationParams(DataFailCause.LOST_CONNECTION); 3099 transitionTo(mInactiveState); 3100 retVal = HANDLED; 3101 break; 3102 } 3103 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: { 3104 AsyncResult ar = (AsyncResult) msg.obj; 3105 Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>) ar.result; 3106 mDataRegState = drsRatPair.first; 3107 updateTcpBufferSizes(drsRatPair.second); 3108 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 3109 updateLinkBandwidthsFromCarrierConfig(drsRatPair.second); 3110 } 3111 mRilRat = drsRatPair.second; 3112 if (DBG) { 3113 log("DcActiveState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED" 3114 + " drs=" + mDataRegState 3115 + " mRilRat=" + mRilRat); 3116 } 3117 updateSuspendState(); 3118 if (mNetworkAgent != null) { 3119 mNetworkAgent.updateLegacySubtype(DataConnection.this); 3120 // The new suspended state will be passed through connectivity service 3121 // through NET_CAPABILITY_NOT_SUSPENDED. 3122 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3123 DataConnection.this); 3124 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 3125 } 3126 retVal = HANDLED; 3127 mDataCallSessionStats.onDrsOrRatChanged( 3128 ServiceState.rilRadioTechnologyToNetworkType(mRilRat)); 3129 break; 3130 } 3131 case EVENT_NR_FREQUENCY_CHANGED: 3132 // fallthrough 3133 case EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED: 3134 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 3135 updateLinkBandwidthsFromCarrierConfig(mRilRat); 3136 } 3137 if (mNetworkAgent != null) { 3138 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3139 DataConnection.this); 3140 } 3141 retVal = HANDLED; 3142 break; 3143 case EVENT_DATA_CONNECTION_METEREDNESS_CHANGED: 3144 boolean isUnmetered = (boolean) msg.obj; 3145 if (isUnmetered == mUnmeteredOverride) { 3146 retVal = HANDLED; 3147 break; 3148 } 3149 mUnmeteredOverride = isUnmetered; 3150 if (mNetworkAgent != null) { 3151 mNetworkAgent.updateLegacySubtype(DataConnection.this); 3152 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3153 DataConnection.this); 3154 } 3155 retVal = HANDLED; 3156 break; 3157 case EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED: 3158 boolean isCongested = (boolean) msg.obj; 3159 if (isCongested == mCongestedOverride) { 3160 retVal = HANDLED; 3161 break; 3162 } 3163 mCongestedOverride = isCongested; 3164 if (mNetworkAgent != null) { 3165 mNetworkAgent.updateLegacySubtype(DataConnection.this); 3166 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3167 DataConnection.this); 3168 } 3169 retVal = HANDLED; 3170 break; 3171 case EVENT_DATA_CONNECTION_ROAM_ON: 3172 case EVENT_DATA_CONNECTION_ROAM_OFF: { 3173 if (mNetworkAgent != null) { 3174 mNetworkAgent.updateLegacySubtype(DataConnection.this); 3175 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3176 DataConnection.this); 3177 } 3178 retVal = HANDLED; 3179 break; 3180 } 3181 case EVENT_DATA_CONNECTION_VOICE_CALL_STARTED: 3182 case EVENT_DATA_CONNECTION_VOICE_CALL_ENDED: 3183 case EVENT_CSS_INDICATOR_CHANGED: 3184 case EVENT_UPDATE_SUSPENDED_STATE: { 3185 updateSuspendState(); 3186 if (mNetworkAgent != null) { 3187 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3188 DataConnection.this); 3189 } 3190 retVal = HANDLED; 3191 break; 3192 } 3193 case EVENT_BW_REFRESH_RESPONSE: { 3194 AsyncResult ar = (AsyncResult)msg.obj; 3195 if (ar.exception != null) { 3196 log("EVENT_BW_REFRESH_RESPONSE: error ignoring, e=" + ar.exception); 3197 } else { 3198 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) { 3199 updateLinkBandwidthsFromModem((List<LinkCapacityEstimate>) ar.result); 3200 } 3201 } 3202 retVal = HANDLED; 3203 break; 3204 } 3205 case EVENT_KEEPALIVE_START_REQUEST: { 3206 KeepalivePacketData pkt = (KeepalivePacketData) msg.obj; 3207 int slotId = msg.arg1; 3208 int intervalMillis = msg.arg2 * 1000; 3209 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 3210 mPhone.mCi.startNattKeepalive( 3211 DataConnection.this.mCid, pkt, intervalMillis, 3212 DataConnection.this.obtainMessage( 3213 EVENT_KEEPALIVE_STARTED, slotId, 0, null)); 3214 } else { 3215 // We currently do not support NATT Keepalive requests using the 3216 // DataService API, so unless the request is WWAN (always bound via 3217 // the CommandsInterface), the request cannot be honored. 3218 // 3219 // TODO: b/72331356 to add support for Keepalive to the DataService 3220 // so that keepalive requests can be handled (if supported) by the 3221 // underlying transport. 3222 if (mNetworkAgent != null) { 3223 mNetworkAgent.sendSocketKeepaliveEvent( 3224 msg.arg1, SocketKeepalive.ERROR_INVALID_NETWORK); 3225 } 3226 } 3227 retVal = HANDLED; 3228 break; 3229 } 3230 case EVENT_KEEPALIVE_STOP_REQUEST: { 3231 int slotId = msg.arg1; 3232 int handle = mNetworkAgent.keepaliveTracker.getHandleForSlot(slotId); 3233 if (handle < 0) { 3234 loge("No slot found for stopSocketKeepalive! " + slotId); 3235 mNetworkAgent.sendSocketKeepaliveEvent( 3236 slotId, SocketKeepalive.ERROR_NO_SUCH_SLOT); 3237 retVal = HANDLED; 3238 break; 3239 } else { 3240 logd("Stopping keepalive with handle: " + handle); 3241 } 3242 3243 mPhone.mCi.stopNattKeepalive( 3244 handle, DataConnection.this.obtainMessage( 3245 EVENT_KEEPALIVE_STOPPED, handle, slotId, null)); 3246 retVal = HANDLED; 3247 break; 3248 } 3249 case EVENT_KEEPALIVE_STARTED: { 3250 AsyncResult ar = (AsyncResult) msg.obj; 3251 final int slot = msg.arg1; 3252 if (ar.exception != null || ar.result == null) { 3253 loge("EVENT_KEEPALIVE_STARTED: error starting keepalive, e=" 3254 + ar.exception); 3255 mNetworkAgent.sendSocketKeepaliveEvent( 3256 slot, SocketKeepalive.ERROR_HARDWARE_ERROR); 3257 } else { 3258 KeepaliveStatus ks = (KeepaliveStatus) ar.result; 3259 if (ks == null) { 3260 loge("Null KeepaliveStatus received!"); 3261 } else { 3262 mNetworkAgent.keepaliveTracker.handleKeepaliveStarted(slot, ks); 3263 } 3264 } 3265 retVal = HANDLED; 3266 break; 3267 } 3268 case EVENT_KEEPALIVE_STATUS: { 3269 AsyncResult ar = (AsyncResult) msg.obj; 3270 if (ar.exception != null) { 3271 loge("EVENT_KEEPALIVE_STATUS: error in keepalive, e=" + ar.exception); 3272 // We have no way to notify connectivity in this case. 3273 } 3274 if (ar.result != null) { 3275 KeepaliveStatus ks = (KeepaliveStatus) ar.result; 3276 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(ks); 3277 } 3278 3279 retVal = HANDLED; 3280 break; 3281 } 3282 case EVENT_KEEPALIVE_STOPPED: { 3283 AsyncResult ar = (AsyncResult) msg.obj; 3284 final int handle = msg.arg1; 3285 final int slotId = msg.arg2; 3286 3287 if (ar.exception != null) { 3288 loge("EVENT_KEEPALIVE_STOPPED: error stopping keepalive for handle=" 3289 + handle + " e=" + ar.exception); 3290 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus( 3291 new KeepaliveStatus(KeepaliveStatus.ERROR_UNKNOWN)); 3292 } else { 3293 log("Keepalive Stop Requested for handle=" + handle); 3294 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus( 3295 new KeepaliveStatus( 3296 handle, KeepaliveStatus.STATUS_INACTIVE)); 3297 } 3298 retVal = HANDLED; 3299 break; 3300 } 3301 case EVENT_LINK_CAPACITY_CHANGED: { 3302 AsyncResult ar = (AsyncResult) msg.obj; 3303 if (ar.exception != null) { 3304 loge("EVENT_LINK_CAPACITY_CHANGED e=" + ar.exception); 3305 } else { 3306 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) { 3307 updateLinkBandwidthsFromModem((List<LinkCapacityEstimate>) ar.result); 3308 } 3309 } 3310 retVal = HANDLED; 3311 break; 3312 } 3313 case EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE: { 3314 AsyncResult ar = (AsyncResult) msg.obj; 3315 if (ar.exception != null) { 3316 loge("EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE e=" + ar.exception); 3317 } else { 3318 Pair<Integer, Integer> pair = (Pair<Integer, Integer>) ar.result; 3319 if (isBandwidthSourceKey( 3320 DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) { 3321 updateLinkBandwidthsFromBandwidthEstimator(pair.first, pair.second); 3322 } 3323 } 3324 retVal = HANDLED; 3325 break; 3326 } 3327 case EVENT_REEVALUATE_RESTRICTED_STATE: { 3328 // If the network was restricted, and now it does not need to be restricted 3329 // anymore, we should add the NET_CAPABILITY_NOT_RESTRICTED capability. 3330 if (mRestrictedNetworkOverride && !shouldRestrictNetwork()) { 3331 if (DBG) { 3332 log("Data connection becomes not-restricted. dc=" + this); 3333 } 3334 // Note we only do this when network becomes non-restricted. When a 3335 // non-restricted becomes restricted (e.g. users disable data, or turn off 3336 // data roaming), DCT will explicitly tear down the networks (because 3337 // connectivity service does not support force-close TCP connections today). 3338 // Also note that NET_CAPABILITY_NOT_RESTRICTED is an immutable capability 3339 // (see {@link NetworkCapabilities}) once we add it to the network, we can't 3340 // remove it through the entire life cycle of the connection. 3341 mRestrictedNetworkOverride = false; 3342 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3343 DataConnection.this); 3344 } 3345 3346 // If the data does need to be unmetered use only (e.g. users turn on data, or 3347 // device is not roaming anymore assuming data roaming is off), then we can 3348 // dynamically add those metered APN type capabilities back. (But not the 3349 // other way around because most of the APN-type capabilities are immutable 3350 // capabilities.) 3351 if (mUnmeteredUseOnly && !isUnmeteredUseOnly()) { 3352 mUnmeteredUseOnly = false; 3353 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3354 DataConnection.this); 3355 } 3356 3357 mMmsUseOnly = isMmsUseOnly(); 3358 3359 retVal = HANDLED; 3360 break; 3361 } 3362 case EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES: { 3363 // Update other properties like link properties if needed in future. 3364 updateScore(); 3365 retVal = HANDLED; 3366 break; 3367 } 3368 case EVENT_NR_STATE_CHANGED: { 3369 updateTcpBufferSizes(mRilRat); 3370 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 3371 updateLinkBandwidthsFromCarrierConfig(mRilRat); 3372 } 3373 if (mNetworkAgent != null) { 3374 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 3375 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3376 DataConnection.this); 3377 } 3378 retVal = HANDLED; 3379 break; 3380 } 3381 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: 3382 AsyncResult asyncResult = (AsyncResult) msg.obj; 3383 int[] administratorUids = (int[]) asyncResult.result; 3384 mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); 3385 3386 // Administrator UIDs changed, so update NetworkAgent with new 3387 // NetworkCapabilities 3388 if (mNetworkAgent != null) { 3389 mNetworkAgent.sendNetworkCapabilities( 3390 getNetworkCapabilities(), DataConnection.this); 3391 } 3392 retVal = HANDLED; 3393 break; 3394 case EVENT_START_HANDOVER: //calls startHandover() 3395 Consumer<Integer> r = (Consumer<Integer>) msg.obj; 3396 r.accept(msg.arg1); 3397 retVal = HANDLED; 3398 break; 3399 3400 default: 3401 if (VDBG) { 3402 log("DcActiveState not handled msg.what=" + getWhatToString(msg.what)); 3403 } 3404 retVal = NOT_HANDLED; 3405 break; 3406 } 3407 return retVal; 3408 } 3409 } 3410 private DcActiveState mActiveState = new DcActiveState(); 3411 3412 /** 3413 * The state machine is disconnecting. 3414 */ 3415 private class DcDisconnectingState extends State { 3416 @Override enter()3417 public void enter() { 3418 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 3419 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTING, 3420 mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault()); 3421 notifyDataConnectionState(); 3422 } 3423 @Override processMessage(Message msg)3424 public boolean processMessage(Message msg) { 3425 boolean retVal; 3426 3427 switch (msg.what) { 3428 case EVENT_CONNECT: 3429 if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = " 3430 + mApnContexts.size()); 3431 deferMessage(msg); 3432 retVal = HANDLED; 3433 break; 3434 3435 case EVENT_DEACTIVATE_DONE: 3436 DisconnectParams dp = (DisconnectParams) msg.obj; 3437 3438 String str = "DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE RefCount=" 3439 + mApnContexts.size(); 3440 3441 if (DBG) log(str); 3442 ApnContext.requestLog(dp.mApnContext, str); 3443 3444 // Clear out existing qos sessions 3445 updateQosParameters(null); 3446 3447 if (dp.mTag == mTag) { 3448 // Transition to inactive but send notifications after 3449 // we've entered the mInactive state. 3450 mInactiveState.setEnterNotificationParams(dp); 3451 transitionTo(mInactiveState); 3452 } else { 3453 if (DBG) log("DcDisconnectState stale EVENT_DEACTIVATE_DONE" 3454 + " dp.tag=" + dp.mTag + " mTag=" + mTag); 3455 } 3456 retVal = HANDLED; 3457 break; 3458 3459 default: 3460 if (VDBG) { 3461 log("DcDisconnectingState not handled msg.what=" 3462 + getWhatToString(msg.what)); 3463 } 3464 retVal = NOT_HANDLED; 3465 break; 3466 } 3467 return retVal; 3468 } 3469 } 3470 private DcDisconnectingState mDisconnectingState = new DcDisconnectingState(); 3471 3472 /** 3473 * The state machine is disconnecting after an creating a connection. 3474 */ 3475 private class DcDisconnectionErrorCreatingConnection extends State { 3476 @Override enter()3477 public void enter() { 3478 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 3479 TelephonyStatsLog 3480 .MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTION_ERROR_CREATING_CONNECTION, 3481 mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault()); 3482 notifyDataConnectionState(); 3483 } 3484 @Override processMessage(Message msg)3485 public boolean processMessage(Message msg) { 3486 boolean retVal; 3487 3488 switch (msg.what) { 3489 case EVENT_DEACTIVATE_DONE: 3490 ConnectionParams cp = (ConnectionParams) msg.obj; 3491 if (cp.mTag == mTag) { 3492 String str = "DcDisconnectionErrorCreatingConnection" + 3493 " msg.what=EVENT_DEACTIVATE_DONE"; 3494 if (DBG) log(str); 3495 ApnContext.requestLog(cp.mApnContext, str); 3496 3497 // Transition to inactive but send notifications after 3498 // we've entered the mInactive state. 3499 mInactiveState.setEnterNotificationParams(cp, 3500 DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER, 3501 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN); 3502 transitionTo(mInactiveState); 3503 } else { 3504 if (DBG) { 3505 log("DcDisconnectionErrorCreatingConnection stale EVENT_DEACTIVATE_DONE" 3506 + " dp.tag=" + cp.mTag + ", mTag=" + mTag); 3507 } 3508 } 3509 retVal = HANDLED; 3510 break; 3511 3512 default: 3513 if (VDBG) { 3514 log("DcDisconnectionErrorCreatingConnection not handled msg.what=" 3515 + getWhatToString(msg.what)); 3516 } 3517 retVal = NOT_HANDLED; 3518 break; 3519 } 3520 return retVal; 3521 } 3522 } 3523 private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection = 3524 new DcDisconnectionErrorCreatingConnection(); 3525 3526 /** 3527 * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg. 3528 * Used for cellular networks that use Access Point Names (APN) such 3529 * as GSM networks. 3530 * 3531 * @param apnContext is the Access Point Name to bring up a connection to 3532 * @param profileId for the connection 3533 * @param rilRadioTechnology Radio technology for the data connection 3534 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 3535 * With AsyncResult.userObj set to the original msg.obj, 3536 * AsyncResult.result = FailCause and AsyncResult.exception = Exception(). 3537 * @param connectionGeneration used to track a single connection request so disconnects can get 3538 * ignored if obsolete. 3539 * @param requestType Data request type 3540 * @param subId the subscription id associated with this data connection. 3541 * @param isApnPreferred whether or not the apn is preferred. 3542 */ bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isApnPreferred)3543 public void bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology, 3544 Message onCompletedMsg, int connectionGeneration, 3545 @RequestNetworkType int requestType, int subId, boolean isApnPreferred) { 3546 if (DBG) { 3547 log("bringUp: apnContext=" + apnContext + " onCompletedMsg=" + onCompletedMsg); 3548 } 3549 3550 if (mApnSetting == null) { 3551 mApnSetting = apnContext.getApnSetting(); 3552 } 3553 3554 sendMessage(DataConnection.EVENT_CONNECT, 3555 new ConnectionParams(apnContext, profileId, rilRadioTechnology, onCompletedMsg, 3556 connectionGeneration, requestType, subId, isApnPreferred)); 3557 } 3558 3559 /** 3560 * Tear down the connection through the apn on the network. 3561 * 3562 * @param apnContext APN context 3563 * @param reason reason to tear down 3564 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 3565 * With AsyncResult.userObj set to the original msg.obj. 3566 */ tearDown(ApnContext apnContext, String reason, Message onCompletedMsg)3567 public void tearDown(ApnContext apnContext, String reason, Message onCompletedMsg) { 3568 if (DBG) { 3569 log("tearDown: apnContext=" + apnContext + " reason=" + reason + " onCompletedMsg=" 3570 + onCompletedMsg); 3571 } 3572 sendMessage(DataConnection.EVENT_DISCONNECT, 3573 new DisconnectParams(apnContext, reason, DcTracker.RELEASE_TYPE_DETACH, 3574 onCompletedMsg)); 3575 } 3576 3577 // ******* "public" interface 3578 3579 /** 3580 * Used for testing purposes. 3581 */ tearDownNow()3582 void tearDownNow() { 3583 if (DBG) log("tearDownNow()"); 3584 sendMessage(obtainMessage(EVENT_TEAR_DOWN_NOW)); 3585 } 3586 3587 /** 3588 * Tear down the connection through the apn on the network. Ignores reference count and 3589 * and always tears down. 3590 * 3591 * @param releaseType Data release type 3592 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 3593 * With AsyncResult.userObj set to the original msg.obj. 3594 */ tearDownAll(String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)3595 public void tearDownAll(String reason, @ReleaseNetworkType int releaseType, 3596 Message onCompletedMsg) { 3597 if (DBG) { 3598 log("tearDownAll: reason=" + reason + ", releaseType=" 3599 + DcTracker.releaseTypeToString(releaseType)); 3600 } 3601 sendMessage(DataConnection.EVENT_DISCONNECT_ALL, 3602 new DisconnectParams(null, reason, releaseType, onCompletedMsg)); 3603 } 3604 3605 /** 3606 * Reset the data connection to inactive state. 3607 */ reset()3608 public void reset() { 3609 sendMessage(EVENT_RESET); 3610 if (DBG) log("reset"); 3611 } 3612 3613 /** 3614 * Re-evaluate the restricted state. If the restricted data connection does not need to be 3615 * restricted anymore, we need to dynamically change the network's capability. 3616 */ reevaluateRestrictedState()3617 void reevaluateRestrictedState() { 3618 sendMessage(EVENT_REEVALUATE_RESTRICTED_STATE); 3619 if (DBG) log("reevaluate restricted state"); 3620 } 3621 3622 /** 3623 * Re-evaluate the data connection properties. For example, it will recalculate data connection 3624 * score and update through network agent it if changed. 3625 */ reevaluateDataConnectionProperties()3626 void reevaluateDataConnectionProperties() { 3627 sendMessage(EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES); 3628 if (DBG) log("reevaluate data connection properties"); 3629 } 3630 3631 /** 3632 * @return The parameters used for initiating a data connection. 3633 */ getConnectionParams()3634 public ConnectionParams getConnectionParams() { 3635 return mConnectionParams; 3636 } 3637 3638 /** 3639 * Update PCSCF addresses 3640 * 3641 * @param response 3642 */ updatePcscfAddr(DataCallResponse response)3643 public void updatePcscfAddr(DataCallResponse response) { 3644 mPcscfAddr = response.getPcscfAddresses().stream() 3645 .map(InetAddress::getHostAddress).toArray(String[]::new); 3646 } 3647 3648 /** 3649 * @return The list of PCSCF addresses 3650 */ getPcscfAddresses()3651 public String[] getPcscfAddresses() { 3652 return mPcscfAddr; 3653 } 3654 3655 /** 3656 * Using the result of the SETUP_DATA_CALL determine the retry delay. 3657 * 3658 * @param response The response from setup data call 3659 * @return {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} if not suggested. 3660 * {@link RetryManager#NO_RETRY} if retry should not happen. Otherwise the delay in milliseconds 3661 * to the next SETUP_DATA_CALL. 3662 */ getSuggestedRetryDelay(DataCallResponse response)3663 private long getSuggestedRetryDelay(DataCallResponse response) { 3664 /** According to ril.h 3665 * The value < 0 means no value is suggested 3666 * The value 0 means retry should be done ASAP. 3667 * The value of Long.MAX_VALUE(0x7fffffffffffffff) means no retry. 3668 */ 3669 if (response == null) { 3670 return RetryManager.NO_SUGGESTED_RETRY_DELAY; 3671 } 3672 3673 long suggestedRetryTime = response.getRetryDurationMillis(); 3674 3675 // The value < 0 means no value is suggested 3676 if (suggestedRetryTime < 0) { 3677 if (DBG) log("No suggested retry delay."); 3678 return RetryManager.NO_SUGGESTED_RETRY_DELAY; 3679 } else if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6) 3680 && suggestedRetryTime == Long.MAX_VALUE) { 3681 if (DBG) log("Network suggested not retrying."); 3682 return RetryManager.NO_RETRY; 3683 } else if (mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_6) 3684 && suggestedRetryTime == Integer.MAX_VALUE) { 3685 if (DBG) log("Network suggested not retrying."); 3686 return RetryManager.NO_RETRY; 3687 } 3688 3689 return suggestedRetryTime; 3690 } 3691 getApnContexts()3692 public List<ApnContext> getApnContexts() { 3693 return new ArrayList<>(mApnContexts.keySet()); 3694 } 3695 3696 /** 3697 * Return whether there is an ApnContext for the given type in this DataConnection. 3698 * @param type APN type to check 3699 * @param exclusive true if the given APN type should be the only APN type that exists 3700 * @return True if there is an ApnContext for the given type 3701 */ isApnContextAttached(@pnType int type, boolean exclusive)3702 private boolean isApnContextAttached(@ApnType int type, boolean exclusive) { 3703 boolean attached = mApnContexts.keySet().stream() 3704 .map(ApnContext::getApnTypeBitmask) 3705 .anyMatch(bitmask -> bitmask == type); 3706 if (exclusive) { 3707 attached &= mApnContexts.size() == 1; 3708 } 3709 return attached; 3710 } 3711 3712 /** Get the network agent of the data connection */ 3713 @Nullable getNetworkAgent()3714 DcNetworkAgent getNetworkAgent() { 3715 return mNetworkAgent; 3716 } 3717 setHandoverState(@andoverState int state)3718 void setHandoverState(@HandoverState int state) { 3719 if (mHandoverState != state) { 3720 String logStr = "State changed from " + handoverStateToString(mHandoverState) 3721 + " to " + handoverStateToString(state); 3722 mHandoverLocalLog.log(logStr); 3723 logd(logStr); 3724 mHandoverState = state; 3725 } 3726 } 3727 3728 /** Sets the {@link DataCallSessionStats} mock for this data connection during unit testing. */ 3729 @VisibleForTesting setDataCallSessionStats(DataCallSessionStats dataCallSessionStats)3730 public void setDataCallSessionStats(DataCallSessionStats dataCallSessionStats) { 3731 mDataCallSessionStats = dataCallSessionStats; 3732 } 3733 3734 /** 3735 * @return the string for msg.what as our info. 3736 */ 3737 @Override getWhatToString(int what)3738 protected String getWhatToString(int what) { 3739 return cmdToString(what); 3740 } 3741 msgToString(Message msg)3742 private static String msgToString(Message msg) { 3743 String retVal; 3744 if (msg == null) { 3745 retVal = "null"; 3746 } else { 3747 StringBuilder b = new StringBuilder(); 3748 3749 b.append("{what="); 3750 b.append(cmdToString(msg.what)); 3751 3752 b.append(" when="); 3753 TimeUtils.formatDuration(msg.getWhen() - SystemClock.uptimeMillis(), b); 3754 3755 if (msg.arg1 != 0) { 3756 b.append(" arg1="); 3757 b.append(msg.arg1); 3758 } 3759 3760 if (msg.arg2 != 0) { 3761 b.append(" arg2="); 3762 b.append(msg.arg2); 3763 } 3764 3765 if (msg.obj != null) { 3766 b.append(" obj="); 3767 b.append(msg.obj); 3768 } 3769 3770 b.append(" target="); 3771 b.append(msg.getTarget()); 3772 3773 b.append(" replyTo="); 3774 b.append(msg.replyTo); 3775 3776 b.append("}"); 3777 3778 retVal = b.toString(); 3779 } 3780 return retVal; 3781 } 3782 slog(String s)3783 static void slog(String s) { 3784 Rlog.d("DC", s); 3785 } 3786 3787 /** 3788 * Log with debug 3789 * 3790 * @param s is string log 3791 */ 3792 @Override log(String s)3793 protected void log(String s) { 3794 Rlog.d(getName(), s); 3795 } 3796 3797 /** 3798 * Log with debug attribute 3799 * 3800 * @param s is string log 3801 */ 3802 @Override logd(String s)3803 protected void logd(String s) { 3804 Rlog.d(getName(), s); 3805 } 3806 3807 /** 3808 * Log with verbose attribute 3809 * 3810 * @param s is string log 3811 */ 3812 @Override logv(String s)3813 protected void logv(String s) { 3814 Rlog.v(getName(), s); 3815 } 3816 3817 /** 3818 * Log with info attribute 3819 * 3820 * @param s is string log 3821 */ 3822 @Override logi(String s)3823 protected void logi(String s) { 3824 Rlog.i(getName(), s); 3825 } 3826 3827 /** 3828 * Log with warning attribute 3829 * 3830 * @param s is string log 3831 */ 3832 @Override logw(String s)3833 protected void logw(String s) { 3834 Rlog.w(getName(), s); 3835 } 3836 3837 /** 3838 * Log with error attribute 3839 * 3840 * @param s is string log 3841 */ 3842 @Override loge(String s)3843 protected void loge(String s) { 3844 Rlog.e(getName(), s); 3845 } 3846 3847 /** 3848 * Log with error attribute 3849 * 3850 * @param s is string log 3851 * @param e is a Throwable which logs additional information. 3852 */ 3853 @Override loge(String s, Throwable e)3854 protected void loge(String s, Throwable e) { 3855 Rlog.e(getName(), s, e); 3856 } 3857 3858 /** Doesn't print mApnList of ApnContext's which would be recursive */ toStringSimple()3859 public synchronized String toStringSimple() { 3860 return getName() + ": State=" + getCurrentState().getName() 3861 + " mApnSetting=" + mApnSetting + " RefCount=" + mApnContexts.size() 3862 + " mCid=" + mCid + " mCreateTime=" + mCreateTime 3863 + " mLastastFailTime=" + mLastFailTime 3864 + " mLastFailCause=" + DataFailCause.toString(mLastFailCause) 3865 + " mTag=" + mTag 3866 + " mLinkProperties=" + mLinkProperties 3867 + " linkCapabilities=" + getNetworkCapabilities() 3868 + " mRestrictedNetworkOverride=" + mRestrictedNetworkOverride; 3869 } 3870 3871 @Override toString()3872 public String toString() { 3873 return "{" + toStringSimple() + " mApnContexts=" + mApnContexts + "}"; 3874 } 3875 3876 /** Check if the device is connected to NR 5G Non-Standalone network. */ isNRConnected()3877 private boolean isNRConnected() { 3878 return mPhone.getServiceState().getNrState() 3879 == NetworkRegistrationInfo.NR_STATE_CONNECTED; 3880 } 3881 3882 /** 3883 * @return The disallowed APN types bitmask 3884 */ getDisallowedApnTypes()3885 private @ApnType int getDisallowedApnTypes() { 3886 CarrierConfigManager configManager = (CarrierConfigManager) 3887 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 3888 int apnTypesBitmask = 0; 3889 if (configManager != null) { 3890 PersistableBundle bundle = configManager.getConfigForSubId(mSubId); 3891 if (bundle != null) { 3892 String key = (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 3893 ? CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY 3894 : CarrierConfigManager.KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY; 3895 if (bundle.getStringArray(key) != null) { 3896 String disallowedApnTypesString = 3897 TextUtils.join(",", bundle.getStringArray(key)); 3898 if (!TextUtils.isEmpty(disallowedApnTypesString)) { 3899 apnTypesBitmask = ApnSetting.getApnTypesBitmaskFromString( 3900 disallowedApnTypesString); 3901 } 3902 } 3903 } 3904 } 3905 3906 return apnTypesBitmask; 3907 } 3908 dumpToLog()3909 private void dumpToLog() { 3910 dump(null, new PrintWriter(new StringWriter(0)) { 3911 @Override 3912 public void println(String s) { 3913 DataConnection.this.logd(s); 3914 } 3915 3916 @Override 3917 public void flush() { 3918 } 3919 }, null); 3920 } 3921 3922 /** 3923 * Re-calculate score and update through network agent if it changes. 3924 */ updateScore()3925 private void updateScore() { 3926 int oldScore = mScore; 3927 mScore = calculateScore(); 3928 if (oldScore != mScore && mNetworkAgent != null) { 3929 log("Updating score from " + oldScore + " to " + mScore); 3930 mNetworkAgent.sendNetworkScore(mScore, this); 3931 } 3932 } 3933 calculateScore()3934 private int calculateScore() { 3935 int score = OTHER_CONNECTION_SCORE; 3936 3937 // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have 3938 // specify a subId, this dataConnection is considered to be default Internet data 3939 // connection. In this case we assign a slightly higher score of 50. The intention is 3940 // it will not be replaced by other data connections accidentally in DSDS usecase. 3941 for (ApnContext apnContext : mApnContexts.keySet()) { 3942 for (NetworkRequest networkRequest : apnContext.getNetworkRequests()) { 3943 if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 3944 && networkRequest.getNetworkSpecifier() == null) { 3945 score = DEFAULT_INTERNET_CONNECTION_SCORE; 3946 break; 3947 } 3948 } 3949 } 3950 3951 return score; 3952 } 3953 handoverStateToString(@andoverState int state)3954 private String handoverStateToString(@HandoverState int state) { 3955 switch (state) { 3956 case HANDOVER_STATE_IDLE: return "IDLE"; 3957 case HANDOVER_STATE_BEING_TRANSFERRED: return "BEING_TRANSFERRED"; 3958 case HANDOVER_STATE_COMPLETED: return "COMPLETED"; 3959 default: return "UNKNOWN"; 3960 } 3961 } 3962 getState()3963 private @DataState int getState() { 3964 if (isInactive()) { 3965 return TelephonyManager.DATA_DISCONNECTED; 3966 } else if (isActivating()) { 3967 return TelephonyManager.DATA_CONNECTING; 3968 } else if (isActive()) { 3969 // The data connection can only be suspended when it's in active state. 3970 if (mIsSuspended) { 3971 return TelephonyManager.DATA_SUSPENDED; 3972 } 3973 return TelephonyManager.DATA_CONNECTED; 3974 } else if (isDisconnecting()) { 3975 return TelephonyManager.DATA_DISCONNECTING; 3976 } 3977 3978 return TelephonyManager.DATA_UNKNOWN; 3979 } 3980 3981 /** 3982 * Get precise data connection state 3983 * 3984 * @return The {@link PreciseDataConnectionState} 3985 */ getPreciseDataConnectionState()3986 public PreciseDataConnectionState getPreciseDataConnectionState() { 3987 return new PreciseDataConnectionState.Builder() 3988 .setTransportType(mTransportType) 3989 .setId(mCid) 3990 .setState(getState()) 3991 .setApnSetting(mApnSetting) 3992 .setLinkProperties(mLinkProperties) 3993 .setNetworkType(getNetworkType()) 3994 .setFailCause(mDcFailCause) 3995 .build(); 3996 } 3997 3998 /** 3999 * Dump the current state. 4000 * 4001 * @param fd 4002 * @param printWriter 4003 * @param args 4004 */ 4005 @Override dump(FileDescriptor fd, PrintWriter printWriter, String[] args)4006 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 4007 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 4008 pw.print("DataConnection "); 4009 super.dump(fd, pw, args); 4010 pw.flush(); 4011 pw.increaseIndent(); 4012 pw.println("transport type=" 4013 + AccessNetworkConstants.transportTypeToString(mTransportType)); 4014 pw.println("mApnContexts.size=" + mApnContexts.size()); 4015 pw.println("mApnContexts=" + mApnContexts); 4016 pw.println("mApnSetting=" + mApnSetting); 4017 pw.println("mTag=" + mTag); 4018 pw.println("mCid=" + mCid); 4019 pw.println("mConnectionParams=" + mConnectionParams); 4020 pw.println("mDisconnectParams=" + mDisconnectParams); 4021 pw.println("mDcFailCause=" + DataFailCause.toString(mDcFailCause)); 4022 pw.println("mPhone=" + mPhone); 4023 pw.println("mSubId=" + mSubId); 4024 pw.println("mLinkProperties=" + mLinkProperties); 4025 pw.flush(); 4026 pw.println("mDataRegState=" + mDataRegState); 4027 pw.println("mHandoverState=" + handoverStateToString(mHandoverState)); 4028 pw.println("mRilRat=" + mRilRat); 4029 pw.println("mNetworkCapabilities=" + getNetworkCapabilities()); 4030 pw.println("mCreateTime=" + TimeUtils.logTimeOfDay(mCreateTime)); 4031 pw.println("mLastFailTime=" + TimeUtils.logTimeOfDay(mLastFailTime)); 4032 pw.println("mLastFailCause=" + DataFailCause.toString(mLastFailCause)); 4033 pw.println("mUserData=" + mUserData); 4034 pw.println("mRestrictedNetworkOverride=" + mRestrictedNetworkOverride); 4035 pw.println("mUnmeteredUseOnly=" + mUnmeteredUseOnly); 4036 pw.println("mMmsUseOnly=" + mMmsUseOnly); 4037 pw.println("mEnterpriseUse=" + mEnterpriseUse); 4038 pw.println("mUnmeteredOverride=" + mUnmeteredOverride); 4039 pw.println("mCongestedOverride=" + mCongestedOverride); 4040 pw.println("mDownlinkBandwidth" + mDownlinkBandwidth); 4041 pw.println("mUplinkBandwidth=" + mUplinkBandwidth); 4042 pw.println("mDefaultQos=" + mDefaultQos); 4043 pw.println("mQosBearerSessions=" + mQosBearerSessions); 4044 pw.println("disallowedApnTypes=" 4045 + ApnSetting.getApnTypesStringFromBitmask(getDisallowedApnTypes())); 4046 pw.println("mInstanceNumber=" + mInstanceNumber); 4047 pw.println("mAc=" + mAc); 4048 pw.println("mScore=" + mScore); 4049 if (mNetworkAgent != null) { 4050 mNetworkAgent.dump(fd, pw, args); 4051 } 4052 pw.println("handover local log:"); 4053 pw.increaseIndent(); 4054 mHandoverLocalLog.dump(fd, pw, args); 4055 pw.decreaseIndent(); 4056 pw.decreaseIndent(); 4057 pw.println(); 4058 pw.flush(); 4059 } 4060 4061 /** 4062 * Class used to track VCN-defined Network policies for this DataConnection. 4063 * 4064 * <p>MUST be registered with the associated DataConnection's Handler. 4065 */ 4066 private class DataConnectionVcnNetworkPolicyChangeListener 4067 implements VcnNetworkPolicyChangeListener { 4068 @Override onPolicyChanged()4069 public void onPolicyChanged() { 4070 // Poll the current underlying Network policy from VcnManager and send to NetworkAgent. 4071 final NetworkCapabilities networkCapabilities = getNetworkCapabilities(); 4072 VcnNetworkPolicyResult policyResult = 4073 mVcnManager.applyVcnNetworkPolicy( 4074 networkCapabilities, getLinkProperties()); 4075 if (policyResult.isTeardownRequested()) { 4076 tearDownAll( 4077 Phone.REASON_VCN_REQUESTED_TEARDOWN, 4078 DcTracker.RELEASE_TYPE_DETACH, 4079 null /* onCompletedMsg */); 4080 } 4081 4082 if (mNetworkAgent != null) { 4083 mNetworkAgent.sendNetworkCapabilities(networkCapabilities, DataConnection.this); 4084 } 4085 } 4086 } 4087 } 4088 4089