1 /* 2 * Copyright 2021 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.data; 18 19 import android.annotation.CallbackExecutor; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.content.Intent; 24 import android.net.ConnectivityManager; 25 import android.net.LinkAddress; 26 import android.net.LinkProperties; 27 import android.net.NetworkAgent; 28 import android.net.NetworkAgentConfig; 29 import android.net.NetworkCapabilities; 30 import android.net.NetworkFactory; 31 import android.net.NetworkProvider; 32 import android.net.NetworkScore; 33 import android.net.ProxyInfo; 34 import android.net.RouteInfo; 35 import android.net.TelephonyNetworkSpecifier; 36 import android.net.Uri; 37 import android.net.vcn.VcnManager; 38 import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener; 39 import android.net.vcn.VcnNetworkPolicyResult; 40 import android.os.AsyncResult; 41 import android.os.Looper; 42 import android.os.Message; 43 import android.os.Process; 44 import android.os.SystemClock; 45 import android.provider.Telephony; 46 import android.telephony.AccessNetworkConstants; 47 import android.telephony.AccessNetworkConstants.AccessNetworkType; 48 import android.telephony.AccessNetworkConstants.TransportType; 49 import android.telephony.Annotation.DataFailureCause; 50 import android.telephony.Annotation.DataState; 51 import android.telephony.Annotation.NetCapability; 52 import android.telephony.Annotation.NetworkType; 53 import android.telephony.Annotation.ValidationStatus; 54 import android.telephony.AnomalyReporter; 55 import android.telephony.DataFailCause; 56 import android.telephony.DataSpecificRegistrationInfo; 57 import android.telephony.LinkCapacityEstimate; 58 import android.telephony.NetworkRegistrationInfo; 59 import android.telephony.PcoData; 60 import android.telephony.PreciseDataConnectionState; 61 import android.telephony.ServiceState; 62 import android.telephony.SubscriptionManager; 63 import android.telephony.SubscriptionPlan; 64 import android.telephony.TelephonyDisplayInfo; 65 import android.telephony.TelephonyManager; 66 import android.telephony.data.ApnSetting; 67 import android.telephony.data.DataCallResponse; 68 import android.telephony.data.DataCallResponse.HandoverFailureMode; 69 import android.telephony.data.DataCallResponse.LinkStatus; 70 import android.telephony.data.DataProfile; 71 import android.telephony.data.DataService; 72 import android.telephony.data.DataServiceCallback; 73 import android.telephony.data.NetworkSliceInfo; 74 import android.telephony.data.QosBearerSession; 75 import android.telephony.data.TrafficDescriptor; 76 import android.telephony.data.TrafficDescriptor.OsAppId; 77 import android.text.TextUtils; 78 import android.util.ArrayMap; 79 import android.util.IndentingPrintWriter; 80 import android.util.LocalLog; 81 import android.util.SparseArray; 82 import android.util.SparseIntArray; 83 84 import com.android.internal.telephony.CarrierSignalAgent; 85 import com.android.internal.telephony.CommandsInterface; 86 import com.android.internal.telephony.Phone; 87 import com.android.internal.telephony.PhoneConstants; 88 import com.android.internal.telephony.PhoneFactory; 89 import com.android.internal.telephony.RIL; 90 import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback; 91 import com.android.internal.telephony.data.DataEvaluation.DataAllowedReason; 92 import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList; 93 import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryEntry; 94 import com.android.internal.telephony.data.DataRetryManager.DataRetryEntry; 95 import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback; 96 import com.android.internal.telephony.data.TelephonyNetworkAgent.TelephonyNetworkAgentCallback; 97 import com.android.internal.telephony.metrics.DataCallSessionStats; 98 import com.android.internal.telephony.metrics.TelephonyMetrics; 99 import com.android.internal.util.ArrayUtils; 100 import com.android.internal.util.IState; 101 import com.android.internal.util.State; 102 import com.android.internal.util.StateMachine; 103 import com.android.net.module.util.LinkPropertiesUtils; 104 import com.android.net.module.util.NetUtils; 105 import com.android.net.module.util.NetworkCapabilitiesUtils; 106 import com.android.telephony.Rlog; 107 108 import java.io.FileDescriptor; 109 import java.io.PrintWriter; 110 import java.math.BigInteger; 111 import java.net.InetAddress; 112 import java.util.ArrayList; 113 import java.util.Arrays; 114 import java.util.Collections; 115 import java.util.Comparator; 116 import java.util.List; 117 import java.util.Map; 118 import java.util.Objects; 119 import java.util.Set; 120 import java.util.UUID; 121 import java.util.concurrent.Executor; 122 import java.util.concurrent.TimeUnit; 123 import java.util.function.Consumer; 124 import java.util.stream.Collectors; 125 126 /** 127 * DataNetwork class represents a single PDN (Packet Data Network). 128 * 129 * The life cycle of a data network starts from {@link ConnectingState}. If setup data request 130 * succeeds, then it enters {@link ConnectedState}, otherwise it enters 131 * {@link DisconnectedState}. 132 * 133 * When data network is in {@link ConnectingState}, it can enter {@link HandoverState} if handover 134 * between IWLAN and cellular occurs. After handover completes or fails, it return back to 135 * {@link ConnectedState}. When the data network is about to be disconnected, it first enters 136 * {@link DisconnectingState} when performing graceful tear down or when sending the data 137 * deactivation request. At the end, it enters {@link DisconnectedState} when {@link DataService} 138 * notifies data disconnected. Note that an unsolicited disconnected event from {@link DataService} 139 * or any vendor HAL failure response can immediately move data network from {@link ConnectedState} 140 * to {@link DisconnectedState}. {@link DisconnectedState} is the final state of a data network. 141 * 142 * State machine diagram: 143 * 144 * 145 * ┌─────────┐ 146 * │Handover │ 147 * └─▲────┬──┘ 148 * │ │ 149 * ┌───────────┐ ┌─┴────▼──┐ ┌──────────────┐ 150 * │Connecting ├────────►Connected├────────►Disconnecting │ 151 * └─────┬─────┘ └────┬────┘ └───────┬──────┘ 152 * │ │ │ 153 * │ ┌─────▼──────┐ │ 154 * └─────────────►Disconnected◄──────────────┘ 155 * └────────────┘ 156 * 157 */ 158 public class DataNetwork extends StateMachine { 159 private static final boolean VDBG = false; 160 /** Event for data config updated. */ 161 private static final int EVENT_DATA_CONFIG_UPDATED = 1; 162 163 /** Event for attaching a network request. */ 164 private static final int EVENT_ATTACH_NETWORK_REQUEST = 2; 165 166 /** Event for detaching a network request. */ 167 private static final int EVENT_DETACH_NETWORK_REQUEST = 3; 168 169 /** Event when detect radio not available. */ 170 private static final int EVENT_RADIO_NOT_AVAILABLE = 4; 171 172 /** Event for allocating PDU session id response. */ 173 private static final int EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE = 5; 174 175 /** Event for setup data network response. */ 176 private static final int EVENT_SETUP_DATA_NETWORK_RESPONSE = 6; 177 178 /** Event for tearing down data network. */ 179 private static final int EVENT_TEAR_DOWN_NETWORK = 7; 180 181 /** Event triggered by {@link DataServiceCallback#onDataCallListChanged(List)}. */ 182 private static final int EVENT_DATA_STATE_CHANGED = 8; 183 184 /** Data network service state changed event. */ 185 private static final int EVENT_SERVICE_STATE_CHANGED = 9; 186 187 /** Event for detaching all network requests. */ 188 private static final int EVENT_DETACH_ALL_NETWORK_REQUESTS = 10; 189 190 /** Event for bandwidth estimation from the modem changed. */ 191 private static final int EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED = 11; 192 193 /** Event for display info changed. This is for getting 5G NSA or mmwave information. */ 194 private static final int EVENT_DISPLAY_INFO_CHANGED = 13; 195 196 /** Event for setup data call (for handover) response from the data service. */ 197 private static final int EVENT_HANDOVER_RESPONSE = 15; 198 199 /** Event for subscription plan changed or unmetered/congested override set. */ 200 private static final int EVENT_SUBSCRIPTION_PLAN_OVERRIDE = 16; 201 202 /** Event for PCO data received from network. */ 203 private static final int EVENT_PCO_DATA_RECEIVED = 17; 204 205 /** Event for carrier privileged UIDs changed. */ 206 private static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = 18; 207 208 /** Event for deactivate data network response. */ 209 private static final int EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE = 19; 210 211 /** 212 * Event for data network stuck in transient (i.e. connecting/disconnecting/handover) state for 213 * too long time. Timeout value specified in 214 * {@link DataConfigManager#getAnomalyNetworkConnectingTimeoutMs()}, 215 * {@link DataConfigManager#getAnomalyNetworkDisconnectingTimeoutMs()}, 216 * {@link DataConfigManager#getNetworkHandoverTimeoutMs()}. 217 */ 218 private static final int EVENT_STUCK_IN_TRANSIENT_STATE = 20; 219 220 /** 221 * Event for waiting for tearing down condition met. This will cause data network entering 222 * disconnecting state. 223 */ 224 private static final int EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET = 21; 225 226 /** Event for call started. */ 227 private static final int EVENT_VOICE_CALL_STARTED = 22; 228 229 /** Event for call ended. */ 230 private static final int EVENT_VOICE_CALL_ENDED = 23; 231 232 /** Event for CSS indicator changed. */ 233 private static final int EVENT_CSS_INDICATOR_CHANGED = 24; 234 235 /** 236 * Event for notifying source transport that handover is about to be initiated on target 237 * transport. 238 */ 239 private static final int EVENT_NOTIFY_HANDOVER_STARTED = 25; 240 241 /** 242 * Event for the response of notifying source transport that handover is about to be initiated 243 * on target transport. 244 */ 245 private static final int EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE = 26; 246 247 /** 248 * Event for the response of notifying source transport that handover is cancelled/failed on the 249 * target transport. 250 */ 251 private static final int EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE = 27; 252 253 /** Invalid context id. */ 254 private static final int INVALID_CID = -1; 255 256 /** 257 * The data network providing default internet will have a higher score of 50. Other network 258 * will have a slightly lower score of 45. The intention is other connections will not cause 259 * connectivity service to tear down default internet connection. For example, to validate 260 * internet connection on non-default data SIM, we'll set up a temporary internet network on 261 * that data SIM. In this case, score of 45 is assigned so connectivity service will not replace 262 * the default internet network with it. 263 */ 264 private static final int DEFAULT_INTERNET_NETWORK_SCORE = 50; 265 private static final int OTHER_NETWORK_SCORE = 45; 266 267 @IntDef(prefix = {"DEACTIVATION_REASON_"}, 268 value = { 269 TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED, 270 TEAR_DOWN_REASON_SIM_REMOVAL, 271 TEAR_DOWN_REASON_AIRPLANE_MODE_ON, 272 TEAR_DOWN_REASON_DATA_DISABLED, 273 TEAR_DOWN_REASON_NO_LIVE_REQUEST, 274 TEAR_DOWN_REASON_RAT_NOT_ALLOWED, 275 TEAR_DOWN_REASON_ROAMING_DISABLED, 276 TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED, 277 TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY, 278 TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER, 279 TEAR_DOWN_REASON_DATA_STALL, 280 TEAR_DOWN_REASON_HANDOVER_FAILED, 281 TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED, 282 TEAR_DOWN_REASON_VCN_REQUESTED, 283 TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED, 284 TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED, 285 TEAR_DOWN_REASON_NOT_IN_SERVICE, 286 TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY, 287 TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL, 288 TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE, 289 TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE, 290 TEAR_DOWN_REASON_RETRY_SCHEDULED, 291 TEAR_DOWN_REASON_DATA_THROTTLED, 292 TEAR_DOWN_REASON_DATA_PROFILE_INVALID, 293 TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED, 294 TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY, 295 TEAR_DOWN_REASON_ILLEGAL_STATE, 296 TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK, 297 TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED, 298 }) 299 public @interface TearDownReason {} 300 301 /** Data network tear down requested by connectivity service. */ 302 public static final int TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED = 1; 303 304 /** Data network tear down due to SIM removal. */ 305 public static final int TEAR_DOWN_REASON_SIM_REMOVAL = 2; 306 307 /** Data network tear down due to airplane mode turned on. */ 308 public static final int TEAR_DOWN_REASON_AIRPLANE_MODE_ON = 3; 309 310 /** Data network tear down due to data disabled (by user, policy, carrier, etc...). */ 311 public static final int TEAR_DOWN_REASON_DATA_DISABLED = 4; 312 313 /** Data network tear down due to no live network request. */ 314 public static final int TEAR_DOWN_REASON_NO_LIVE_REQUEST = 5; 315 316 /** Data network tear down due to current RAT is not allowed by the data profile. */ 317 public static final int TEAR_DOWN_REASON_RAT_NOT_ALLOWED = 6; 318 319 /** Data network tear down due to data roaming not enabled. */ 320 public static final int TEAR_DOWN_REASON_ROAMING_DISABLED = 7; 321 322 /** Data network tear down due to concurrent voice/data not allowed. */ 323 public static final int TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED = 8; 324 325 326 327 /** Data network tear down due to data service unbound. */ 328 public static final int TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY = 10; 329 330 /** Data network tear down due to radio turned off by the carrier. */ 331 public static final int TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER = 11; 332 333 /** Data network tear down due to data stall. */ 334 public static final int TEAR_DOWN_REASON_DATA_STALL = 12; 335 336 /** Data network tear down due to handover failed. */ 337 public static final int TEAR_DOWN_REASON_HANDOVER_FAILED = 13; 338 339 /** Data network tear down due to handover not allowed. */ 340 public static final int TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED = 14; 341 342 /** Data network tear down due to VCN service requested. */ 343 public static final int TEAR_DOWN_REASON_VCN_REQUESTED = 15; 344 345 /** Data network tear down due to VOPS no longer supported. */ 346 public static final int TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED = 16; 347 348 /** Data network tear down due to default data unselected. */ 349 public static final int TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED = 17; 350 351 /** Data network tear down due to device not in service. */ 352 public static final int TEAR_DOWN_REASON_NOT_IN_SERVICE = 18; 353 354 /** Data network tear down due to data config not ready. */ 355 public static final int TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY = 19; 356 357 /** Data network tear down due to tear down all pending. */ 358 public static final int TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL = 20; 359 360 /** Data network tear down due to no suitable data profile. */ 361 public static final int TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE = 21; 362 363 /** Data network tear down due to CDMA ECBM. */ 364 public static final int TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE = 22; 365 366 /** Data network tear down due to retry scheduled. */ 367 public static final int TEAR_DOWN_REASON_RETRY_SCHEDULED = 23; 368 369 /** Data network tear down due to data throttled. */ 370 public static final int TEAR_DOWN_REASON_DATA_THROTTLED = 24; 371 372 /** Data network tear down due to data profile invalid. */ 373 public static final int TEAR_DOWN_REASON_DATA_PROFILE_INVALID = 25; 374 375 /** Data network tear down due to data profile not preferred. */ 376 public static final int TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED = 26; 377 378 /** Data network tear down due to not allowed by policy. */ 379 public static final int TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY = 27; 380 381 /** Data network tear down due to illegal state. */ 382 public static final int TEAR_DOWN_REASON_ILLEGAL_STATE = 28; 383 384 /** Data network tear down due to only allowed single network. */ 385 public static final int TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK = 29; 386 387 /** Data network tear down due to preferred data switched to another phone. */ 388 public static final int TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED = 30; 389 390 @IntDef(prefix = {"BANDWIDTH_SOURCE_"}, 391 value = { 392 BANDWIDTH_SOURCE_UNKNOWN, 393 BANDWIDTH_SOURCE_MODEM, 394 BANDWIDTH_SOURCE_CARRIER_CONFIG, 395 BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR, 396 }) 397 public @interface BandwidthEstimationSource {} 398 399 /** Indicates the bandwidth estimation source is unknown. This must be a configuration error. */ 400 public static final int BANDWIDTH_SOURCE_UNKNOWN = 0; 401 402 /** Indicates the bandwidth estimation source is from the modem. */ 403 public static final int BANDWIDTH_SOURCE_MODEM = 1; 404 405 /** Indicates the bandwidth estimation source is from the static carrier config. */ 406 public static final int BANDWIDTH_SOURCE_CARRIER_CONFIG = 2; 407 408 /** Indicates the bandwidth estimation source is from {@link LinkBandwidthEstimator}. */ 409 public static final int BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR = 3; 410 411 /** 412 * The capabilities that are allowed to changed dynamically during the life cycle of network. 413 * This is copied from {@code NetworkCapabilities#MUTABLE_CAPABILITIES}. There is no plan to 414 * make this a connectivity manager API since in the future, immutable network capabilities 415 * would be allowed to changed dynamically. (i.e. not immutable anymore.) 416 */ 417 private static final List<Integer> MUTABLE_CAPABILITIES = List.of( 418 NetworkCapabilities.NET_CAPABILITY_TRUSTED, 419 NetworkCapabilities.NET_CAPABILITY_VALIDATED, 420 NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL, 421 NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, 422 NetworkCapabilities.NET_CAPABILITY_FOREGROUND, 423 NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED, 424 NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED, 425 NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY, 426 NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED, 427 NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED, 428 NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT, 429 // Connectivity service will support NOT_METERED as a mutable and requestable 430 // capability. 431 NetworkCapabilities.NET_CAPABILITY_NOT_METERED, 432 // Even though MMTEL is an immutable capability, we still make it an mutable capability 433 // here before we have a better solution to deal with network transition from VoPS 434 // to non-VoPS network. 435 NetworkCapabilities.NET_CAPABILITY_MMTEL 436 ); 437 438 /** The parent state. Any messages not handled by the child state fallback to this. */ 439 private final DefaultState mDefaultState = new DefaultState(); 440 441 /** 442 * The connecting state. This is the initial state of a data network. 443 * 444 * @see DataNetwork for the state machine diagram. 445 */ 446 private final ConnectingState mConnectingState = new ConnectingState(); 447 448 /** 449 * The connected state. This is the state when data network becomes usable. 450 * 451 * @see DataNetwork for the state machine diagram. 452 */ 453 private final ConnectedState mConnectedState = new ConnectedState(); 454 455 /** 456 * The handover state. This is the state when data network handover between IWLAN and cellular. 457 * 458 * @see DataNetwork for the state machine diagram. 459 */ 460 private final HandoverState mHandoverState = new HandoverState(); 461 462 /** 463 * The disconnecting state. This is the state when data network is about to be disconnected. 464 * The network is still usable in this state, but the clients should be prepared to lose the 465 * network in any moment. This state is particular useful for IMS graceful tear down, where 466 * the network enters disconnecting state while waiting for IMS de-registration signal. 467 * 468 * @see DataNetwork for the state machine diagram. 469 */ 470 private final DisconnectingState mDisconnectingState = new DisconnectingState(); 471 472 /** 473 * The disconnected state. This is the final state of a data network. 474 * 475 * @see DataNetwork for the state machine diagram. 476 */ 477 private final DisconnectedState mDisconnectedState = new DisconnectedState(); 478 479 /** The phone instance. */ 480 private final @NonNull Phone mPhone; 481 482 /** 483 * The subscription id. This is assigned when the network is created, and not supposed to 484 * change afterwards. 485 */ 486 private final int mSubId; 487 488 /** The network score of this network. */ 489 private int mNetworkScore; 490 491 /** 492 * Indicates that 493 * {@link DataService.DataServiceProvider#deactivateDataCall(int, int, DataServiceCallback)} 494 * has been called. This flag can be only changed from {@code false} to {@code true}. 495 */ 496 private boolean mInvokedDataDeactivation = false; 497 498 /** 499 * Indicates that if the data network has ever entered {@link ConnectedState}. 500 */ 501 private boolean mEverConnected = false; 502 503 /** RIL interface. */ 504 private final @NonNull CommandsInterface mRil; 505 506 /** Local log. */ 507 private final LocalLog mLocalLog = new LocalLog(128); 508 509 /** The callback to receives data network state update. */ 510 private final @NonNull DataNetworkCallback mDataNetworkCallback; 511 512 /** The log tag. */ 513 private String mLogTag; 514 515 /** Metrics of per data network connection. */ 516 private final DataCallSessionStats mDataCallSessionStats; 517 518 /** 519 * The unique context id assigned by the data service in {@link DataCallResponse#getId()}. One 520 * for {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} and one for 521 * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}. The reason for storing both is that 522 * during handover, both cid will be used. 523 */ 524 private final SparseIntArray mCid = new SparseIntArray(2); 525 526 /** 527 * The initial network agent id. The network agent can be re-created due to immutable capability 528 * changed. This is to preserve the initial network agent id so the id in the logging tag won't 529 * change for the entire life cycle of data network. 530 */ 531 private int mInitialNetworkAgentId; 532 533 /** PDU session id. */ 534 private int mPduSessionId = DataCallResponse.PDU_SESSION_ID_NOT_SET; 535 536 /** 537 * Data service managers for accessing {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} and 538 * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN} data services. 539 */ 540 private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers; 541 542 /** Access networks manager. */ 543 private final @NonNull AccessNetworksManager mAccessNetworksManager; 544 545 /** Data network controller. */ 546 private final @NonNull DataNetworkController mDataNetworkController; 547 548 /** Data network controller callback. */ 549 private final @NonNull DataNetworkController.DataNetworkControllerCallback 550 mDataNetworkControllerCallback; 551 552 /** Data config manager. */ 553 private final @NonNull DataConfigManager mDataConfigManager; 554 555 /** VCN manager. */ 556 private final @Nullable VcnManager mVcnManager; 557 558 /** VCN policy changed listener. */ 559 private @Nullable VcnNetworkPolicyChangeListener mVcnPolicyChangeListener; 560 561 /** The network agent associated with this data network. */ 562 private @NonNull TelephonyNetworkAgent mNetworkAgent; 563 564 /** QOS callback tracker. This is only created after network connected on WWAN. */ 565 private @Nullable QosCallbackTracker mQosCallbackTracker; 566 567 /** NAT keepalive tracker. */ 568 private @Nullable KeepaliveTracker mKeepaliveTracker; 569 570 /** The data profile used to establish this data network. */ 571 private @NonNull DataProfile mDataProfile; 572 573 /** 574 * The data profile used for data handover. Some carriers might use different data profile 575 * between IWLAN and cellular. Only set before handover started. 576 */ 577 private @Nullable DataProfile mHandoverDataProfile; 578 579 /** The network capabilities of this data network. */ 580 private @NonNull NetworkCapabilities mNetworkCapabilities; 581 582 /** The matched traffic descriptor returned from setup data call request. */ 583 private final @NonNull List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>(); 584 585 /** The link properties of this data network. */ 586 private @NonNull LinkProperties mLinkProperties; 587 588 /** The network slice info. */ 589 private @Nullable NetworkSliceInfo mNetworkSliceInfo; 590 591 /** The link status (i.e. RRC state). */ 592 private @LinkStatus int mLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN; 593 594 /** The network bandwidth. */ 595 private @NonNull NetworkBandwidth mNetworkBandwidth = new NetworkBandwidth(14, 14); 596 597 /** The TCP buffer sizes config. */ 598 private @NonNull String mTcpBufferSizes; 599 600 /** The telephony display info. */ 601 private @NonNull TelephonyDisplayInfo mTelephonyDisplayInfo; 602 603 /** Whether {@link NetworkCapabilities#NET_CAPABILITY_TEMPORARILY_NOT_METERED} is supported. */ 604 private boolean mTempNotMeteredSupported = false; 605 606 /** Whether the current data network is temporarily not metered. */ 607 private boolean mTempNotMetered = false; 608 609 /** Whether the current data network is congested. */ 610 private boolean mCongested = false; 611 612 /** The network requests associated with this data network */ 613 private final @NonNull NetworkRequestList mAttachedNetworkRequestList = 614 new NetworkRequestList(); 615 616 /** 617 * The latest data call response received from either 618 * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)} or 619 * {@link DataServiceCallback#onDataCallListChanged(List)}. The very first update must be 620 * from {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}. 621 */ 622 private @Nullable DataCallResponse mDataCallResponse = null; 623 624 /** 625 * The fail cause from either setup data failure or unsolicited disconnect reported by data 626 * service. 627 */ 628 private @DataFailureCause int mFailCause = DataFailCause.NONE; 629 630 /** 631 * The retry delay in milliseconds from setup data failure. 632 */ 633 private long mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED; 634 635 /** 636 * Indicates if data network is suspended. Note this is slightly different from the 637 * {@link TelephonyManager#DATA_SUSPENDED}, which is only possible when data network is in 638 * connected state. This flag reflects to the 639 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_SUSPENDED} which can happen when data network 640 * is in connected or disconnecting state. 641 */ 642 private boolean mSuspended = false; 643 644 /** 645 * The current transport of the data network. For handover, the current transport will be set 646 * after handover completes. 647 */ 648 private @TransportType int mTransport; 649 650 /** The reason that why setting up this data network is allowed. */ 651 private @NonNull DataAllowedReason mDataAllowedReason; 652 653 /** 654 * PCO (Protocol Configuration Options) data received from the network. The first key is the 655 * cid of the PCO data, the second key is the PCO id, the value is the PCO data. 656 */ 657 private final @NonNull Map<Integer, Map<Integer, PcoData>> mPcoData = new ArrayMap<>(); 658 659 /** The QOS bearer sessions. */ 660 private final @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); 661 662 /** 663 * The UIDs of packages that have carrier privilege. 664 */ 665 private @NonNull int[] mAdministratorUids = new int[0]; 666 667 /** 668 * Carrier service package uid. This UID will not change through the life cycle of data network. 669 */ 670 private int mCarrierServicePackageUid = Process.INVALID_UID; 671 672 /** 673 * Link bandwidth estimator callback for receiving latest link bandwidth information. 674 */ 675 private @Nullable LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback; 676 677 /** 678 * Data config callback for carrier config update. 679 */ 680 private @Nullable DataConfigManagerCallback mDataConfigManagerCallback; 681 682 /** 683 * The network bandwidth. 684 */ 685 public static class NetworkBandwidth { 686 /** The downlink bandwidth in Kbps. */ 687 public final int downlinkBandwidthKbps; 688 689 /** The uplink Bandwidth in Kbps. */ 690 public final int uplinkBandwidthKbps; 691 692 /** 693 * Constructor. 694 * 695 * @param downlinkBandwidthKbps The downlink bandwidth in Kbps. 696 * @param uplinkBandwidthKbps The uplink Bandwidth in Kbps. 697 */ NetworkBandwidth(int downlinkBandwidthKbps, int uplinkBandwidthKbps)698 public NetworkBandwidth(int downlinkBandwidthKbps, int uplinkBandwidthKbps) { 699 this.downlinkBandwidthKbps = downlinkBandwidthKbps; 700 this.uplinkBandwidthKbps = uplinkBandwidthKbps; 701 } 702 703 @Override toString()704 public String toString() { 705 return String.format("NetworkBandwidth=[downlink=%d, uplink=%d]", 706 downlinkBandwidthKbps, uplinkBandwidthKbps); 707 } 708 } 709 710 /** 711 * Data network callback. Should only be used by {@link DataNetworkController}. 712 */ 713 public abstract static class DataNetworkCallback extends DataCallback { 714 /** 715 * Constructor 716 * 717 * @param executor The executor of the callback. 718 */ DataNetworkCallback(@onNull @allbackExecutor Executor executor)719 public DataNetworkCallback(@NonNull @CallbackExecutor Executor executor) { 720 super(executor); 721 } 722 723 /** 724 * Called when data setup failed. 725 * 726 * @param dataNetwork The data network. 727 * @param requestList The network requests attached to this data network. 728 * @param cause The fail cause of setup data network. 729 * @param retryDurationMillis The network suggested data retry duration in milliseconds as 730 * specified in 3GPP TS 24.302 section 8.2.9.1. The {@link DataProfile} associated to this 731 * data network will be throttled for the specified duration unless 732 * {@link DataServiceCallback#onApnUnthrottled} is called. {@link Long#MAX_VALUE} indicates 733 * data retry should not occur. {@link DataCallResponse#RETRY_DURATION_UNDEFINED} indicates 734 * network did not suggest any retry duration. 735 */ onSetupDataFailed(@onNull DataNetwork dataNetwork, @NonNull NetworkRequestList requestList, @DataFailureCause int cause, long retryDurationMillis)736 public abstract void onSetupDataFailed(@NonNull DataNetwork dataNetwork, 737 @NonNull NetworkRequestList requestList, @DataFailureCause int cause, 738 long retryDurationMillis); 739 740 /** 741 * Called when data network enters {@link ConnectedState}. 742 * 743 * @param dataNetwork The data network. 744 */ onConnected(@onNull DataNetwork dataNetwork)745 public abstract void onConnected(@NonNull DataNetwork dataNetwork); 746 747 /** 748 * Called when data network validation status changed. 749 * 750 * @param dataNetwork The data network. 751 * @param status one of {@link NetworkAgent#VALIDATION_STATUS_VALID} or 752 * {@link NetworkAgent#VALIDATION_STATUS_NOT_VALID}. 753 * @param redirectUri If internet connectivity is being redirected (e.g., on a captive 754 * portal), this is the destination the probes are being redirected to, otherwise 755 * {@code null}. 756 */ onValidationStatusChanged(@onNull DataNetwork dataNetwork, @ValidationStatus int status, @Nullable Uri redirectUri)757 public abstract void onValidationStatusChanged(@NonNull DataNetwork dataNetwork, 758 @ValidationStatus int status, @Nullable Uri redirectUri); 759 760 /** 761 * Called when data network suspended state changed. 762 * 763 * @param dataNetwork The data network. 764 * @param suspended {@code true} if data is suspended. 765 */ onSuspendedStateChanged(@onNull DataNetwork dataNetwork, boolean suspended)766 public abstract void onSuspendedStateChanged(@NonNull DataNetwork dataNetwork, 767 boolean suspended); 768 769 /** 770 * Called when network requests were failed to attach to the data network. 771 * 772 * @param dataNetwork The data network. 773 * @param requestList The requests failed to attach. 774 */ onAttachFailed(@onNull DataNetwork dataNetwork, @NonNull NetworkRequestList requestList)775 public abstract void onAttachFailed(@NonNull DataNetwork dataNetwork, 776 @NonNull NetworkRequestList requestList); 777 778 /** 779 * Called when data network enters {@link DisconnectedState}. Note this is only called 780 * when the data network was previously connected. For setup data network failed, 781 * {@link #onSetupDataFailed(DataNetwork, NetworkRequestList, int, long)} is called. 782 * 783 * @param dataNetwork The data network. 784 * @param cause The disconnect cause. 785 */ onDisconnected(@onNull DataNetwork dataNetwork, @DataFailureCause int cause)786 public abstract void onDisconnected(@NonNull DataNetwork dataNetwork, 787 @DataFailureCause int cause); 788 789 /** 790 * Called when handover between IWLAN and cellular network succeeded. 791 * 792 * @param dataNetwork The data network. 793 */ onHandoverSucceeded(@onNull DataNetwork dataNetwork)794 public abstract void onHandoverSucceeded(@NonNull DataNetwork dataNetwork); 795 796 /** 797 * Called when data network handover between IWLAN and cellular network failed. 798 * 799 * @param dataNetwork The data network. 800 * @param cause The fail cause. 801 * @param retryDurationMillis Network suggested retry time in milliseconds. 802 * {@link Long#MAX_VALUE} indicates data retry should not occur. 803 * {@link DataCallResponse#RETRY_DURATION_UNDEFINED} indicates network did not suggest any 804 * retry duration. 805 * @param handoverFailureMode The handover failure mode that determine the behavior of 806 * how frameworks should handle the handover failure. 807 */ onHandoverFailed(@onNull DataNetwork dataNetwork, @DataFailureCause int cause, long retryDurationMillis, @HandoverFailureMode int handoverFailureMode)808 public abstract void onHandoverFailed(@NonNull DataNetwork dataNetwork, 809 @DataFailureCause int cause, long retryDurationMillis, 810 @HandoverFailureMode int handoverFailureMode); 811 812 /** 813 * Called when data network link status (i.e. RRC state) changed. 814 * 815 * @param dataNetwork The data network. 816 * @param linkStatus The link status (i.e. RRC state). 817 */ onLinkStatusChanged(@onNull DataNetwork dataNetwork, @LinkStatus int linkStatus)818 public abstract void onLinkStatusChanged(@NonNull DataNetwork dataNetwork, 819 @LinkStatus int linkStatus); 820 821 /** 822 * Called when PCO data changed. 823 * 824 * @param dataNetwork The data network. 825 */ onPcoDataChanged(@onNull DataNetwork dataNetwork)826 public abstract void onPcoDataChanged(@NonNull DataNetwork dataNetwork); 827 828 /** 829 * Called when network capabilities changed. 830 * 831 * @param dataNetwork The data network. 832 */ onNetworkCapabilitiesChanged(@onNull DataNetwork dataNetwork)833 public abstract void onNetworkCapabilitiesChanged(@NonNull DataNetwork dataNetwork); 834 835 /** 836 * Called when attempt to tear down a data network 837 * 838 * @param dataNetwork The data network. 839 */ onTrackNetworkUnwanted(@onNull DataNetwork dataNetwork)840 public abstract void onTrackNetworkUnwanted(@NonNull DataNetwork dataNetwork); 841 } 842 843 /** 844 * Constructor 845 * 846 * @param phone The phone instance. 847 * @param looper The looper to be used by the state machine. Currently the handler thread is the 848 * phone process's main thread. 849 * @param dataServiceManagers Data service managers. 850 * @param dataProfile The data profile for establishing the data network. 851 * @param networkRequestList The initial network requests attached to this data network. 852 * @param transport The initial transport of the data network. 853 * @param dataAllowedReason The reason that why setting up this data network is allowed. 854 * @param callback The callback to receives data network state update. 855 */ DataNetwork(@onNull Phone phone, @NonNull Looper looper, @NonNull SparseArray<DataServiceManager> dataServiceManagers, @NonNull DataProfile dataProfile, @NonNull NetworkRequestList networkRequestList, @TransportType int transport, @NonNull DataAllowedReason dataAllowedReason, @NonNull DataNetworkCallback callback)856 public DataNetwork(@NonNull Phone phone, @NonNull Looper looper, 857 @NonNull SparseArray<DataServiceManager> dataServiceManagers, 858 @NonNull DataProfile dataProfile, 859 @NonNull NetworkRequestList networkRequestList, 860 @TransportType int transport, 861 @NonNull DataAllowedReason dataAllowedReason, 862 @NonNull DataNetworkCallback callback) { 863 super("DataNetwork", looper); 864 // State machine should be initialized at the top of constructor. log() can be only used 865 // after state machine initialized (because getCurrentState() crashes if state machine has 866 // not started.) 867 initializeStateMachine(); 868 869 mPhone = phone; 870 mSubId = phone.getSubId(); 871 mRil = mPhone.mCi; 872 mLinkProperties = new LinkProperties(); 873 mDataServiceManagers = dataServiceManagers; 874 mAccessNetworksManager = phone.getAccessNetworksManager(); 875 mVcnManager = mPhone.getContext().getSystemService(VcnManager.class); 876 mDataNetworkController = phone.getDataNetworkController(); 877 mDataNetworkControllerCallback = new DataNetworkController.DataNetworkControllerCallback( 878 getHandler()::post) { 879 @Override 880 public void onSubscriptionPlanOverride() { 881 sendMessage(EVENT_SUBSCRIPTION_PLAN_OVERRIDE); 882 }}; 883 mDataNetworkController.registerDataNetworkControllerCallback( 884 mDataNetworkControllerCallback); 885 mDataConfigManager = mDataNetworkController.getDataConfigManager(); 886 mDataCallSessionStats = new DataCallSessionStats(mPhone); 887 mDataNetworkCallback = callback; 888 mDataProfile = dataProfile; 889 if (dataProfile.getTrafficDescriptor() != null) { 890 // The initial traffic descriptor is from the data profile. After that traffic 891 // descriptors will be updated by modem through setup data call response and data call 892 // list changed event. 893 mTrafficDescriptors.add(dataProfile.getTrafficDescriptor()); 894 } 895 mTransport = transport; 896 mDataAllowedReason = dataAllowedReason; 897 dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime()); 898 mAttachedNetworkRequestList.addAll(networkRequestList); 899 mCid.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, INVALID_CID); 900 mCid.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, INVALID_CID); 901 mTcpBufferSizes = mDataConfigManager.getDefaultTcpConfigString(); 902 mTelephonyDisplayInfo = mPhone.getDisplayInfoController().getTelephonyDisplayInfo(); 903 904 for (TelephonyNetworkRequest networkRequest : networkRequestList) { 905 networkRequest.setAttachedNetwork(DataNetwork.this); 906 networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED); 907 } 908 909 // Update the capabilities in the constructor is to make sure the data network has initial 910 // capability immediately after created. Doing this connecting state creates the window that 911 // DataNetworkController might check if existing data network's capability can satisfy the 912 // next network request within this window. 913 updateNetworkCapabilities(); 914 } 915 916 /** 917 * Initialize and start the state machine. 918 */ initializeStateMachine()919 private void initializeStateMachine() { 920 addState(mDefaultState); 921 addState(mConnectingState, mDefaultState); 922 addState(mConnectedState, mDefaultState); 923 addState(mHandoverState, mDefaultState); 924 addState(mDisconnectingState, mDefaultState); 925 addState(mDisconnectedState, mDefaultState); 926 setInitialState(mConnectingState); 927 start(); 928 } 929 930 /** 931 * @return {@code true} if 464xlat should be skipped. 932 */ shouldSkip464Xlat()933 private boolean shouldSkip464Xlat() { 934 if (mDataProfile.getApnSetting() != null) { 935 switch (mDataProfile.getApnSetting().getSkip464Xlat()) { 936 case Telephony.Carriers.SKIP_464XLAT_ENABLE: 937 return true; 938 case Telephony.Carriers.SKIP_464XLAT_DISABLE: 939 return false; 940 case Telephony.Carriers.SKIP_464XLAT_DEFAULT: 941 default: 942 break; 943 } 944 } 945 946 // As default, return true if ims and no internet 947 final NetworkCapabilities nc = getNetworkCapabilities(); 948 return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS) 949 && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 950 } 951 952 /** 953 * Create the telephony network agent. 954 * 955 * @return The telephony network agent. 956 */ createNetworkAgent()957 private @NonNull TelephonyNetworkAgent createNetworkAgent() { 958 final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder(); 959 configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE); 960 configBuilder.setLegacyTypeName("MOBILE"); 961 int networkType = getDataNetworkType(); 962 configBuilder.setLegacySubType(networkType); 963 configBuilder.setLegacySubTypeName(TelephonyManager.getNetworkTypeName(networkType)); 964 if (mDataProfile.getApnSetting() != null) { 965 configBuilder.setLegacyExtraInfo(mDataProfile.getApnSetting().getApnName()); 966 } 967 968 final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent(); 969 if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager 970 .ACTION_CARRIER_SIGNAL_REDIRECTED)) { 971 // carrierSignal Receivers will place the carrier-specific provisioning notification 972 configBuilder.setProvisioningNotificationEnabled(false); 973 } 974 975 // Fill the IMSI 976 final String subscriberId = mPhone.getSubscriberId(); 977 if (!TextUtils.isEmpty(subscriberId)) { 978 configBuilder.setSubscriberId(subscriberId); 979 } 980 981 // set skip464xlat if it is not default otherwise 982 if (shouldSkip464Xlat()) { 983 configBuilder.setNat64DetectionEnabled(false); 984 } 985 986 final NetworkFactory factory = PhoneFactory.getNetworkFactory( 987 mPhone.getPhoneId()); 988 final NetworkProvider provider = (null == factory) ? null : factory.getProvider(); 989 990 mNetworkScore = getNetworkScore(); 991 return new TelephonyNetworkAgent(mPhone, getHandler().getLooper(), this, 992 new NetworkScore.Builder().setLegacyInt(mNetworkScore).build(), 993 configBuilder.build(), provider, 994 new TelephonyNetworkAgentCallback(getHandler()::post) { 995 @Override 996 public void onValidationStatus(@ValidationStatus int status, 997 @Nullable Uri redirectUri) { 998 mDataNetworkCallback.invokeFromExecutor( 999 () -> mDataNetworkCallback.onValidationStatusChanged( 1000 DataNetwork.this, status, redirectUri)); 1001 } 1002 }); 1003 } 1004 1005 /** 1006 * The default state. Any events that were not handled by the child states fallback to this 1007 * state. 1008 * 1009 * @see DataNetwork for the state machine diagram. 1010 */ 1011 private final class DefaultState extends State { 1012 @Override 1013 public void enter() { 1014 logv("Registering all events."); 1015 mDataConfigManagerCallback = new DataConfigManagerCallback(getHandler()::post) { 1016 @Override 1017 public void onCarrierConfigChanged() { 1018 sendMessage(EVENT_DATA_CONFIG_UPDATED); 1019 } 1020 }; 1021 mRil.registerForPcoData(getHandler(), EVENT_PCO_DATA_RECEIVED, null); 1022 1023 mDataConfigManager.registerCallback(mDataConfigManagerCallback); 1024 mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged( 1025 getHandler(), EVENT_DISPLAY_INFO_CHANGED, null); 1026 mPhone.getServiceStateTracker().registerForServiceStateChanged(getHandler(), 1027 EVENT_SERVICE_STATE_CHANGED); 1028 for (int transport : mAccessNetworksManager.getAvailableTransports()) { 1029 mDataServiceManagers.get(transport) 1030 .registerForDataCallListChanged(getHandler(), EVENT_DATA_STATE_CHANGED); 1031 } 1032 mPhone.getCarrierPrivilegesTracker().registerCarrierPrivilegesListener(getHandler(), 1033 EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null); 1034 1035 mPhone.getServiceStateTracker().registerForCssIndicatorChanged( 1036 getHandler(), EVENT_CSS_INDICATOR_CHANGED, null); 1037 mPhone.getCallTracker().registerForVoiceCallStarted( 1038 getHandler(), EVENT_VOICE_CALL_STARTED, null); 1039 mPhone.getCallTracker().registerForVoiceCallEnded( 1040 getHandler(), EVENT_VOICE_CALL_ENDED, null); 1041 // Check null for devices not supporting FEATURE_TELEPHONY_IMS. 1042 if (mPhone.getImsPhone() != null) { 1043 mPhone.getImsPhone().getCallTracker().registerForVoiceCallStarted( 1044 getHandler(), EVENT_VOICE_CALL_STARTED, null); 1045 mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded( 1046 getHandler(), EVENT_VOICE_CALL_ENDED, null); 1047 } 1048 1049 // Only add symmetric code here, for example, registering and unregistering. 1050 // DefaultState.enter() is the starting point in the life cycle of the DataNetwork, 1051 // and DefaultState.exit() is the end. For non-symmetric initializing works, put them 1052 // in ConnectingState.enter(). 1053 } 1054 1055 @Override 1056 public void exit() { 1057 logv("Unregistering all events."); 1058 // Check null for devices not supporting FEATURE_TELEPHONY_IMS. 1059 if (mPhone.getImsPhone() != null) { 1060 mPhone.getImsPhone().getCallTracker().unregisterForVoiceCallStarted(getHandler()); 1061 mPhone.getImsPhone().getCallTracker().unregisterForVoiceCallEnded(getHandler()); 1062 } 1063 mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler()); 1064 mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler()); 1065 1066 mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler()); 1067 mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler()); 1068 for (int transport : mAccessNetworksManager.getAvailableTransports()) { 1069 mDataServiceManagers.get(transport) 1070 .unregisterForDataCallListChanged(getHandler()); 1071 } 1072 mPhone.getServiceStateTracker().unregisterForServiceStateChanged(getHandler()); 1073 mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged( 1074 getHandler()); 1075 mRil.unregisterForPcoData(getHandler()); 1076 mDataConfigManager.unregisterCallback(mDataConfigManagerCallback); 1077 } 1078 1079 @Override 1080 public boolean processMessage(Message msg) { 1081 switch (msg.what) { 1082 case EVENT_DATA_CONFIG_UPDATED: 1083 onCarrierConfigUpdated(); 1084 break; 1085 case EVENT_SERVICE_STATE_CHANGED: { 1086 mDataCallSessionStats.onDrsOrRatChanged(getDataNetworkType()); 1087 updateSuspendState(); 1088 updateNetworkCapabilities(); 1089 break; 1090 } 1091 case EVENT_ATTACH_NETWORK_REQUEST: { 1092 onAttachNetworkRequests((NetworkRequestList) msg.obj); 1093 updateNetworkScore(); 1094 break; 1095 } 1096 case EVENT_DETACH_NETWORK_REQUEST: { 1097 onDetachNetworkRequest((TelephonyNetworkRequest) msg.obj); 1098 updateNetworkScore(); 1099 break; 1100 } 1101 case EVENT_DETACH_ALL_NETWORK_REQUESTS: { 1102 for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) { 1103 networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED); 1104 networkRequest.setAttachedNetwork(null); 1105 } 1106 log("All network requests detached."); 1107 mAttachedNetworkRequestList.clear(); 1108 break; 1109 } 1110 case EVENT_DATA_STATE_CHANGED: { 1111 AsyncResult ar = (AsyncResult) msg.obj; 1112 int transport = (int) ar.userObj; 1113 onDataStateChanged(transport, (List<DataCallResponse>) ar.result); 1114 break; 1115 } 1116 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: { 1117 AsyncResult asyncResult = (AsyncResult) msg.obj; 1118 int[] administratorUids = (int[]) asyncResult.result; 1119 mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); 1120 updateNetworkCapabilities(); 1121 break; 1122 } 1123 case EVENT_PCO_DATA_RECEIVED: { 1124 AsyncResult ar = (AsyncResult) msg.obj; 1125 onPcoDataReceived((PcoData) ar.result); 1126 break; 1127 } 1128 case EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE: 1129 log("Notified handover cancelled."); 1130 break; 1131 case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED: 1132 case EVENT_TEAR_DOWN_NETWORK: 1133 case EVENT_STUCK_IN_TRANSIENT_STATE: 1134 case EVENT_DISPLAY_INFO_CHANGED: 1135 case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET: 1136 case EVENT_CSS_INDICATOR_CHANGED: 1137 case EVENT_VOICE_CALL_STARTED: 1138 case EVENT_VOICE_CALL_ENDED: 1139 // Ignore the events when not in the correct state. 1140 log("Ignored " + eventToString(msg.what)); 1141 break; 1142 case EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE: 1143 case EVENT_NOTIFY_HANDOVER_STARTED: 1144 // We reach here if network is not in the right state. 1145 if (msg.obj != null) { 1146 // Cancel it because it's either HO in progress or will soon disconnect. 1147 // Either case we want to clean up obsolete retry attempts. 1148 DataHandoverRetryEntry retryEntry = (DataHandoverRetryEntry) msg.obj; 1149 retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 1150 } 1151 log("Ignore handover to " + AccessNetworkConstants 1152 .transportTypeToString(msg.arg1) + " request."); 1153 break; 1154 case EVENT_RADIO_NOT_AVAILABLE: 1155 mFailCause = DataFailCause.RADIO_NOT_AVAILABLE; 1156 loge(eventToString(msg.what) + ": transition to disconnected state"); 1157 transitionTo(mDisconnectedState); 1158 break; 1159 default: 1160 loge("Unhandled event " + eventToString(msg.what)); 1161 break; 1162 } 1163 return HANDLED; 1164 } 1165 } 1166 1167 /** 1168 * The connecting state. This is the initial state of a data network. 1169 * 1170 * @see DataNetwork for the state machine diagram. 1171 */ 1172 private final class ConnectingState extends State { 1173 @Override 1174 public void enter() { 1175 sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE, 1176 mDataConfigManager.getAnomalyNetworkConnectingTimeoutMs()); 1177 mNetworkAgent = createNetworkAgent(); 1178 mInitialNetworkAgentId = mNetworkAgent.getId(); 1179 mLogTag = "DN-" + mInitialNetworkAgentId + "-" 1180 + ((mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) ? "C" : "I"); 1181 1182 // Get carrier config package uid. Note that this uid will not change through the life 1183 // cycle of this data network. So there is no need to listen to the change event. 1184 mCarrierServicePackageUid = mPhone.getCarrierPrivilegesTracker() 1185 .getCarrierServicePackageUid(); 1186 1187 notifyPreciseDataConnectionState(); 1188 if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1189 // Defer setupData until we get the PDU session ID response 1190 allocatePduSessionId(); 1191 return; 1192 } 1193 1194 setupData(); 1195 } 1196 1197 @Override 1198 public void exit() { 1199 removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE); 1200 } 1201 1202 @Override 1203 public boolean processMessage(Message msg) { 1204 logv("event=" + eventToString(msg.what)); 1205 switch (msg.what) { 1206 case EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE: 1207 AsyncResult ar = (AsyncResult) msg.obj; 1208 if (ar.exception == null) { 1209 mPduSessionId = (int) ar.result; 1210 log("Set PDU session id to " + mPduSessionId); 1211 } else { 1212 loge("Failed to allocate PDU session id. e=" + ar.exception); 1213 } 1214 setupData(); 1215 break; 1216 case EVENT_SETUP_DATA_NETWORK_RESPONSE: 1217 int resultCode = msg.arg1; 1218 DataCallResponse dataCallResponse = 1219 msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE); 1220 onSetupResponse(resultCode, dataCallResponse); 1221 break; 1222 case EVENT_NOTIFY_HANDOVER_STARTED: 1223 case EVENT_TEAR_DOWN_NETWORK: 1224 case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET: 1225 // Defer the request until connected or disconnected. 1226 log("Defer message " + eventToString(msg.what)); 1227 deferMessage(msg); 1228 break; 1229 case EVENT_STUCK_IN_TRANSIENT_STATE: 1230 reportAnomaly("Data network stuck in connecting state for " 1231 + TimeUnit.MILLISECONDS.toSeconds( 1232 mDataConfigManager.getAnomalyNetworkConnectingTimeoutMs()) 1233 + " seconds.", "58c56403-7ea7-4e56-a0c7-e467114d09b8"); 1234 // Setup data failed. Use the retry logic defined in 1235 // CarrierConfigManager.KEY_TELEPHONY_DATA_SETUP_RETRY_RULES_STRING_ARRAY. 1236 mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED; 1237 mFailCause = DataFailCause.NO_RETRY_FAILURE; 1238 transitionTo(mDisconnectedState); 1239 break; 1240 default: 1241 return NOT_HANDLED; 1242 } 1243 return HANDLED; 1244 } 1245 } 1246 1247 /** 1248 * The connected state. This is the state when data network becomes usable. 1249 * 1250 * @see DataNetwork for the state machine diagram. 1251 */ 1252 private final class ConnectedState extends State { 1253 @Override 1254 public void enter() { 1255 // Note that reaching here could mean from connecting -> connected, or from 1256 // handover -> connected. 1257 if (!mEverConnected) { 1258 // Transited from ConnectingState 1259 log("network connected."); 1260 mEverConnected = true; 1261 mNetworkAgent.markConnected(); 1262 mDataNetworkCallback.invokeFromExecutor( 1263 () -> mDataNetworkCallback.onConnected(DataNetwork.this)); 1264 1265 mQosCallbackTracker = new QosCallbackTracker(mNetworkAgent, mPhone); 1266 mQosCallbackTracker.updateSessions(mQosBearerSessions); 1267 mKeepaliveTracker = new KeepaliveTracker(mPhone, 1268 getHandler().getLooper(), DataNetwork.this, mNetworkAgent); 1269 if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1270 registerForWwanEvents(); 1271 } 1272 1273 // Create the VCN policy changed listener. When the policy changed, we might need 1274 // to tear down the VCN-managed network. 1275 if (mVcnManager != null) { 1276 mVcnPolicyChangeListener = () -> { 1277 log("VCN policy changed."); 1278 if (mVcnManager.applyVcnNetworkPolicy(mNetworkCapabilities, mLinkProperties) 1279 .isTeardownRequested()) { 1280 tearDown(TEAR_DOWN_REASON_VCN_REQUESTED); 1281 } else { 1282 updateNetworkCapabilities(); 1283 } 1284 }; 1285 mVcnManager.addVcnNetworkPolicyChangeListener( 1286 getHandler()::post, mVcnPolicyChangeListener); 1287 } 1288 } 1289 1290 // If we've ever received PCO data before connected, now it's the time to 1291 // process it. 1292 mPcoData.getOrDefault(mCid.get(mTransport), Collections.emptyMap()) 1293 .forEach((pcoId, pcoData) -> { 1294 onPcoDataChanged(pcoData); 1295 }); 1296 1297 notifyPreciseDataConnectionState(); 1298 updateSuspendState(); 1299 } 1300 1301 @Override 1302 public boolean processMessage(Message msg) { 1303 logv("event=" + eventToString(msg.what)); 1304 switch (msg.what) { 1305 case EVENT_TEAR_DOWN_NETWORK: 1306 if (mInvokedDataDeactivation) { 1307 log("Ignore tear down request because network is being torn down."); 1308 break; 1309 } 1310 1311 int tearDownReason = msg.arg1; 1312 // If the tear down request is from upper layer, for example, IMS service 1313 // releases network request, we don't need to delay. The purpose of the delay 1314 // is to have IMS service have time to perform IMS de-registration, so if this 1315 // request is from IMS service itself, that means IMS service is already aware 1316 // of the tear down. So there is no need to delay in this case. 1317 if (tearDownReason != TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED 1318 && shouldDelayImsTearDown()) { 1319 logl("Delay IMS tear down until call ends. reason=" 1320 + tearDownReasonToString(tearDownReason)); 1321 break; 1322 } 1323 1324 removeMessages(EVENT_TEAR_DOWN_NETWORK); 1325 removeDeferredMessages(EVENT_TEAR_DOWN_NETWORK); 1326 transitionTo(mDisconnectingState); 1327 onTearDown(tearDownReason); 1328 break; 1329 case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED: 1330 AsyncResult ar = (AsyncResult) msg.obj; 1331 if (ar.exception != null) { 1332 log("EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED: error ignoring, e=" 1333 + ar.exception); 1334 break; 1335 } 1336 onBandwidthUpdatedFromModem((List<LinkCapacityEstimate>) ar.result); 1337 break; 1338 case EVENT_DISPLAY_INFO_CHANGED: 1339 onDisplayInfoChanged(); 1340 break; 1341 case EVENT_NOTIFY_HANDOVER_STARTED: 1342 // Notify source transport that handover is about to start. Note this will not 1343 // initiate the handover process on target transport, but more for notifying 1344 // the source transport so that PDU session id can be preserved if network 1345 // notifies PDN lost during handover. The real handover process will kick off 1346 // after receiving EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE. 1347 log("Notifying source transport " 1348 + AccessNetworkConstants.transportTypeToString(mTransport) 1349 + " that handover is about to start."); 1350 mDataServiceManagers.get(mTransport).startHandover(mCid.get(mTransport), 1351 obtainMessage(EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE, 0, msg.arg2, 1352 msg.obj)); 1353 // We enter handover state here because this is the first action we do for 1354 // handover. 1355 transitionTo(mHandoverState); 1356 break; 1357 case EVENT_SUBSCRIPTION_PLAN_OVERRIDE: 1358 updateMeteredAndCongested(); 1359 break; 1360 case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE: 1361 int resultCode = msg.arg1; 1362 onDeactivateResponse(resultCode); 1363 break; 1364 case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET: 1365 transitionTo(mDisconnectingState); 1366 sendMessageDelayed(EVENT_TEAR_DOWN_NETWORK, msg.arg1, msg.arg2); 1367 break; 1368 case EVENT_VOICE_CALL_STARTED: 1369 case EVENT_VOICE_CALL_ENDED: 1370 case EVENT_CSS_INDICATOR_CHANGED: 1371 updateSuspendState(); 1372 updateNetworkCapabilities(); 1373 break; 1374 default: 1375 return NOT_HANDLED; 1376 } 1377 return HANDLED; 1378 } 1379 } 1380 1381 /** 1382 * The handover state. This is the state when data network handover between IWLAN and cellular. 1383 * 1384 * @see DataNetwork for the state machine diagram. 1385 */ 1386 private final class HandoverState extends State { 1387 @Override 1388 public void enter() { 1389 sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE, 1390 mDataConfigManager.getNetworkHandoverTimeoutMs()); 1391 notifyPreciseDataConnectionState(); 1392 } 1393 1394 @Override 1395 public void exit() { 1396 removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE); 1397 } 1398 1399 @Override 1400 public boolean processMessage(Message msg) { 1401 logv("event=" + eventToString(msg.what)); 1402 switch (msg.what) { 1403 case EVENT_DATA_STATE_CHANGED: 1404 // The data call list changed event should be conditionally deferred. 1405 // Otherwise the deferred message might be incorrectly treated as "disconnected" 1406 // signal. So we only defer the related data call list changed event, and drop 1407 // the unrelated. 1408 AsyncResult ar = (AsyncResult) msg.obj; 1409 int transport = (int) ar.userObj; 1410 List<DataCallResponse> responseList = (List<DataCallResponse>) ar.result; 1411 if (transport != mTransport) { 1412 log("Dropped unrelated " 1413 + AccessNetworkConstants.transportTypeToString(transport) 1414 + " data call list changed event. " + responseList); 1415 } else { 1416 log("Defer message " + eventToString(msg.what) + ":" + responseList); 1417 deferMessage(msg); 1418 } 1419 break; 1420 case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET: 1421 case EVENT_DISPLAY_INFO_CHANGED: 1422 case EVENT_TEAR_DOWN_NETWORK: 1423 case EVENT_CSS_INDICATOR_CHANGED: 1424 case EVENT_VOICE_CALL_ENDED: 1425 case EVENT_VOICE_CALL_STARTED: 1426 // Defer the request until handover succeeds or fails. 1427 log("Defer message " + eventToString(msg.what)); 1428 deferMessage(msg); 1429 break; 1430 case EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE: 1431 onStartHandover(msg.arg2, (DataHandoverRetryEntry) msg.obj); 1432 break; 1433 case EVENT_HANDOVER_RESPONSE: 1434 int resultCode = msg.arg1; 1435 DataCallResponse dataCallResponse = 1436 msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE); 1437 onHandoverResponse(resultCode, dataCallResponse, 1438 (DataHandoverRetryEntry) msg.obj); 1439 break; 1440 case EVENT_STUCK_IN_TRANSIENT_STATE: 1441 // enable detection only for valid timeout range 1442 reportAnomaly("Data service did not respond the handover request within " 1443 + TimeUnit.MILLISECONDS.toSeconds( 1444 mDataConfigManager.getNetworkHandoverTimeoutMs()) + " seconds.", 1445 "1afe68cb-8b41-4964-a737-4f34372429ea"); 1446 // Handover failed. Use the retry logic defined in 1447 // CarrierConfigManager.KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY. 1448 long retry = DataCallResponse.RETRY_DURATION_UNDEFINED; 1449 int handoverFailureMode = 1450 DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL; 1451 mFailCause = DataFailCause.ERROR_UNSPECIFIED; 1452 mDataNetworkCallback.invokeFromExecutor( 1453 () -> mDataNetworkCallback.onHandoverFailed(DataNetwork.this, 1454 mFailCause, retry, handoverFailureMode)); 1455 // No matter handover succeeded or not, transit back to connected state. 1456 transitionTo(mConnectedState); 1457 break; 1458 default: 1459 return NOT_HANDLED; 1460 } 1461 return HANDLED; 1462 } 1463 } 1464 1465 /** 1466 * The disconnecting state. This is the state when data network is about to be disconnected. 1467 * The network is still usable in this state, but the clients should be prepared to lose the 1468 * network in any moment. This state is particular useful for IMS graceful tear down, where 1469 * the network enters disconnecting state while waiting for IMS de-registration signal. 1470 * 1471 * @see DataNetwork for the state machine diagram. 1472 */ 1473 private final class DisconnectingState extends State { 1474 @Override 1475 public void enter() { 1476 sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE, 1477 mDataConfigManager.getAnomalyNetworkDisconnectingTimeoutMs()); 1478 notifyPreciseDataConnectionState(); 1479 } 1480 1481 @Override 1482 public void exit() { 1483 removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE); 1484 } 1485 1486 @Override 1487 public boolean processMessage(Message msg) { 1488 logv("event=" + eventToString(msg.what)); 1489 switch (msg.what) { 1490 case EVENT_TEAR_DOWN_NETWORK: 1491 if (mInvokedDataDeactivation) { 1492 log("Ignore tear down request because network is being torn down."); 1493 break; 1494 } 1495 removeMessages(EVENT_TEAR_DOWN_NETWORK); 1496 removeDeferredMessages(EVENT_TEAR_DOWN_NETWORK); 1497 onTearDown(msg.arg1); 1498 break; 1499 case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE: 1500 int resultCode = msg.arg1; 1501 onDeactivateResponse(resultCode); 1502 break; 1503 case EVENT_STUCK_IN_TRANSIENT_STATE: 1504 // After frameworks issues deactivate data call request, RIL should report 1505 // data disconnected through data call list changed event subsequently. 1506 1507 reportAnomaly("RIL did not send data call list changed event after " 1508 + "deactivate data call request within " 1509 + TimeUnit.MILLISECONDS.toSeconds( 1510 mDataConfigManager.getAnomalyNetworkDisconnectingTimeoutMs()) 1511 + " seconds.", "d0e4fa1c-c57b-4ba5-b4b6-8955487012cc"); 1512 mFailCause = DataFailCause.LOST_CONNECTION; 1513 transitionTo(mDisconnectedState); 1514 break; 1515 case EVENT_DISPLAY_INFO_CHANGED: 1516 onDisplayInfoChanged(); 1517 break; 1518 case EVENT_CSS_INDICATOR_CHANGED: 1519 case EVENT_VOICE_CALL_STARTED: 1520 case EVENT_VOICE_CALL_ENDED: 1521 updateSuspendState(); 1522 updateNetworkCapabilities(); 1523 break; 1524 default: 1525 return NOT_HANDLED; 1526 } 1527 return HANDLED; 1528 } 1529 } 1530 1531 /** 1532 * The disconnected state. This is the final state of a data network. 1533 * 1534 * @see DataNetwork for the state machine diagram. 1535 */ 1536 private final class DisconnectedState extends State { 1537 @Override 1538 public void enter() { 1539 logl("Data network disconnected. mEverConnected=" + mEverConnected); 1540 // Preserve the list for onSetupDataFailed callback, because we need to pass that list 1541 // back to DataNetworkController, but after EVENT_DETACH_ALL_NETWORK_REQUESTS gets 1542 // processed, the network request list would become empty. 1543 NetworkRequestList requestList = new NetworkRequestList(mAttachedNetworkRequestList); 1544 1545 // The detach all network requests must be the last message to handle. 1546 sendMessage(EVENT_DETACH_ALL_NETWORK_REQUESTS); 1547 // Gracefully handle all the un-processed events then quit the state machine. 1548 // quit() throws a QUIT event to the end of message queue. All the events before quit() 1549 // will be processed. Events after quit() will not be processed. 1550 quit(); 1551 1552 //************************************************************// 1553 // DO NOT POST ANY EVENTS AFTER HERE. // 1554 // THE STATE MACHINE WONT PROCESS EVENTS AFTER QUIT. // 1555 // ONLY CLEANUP SHOULD BE PERFORMED AFTER THIS. // 1556 //************************************************************// 1557 1558 if (mEverConnected) { 1559 mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback 1560 .onDisconnected(DataNetwork.this, mFailCause)); 1561 if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1562 unregisterForWwanEvents(); 1563 } 1564 } else { 1565 mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback 1566 .onSetupDataFailed(DataNetwork.this, 1567 requestList, mFailCause, mRetryDelayMillis)); 1568 } 1569 notifyPreciseDataConnectionState(); 1570 mNetworkAgent.unregister(); 1571 mDataNetworkController.unregisterDataNetworkControllerCallback( 1572 mDataNetworkControllerCallback); 1573 mDataCallSessionStats.onDataCallDisconnected(mFailCause); 1574 1575 if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1576 && mPduSessionId != DataCallResponse.PDU_SESSION_ID_NOT_SET) { 1577 mRil.releasePduSessionId(null, mPduSessionId); 1578 } 1579 1580 if (mVcnManager != null && mVcnPolicyChangeListener != null) { 1581 mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener); 1582 } 1583 } 1584 1585 @Override 1586 public boolean processMessage(Message msg) { 1587 logv("event=" + eventToString(msg.what)); 1588 return NOT_HANDLED; 1589 } 1590 } 1591 1592 /** 1593 * Register for events that can only happen on cellular networks. 1594 */ 1595 private void registerForWwanEvents() { 1596 registerForBandwidthUpdate(); 1597 mKeepaliveTracker.registerForKeepaliveStatus(); 1598 mRil.registerForNotAvailable(this.getHandler(), EVENT_RADIO_NOT_AVAILABLE, null); 1599 } 1600 1601 /** 1602 * Unregister for events that can only happen on cellular networks. 1603 */ 1604 private void unregisterForWwanEvents() { 1605 unregisterForBandwidthUpdate(); 1606 mKeepaliveTracker.unregisterForKeepaliveStatus(); 1607 mRil.unregisterForNotAvailable(this.getHandler()); 1608 } 1609 1610 @Override 1611 protected void unhandledMessage(Message msg) { 1612 IState state = getCurrentState(); 1613 loge("Unhandled message " + msg.what + " in state " 1614 + (state == null ? "null" : state.getName())); 1615 } 1616 1617 /** 1618 * Attempt to attach the network request list to this data network. Whether the network can 1619 * satisfy the request or not will be checked when EVENT_ATTACH_NETWORK_REQUEST is processed. 1620 * If the request can't be attached, {@link DataNetworkCallback#onAttachFailed( 1621 * DataNetwork, NetworkRequestList)}. 1622 * 1623 * @param requestList Network request list to attach. 1624 * @return {@code false} if the network is already disconnected. {@code true} means the request 1625 * has been scheduled to attach to the network. If attach succeeds, the network request's state 1626 * will be set to {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed, the 1627 * callback {@link DataNetworkCallback#onAttachFailed(DataNetwork, NetworkRequestList)} will 1628 * be called. 1629 */ 1630 public boolean attachNetworkRequests(@NonNull NetworkRequestList requestList) { 1631 // If the network is already ended, we still attach the network request to the data network, 1632 // so it can be retried later by data network controller. 1633 if (getCurrentState() == null || isDisconnected()) { 1634 // The state machine has already stopped. This is due to data network is disconnected. 1635 return false; 1636 } 1637 sendMessage(obtainMessage(EVENT_ATTACH_NETWORK_REQUEST, requestList)); 1638 return true; 1639 } 1640 1641 /** 1642 * Called when attaching network request list to this data network. 1643 * 1644 * @param requestList Network request list to attach. 1645 */ 1646 public void onAttachNetworkRequests(@NonNull NetworkRequestList requestList) { 1647 NetworkRequestList failedList = new NetworkRequestList(); 1648 for (TelephonyNetworkRequest networkRequest : requestList) { 1649 if (!mDataNetworkController.isNetworkRequestExisting(networkRequest)) { 1650 failedList.add(networkRequest); 1651 log("Attached failed. Network request was already removed. " + networkRequest); 1652 } else if (!networkRequest.canBeSatisfiedBy(getNetworkCapabilities())) { 1653 failedList.add(networkRequest); 1654 log("Attached failed. Cannot satisfy the network request " 1655 + networkRequest); 1656 } else { 1657 mAttachedNetworkRequestList.add(networkRequest); 1658 networkRequest.setAttachedNetwork(DataNetwork.this); 1659 networkRequest.setState( 1660 TelephonyNetworkRequest.REQUEST_STATE_SATISFIED); 1661 log("Successfully attached network request " + networkRequest); 1662 } 1663 } 1664 if (failedList.size() > 0) { 1665 mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback 1666 .onAttachFailed(DataNetwork.this, failedList)); 1667 } 1668 } 1669 1670 /** 1671 * Called when detaching the network request from this data network. 1672 * 1673 * @param networkRequest Network request to detach. 1674 */ 1675 private void onDetachNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) { 1676 mAttachedNetworkRequestList.remove(networkRequest); 1677 networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED); 1678 networkRequest.setAttachedNetwork(null); 1679 1680 if (mAttachedNetworkRequestList.isEmpty()) { 1681 log("All network requests are detached."); 1682 1683 // If there is no network request attached, and we are not preferred data phone, then 1684 // this detach is likely due to temp DDS switch. We should tear down the network when 1685 // all requests are detached so the other network on preferred data sub can be 1686 // established properly. 1687 int preferredDataPhoneId = PhoneSwitcher.getInstance().getPreferredDataPhoneId(); 1688 if (preferredDataPhoneId != SubscriptionManager.INVALID_PHONE_INDEX 1689 && preferredDataPhoneId != mPhone.getPhoneId()) { 1690 tearDown(TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED); 1691 } 1692 } 1693 } 1694 1695 /** 1696 * Detach the network request from this data network. Note that this will not tear down the 1697 * network. 1698 * 1699 * @param networkRequest Network request to detach. 1700 */ 1701 public void detachNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) { 1702 if (getCurrentState() == null || isDisconnected()) { 1703 return; 1704 } 1705 sendMessage(obtainMessage(EVENT_DETACH_NETWORK_REQUEST, networkRequest)); 1706 } 1707 1708 /** 1709 * Register for bandwidth update. 1710 */ 1711 private void registerForBandwidthUpdate() { 1712 int bandwidthEstimateSource = mDataConfigManager.getBandwidthEstimateSource(); 1713 if (bandwidthEstimateSource == BANDWIDTH_SOURCE_MODEM) { 1714 mPhone.mCi.registerForLceInfo( 1715 getHandler(), EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED, null); 1716 } else if (bandwidthEstimateSource == BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR) { 1717 if (mLinkBandwidthEstimatorCallback == null) { 1718 mLinkBandwidthEstimatorCallback = 1719 new LinkBandwidthEstimatorCallback(getHandler()::post) { 1720 @Override 1721 public void onBandwidthChanged(int uplinkBandwidthKbps, 1722 int downlinkBandwidthKbps) { 1723 if (isConnected()) { 1724 onBandwidthUpdated(uplinkBandwidthKbps, downlinkBandwidthKbps); 1725 } 1726 } 1727 }; 1728 mPhone.getLinkBandwidthEstimator().registerCallback( 1729 mLinkBandwidthEstimatorCallback); 1730 } 1731 } else { 1732 loge("Invalid bandwidth source configuration: " + bandwidthEstimateSource); 1733 } 1734 } 1735 1736 /** 1737 * Unregister bandwidth update. 1738 */ 1739 private void unregisterForBandwidthUpdate() { 1740 int bandwidthEstimateSource = mDataConfigManager.getBandwidthEstimateSource(); 1741 if (bandwidthEstimateSource == BANDWIDTH_SOURCE_MODEM) { 1742 mPhone.mCi.unregisterForLceInfo(getHandler()); 1743 } else if (bandwidthEstimateSource == BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR) { 1744 if (mLinkBandwidthEstimatorCallback != null) { 1745 mPhone.getLinkBandwidthEstimator() 1746 .unregisterCallback(mLinkBandwidthEstimatorCallback); 1747 mLinkBandwidthEstimatorCallback = null; 1748 } 1749 } else { 1750 loge("Invalid bandwidth source configuration: " + bandwidthEstimateSource); 1751 } 1752 } 1753 1754 /** 1755 * Remove network requests that can't be satisfied anymore. 1756 */ 1757 private void removeUnsatisfiedNetworkRequests() { 1758 for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) { 1759 if (!networkRequest.canBeSatisfiedBy(mNetworkCapabilities)) { 1760 log("removeUnsatisfiedNetworkRequests: " + networkRequest 1761 + " can't be satisfied anymore. Will be detached."); 1762 detachNetworkRequest(networkRequest); 1763 } 1764 } 1765 } 1766 1767 /** 1768 * Check if the new link properties are compatible with the old link properties. For example, 1769 * if IP changes, that's considered incompatible. 1770 * 1771 * @param oldLinkProperties Old link properties. 1772 * @param newLinkProperties New Link properties. 1773 * 1774 * @return {@code true} if the new link properties is compatible with the old link properties. 1775 */ 1776 private boolean isLinkPropertiesCompatible(@NonNull LinkProperties oldLinkProperties, 1777 @NonNull LinkProperties newLinkProperties) { 1778 if (Objects.equals(oldLinkProperties, newLinkProperties)) return true; 1779 1780 if (!LinkPropertiesUtils.isIdenticalAddresses(oldLinkProperties, newLinkProperties)) { 1781 // If the same address type was removed and added we need to cleanup. 1782 LinkPropertiesUtils.CompareOrUpdateResult<Integer, LinkAddress> result = 1783 new LinkPropertiesUtils.CompareOrUpdateResult<>( 1784 oldLinkProperties.getLinkAddresses(), 1785 newLinkProperties.getLinkAddresses(), 1786 linkAddress -> Objects.hash(linkAddress.getAddress(), 1787 linkAddress.getPrefixLength(), linkAddress.getScope())); 1788 log("isLinkPropertiesCompatible: old=" + oldLinkProperties 1789 + " new=" + newLinkProperties + " result=" + result); 1790 for (LinkAddress added : result.added) { 1791 for (LinkAddress removed : result.removed) { 1792 if (NetUtils.addressTypeMatches(removed.getAddress(), added.getAddress())) { 1793 return false; 1794 } 1795 } 1796 } 1797 } 1798 1799 return true; 1800 } 1801 1802 /** 1803 * Check if there are immutable capabilities changed. The connectivity service is not able 1804 * to handle immutable capabilities changed, but in very rare scenarios, immutable capabilities 1805 * need to be changed dynamically, such as in setup data call response, modem responded with the 1806 * same cid. In that case, we need to merge the new capabilities into the existing data network. 1807 * 1808 * @param oldCapabilities The old network capabilities. 1809 * @param newCapabilities The new network capabilities. 1810 * @return {@code true} if there are immutable network capabilities changed. 1811 */ 1812 private static boolean areImmutableCapabilitiesChanged( 1813 @NonNull NetworkCapabilities oldCapabilities, 1814 @NonNull NetworkCapabilities newCapabilities) { 1815 if (oldCapabilities == null 1816 || ArrayUtils.isEmpty(oldCapabilities.getCapabilities())) return false; 1817 1818 // Remove mutable capabilities from both old and new capabilities, the remaining 1819 // capabilities would be immutable capabilities. 1820 List<Integer> oldImmutableCapabilities = Arrays.stream(oldCapabilities.getCapabilities()) 1821 .boxed().collect(Collectors.toList()); 1822 oldImmutableCapabilities.removeAll(MUTABLE_CAPABILITIES); 1823 List<Integer> newImmutableCapabilities = Arrays.stream(newCapabilities.getCapabilities()) 1824 .boxed().collect(Collectors.toList()); 1825 newImmutableCapabilities.removeAll(MUTABLE_CAPABILITIES); 1826 return oldImmutableCapabilities.size() != newImmutableCapabilities.size() 1827 || !oldImmutableCapabilities.containsAll(newImmutableCapabilities); 1828 } 1829 1830 /** 1831 * In some rare cases we need to re-create the network agent, for example, underlying network 1832 * IP changed, or when we unfortunately need to remove/add a immutable network capability. 1833 */ 1834 private void recreateNetworkAgent() { 1835 if (isConnecting() || isDisconnected() || isDisconnecting()) { 1836 loge("Incorrect state for re-creating the network agent."); 1837 return; 1838 } 1839 1840 // Abandon the network agent because we are going to create a new one. 1841 mNetworkAgent.abandon(); 1842 // Create a new network agent and register with connectivity service. Note that the agent 1843 // will always be registered with NOT_SUSPENDED capability. 1844 mNetworkAgent = createNetworkAgent(); 1845 mNetworkAgent.markConnected(); 1846 // Because network agent is always created with NOT_SUSPENDED, we need to update 1847 // the suspended if it's was in suspended state. 1848 if (mSuspended) { 1849 log("recreateNetworkAgent: The network is in suspended state. Update the network" 1850 + " capability again. nc=" + mNetworkCapabilities); 1851 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); 1852 } 1853 } 1854 1855 /** 1856 * Update the network capabilities. 1857 */ 1858 private void updateNetworkCapabilities() { 1859 final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder() 1860 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); 1861 boolean roaming = mPhone.getServiceState().getDataRoaming(); 1862 1863 builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 1864 .setSubscriptionId(mSubId).build()); 1865 builder.setSubscriptionIds(Collections.singleton(mSubId)); 1866 1867 ApnSetting apnSetting = mDataProfile.getApnSetting(); 1868 1869 if (apnSetting != null) { 1870 apnSetting.getApnTypes().stream() 1871 .map(DataUtils::apnTypeToNetworkCapability) 1872 .filter(cap -> cap >= 0) 1873 .forEach(builder::addCapability); 1874 if (apnSetting.getApnTypes().contains(ApnSetting.TYPE_ENTERPRISE)) { 1875 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1876 } 1877 } 1878 1879 // Once we set the MMTEL capability, we should never remove it because it's an immutable 1880 // capability defined by connectivity service. When the device enters from VoPS to non-VoPS, 1881 // we should perform grace tear down from data network controller if needed. 1882 if (mNetworkCapabilities != null 1883 && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) { 1884 // Previous capability has MMTEL, so add it again. 1885 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL); 1886 } else { 1887 // Always add MMTEL capability on IMS network unless network explicitly indicates VoPS 1888 // not supported. 1889 if (mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS)) { 1890 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL); 1891 if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1892 NetworkRegistrationInfo nri = getNetworkRegistrationInfo(); 1893 if (nri != null) { 1894 DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); 1895 // Check if the network is non-VoPS. 1896 if (dsri != null && dsri.getVopsSupportInfo() != null 1897 && !dsri.getVopsSupportInfo().isVopsSupported() 1898 && !mDataConfigManager.shouldKeepNetworkUpInNonVops()) { 1899 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL); 1900 } 1901 log("updateNetworkCapabilities: dsri=" + dsri); 1902 } 1903 } 1904 } 1905 } 1906 1907 // Extract network capabilities from the traffic descriptor. 1908 for (TrafficDescriptor trafficDescriptor : mTrafficDescriptors) { 1909 try { 1910 if (trafficDescriptor.getOsAppId() == null) continue; 1911 OsAppId osAppId = new OsAppId(trafficDescriptor.getOsAppId()); 1912 if (!osAppId.getOsId().equals(OsAppId.ANDROID_OS_ID)) { 1913 loge("Received non-Android OS id " + osAppId.getOsId()); 1914 continue; 1915 } 1916 int networkCapability = DataUtils.getNetworkCapabilityFromString( 1917 osAppId.getAppId()); 1918 switch (networkCapability) { 1919 case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE: 1920 builder.addCapability(networkCapability); 1921 // Always add internet if TD contains enterprise. 1922 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1923 builder.addEnterpriseId(osAppId.getDifferentiator()); 1924 break; 1925 case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY: 1926 case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH: 1927 case NetworkCapabilities.NET_CAPABILITY_CBS: 1928 builder.addCapability(networkCapability); 1929 break; 1930 default: 1931 loge("Invalid app id " + osAppId.getAppId()); 1932 } 1933 } catch (Exception e) { 1934 loge("Exception: " + e + ". Failed to create osAppId from " 1935 + new BigInteger(1, trafficDescriptor.getOsAppId()).toString(16)); 1936 } 1937 } 1938 1939 if (!mCongested) { 1940 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); 1941 } 1942 1943 if (mTempNotMeteredSupported && mTempNotMetered) { 1944 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED); 1945 } 1946 1947 // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a 1948 // VCN. 1949 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 1950 final VcnNetworkPolicyResult vcnPolicy = getVcnPolicy(builder.build()); 1951 if (vcnPolicy != null && !vcnPolicy.getNetworkCapabilities() 1952 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)) { 1953 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 1954 } 1955 1956 if (!roaming) { 1957 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 1958 } 1959 1960 if (!mSuspended) { 1961 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED); 1962 } 1963 1964 if (mCarrierServicePackageUid != Process.INVALID_UID 1965 && ArrayUtils.contains(mAdministratorUids, mCarrierServicePackageUid)) { 1966 builder.setOwnerUid(mCarrierServicePackageUid); 1967 builder.setAllowedUids(Collections.singleton(mCarrierServicePackageUid)); 1968 } 1969 builder.setAdministratorUids(mAdministratorUids); 1970 1971 Set<Integer> meteredCapabilities = mDataConfigManager 1972 .getMeteredNetworkCapabilities(roaming).stream() 1973 .filter(cap -> mAccessNetworksManager.getPreferredTransportByNetworkCapability(cap) 1974 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 1975 .collect(Collectors.toSet()); 1976 boolean unmeteredNetwork = meteredCapabilities.stream().noneMatch( 1977 Arrays.stream(builder.build().getCapabilities()).boxed() 1978 .collect(Collectors.toSet())::contains); 1979 1980 if (unmeteredNetwork) { 1981 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1982 } 1983 1984 // Always start with not-restricted, and then remove if needed. 1985 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1986 1987 // When data is disabled, or data roaming is disabled and the device is roaming, we need 1988 // to remove certain capabilities depending on scenarios. 1989 if (!mDataNetworkController.getDataSettingsManager().isDataEnabled() 1990 || (mPhone.getServiceState().getDataRoaming() 1991 && !mDataNetworkController.getDataSettingsManager().isDataRoamingEnabled())) { 1992 // If data is allowed because the request is a restricted network request, we need 1993 // to mark the network as restricted when data is disabled or data roaming is disabled 1994 // and the device is roaming. If we don't do that, non-privileged apps will be able 1995 // to use this network when data is disabled. 1996 if (mDataAllowedReason == DataAllowedReason.RESTRICTED_REQUEST) { 1997 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1998 } else if (mDataAllowedReason == DataAllowedReason.UNMETERED_USAGE 1999 || mDataAllowedReason == DataAllowedReason.MMS_REQUEST 2000 || mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL) { 2001 // If data is allowed due to unmetered usage, or MMS always-allowed, we need to 2002 // remove unrelated-but-metered capabilities. 2003 for (int capability : meteredCapabilities) { 2004 // 1. If it's unmetered usage, remove all metered capabilities. 2005 // 2. If it's MMS always-allowed, then remove all metered capabilities but MMS. 2006 // 3/ If it's for emergency SUPL, then remove all metered capabilities but SUPL. 2007 if ((capability == NetworkCapabilities.NET_CAPABILITY_MMS 2008 && mDataAllowedReason == DataAllowedReason.MMS_REQUEST) 2009 || (capability == NetworkCapabilities.NET_CAPABILITY_SUPL 2010 && mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL)) { 2011 // Not removing the capability for special uses. 2012 continue; 2013 } 2014 builder.removeCapability(capability); 2015 } 2016 } 2017 } 2018 2019 // If one of the capabilities are for special use, for example, IMS, CBS, then this 2020 // network should be restricted, regardless data is enabled or not. 2021 if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build()) 2022 || (vcnPolicy != null && !vcnPolicy.getNetworkCapabilities() 2023 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED))) { 2024 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 2025 } 2026 2027 // Set the bandwidth information. 2028 builder.setLinkDownstreamBandwidthKbps(mNetworkBandwidth.downlinkBandwidthKbps); 2029 builder.setLinkUpstreamBandwidthKbps(mNetworkBandwidth.uplinkBandwidthKbps); 2030 2031 NetworkCapabilities nc = builder.build(); 2032 if (mNetworkCapabilities == null || mNetworkAgent == null) { 2033 // This is the first time when network capabilities is created. The agent is not created 2034 // at this time. Just return here. The network capabilities will be used when network 2035 // agent is created. 2036 mNetworkCapabilities = nc; 2037 logl("Initial capabilities " + mNetworkCapabilities); 2038 return; 2039 } 2040 2041 if (!nc.equals(mNetworkCapabilities)) { 2042 // Check if we are changing the immutable capabilities. Note that we should be very 2043 // careful and limit the use cases of changing immutable capabilities. Connectivity 2044 // service would not close sockets for clients if a network request becomes 2045 // unsatisfiable. 2046 if (mEverConnected && areImmutableCapabilitiesChanged(mNetworkCapabilities, nc) 2047 && (isConnected() || isHandoverInProgress())) { 2048 // Before connectivity service supports making all capabilities mutable, it is 2049 // suggested to de-register and re-register the network agent if it is needed to 2050 // add/remove immutable capabilities. 2051 logl("updateNetworkCapabilities: Immutable capabilities changed. Re-create the " 2052 + "network agent. Attempted to change from " + mNetworkCapabilities + " to " 2053 + nc); 2054 mNetworkCapabilities = nc; 2055 recreateNetworkAgent(); 2056 } else { 2057 // Now we need to inform connectivity service and data network controller 2058 // about the capabilities changed. 2059 mNetworkCapabilities = nc; 2060 log("Capabilities changed to " + mNetworkCapabilities); 2061 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); 2062 } 2063 2064 removeUnsatisfiedNetworkRequests(); 2065 mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback 2066 .onNetworkCapabilitiesChanged(DataNetwork.this)); 2067 } else { 2068 log("updateNetworkCapabilities: Capabilities not changed."); 2069 } 2070 } 2071 2072 /** 2073 * @return The network capabilities of this data network. 2074 */ 2075 public @NonNull NetworkCapabilities getNetworkCapabilities() { 2076 return mNetworkCapabilities; 2077 } 2078 2079 /** 2080 * @return The link properties of this data network. 2081 */ 2082 public @NonNull LinkProperties getLinkProperties() { 2083 return mLinkProperties; 2084 } 2085 2086 /** 2087 * @return The data profile of this data network. 2088 */ 2089 public @NonNull DataProfile getDataProfile() { 2090 return mDataProfile; 2091 } 2092 2093 /** 2094 * Update data suspended state. 2095 */ 2096 private void updateSuspendState() { 2097 if (isConnecting() || isDisconnected()) { 2098 // Return if not in the right state. 2099 return; 2100 } 2101 2102 boolean newSuspendedState = false; 2103 // Get the uncombined service state directly. 2104 NetworkRegistrationInfo nri = getNetworkRegistrationInfo(); 2105 if (nri == null) return; 2106 2107 // Never set suspended for emergency apn. Emergency data connection 2108 // can work while device is not in service. 2109 if (mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) { 2110 newSuspendedState = false; 2111 // If we are not in service, change to suspended. 2112 } else if (nri.getRegistrationState() 2113 != NetworkRegistrationInfo.REGISTRATION_STATE_HOME 2114 && nri.getRegistrationState() 2115 != NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) { 2116 newSuspendedState = true; 2117 // Check voice/data concurrency. 2118 } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed() 2119 && mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 2120 newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE; 2121 } 2122 2123 // Only notify when there is a change. 2124 if (mSuspended != newSuspendedState) { 2125 mSuspended = newSuspendedState; 2126 logl("Network becomes " + (mSuspended ? "suspended" : "unsuspended")); 2127 // To update NOT_SUSPENDED capability. 2128 updateNetworkCapabilities(); 2129 notifyPreciseDataConnectionState(); 2130 mDataNetworkCallback.invokeFromExecutor(() -> 2131 mDataNetworkCallback.onSuspendedStateChanged(DataNetwork.this, mSuspended)); 2132 } 2133 } 2134 2135 /** 2136 * Allocate PDU session ID from the modem. This is only needed when the data network is 2137 * initiated on IWLAN. 2138 */ 2139 private void allocatePduSessionId() { 2140 mRil.allocatePduSessionId(obtainMessage(EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE)); 2141 } 2142 2143 /** 2144 * Setup a data network. 2145 */ 2146 private void setupData() { 2147 int dataNetworkType = getDataNetworkType(); 2148 2149 // We need to use the actual modem roaming state instead of the framework roaming state 2150 // here. This flag is only passed down to ril_service for picking the correct protocol (for 2151 // old modem backward compatibility). 2152 boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration(); 2153 2154 // Set this flag to true if the user turns on data roaming. Or if we override the roaming 2155 // state in framework, we should set this flag to true as well so the modem will not reject 2156 // the data call setup (because the modem actually thinks the device is roaming). 2157 boolean allowRoaming = mPhone.getDataRoamingEnabled() 2158 || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming() 2159 /*|| isUnmeteredUseOnly()*/)); 2160 2161 TrafficDescriptor trafficDescriptor = mDataProfile.getTrafficDescriptor(); 2162 final boolean matchAllRuleAllowed = trafficDescriptor == null 2163 || !TextUtils.isEmpty(trafficDescriptor.getDataNetworkName()); 2164 2165 int accessNetwork = DataUtils.networkTypeToAccessNetworkType(dataNetworkType); 2166 2167 mDataServiceManagers.get(mTransport) 2168 .setupDataCall(accessNetwork, mDataProfile, isModemRoaming, allowRoaming, 2169 DataService.REQUEST_REASON_NORMAL, null, mPduSessionId, null, 2170 trafficDescriptor, matchAllRuleAllowed, 2171 obtainMessage(EVENT_SETUP_DATA_NETWORK_RESPONSE)); 2172 2173 int apnTypeBitmask = mDataProfile.getApnSetting() != null 2174 ? mDataProfile.getApnSetting().getApnTypeBitmask() : ApnSetting.TYPE_NONE; 2175 mDataCallSessionStats.onSetupDataCall(apnTypeBitmask); 2176 2177 logl("setupData: accessNetwork=" 2178 + AccessNetworkType.toString(accessNetwork) + ", " + mDataProfile 2179 + ", isModemRoaming=" + isModemRoaming + ", allowRoaming=" + allowRoaming 2180 + ", PDU session id=" + mPduSessionId + ", matchAllRuleAllowed=" 2181 + matchAllRuleAllowed); 2182 TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), 2183 ServiceState.networkTypeToRilRadioTechnology(dataNetworkType), 2184 mDataProfile.getProfileId(), mDataProfile.getApn(), mDataProfile.getProtocolType()); 2185 } 2186 2187 /** 2188 * Get fail cause from {@link DataCallResponse} and the result code. 2189 * 2190 * @param resultCode The result code returned from 2191 * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}. 2192 * @param response The data call response returned from 2193 * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}. 2194 * 2195 * @return The fail cause. {@link DataFailCause#NONE} if succeeds. 2196 */ 2197 private @DataFailureCause int getFailCauseFromDataCallResponse( 2198 @DataServiceCallback.ResultCode int resultCode, @Nullable DataCallResponse response) { 2199 int failCause = DataFailCause.NONE; 2200 switch (resultCode) { 2201 case DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE: 2202 failCause = DataFailCause.RADIO_NOT_AVAILABLE; 2203 break; 2204 case DataServiceCallback.RESULT_ERROR_BUSY: 2205 case DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE: 2206 failCause = DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE; 2207 break; 2208 case DataServiceCallback.RESULT_ERROR_INVALID_ARG: 2209 failCause = DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER; 2210 break; 2211 case DataServiceCallback.RESULT_ERROR_UNSUPPORTED: 2212 failCause = DataFailCause.REQUEST_NOT_SUPPORTED; 2213 break; 2214 case DataServiceCallback.RESULT_SUCCESS: 2215 if (response != null) { 2216 failCause = DataFailCause.getFailCause(response.getCause()); 2217 } 2218 break; 2219 } 2220 return failCause; 2221 } 2222 2223 /** 2224 * Update data network based on the latest {@link DataCallResponse}. 2225 * 2226 * @param response The data call response from data service. 2227 */ 2228 private void updateDataNetwork(@NonNull DataCallResponse response) { 2229 mCid.put(mTransport, response.getId()); 2230 LinkProperties linkProperties = new LinkProperties(); 2231 2232 // Set interface name 2233 linkProperties.setInterfaceName(response.getInterfaceName()); 2234 2235 // Set PDU session id 2236 if (mPduSessionId != response.getPduSessionId()) { 2237 mPduSessionId = response.getPduSessionId(); 2238 log("PDU session id updated to " + mPduSessionId); 2239 } 2240 2241 // Set the link status 2242 if (mLinkStatus != response.getLinkStatus()) { 2243 mLinkStatus = response.getLinkStatus(); 2244 log("Link status updated to " + DataUtils.linkStatusToString(mLinkStatus)); 2245 mDataNetworkCallback.invokeFromExecutor( 2246 () -> mDataNetworkCallback.onLinkStatusChanged(DataNetwork.this, mLinkStatus)); 2247 } 2248 2249 // Set link addresses 2250 if (response.getAddresses().size() > 0) { 2251 for (LinkAddress la : response.getAddresses()) { 2252 if (!la.getAddress().isAnyLocalAddress()) { 2253 logv("addr/pl=" + la.getAddress() + "/" + la.getPrefixLength()); 2254 linkProperties.addLinkAddress(la); 2255 } 2256 } 2257 } else { 2258 loge("no address for ifname=" + response.getInterfaceName()); 2259 } 2260 2261 // Set DNS servers 2262 if (response.getDnsAddresses().size() > 0) { 2263 for (InetAddress dns : response.getDnsAddresses()) { 2264 if (!dns.isAnyLocalAddress()) { 2265 linkProperties.addDnsServer(dns); 2266 } 2267 } 2268 } else { 2269 loge("Empty dns response"); 2270 } 2271 2272 // Set PCSCF 2273 if (response.getPcscfAddresses().size() > 0) { 2274 for (InetAddress pcscf : response.getPcscfAddresses()) { 2275 linkProperties.addPcscfServer(pcscf); 2276 } 2277 } 2278 2279 // For backwards compatibility, use getMtu() if getMtuV4() is not available. 2280 int mtuV4 = response.getMtuV4() > 0 ? response.getMtuV4() : response.getMtu(); 2281 2282 if (mtuV4 <= 0) { 2283 // Use back up value from data profile. 2284 if (mDataProfile.getApnSetting() != null) { 2285 mtuV4 = mDataProfile.getApnSetting().getMtuV4(); 2286 } 2287 if (mtuV4 <= 0) { 2288 mtuV4 = mDataConfigManager.getDefaultMtu(); 2289 } 2290 } 2291 2292 // For backwards compatibility, use getMtu() if getMtuV6() is not available. 2293 int mtuV6 = response.getMtuV6() > 0 ? response.getMtuV6() : response.getMtu(); 2294 if (mtuV6 <= 0) { 2295 // Use back up value from data profile. 2296 if (mDataProfile.getApnSetting() != null) { 2297 mtuV6 = mDataProfile.getApnSetting().getMtuV6(); 2298 } 2299 if (mtuV6 <= 0) { 2300 mtuV6 = mDataConfigManager.getDefaultMtu(); 2301 } 2302 } 2303 2304 // Set MTU for each route. 2305 for (InetAddress gateway : response.getGatewayAddresses()) { 2306 int mtu = gateway instanceof java.net.Inet6Address ? mtuV6 : mtuV4; 2307 linkProperties.addRoute(new RouteInfo(null, gateway, null, 2308 RouteInfo.RTN_UNICAST, mtu)); 2309 } 2310 2311 // LinkProperties.setMtu should be deprecated. The mtu for each route has been already 2312 // provided in addRoute() above. For backwards compatibility, we still need to provide 2313 // a value for the legacy MTU. Use the higher value of v4 and v6 value here. 2314 linkProperties.setMtu(Math.max(mtuV4, mtuV6)); 2315 2316 if (mDataProfile.getApnSetting() != null 2317 && !TextUtils.isEmpty(mDataProfile.getApnSetting().getProxyAddressAsString())) { 2318 int port = mDataProfile.getApnSetting().getProxyPort(); 2319 if (port == -1) { 2320 port = 8080; 2321 } 2322 ProxyInfo proxy = ProxyInfo.buildDirectProxy( 2323 mDataProfile.getApnSetting().getProxyAddressAsString(), port); 2324 linkProperties.setHttpProxy(proxy); 2325 } 2326 2327 linkProperties.setTcpBufferSizes(mTcpBufferSizes); 2328 2329 mNetworkSliceInfo = response.getSliceInfo(); 2330 2331 mTrafficDescriptors.clear(); 2332 mTrafficDescriptors.addAll(response.getTrafficDescriptors()); 2333 2334 mQosBearerSessions.clear(); 2335 mQosBearerSessions.addAll(response.getQosBearerSessions()); 2336 if (mQosCallbackTracker != null) { 2337 mQosCallbackTracker.updateSessions(mQosBearerSessions); 2338 } 2339 2340 if (!linkProperties.equals(mLinkProperties)) { 2341 // If the new link properties is not compatible (e.g. IP changes, interface changes), 2342 // then we should de-register the network agent and re-create a new one. 2343 if ((isConnected() || isHandoverInProgress()) 2344 && !isLinkPropertiesCompatible(linkProperties, mLinkProperties)) { 2345 logl("updateDataNetwork: Incompatible link properties detected. Re-create the " 2346 + "network agent. Changed from " + mLinkProperties + " to " 2347 + linkProperties); 2348 2349 mLinkProperties = linkProperties; 2350 recreateNetworkAgent(); 2351 } else { 2352 mLinkProperties = linkProperties; 2353 log("sendLinkProperties " + mLinkProperties); 2354 mNetworkAgent.sendLinkProperties(mLinkProperties); 2355 } 2356 } 2357 2358 updateNetworkCapabilities(); 2359 } 2360 2361 /** 2362 * Called when receiving setup data network response from the data service. 2363 * 2364 * @param resultCode The result code. 2365 * @param response The response. 2366 */ 2367 private void onSetupResponse(@DataServiceCallback.ResultCode int resultCode, 2368 @Nullable DataCallResponse response) { 2369 logl("onSetupResponse: resultCode=" + DataServiceCallback.resultCodeToString(resultCode) 2370 + ", response=" + response); 2371 mFailCause = getFailCauseFromDataCallResponse(resultCode, response); 2372 validateDataCallResponse(response, true /*isSetupResponse*/); 2373 if (mFailCause == DataFailCause.NONE) { 2374 if (mDataNetworkController.isNetworkInterfaceExisting(response.getInterfaceName())) { 2375 logl("Interface " + response.getInterfaceName() + " already existing. Silently " 2376 + "tear down now."); 2377 // If this is a pre-5G data setup, that means APN database has some problems. For 2378 // example, different APN settings have the same APN name. 2379 if (response.getTrafficDescriptors().isEmpty()) { 2380 reportAnomaly("Duplicate network interface " + response.getInterfaceName() 2381 + " detected.", "62f66e7e-8d71-45de-a57b-dc5c78223fd5"); 2382 } 2383 2384 // Do not actually invoke onTearDown, otherwise the existing data network will be 2385 // torn down. 2386 mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED; 2387 mFailCause = DataFailCause.NO_RETRY_FAILURE; 2388 transitionTo(mDisconnectedState); 2389 return; 2390 } 2391 2392 updateDataNetwork(response); 2393 2394 // TODO: Evaluate all network requests and see if each request still can be satisfied. 2395 // For requests that can't be satisfied anymore, we need to put them back to the 2396 // unsatisfied pool. If none of network requests can be satisfied, then there is no 2397 // need to mark network agent connected. Just silently deactivate the data network. 2398 if (mAttachedNetworkRequestList.size() == 0) { 2399 log("Tear down the network since there is no live network request."); 2400 // Directly call onTearDown here. Calling tearDown will cause deadlock because 2401 // EVENT_TEAR_DOWN_NETWORK is deferred until state machine enters connected state, 2402 // which will never happen in this case. 2403 onTearDown(TEAR_DOWN_REASON_NO_LIVE_REQUEST); 2404 return; 2405 } 2406 2407 if (mVcnManager != null && mVcnManager.applyVcnNetworkPolicy(mNetworkCapabilities, 2408 mLinkProperties).isTeardownRequested()) { 2409 log("VCN service requested to tear down the network."); 2410 // Directly call onTearDown here. Calling tearDown will cause deadlock because 2411 // EVENT_TEAR_DOWN_NETWORK is deferred until state machine enters connected state, 2412 // which will never happen in this case. 2413 onTearDown(TEAR_DOWN_REASON_VCN_REQUESTED); 2414 return; 2415 } 2416 2417 transitionTo(mConnectedState); 2418 } else { 2419 // Setup data failed. 2420 mRetryDelayMillis = response != null ? response.getRetryDurationMillis() 2421 : DataCallResponse.RETRY_DURATION_UNDEFINED; 2422 transitionTo(mDisconnectedState); 2423 } 2424 2425 int apnTypeBitmask = ApnSetting.TYPE_NONE; 2426 int protocol = ApnSetting.PROTOCOL_UNKNOWN; 2427 if (mDataProfile.getApnSetting() != null) { 2428 apnTypeBitmask = mDataProfile.getApnSetting().getApnTypeBitmask(); 2429 protocol = mDataProfile.getApnSetting().getProtocol(); 2430 } 2431 mDataCallSessionStats.onSetupDataCallResponse(response, 2432 getDataNetworkType(), 2433 apnTypeBitmask, 2434 protocol, 2435 mFailCause); 2436 } 2437 2438 /** 2439 * If the {@link DataCallResponse} contains invalid info, triggers an anomaly report. 2440 * 2441 * @param response The response to be validated 2442 * @param isSetupResponse {@code true} if the response is for initial data call setup 2443 */ 2444 private void validateDataCallResponse(@Nullable DataCallResponse response, 2445 boolean isSetupResponse) { 2446 if (response == null 2447 || response.getLinkStatus() == DataCallResponse.LINK_STATUS_INACTIVE) return; 2448 int failCause = response.getCause(); 2449 if (failCause == DataFailCause.NONE) { 2450 if (TextUtils.isEmpty(response.getInterfaceName()) 2451 || response.getAddresses().isEmpty() 2452 // if out of range 2453 || response.getLinkStatus() < DataCallResponse.LINK_STATUS_UNKNOWN 2454 || response.getLinkStatus() > DataCallResponse.LINK_STATUS_ACTIVE 2455 || response.getProtocolType() < ApnSetting.PROTOCOL_UNKNOWN 2456 || response.getProtocolType() > ApnSetting.PROTOCOL_UNSTRUCTURED 2457 || response.getHandoverFailureMode() 2458 < DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN 2459 || response.getHandoverFailureMode() 2460 > DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL) { 2461 loge("Invalid DataCallResponse:" + response); 2462 reportAnomaly("Invalid DataCallResponse detected", 2463 "1f273e9d-b09c-46eb-ad1c-421d01f61164"); 2464 } 2465 // Check IP for initial setup response 2466 NetworkRegistrationInfo nri = getNetworkRegistrationInfo(); 2467 if (isSetupResponse 2468 && mDataProfile.getApnSetting() != null && nri != null && nri.isInService()) { 2469 boolean isRoaming = nri.getInitialRegistrationState() 2470 == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING; 2471 int protocol = isRoaming ? mDataProfile.getApnSetting().getRoamingProtocol() 2472 : mDataProfile.getApnSetting().getProtocol(); 2473 String underlyingDataService = mTransport 2474 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 2475 ? "RIL" : "IWLAN data service"; 2476 if (protocol == ApnSetting.PROTOCOL_IP) { 2477 if (response.getAddresses().stream().anyMatch( 2478 la -> la.getAddress() instanceof java.net.Inet6Address)) { 2479 loge("Invalid DataCallResponse. Requested IPv4 but got IPv6 address. " 2480 + response); 2481 reportAnomaly(underlyingDataService + " reported mismatched IP " 2482 + "type. Requested IPv4 but got IPv6 address.", 2483 "7744f920-fb64-4db0-ba47-de0eae485a80"); 2484 } 2485 } else if (protocol == ApnSetting.PROTOCOL_IPV6) { 2486 if (response.getAddresses().stream().anyMatch( 2487 la -> la.getAddress() instanceof java.net.Inet4Address)) { 2488 loge("Invalid DataCallResponse. Requested IPv6 but got IPv4 address. " 2489 + response); 2490 reportAnomaly(underlyingDataService + " reported mismatched IP " 2491 + "type. Requested IPv6 but got IPv4 address.", 2492 "7744f920-fb64-4db0-ba47-de0eae485a80"); 2493 } 2494 } 2495 } 2496 } else if (!DataFailCause.isFailCauseExisting(failCause)) { // Setup data failed. 2497 loge("Invalid DataFailCause in " + response); 2498 reportAnomaly("Invalid DataFailCause: (0x" + Integer.toHexString(failCause) 2499 + ")", 2500 "6b264f28-9f58-4cbd-9e0e-d7624ba30879"); 2501 } 2502 } 2503 2504 /** 2505 * Called when receiving deactivate data network response from the data service. 2506 * 2507 * @param resultCode The result code. 2508 */ 2509 private void onDeactivateResponse(@DataServiceCallback.ResultCode int resultCode) { 2510 logl("onDeactivateResponse: resultCode=" 2511 + DataServiceCallback.resultCodeToString(resultCode)); 2512 if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) { 2513 log("Remove network since deactivate request returned an error."); 2514 mFailCause = DataFailCause.RADIO_NOT_AVAILABLE; 2515 transitionTo(mDisconnectedState); 2516 } else if (mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_2_0)) { 2517 log("Remove network on deactivate data response on old HAL " 2518 + mPhone.getHalVersion()); 2519 mFailCause = DataFailCause.LOST_CONNECTION; 2520 transitionTo(mDisconnectedState); 2521 } 2522 } 2523 2524 /** 2525 * Tear down the data network immediately. 2526 * 2527 * @param reason The reason of tearing down the network. 2528 */ 2529 public void tearDown(@TearDownReason int reason) { 2530 if (getCurrentState() == null || isDisconnected()) { 2531 return; 2532 } 2533 sendMessage(obtainMessage(EVENT_TEAR_DOWN_NETWORK, reason)); 2534 } 2535 2536 private void onTearDown(@TearDownReason int reason) { 2537 logl("onTearDown: reason=" + tearDownReasonToString(reason)); 2538 2539 // track frequent NetworkAgent.onNetworkUnwanted() call of IMS and INTERNET 2540 if (reason == TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED 2541 && isConnected() 2542 && (mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS) 2543 || mNetworkCapabilities.hasCapability( 2544 NetworkCapabilities.NET_CAPABILITY_INTERNET))) { 2545 mDataNetworkCallback.onTrackNetworkUnwanted(this); 2546 } 2547 2548 mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport), 2549 reason == TEAR_DOWN_REASON_AIRPLANE_MODE_ON ? DataService.REQUEST_REASON_SHUTDOWN 2550 : DataService.REQUEST_REASON_NORMAL, 2551 obtainMessage(EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE)); 2552 mDataCallSessionStats.setDeactivateDataCallReason(DataService.REQUEST_REASON_NORMAL); 2553 mInvokedDataDeactivation = true; 2554 } 2555 2556 /** 2557 * @return {@code true} if this is an IMS network and tear down should be delayed until call 2558 * ends on this data network. 2559 */ 2560 public boolean shouldDelayImsTearDown() { 2561 return mDataConfigManager.isImsDelayTearDownEnabled() 2562 && mNetworkCapabilities != null 2563 && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL) 2564 && mPhone.getImsPhone() != null 2565 && mPhone.getImsPhone().getCallTracker().getState() 2566 != PhoneConstants.State.IDLE; 2567 } 2568 2569 /** 2570 * Tear down the data network when condition is met or timed out. Data network will enter 2571 * {@link DisconnectingState} immediately and waiting for condition met. When condition is met, 2572 * {@link DataNetworkController} should invoke {@link Consumer#accept(Object)} so the actual 2573 * tear down work can be performed. 2574 * 2575 * This is primarily used for IMS graceful tear down. {@link DataNetworkController} inform 2576 * {@link DataNetwork} to enter {@link DisconnectingState}. IMS service can observe this 2577 * through {@link PreciseDataConnectionState#getState()} and then perform IMS de-registration 2578 * work. After IMS de-registered, {@link DataNetworkController} informs {@link DataNetwork} 2579 * that it's okay to tear down the network. 2580 * 2581 * @param reason The tear down reason. 2582 * 2583 * @param timeoutMillis Timeout in milliseconds. Within the time window, clients will have to 2584 * call {@link Consumer#accept(Object)}, otherwise, data network will be torn down when 2585 * timed out. 2586 * 2587 * @return The runnable for client to execute when condition is met. When executed, tear down 2588 * will be performed. {@code null} if the data network is already disconnected or being 2589 * disconnected. 2590 */ 2591 public @Nullable Runnable tearDownWhenConditionMet(@TearDownReason int reason, 2592 long timeoutMillis) { 2593 if (getCurrentState() == null || isDisconnected() || isDisconnecting()) { 2594 loge("tearDownWhenConditionMet: Not in the right state. State=" + getCurrentState()); 2595 return null; 2596 } 2597 logl("tearDownWhenConditionMet: reason=" + tearDownReasonToString(reason) + ", timeout=" 2598 + timeoutMillis + "ms."); 2599 sendMessage(EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET, reason, (int) timeoutMillis); 2600 return () -> this.tearDown(reason); 2601 } 2602 2603 /** 2604 * Called when receiving {@link DataServiceCallback#onDataCallListChanged(List)} from the data 2605 * service. 2606 * 2607 * @param transport The transport where this event from. 2608 * @param responseList The data call response list. 2609 */ 2610 private void onDataStateChanged(@TransportType int transport, 2611 @NonNull List<DataCallResponse> responseList) { 2612 // Ignore the update if it's not from the data service on the right transport. 2613 // Also if never received data call response from setup call response, which updates the 2614 // cid, ignore the update here. 2615 logv("onDataStateChanged: " + responseList); 2616 if (transport != mTransport || mCid.get(mTransport) == INVALID_CID || isDisconnected()) { 2617 return; 2618 } 2619 2620 DataCallResponse response = responseList.stream() 2621 .filter(r -> mCid.get(mTransport) == r.getId()) 2622 .findFirst() 2623 .orElse(null); 2624 if (response != null) { 2625 if (!response.equals(mDataCallResponse)) { 2626 log("onDataStateChanged: " + response); 2627 validateDataCallResponse(response, false /*isSetupResponse*/); 2628 mDataCallResponse = response; 2629 if (response.getLinkStatus() != DataCallResponse.LINK_STATUS_INACTIVE) { 2630 updateDataNetwork(response); 2631 } else { 2632 log("onDataStateChanged: PDN inactive reported by " 2633 + AccessNetworkConstants.transportTypeToString(mTransport) 2634 + " data service."); 2635 mFailCause = mEverConnected ? response.getCause() 2636 : DataFailCause.NO_RETRY_FAILURE; 2637 mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED; 2638 transitionTo(mDisconnectedState); 2639 } 2640 } 2641 } else { 2642 // The data call response is missing from the list. This means the PDN is gone. This 2643 // is the PDN lost reported by the modem. We don't send another DEACTIVATE_DATA request 2644 // for that 2645 log("onDataStateChanged: PDN disconnected reported by " 2646 + AccessNetworkConstants.transportTypeToString(mTransport) + " data service."); 2647 mFailCause = mEverConnected ? DataFailCause.LOST_CONNECTION 2648 : DataFailCause.NO_RETRY_FAILURE; 2649 mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED; 2650 transitionTo(mDisconnectedState); 2651 } 2652 } 2653 2654 /** 2655 * Called when carrier config updated. 2656 */ 2657 private void onCarrierConfigUpdated() { 2658 log("onCarrierConfigUpdated"); 2659 2660 updateBandwidthFromDataConfig(); 2661 updateTcpBufferSizes(); 2662 updateMeteredAndCongested(); 2663 } 2664 2665 /** 2666 * Called when receiving bandwidth update from the modem. 2667 * 2668 * @param linkCapacityEstimates The link capacity estimate list from the modem. 2669 */ 2670 private void onBandwidthUpdatedFromModem( 2671 @NonNull List<LinkCapacityEstimate> linkCapacityEstimates) { 2672 Objects.requireNonNull(linkCapacityEstimates); 2673 if (linkCapacityEstimates.isEmpty()) return; 2674 2675 int uplinkBandwidthKbps = 0, downlinkBandwidthKbps = 0; 2676 for (LinkCapacityEstimate linkCapacityEstimate : linkCapacityEstimates) { 2677 if (linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_COMBINED) { 2678 uplinkBandwidthKbps = linkCapacityEstimate.getUplinkCapacityKbps(); 2679 downlinkBandwidthKbps = linkCapacityEstimate.getDownlinkCapacityKbps(); 2680 break; 2681 } else if (linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_PRIMARY 2682 || linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_SECONDARY) { 2683 uplinkBandwidthKbps += linkCapacityEstimate.getUplinkCapacityKbps(); 2684 downlinkBandwidthKbps += linkCapacityEstimate.getDownlinkCapacityKbps(); 2685 } else { 2686 loge("Invalid LinkCapacityEstimate type " + linkCapacityEstimate.getType()); 2687 } 2688 } 2689 onBandwidthUpdated(uplinkBandwidthKbps, downlinkBandwidthKbps); 2690 } 2691 2692 /** 2693 * Called when bandwidth estimation updated from either modem or the bandwidth estimator. 2694 * 2695 * @param uplinkBandwidthKbps Uplink bandwidth estimate in Kbps. 2696 * @param downlinkBandwidthKbps Downlink bandwidth estimate in Kbps. 2697 */ 2698 private void onBandwidthUpdated(int uplinkBandwidthKbps, int downlinkBandwidthKbps) { 2699 log("onBandwidthUpdated: downlinkBandwidthKbps=" + downlinkBandwidthKbps 2700 + ", uplinkBandwidthKbps=" + uplinkBandwidthKbps); 2701 NetworkBandwidth bandwidthFromConfig = mDataConfigManager.getBandwidthForNetworkType( 2702 mTelephonyDisplayInfo); 2703 2704 if (downlinkBandwidthKbps == LinkCapacityEstimate.INVALID && bandwidthFromConfig != null) { 2705 // Fallback to carrier config. 2706 downlinkBandwidthKbps = bandwidthFromConfig.downlinkBandwidthKbps; 2707 } 2708 2709 if (uplinkBandwidthKbps == LinkCapacityEstimate.INVALID && bandwidthFromConfig != null) { 2710 // Fallback to carrier config. 2711 uplinkBandwidthKbps = bandwidthFromConfig.uplinkBandwidthKbps; 2712 } 2713 2714 // Make sure uplink is not greater than downlink. 2715 uplinkBandwidthKbps = Math.min(uplinkBandwidthKbps, downlinkBandwidthKbps); 2716 mNetworkBandwidth = new NetworkBandwidth(downlinkBandwidthKbps, uplinkBandwidthKbps); 2717 2718 updateNetworkCapabilities(); 2719 } 2720 2721 /** 2722 * Called when {@link TelephonyDisplayInfo} changed. This can happen when network types or 2723 * override network types (5G NSA, 5G MMWAVE) change. 2724 */ 2725 private void onDisplayInfoChanged() { 2726 mTelephonyDisplayInfo = mPhone.getDisplayInfoController().getTelephonyDisplayInfo(); 2727 updateBandwidthFromDataConfig(); 2728 updateTcpBufferSizes(); 2729 updateMeteredAndCongested(); 2730 } 2731 2732 /** 2733 * Update the bandwidth from carrier config. Note this is no-op if the bandwidth source is not 2734 * carrier config. 2735 */ 2736 private void updateBandwidthFromDataConfig() { 2737 if (mDataConfigManager.getBandwidthEstimateSource() != BANDWIDTH_SOURCE_CARRIER_CONFIG) { 2738 return; 2739 } 2740 log("updateBandwidthFromDataConfig"); 2741 mNetworkBandwidth = mDataConfigManager.getBandwidthForNetworkType(mTelephonyDisplayInfo); 2742 updateNetworkCapabilities(); 2743 } 2744 2745 /** 2746 * Update the TCP buffer sizes from resource overlays. 2747 */ 2748 private void updateTcpBufferSizes() { 2749 log("updateTcpBufferSizes"); 2750 mTcpBufferSizes = mDataConfigManager.getTcpConfigString(mTelephonyDisplayInfo); 2751 LinkProperties linkProperties = new LinkProperties(mLinkProperties); 2752 linkProperties.setTcpBufferSizes(mTcpBufferSizes); 2753 if (!linkProperties.equals(mLinkProperties)) { 2754 mLinkProperties = linkProperties; 2755 log("sendLinkProperties " + mLinkProperties); 2756 mNetworkAgent.sendLinkProperties(mLinkProperties); 2757 } 2758 } 2759 2760 /** 2761 * Update the metered and congested values from carrier configs and subscription overrides 2762 */ 2763 private void updateMeteredAndCongested() { 2764 int networkType = mTelephonyDisplayInfo.getNetworkType(); 2765 switch (mTelephonyDisplayInfo.getOverrideNetworkType()) { 2766 case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED: 2767 case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA: 2768 networkType = TelephonyManager.NETWORK_TYPE_NR; 2769 break; 2770 case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO: 2771 case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA: 2772 networkType = TelephonyManager.NETWORK_TYPE_LTE_CA; 2773 break; 2774 } 2775 log("updateMeteredAndCongested: networkType=" 2776 + TelephonyManager.getNetworkTypeName(networkType)); 2777 boolean changed = false; 2778 if (mDataConfigManager.isTempNotMeteredSupportedByCarrier() != mTempNotMeteredSupported) { 2779 mTempNotMeteredSupported = !mTempNotMeteredSupported; 2780 changed = true; 2781 log("updateMeteredAndCongested: mTempNotMeteredSupported changed to " 2782 + mTempNotMeteredSupported); 2783 } 2784 if ((mDataNetworkController.getUnmeteredOverrideNetworkTypes().contains(networkType) 2785 || isNetworkTypeUnmetered(networkType)) != mTempNotMetered) { 2786 mTempNotMetered = !mTempNotMetered; 2787 changed = true; 2788 log("updateMeteredAndCongested: mTempNotMetered changed to " + mTempNotMetered); 2789 } 2790 if (mDataNetworkController.getCongestedOverrideNetworkTypes().contains(networkType) 2791 != mCongested) { 2792 mCongested = !mCongested; 2793 changed = true; 2794 log("updateMeteredAndCongested: mCongested changed to " + mCongested); 2795 } 2796 if (changed) { 2797 updateNetworkCapabilities(); 2798 } 2799 if (mTempNotMetered && isInternetSupported()) { 2800 // NR NSA and NR have the same network type: NR 2801 mDataCallSessionStats.onUnmeteredUpdate(networkType); 2802 } 2803 } 2804 2805 /** 2806 * Get whether the network type is unmetered from SubscriptionPlans, from either an unmetered 2807 * general plan or specific plan for the given network type. 2808 * 2809 * @param networkType The network type to check meteredness for 2810 * @return Whether the given network type is unmetered based on SubscriptionPlans 2811 */ 2812 private boolean isNetworkTypeUnmetered(@NetworkType int networkType) { 2813 List<SubscriptionPlan> plans = mDataNetworkController.getSubscriptionPlans(); 2814 if (plans.isEmpty()) return false; 2815 boolean isGeneralUnmetered = true; 2816 Set<Integer> allNetworkTypes = Arrays.stream(TelephonyManager.getAllNetworkTypes()) 2817 .boxed().collect(Collectors.toSet()); 2818 for (SubscriptionPlan plan : plans) { 2819 // Check if plan is general (applies to all network types) or specific 2820 if (Arrays.stream(plan.getNetworkTypes()).boxed().collect(Collectors.toSet()) 2821 .containsAll(allNetworkTypes)) { 2822 if (plan.getDataLimitBytes() != SubscriptionPlan.BYTES_UNLIMITED) { 2823 // Metered takes precedence over unmetered for safety 2824 isGeneralUnmetered = false; 2825 } 2826 } else { 2827 // Check if plan applies to given network type 2828 if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) { 2829 for (int planNetworkType : plan.getNetworkTypes()) { 2830 if (planNetworkType == networkType) { 2831 return plan.getDataLimitBytes() == SubscriptionPlan.BYTES_UNLIMITED; 2832 } 2833 } 2834 } 2835 } 2836 } 2837 return isGeneralUnmetered; 2838 } 2839 2840 /** 2841 * @return The unique context id assigned by the data service in 2842 * {@link DataCallResponse#getId()}. 2843 */ 2844 public int getId() { 2845 return mCid.get(mTransport); 2846 } 2847 2848 /** 2849 * @return The current network type reported by the network service. 2850 */ 2851 private @NetworkType int getDataNetworkType() { 2852 return getDataNetworkType(mTransport); 2853 } 2854 2855 /** 2856 * Get the data network type on the specified transport. 2857 * 2858 * @param transport The transport. 2859 * @return The data network type. 2860 */ 2861 private @NetworkType int getDataNetworkType(@TransportType int transport) { 2862 // WLAN transport can't have network type other than IWLAN. Ideally service state tracker 2863 // should report the correct RAT, but sometimes race condition could happen that service 2864 // state is reset to out of service and RAT not updated to IWLAN yet. 2865 if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 2866 return TelephonyManager.NETWORK_TYPE_IWLAN; 2867 } 2868 2869 ServiceState ss = mPhone.getServiceState(); 2870 NetworkRegistrationInfo nrs = ss.getNetworkRegistrationInfo( 2871 NetworkRegistrationInfo.DOMAIN_PS, transport); 2872 if (nrs != null) { 2873 return nrs.getAccessNetworkTechnology(); 2874 } 2875 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2876 } 2877 2878 /** 2879 * @return The physical link status (i.e. RRC state). 2880 */ 2881 public @LinkStatus int getLinkStatus() { 2882 return mLinkStatus; 2883 } 2884 2885 /** 2886 * Update the network score and report to connectivity service if necessary. 2887 */ 2888 private void updateNetworkScore() { 2889 int networkScore = getNetworkScore(); 2890 if (networkScore != mNetworkScore) { 2891 logl("Updating score from " + mNetworkScore + " to " + networkScore); 2892 mNetworkScore = networkScore; 2893 mNetworkAgent.sendNetworkScore(mNetworkScore); 2894 } 2895 } 2896 2897 /** 2898 * @return The network score. The higher score of the network has higher chance to be 2899 * selected by the connectivity service as active network. 2900 */ 2901 private int getNetworkScore() { 2902 // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have 2903 // specify a sub id, this data network is considered to be default internet data 2904 // connection. In this case we assign a slightly higher score of 50. The intention is 2905 // it will not be replaced by other data networks accidentally in DSDS use case. 2906 int score = OTHER_NETWORK_SCORE; 2907 for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) { 2908 if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 2909 && networkRequest.getNetworkSpecifier() == null) { 2910 score = DEFAULT_INTERNET_NETWORK_SCORE; 2911 } 2912 } 2913 2914 return score; 2915 } 2916 2917 /** 2918 * @return Network registration info on the current transport. 2919 */ 2920 private @Nullable NetworkRegistrationInfo getNetworkRegistrationInfo() { 2921 NetworkRegistrationInfo nri = mPhone.getServiceStateTracker().getServiceState() 2922 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, mTransport); 2923 if (nri == null) { 2924 loge("Can't get network registration info for " 2925 + AccessNetworkConstants.transportTypeToString(mTransport)); 2926 return null; 2927 } 2928 return nri; 2929 } 2930 2931 /** 2932 * Get the APN type network capability. If there are more than one capabilities that are 2933 * APN types, then return the highest priority one which also has associated network request. 2934 * For example, if the network supports both MMS and internet, but only internet request 2935 * attached at this time, then the capability would be internet. Later on if MMS network request 2936 * attached to this network, then the APN type capability would be MMS. 2937 * 2938 * @return The APN type network capability from this network. 2939 * 2940 * @see #getPriority() 2941 */ 2942 public @NetCapability int getApnTypeNetworkCapability() { 2943 if (!mAttachedNetworkRequestList.isEmpty()) { 2944 // The highest priority network request is always at the top of list. 2945 return mAttachedNetworkRequestList.get(0).getApnTypeNetworkCapability(); 2946 } else { 2947 return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed() 2948 .filter(cap -> DataUtils.networkCapabilityToApnType(cap) 2949 != ApnSetting.TYPE_NONE) 2950 .max(Comparator.comparingInt(mDataConfigManager::getNetworkCapabilityPriority)) 2951 .orElse(-1); 2952 } 2953 } 2954 2955 /** 2956 * Get the priority of the network. The priority is derived from the highest priority capability 2957 * which also has such associated network request. For example, if the network supports both 2958 * MMS and internet, but only has internet request attached, then this network has internet's 2959 * priority. Later on when the MMS request attached to this network, the network's priority will 2960 * be updated to MMS's priority. 2961 * 2962 * @return The priority of the network. 2963 * 2964 * @see #getApnTypeNetworkCapability() 2965 */ 2966 public int getPriority() { 2967 if (!mAttachedNetworkRequestList.isEmpty()) { 2968 // The highest priority network request is always at the top of list. 2969 return mAttachedNetworkRequestList.get(0).getPriority(); 2970 } else { 2971 // If all network requests are already detached, then just pick the highest priority 2972 // capability's priority. 2973 return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed() 2974 .map(mDataConfigManager::getNetworkCapabilityPriority) 2975 .max(Integer::compare) 2976 .orElse(0); 2977 } 2978 } 2979 2980 /** 2981 * @return The attached network request list. 2982 */ 2983 public @NonNull NetworkRequestList getAttachedNetworkRequestList() { 2984 return mAttachedNetworkRequestList; 2985 } 2986 2987 /** 2988 * @return {@code true} if in connecting state. 2989 */ 2990 public boolean isConnecting() { 2991 return getCurrentState() == mConnectingState; 2992 } 2993 2994 /** 2995 * @return {@code true} if in connected state. 2996 */ 2997 public boolean isConnected() { 2998 return getCurrentState() == mConnectedState; 2999 } 3000 3001 /** 3002 * @return {@code true} if in disconnecting state. 3003 */ 3004 public boolean isDisconnecting() { 3005 return getCurrentState() == mDisconnectingState; 3006 } 3007 3008 /** 3009 * @return {@code true} if in disconnected state. 3010 */ 3011 public boolean isDisconnected() { 3012 return getCurrentState() == mDisconnectedState; 3013 } 3014 3015 /** 3016 * @return {@code true} if in handover state. 3017 */ 3018 public boolean isHandoverInProgress() { 3019 return getCurrentState() == mHandoverState; 3020 } 3021 3022 /** 3023 * @return {@code true} if the data network is suspended. 3024 */ 3025 public boolean isSuspended() { 3026 return getState() == TelephonyManager.DATA_SUSPENDED; 3027 } 3028 3029 /** 3030 * @return The current transport of the data network. 3031 */ 3032 public @TransportType int getTransport() { 3033 return mTransport; 3034 } 3035 3036 private @DataState int getState() { 3037 IState state = getCurrentState(); 3038 if (state == null || isDisconnected()) { 3039 return TelephonyManager.DATA_DISCONNECTED; 3040 } else if (isConnecting()) { 3041 return TelephonyManager.DATA_CONNECTING; 3042 } else if (isConnected()) { 3043 // The data connection can only be suspended when it's in active state. 3044 if (mSuspended) { 3045 return TelephonyManager.DATA_SUSPENDED; 3046 } 3047 return TelephonyManager.DATA_CONNECTED; 3048 } else if (isDisconnecting()) { 3049 return TelephonyManager.DATA_DISCONNECTING; 3050 } else if (isHandoverInProgress()) { 3051 return TelephonyManager.DATA_HANDOVER_IN_PROGRESS; 3052 } 3053 3054 return TelephonyManager.DATA_UNKNOWN; 3055 } 3056 3057 /** 3058 * @return {@code true} if this data network supports internet. 3059 */ 3060 public boolean isInternetSupported() { 3061 return mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 3062 && mNetworkCapabilities.hasCapability( 3063 NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 3064 && mNetworkCapabilities.hasCapability( 3065 NetworkCapabilities.NET_CAPABILITY_TRUSTED) 3066 && mNetworkCapabilities.hasCapability( 3067 NetworkCapabilities.NET_CAPABILITY_NOT_VPN); 3068 } 3069 3070 /** 3071 * @return {@code true} if this network was setup for SUPL during emergency call. {@code false} 3072 * otherwise. 3073 */ 3074 public boolean isEmergencySupl() { 3075 return mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL; 3076 } 3077 3078 /** 3079 * Get precise data connection state 3080 * 3081 * @return The {@link PreciseDataConnectionState} 3082 */ 3083 private PreciseDataConnectionState getPreciseDataConnectionState() { 3084 return new PreciseDataConnectionState.Builder() 3085 .setTransportType(mTransport) 3086 .setId(mCid.get(mTransport)) 3087 .setState(getState()) 3088 .setApnSetting(mDataProfile.getApnSetting()) 3089 .setLinkProperties(mLinkProperties) 3090 .setNetworkType(getDataNetworkType()) 3091 .setFailCause(mFailCause) 3092 .build(); 3093 } 3094 3095 /** 3096 * Send the precise data connection state to the listener of 3097 * {@link android.telephony.TelephonyCallback.PreciseDataConnectionStateListener}. 3098 */ 3099 private void notifyPreciseDataConnectionState() { 3100 PreciseDataConnectionState pdcs = getPreciseDataConnectionState(); 3101 logv("notifyPreciseDataConnectionState=" + pdcs); 3102 mPhone.notifyDataConnection(pdcs); 3103 } 3104 3105 /** 3106 * Request the data network to handover to the target transport. 3107 * 3108 * This is the starting point of initiating IWLAN/cellular handover. It will first call 3109 * {@link DataServiceManager#startHandover(int, Message)} to notify source transport that 3110 * handover is about to start, and then call {@link DataServiceManager#setupDataCall(int, 3111 * DataProfile, boolean, boolean, int, LinkProperties, int, NetworkSliceInfo, TrafficDescriptor, 3112 * boolean, Message)} on target transport to initiate the handover process. 3113 * 3114 * @param targetTransport The target transport. 3115 * @param retryEntry Data handover retry entry. This would be {@code null} for first time 3116 * handover attempt. 3117 * @return {@code true} if the request has been accepted. 3118 */ 3119 public boolean startHandover(@TransportType int targetTransport, 3120 @Nullable DataHandoverRetryEntry retryEntry) { 3121 if (getCurrentState() == null || isDisconnected() || isDisconnecting()) { 3122 // Fail the request if not in the appropriate state. 3123 if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 3124 return false; 3125 } 3126 3127 // Before we really initiate the handover process on target transport, we need to notify 3128 // source transport that handover is about to start. Handover will be eventually initiated 3129 // in onStartHandover(). 3130 sendMessage(obtainMessage(EVENT_NOTIFY_HANDOVER_STARTED, 0, targetTransport, retryEntry)); 3131 return true; 3132 } 3133 3134 /** 3135 * Called when starting IWLAN/cellular handover process on the target transport. 3136 * 3137 * @param targetTransport The target transport. 3138 * @param retryEntry Data handover retry entry. This would be {@code null} for first time 3139 * handover attempt. 3140 */ 3141 private void onStartHandover(@TransportType int targetTransport, 3142 @Nullable DataHandoverRetryEntry retryEntry) { 3143 if (mTransport == targetTransport) { 3144 log("onStartHandover: The network is already on " 3145 + AccessNetworkConstants.transportTypeToString(mTransport) 3146 + ", handover is not needed."); 3147 if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 3148 return; 3149 } 3150 3151 // We need to use the actual modem roaming state instead of the framework roaming state 3152 // here. This flag is only passed down to ril_service for picking the correct protocol (for 3153 // old modem backward compatibility). 3154 boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration(); 3155 3156 // Set this flag to true if the user turns on data roaming. Or if we override the roaming 3157 // state in framework, we should set this flag to true as well so the modem will not reject 3158 // the data call setup (because the modem actually thinks the device is roaming). 3159 boolean allowRoaming = mPhone.getDataRoamingEnabled() 3160 || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming())); 3161 3162 mHandoverDataProfile = mDataProfile; 3163 int targetNetworkType = getDataNetworkType(targetTransport); 3164 if (targetNetworkType != TelephonyManager.NETWORK_TYPE_UNKNOWN 3165 && !mAttachedNetworkRequestList.isEmpty()) { 3166 TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0); 3167 DataProfile dataProfile = mDataNetworkController.getDataProfileManager() 3168 .getDataProfileForNetworkRequest(networkRequest, targetNetworkType, false); 3169 // Some carriers have different profiles between cellular and IWLAN. We need to 3170 // dynamically switch profile, but only when those profiles have same APN name. 3171 if (dataProfile != null && dataProfile.getApnSetting() != null 3172 && mDataProfile.getApnSetting() != null 3173 && TextUtils.equals(dataProfile.getApnSetting().getApnName(), 3174 mDataProfile.getApnSetting().getApnName()) 3175 && !dataProfile.equals(mDataProfile)) { 3176 mHandoverDataProfile = dataProfile; 3177 log("Used different data profile for handover. " + mDataProfile); 3178 } 3179 } 3180 3181 logl("Start handover from " + AccessNetworkConstants.transportTypeToString(mTransport) 3182 + " to " + AccessNetworkConstants.transportTypeToString(targetTransport)); 3183 // Send the handover request to the target transport data service. 3184 mDataServiceManagers.get(targetTransport).setupDataCall( 3185 DataUtils.networkTypeToAccessNetworkType(getDataNetworkType(targetTransport)), 3186 mHandoverDataProfile, isModemRoaming, allowRoaming, 3187 DataService.REQUEST_REASON_HANDOVER, mLinkProperties, mPduSessionId, 3188 mNetworkSliceInfo, mHandoverDataProfile.getTrafficDescriptor(), true, 3189 obtainMessage(EVENT_HANDOVER_RESPONSE, retryEntry)); 3190 } 3191 3192 /** 3193 * Called when receiving handover response from the data service. 3194 * 3195 * @param resultCode The result code. 3196 * @param response The response. 3197 * @param retryEntry Data handover retry entry. This would be {@code null} for first time 3198 * handover attempt. 3199 */ 3200 private void onHandoverResponse(@DataServiceCallback.ResultCode int resultCode, 3201 @Nullable DataCallResponse response, @Nullable DataHandoverRetryEntry retryEntry) { 3202 logl("onHandoverResponse: resultCode=" + DataServiceCallback.resultCodeToString(resultCode) 3203 + ", response=" + response); 3204 mFailCause = getFailCauseFromDataCallResponse(resultCode, response); 3205 validateDataCallResponse(response, false /*isSetupResponse*/); 3206 if (mFailCause == DataFailCause.NONE) { 3207 // Handover succeeded. 3208 3209 // Clean up on the source transport. 3210 mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport), 3211 DataService.REQUEST_REASON_HANDOVER, null); 3212 // Switch the transport to the target. 3213 mTransport = DataUtils.getTargetTransport(mTransport); 3214 // Update the logging tag 3215 mLogTag = "DN-" + mInitialNetworkAgentId + "-" 3216 + ((mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) ? "C" : "I"); 3217 // Switch the data profile. This is no-op in most of the case since almost all carriers 3218 // use same data profile between IWLAN and cellular. 3219 mDataProfile = mHandoverDataProfile; 3220 updateDataNetwork(response); 3221 if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 3222 unregisterForWwanEvents(); 3223 } else { 3224 // Handover from WLAN to WWAN 3225 registerForWwanEvents(); 3226 } 3227 if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_SUCCEEDED); 3228 mDataNetworkCallback.invokeFromExecutor( 3229 () -> mDataNetworkCallback.onHandoverSucceeded(DataNetwork.this)); 3230 } else { 3231 // Handover failed. 3232 3233 // Notify source transport that handover failed on target transport so that PDU session 3234 // id can be released if it is preserved for handover. 3235 mDataServiceManagers.get(mTransport).cancelHandover(mCid.get(mTransport), 3236 obtainMessage(EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE)); 3237 3238 long retry = response != null ? response.getRetryDurationMillis() 3239 : DataCallResponse.RETRY_DURATION_UNDEFINED; 3240 // If the handover mode is unspecified, default to HANDOVER_FAILURE_MODE_UNKNOWN, 3241 // which will retry handover if retry rules are defined. 3242 int handoverFailureMode = response != null ? response.getHandoverFailureMode() 3243 : DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN; 3244 if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED); 3245 mDataNetworkCallback.invokeFromExecutor( 3246 () -> mDataNetworkCallback.onHandoverFailed(DataNetwork.this, 3247 mFailCause, retry, handoverFailureMode)); 3248 trackHandoverFailure(); 3249 } 3250 3251 // No matter handover succeeded or not, transit back to connected state. 3252 transitionTo(mConnectedState); 3253 } 3254 3255 /** 3256 * Called when handover failed. Record the source and target RAT{@link NetworkType} and the 3257 * failure cause {@link android.telephony.DataFailCause}. 3258 */ 3259 private void trackHandoverFailure() { 3260 int sourceRat = getDataNetworkType(); 3261 int targetTransport = DataUtils.getTargetTransport(mTransport); 3262 int targetRat = getDataNetworkType(targetTransport); 3263 3264 mDataCallSessionStats.onHandoverFailure(mFailCause, sourceRat, targetRat); 3265 } 3266 3267 /** 3268 * Called when receiving PCO (Protocol Configuration Options) data from the cellular network. 3269 * 3270 * @param pcoData The PCO data. 3271 */ 3272 private void onPcoDataChanged(@NonNull PcoData pcoData) { 3273 log("onPcoDataChanged: " + pcoData); 3274 mDataNetworkCallback.invokeFromExecutor( 3275 () -> mDataNetworkCallback.onPcoDataChanged(DataNetwork.this)); 3276 if (mDataProfile.getApnSetting() != null) { 3277 for (int apnType : mDataProfile.getApnSetting().getApnTypes()) { 3278 Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE); 3279 intent.putExtra(TelephonyManager.EXTRA_APN_TYPE, apnType); 3280 intent.putExtra(TelephonyManager.EXTRA_APN_PROTOCOL, 3281 ApnSetting.getProtocolIntFromString(pcoData.bearerProto)); 3282 intent.putExtra(TelephonyManager.EXTRA_PCO_ID, pcoData.pcoId); 3283 intent.putExtra(TelephonyManager.EXTRA_PCO_VALUE, pcoData.contents); 3284 mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent); 3285 } 3286 } 3287 } 3288 3289 /** 3290 * Called when receiving PCO (Protocol Configuration Options) data from the cellular network. 3291 * 3292 * @param pcoData PCO data. 3293 */ 3294 private void onPcoDataReceived(@NonNull PcoData pcoData) { 3295 // Save all the PCO data received, even though it might be unrelated to this data network. 3296 // The network might be still in connecting state. Save all now and use it when entering 3297 // connected state. 3298 log("onPcoDataReceived: " + pcoData); 3299 PcoData oldData = mPcoData.computeIfAbsent(pcoData.cid, m -> new ArrayMap<>()) 3300 .put(pcoData.pcoId, pcoData); 3301 if (getId() == INVALID_CID || pcoData.cid != getId()) return; 3302 if (!Objects.equals(oldData, pcoData)) { 3303 onPcoDataChanged(pcoData); 3304 } 3305 } 3306 3307 /** 3308 * @return The PCO data map of the network. The key is the PCO id, the value is the PCO data. 3309 * An empty map if PCO data is not available (or when the network is on IWLAN). 3310 */ 3311 public @NonNull Map<Integer, PcoData> getPcoData() { 3312 if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 3313 || mCid.get(mTransport) == INVALID_CID) { 3314 return Collections.emptyMap(); 3315 } 3316 return mPcoData.getOrDefault(mCid.get(mTransport), Collections.emptyMap()); 3317 } 3318 3319 /** 3320 * Check if the this data network is VCN-managed. 3321 * 3322 * @param networkCapabilities The network capabilities of this data network. 3323 * @return The VCN's policy for this DataNetwork. 3324 */ 3325 private VcnNetworkPolicyResult getVcnPolicy(NetworkCapabilities networkCapabilities) { 3326 if (mVcnManager == null) { 3327 return null; 3328 } 3329 3330 return mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties()); 3331 } 3332 3333 /** 3334 * Check if any of the attached request has the specified network capability. 3335 * 3336 * @param netCapability The network capability to check. 3337 * @return {@code true} if at least one network request has specified network capability. 3338 */ 3339 public boolean hasNetworkCapabilityInNetworkRequests(@NetCapability int netCapability) { 3340 return mAttachedNetworkRequestList.stream().anyMatch( 3341 request -> request.hasCapability(netCapability)); 3342 } 3343 3344 /** 3345 * Convert the data tear down reason to string. 3346 * 3347 * @param reason Data deactivation reason. 3348 * @return The deactivation reason in string format. 3349 */ 3350 public static @NonNull String tearDownReasonToString(@TearDownReason int reason) { 3351 switch (reason) { 3352 case TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED: 3353 return "CONNECTIVITY_SERVICE_UNWANTED"; 3354 case TEAR_DOWN_REASON_SIM_REMOVAL: 3355 return "SIM_REMOVAL"; 3356 case TEAR_DOWN_REASON_AIRPLANE_MODE_ON: 3357 return "AIRPLANE_MODE_ON"; 3358 case TEAR_DOWN_REASON_DATA_DISABLED: 3359 return "DATA_DISABLED"; 3360 case TEAR_DOWN_REASON_NO_LIVE_REQUEST: 3361 return "TEAR_DOWN_REASON_NO_LIVE_REQUEST"; 3362 case TEAR_DOWN_REASON_RAT_NOT_ALLOWED: 3363 return "TEAR_DOWN_REASON_RAT_NOT_ALLOWED"; 3364 case TEAR_DOWN_REASON_ROAMING_DISABLED: 3365 return "TEAR_DOWN_REASON_ROAMING_DISABLED"; 3366 case TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED: 3367 return "TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED"; 3368 case TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY: 3369 return "TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY"; 3370 case TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER: 3371 return "TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER"; 3372 case TEAR_DOWN_REASON_DATA_STALL: 3373 return "TEAR_DOWN_REASON_DATA_STALL"; 3374 case TEAR_DOWN_REASON_HANDOVER_FAILED: 3375 return "TEAR_DOWN_REASON_HANDOVER_FAILED"; 3376 case TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED: 3377 return "TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED"; 3378 case TEAR_DOWN_REASON_VCN_REQUESTED: 3379 return "TEAR_DOWN_REASON_VCN_REQUESTED"; 3380 case TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED: 3381 return "TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED"; 3382 case TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED: 3383 return "TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED"; 3384 case TEAR_DOWN_REASON_NOT_IN_SERVICE: 3385 return "TEAR_DOWN_REASON_NOT_IN_SERVICE"; 3386 case TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY: 3387 return "TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY"; 3388 case TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL: 3389 return "TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL"; 3390 case TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE: 3391 return "TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE"; 3392 case TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE: 3393 return "TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE"; 3394 case TEAR_DOWN_REASON_RETRY_SCHEDULED: 3395 return "TEAR_DOWN_REASON_RETRY_SCHEDULED"; 3396 case TEAR_DOWN_REASON_DATA_THROTTLED: 3397 return "TEAR_DOWN_REASON_DATA_THROTTLED"; 3398 case TEAR_DOWN_REASON_DATA_PROFILE_INVALID: 3399 return "TEAR_DOWN_REASON_DATA_PROFILE_INVALID"; 3400 case TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED: 3401 return "TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED"; 3402 case TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY: 3403 return "TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY"; 3404 case TEAR_DOWN_REASON_ILLEGAL_STATE: 3405 return "TEAR_DOWN_REASON_ILLEGAL_STATE"; 3406 case TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK: 3407 return "TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK"; 3408 case TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED: 3409 return "TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED"; 3410 default: 3411 return "UNKNOWN(" + reason + ")"; 3412 } 3413 } 3414 3415 /** 3416 * Convert event to string 3417 * 3418 * @param event The event 3419 * @return The event in string format. 3420 */ 3421 private static @NonNull String eventToString(int event) { 3422 switch (event) { 3423 case EVENT_DATA_CONFIG_UPDATED: 3424 return "EVENT_DATA_CONFIG_UPDATED"; 3425 case EVENT_ATTACH_NETWORK_REQUEST: 3426 return "EVENT_ATTACH_NETWORK_REQUEST"; 3427 case EVENT_DETACH_NETWORK_REQUEST: 3428 return "EVENT_DETACH_NETWORK_REQUEST"; 3429 case EVENT_RADIO_NOT_AVAILABLE: 3430 return "EVENT_RADIO_NOT_AVAILABLE"; 3431 case EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE: 3432 return "EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE"; 3433 case EVENT_SETUP_DATA_NETWORK_RESPONSE: 3434 return "EVENT_SETUP_DATA_NETWORK_RESPONSE"; 3435 case EVENT_TEAR_DOWN_NETWORK: 3436 return "EVENT_TEAR_DOWN_NETWORK"; 3437 case EVENT_DATA_STATE_CHANGED: 3438 return "EVENT_DATA_STATE_CHANGED"; 3439 case EVENT_SERVICE_STATE_CHANGED: 3440 return "EVENT_DATA_NETWORK_TYPE_REG_STATE_CHANGED"; 3441 case EVENT_DETACH_ALL_NETWORK_REQUESTS: 3442 return "EVENT_DETACH_ALL_NETWORK_REQUESTS"; 3443 case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED: 3444 return "EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED"; 3445 case EVENT_DISPLAY_INFO_CHANGED: 3446 return "EVENT_DISPLAY_INFO_CHANGED"; 3447 case EVENT_HANDOVER_RESPONSE: 3448 return "EVENT_HANDOVER_RESPONSE"; 3449 case EVENT_SUBSCRIPTION_PLAN_OVERRIDE: 3450 return "EVENT_SUBSCRIPTION_PLAN_OVERRIDE"; 3451 case EVENT_PCO_DATA_RECEIVED: 3452 return "EVENT_PCO_DATA_RECEIVED"; 3453 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: 3454 return "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED"; 3455 case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE: 3456 return "EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE"; 3457 case EVENT_STUCK_IN_TRANSIENT_STATE: 3458 return "EVENT_STUCK_IN_TRANSIENT_STATE"; 3459 case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET: 3460 return "EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET"; 3461 case EVENT_VOICE_CALL_STARTED: 3462 return "EVENT_VOICE_CALL_STARTED"; 3463 case EVENT_VOICE_CALL_ENDED: 3464 return "EVENT_VOICE_CALL_ENDED"; 3465 case EVENT_CSS_INDICATOR_CHANGED: 3466 return "EVENT_CSS_INDICATOR_CHANGED"; 3467 case EVENT_NOTIFY_HANDOVER_STARTED: 3468 return "EVENT_NOTIFY_HANDOVER_STARTED"; 3469 case EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE: 3470 return "EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE"; 3471 case EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE: 3472 return "EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE"; 3473 default: 3474 return "Unknown(" + event + ")"; 3475 } 3476 } 3477 3478 @Override 3479 public String toString() { 3480 return "[DataNetwork: " + mLogTag + ", " + (mDataProfile.getApnSetting() != null 3481 ? mDataProfile.getApnSetting().getApnName() : null) + ", state=" 3482 + (getCurrentState() != null ? getCurrentState().getName() : null) + "]"; 3483 } 3484 3485 /** 3486 * @return The short name of the data network (e.g. DN-C-1) 3487 */ 3488 public @NonNull String name() { 3489 return mLogTag; 3490 } 3491 3492 /** 3493 * Trigger the anomaly report with the specified UUID. 3494 * 3495 * @param anomalyMsg Description of the event 3496 * @param uuid UUID associated with that event 3497 */ 3498 private void reportAnomaly(@NonNull String anomalyMsg, @NonNull String uuid) { 3499 logl(anomalyMsg); 3500 AnomalyReporter.reportAnomaly(UUID.fromString(uuid), anomalyMsg, mPhone.getCarrierId()); 3501 } 3502 3503 /** 3504 * Log debug messages. 3505 * @param s debug messages 3506 */ 3507 @Override 3508 protected void log(@NonNull String s) { 3509 Rlog.d(mLogTag, (getCurrentState() != null 3510 ? (getCurrentState().getName() + ": ") : "") + s); 3511 } 3512 3513 /** 3514 * Log error messages. 3515 * @param s error messages 3516 */ 3517 @Override 3518 protected void loge(@NonNull String s) { 3519 Rlog.e(mLogTag, (getCurrentState() != null 3520 ? (getCurrentState().getName() + ": ") : "") + s); 3521 } 3522 3523 /** 3524 * Log verbose messages. 3525 * @param s error messages 3526 */ 3527 @Override 3528 protected void logv(@NonNull String s) { 3529 if (VDBG) { 3530 Rlog.v(mLogTag, (getCurrentState() != null 3531 ? (getCurrentState().getName() + ": ") : "") + s); 3532 } 3533 } 3534 3535 /** 3536 * Log debug messages and also log into the local log. 3537 * @param s debug messages 3538 */ 3539 private void logl(@NonNull String s) { 3540 log(s); 3541 mLocalLog.log((getCurrentState() != null ? (getCurrentState().getName() + ": ") : "") + s); 3542 } 3543 3544 /** 3545 * Dump the state of DataNetwork 3546 * 3547 * @param fd File descriptor 3548 * @param printWriter Print writer 3549 * @param args Arguments 3550 */ 3551 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 3552 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 3553 super.dump(fd, pw, args); 3554 pw.println("Tag: " + name()); 3555 pw.increaseIndent(); 3556 pw.println("mSubId=" + mSubId); 3557 pw.println("mTransport=" + AccessNetworkConstants.transportTypeToString(mTransport)); 3558 pw.println("WWAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)); 3559 pw.println("WLAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)); 3560 pw.println("mNetworkScore=" + mNetworkScore); 3561 pw.println("mDataAllowedReason=" + mDataAllowedReason); 3562 pw.println("mPduSessionId=" + mPduSessionId); 3563 pw.println("mDataProfile=" + mDataProfile); 3564 pw.println("mNetworkCapabilities=" + mNetworkCapabilities); 3565 pw.println("mLinkProperties=" + mLinkProperties); 3566 pw.println("mNetworkSliceInfo=" + mNetworkSliceInfo); 3567 pw.println("mNetworkBandwidth=" + mNetworkBandwidth); 3568 pw.println("mTcpBufferSizes=" + mTcpBufferSizes); 3569 pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfo); 3570 pw.println("mTempNotMeteredSupported=" + mTempNotMeteredSupported); 3571 pw.println("mTempNotMetered=" + mTempNotMetered); 3572 pw.println("mCongested=" + mCongested); 3573 pw.println("mSuspended=" + mSuspended); 3574 pw.println("mDataCallResponse=" + mDataCallResponse); 3575 pw.println("mFailCause=" + DataFailCause.toString(mFailCause)); 3576 pw.println("mAdministratorUids=" + Arrays.toString(mAdministratorUids)); 3577 pw.println("mCarrierServicePackageUid=" + mCarrierServicePackageUid); 3578 pw.println("mEverConnected=" + mEverConnected); 3579 pw.println("mInvokedDataDeactivation=" + mInvokedDataDeactivation); 3580 3581 pw.println("Attached network requests:"); 3582 pw.increaseIndent(); 3583 for (TelephonyNetworkRequest request : mAttachedNetworkRequestList) { 3584 pw.println(request); 3585 } 3586 pw.decreaseIndent(); 3587 pw.println("mQosBearerSessions=" + mQosBearerSessions); 3588 3589 mNetworkAgent.dump(fd, pw, args); 3590 pw.println("Local logs:"); 3591 pw.increaseIndent(); 3592 mLocalLog.dump(fd, pw, args); 3593 pw.decreaseIndent(); 3594 pw.decreaseIndent(); 3595 pw.println("---------------"); 3596 } 3597 } 3598