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.BroadcastReceiver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.IntentFilter; 27 import android.net.NetworkAgent; 28 import android.net.NetworkCapabilities; 29 import android.net.NetworkPolicyManager; 30 import android.net.NetworkPolicyManager.SubscriptionCallback; 31 import android.net.NetworkRequest; 32 import android.net.Uri; 33 import android.os.AsyncResult; 34 import android.os.Handler; 35 import android.os.Looper; 36 import android.os.Message; 37 import android.telecom.TelecomManager; 38 import android.telephony.AccessNetworkConstants; 39 import android.telephony.AccessNetworkConstants.AccessNetworkType; 40 import android.telephony.AccessNetworkConstants.RadioAccessNetworkType; 41 import android.telephony.AccessNetworkConstants.TransportType; 42 import android.telephony.Annotation.DataActivityType; 43 import android.telephony.Annotation.DataFailureCause; 44 import android.telephony.Annotation.NetCapability; 45 import android.telephony.Annotation.NetworkType; 46 import android.telephony.Annotation.ValidationStatus; 47 import android.telephony.AnomalyReporter; 48 import android.telephony.CarrierConfigManager; 49 import android.telephony.CellSignalStrength; 50 import android.telephony.DataFailCause; 51 import android.telephony.DataSpecificRegistrationInfo; 52 import android.telephony.NetworkRegistrationInfo; 53 import android.telephony.NetworkRegistrationInfo.RegistrationState; 54 import android.telephony.PcoData; 55 import android.telephony.ServiceState; 56 import android.telephony.SubscriptionManager; 57 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; 58 import android.telephony.SubscriptionPlan; 59 import android.telephony.TelephonyManager; 60 import android.telephony.TelephonyManager.DataState; 61 import android.telephony.TelephonyManager.SimState; 62 import android.telephony.TelephonyRegistryManager; 63 import android.telephony.data.DataCallResponse; 64 import android.telephony.data.DataCallResponse.HandoverFailureMode; 65 import android.telephony.data.DataCallResponse.LinkStatus; 66 import android.telephony.data.DataProfile; 67 import android.telephony.ims.ImsException; 68 import android.telephony.ims.ImsManager; 69 import android.telephony.ims.ImsReasonInfo; 70 import android.telephony.ims.ImsRegistrationAttributes; 71 import android.telephony.ims.ImsStateCallback; 72 import android.telephony.ims.RegistrationManager; 73 import android.telephony.ims.feature.ImsFeature; 74 import android.text.TextUtils; 75 import android.util.ArrayMap; 76 import android.util.ArraySet; 77 import android.util.IndentingPrintWriter; 78 import android.util.LocalLog; 79 import android.util.SparseArray; 80 import android.util.SparseBooleanArray; 81 82 import com.android.internal.annotations.VisibleForTesting; 83 import com.android.internal.telephony.Phone; 84 import com.android.internal.telephony.PhoneConstants; 85 import com.android.internal.telephony.SlidingWindowEventCounter; 86 import com.android.internal.telephony.TelephonyComponentFactory; 87 import com.android.internal.telephony.data.AccessNetworksManager.AccessNetworksManagerCallback; 88 import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback; 89 import com.android.internal.telephony.data.DataEvaluation.DataAllowedReason; 90 import com.android.internal.telephony.data.DataEvaluation.DataDisallowedReason; 91 import com.android.internal.telephony.data.DataEvaluation.DataEvaluationReason; 92 import com.android.internal.telephony.data.DataNetwork.DataNetworkCallback; 93 import com.android.internal.telephony.data.DataNetwork.TearDownReason; 94 import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback; 95 import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryEntry; 96 import com.android.internal.telephony.data.DataRetryManager.DataRetryEntry; 97 import com.android.internal.telephony.data.DataRetryManager.DataRetryManagerCallback; 98 import com.android.internal.telephony.data.DataRetryManager.DataSetupRetryEntry; 99 import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback; 100 import com.android.internal.telephony.data.DataStallRecoveryManager.DataStallRecoveryManagerCallback; 101 import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback; 102 import com.android.internal.telephony.ims.ImsResolver; 103 import com.android.internal.telephony.util.TelephonyUtils; 104 import com.android.telephony.Rlog; 105 106 import java.io.FileDescriptor; 107 import java.io.PrintWriter; 108 import java.lang.annotation.Retention; 109 import java.lang.annotation.RetentionPolicy; 110 import java.util.ArrayList; 111 import java.util.Arrays; 112 import java.util.Collection; 113 import java.util.Collections; 114 import java.util.Comparator; 115 import java.util.Iterator; 116 import java.util.LinkedList; 117 import java.util.List; 118 import java.util.Locale; 119 import java.util.Map; 120 import java.util.Objects; 121 import java.util.Set; 122 import java.util.UUID; 123 import java.util.concurrent.Executor; 124 import java.util.concurrent.TimeUnit; 125 import java.util.function.Function; 126 import java.util.stream.Collectors; 127 128 /** 129 * DataNetworkController in the central module of the telephony data stack. It is responsible to 130 * create and manage all the mobile data networks. It is per-SIM basis which means for DSDS devices, 131 * there will be two DataNetworkController instances. Unlike the Android 12 DcTracker, which is 132 * designed to be per-transport (i.e. cellular, IWLAN), DataNetworkController is designed to handle 133 * data networks on both cellular and IWLAN. 134 */ 135 public class DataNetworkController extends Handler { 136 private static final boolean VDBG = false; 137 138 /** Event for adding a network request. */ 139 private static final int EVENT_ADD_NETWORK_REQUEST = 2; 140 141 /** Event for removing a network request. */ 142 private static final int EVENT_REMOVE_NETWORK_REQUEST = 3; 143 144 /** Event for SRVCC state changed. */ 145 private static final int EVENT_SRVCC_STATE_CHANGED = 4; 146 147 /** Re-evaluate all unsatisfied network requests. */ 148 private static final int EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS = 5; 149 150 /** Event for packet switch restricted enabled by network. */ 151 private static final int EVENT_PS_RESTRICT_ENABLED = 6; 152 153 /** Event for packet switch restricted disabled by network. */ 154 private static final int EVENT_PS_RESTRICT_DISABLED = 7; 155 156 /** Event for data service binding changed. */ 157 private static final int EVENT_DATA_SERVICE_BINDING_CHANGED = 8; 158 159 /** Event for SIM state changed. */ 160 private static final int EVENT_SIM_STATE_CHANGED = 9; 161 162 /** Event for tearing down all data networks. */ 163 private static final int EVENT_TEAR_DOWN_ALL_DATA_NETWORKS = 12; 164 165 /** Event for registering data network controller callback. */ 166 private static final int EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK = 13; 167 168 /** Event for unregistering data network controller callback. */ 169 private static final int EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK = 14; 170 171 /** Event for subscription info changed. */ 172 private static final int EVENT_SUBSCRIPTION_CHANGED = 15; 173 174 /** Event for re-evaluating existing data networks. */ 175 private static final int EVENT_REEVALUATE_EXISTING_DATA_NETWORKS = 16; 176 177 /** Event for data RAT or registration state changed. */ 178 private static final int EVENT_SERVICE_STATE_CHANGED = 17; 179 180 /** Event for voice call ended. */ 181 private static final int EVENT_VOICE_CALL_ENDED = 18; 182 183 /** Event for registering all events. */ 184 private static final int EVENT_REGISTER_ALL_EVENTS = 19; 185 186 /** Event for emergency call started or ended. */ 187 private static final int EVENT_EMERGENCY_CALL_CHANGED = 20; 188 189 /** Event for evaluating preferred transport. */ 190 private static final int EVENT_EVALUATE_PREFERRED_TRANSPORT = 21; 191 192 /** Event for subscription plans changed. */ 193 private static final int EVENT_SUBSCRIPTION_PLANS_CHANGED = 22; 194 195 /** Event for unmetered or congested subscription override. */ 196 private static final int EVENT_SUBSCRIPTION_OVERRIDE = 23; 197 198 /** Event for slice config changed. */ 199 private static final int EVENT_SLICE_CONFIG_CHANGED = 24; 200 201 /** Event for tracking area code changed. */ 202 private static final int EVENT_TAC_CHANGED = 25; 203 204 /** The supported IMS features. This is for IMS graceful tear down support. */ 205 private static final Collection<Integer> SUPPORTED_IMS_FEATURES = 206 List.of(ImsFeature.FEATURE_MMTEL, ImsFeature.FEATURE_RCS); 207 208 /** The maximum number of previously connected data networks for debugging purposes. */ 209 private static final int MAX_HISTORICAL_CONNECTED_DATA_NETWORKS = 10; 210 211 /** 212 * The delay in milliseconds to re-evaluate preferred transport when handover failed and 213 * fallback to source. 214 */ 215 private static final long REEVALUATE_PREFERRED_TRANSPORT_DELAY_MILLIS = 216 TimeUnit.SECONDS.toMillis(3); 217 218 /** The delay in milliseconds to re-evaluate unsatisfied network requests after call end. */ 219 private static final long REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_AFTER_CALL_END_DELAY_MILLIS = 220 TimeUnit.MILLISECONDS.toMillis(500); 221 222 /** The delay in milliseconds to re-evaluate unsatisfied network requests after TAC changes. */ 223 private static final long REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_TAC_CHANGED_DELAY_MILLIS = 224 TimeUnit.MILLISECONDS.toMillis(100); 225 226 /** 227 * The delay in milliseconds to re-evaluate unsatisfied network requests after network request 228 * detached. 229 */ 230 private static final long REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_AFTER_DETACHED_DELAY_MILLIS = 231 TimeUnit.SECONDS.toMillis(1); 232 233 private final Phone mPhone; 234 private final String mLogTag; 235 private final LocalLog mLocalLog = new LocalLog(128); 236 237 private final @NonNull DataConfigManager mDataConfigManager; 238 private final @NonNull DataSettingsManager mDataSettingsManager; 239 private final @NonNull DataProfileManager mDataProfileManager; 240 private final @NonNull DataStallRecoveryManager mDataStallRecoveryManager; 241 private final @NonNull AccessNetworksManager mAccessNetworksManager; 242 private final @NonNull DataRetryManager mDataRetryManager; 243 private final @NonNull ImsManager mImsManager; 244 private final @NonNull TelecomManager mTelecomManager; 245 private final @NonNull NetworkPolicyManager mNetworkPolicyManager; 246 private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers = 247 new SparseArray<>(); 248 249 /** The subscription index associated with this data network controller. */ 250 private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 251 252 /** The current service state of the device. */ 253 // Note that keeping a copy here instead of directly using ServiceStateTracker.getServiceState() 254 // is intended for detecting the delta. 255 private @NonNull ServiceState mServiceState; 256 257 /** The list of SubscriptionPlans, updated when initialized and when plans are changed. */ 258 private final @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>(); 259 260 /** 261 * The set of network types an unmetered override applies to, set by onSubscriptionOverride 262 * and cleared when the device is rebooted or the override expires. 263 */ 264 private final @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes = 265 new ArraySet<>(); 266 267 /** 268 * The set of network types a congested override applies to, set by onSubscriptionOverride 269 * and cleared when the device is rebooted or the override expires. 270 */ 271 private final @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes = 272 new ArraySet<>(); 273 274 /** 275 * The list of all network requests. 276 */ 277 private final @NonNull NetworkRequestList mAllNetworkRequestList = new NetworkRequestList(); 278 279 /** 280 * The current data network list, including the ones that are connected, connecting, or 281 * disconnecting. 282 */ 283 private final @NonNull List<DataNetwork> mDataNetworkList = new ArrayList<>(); 284 285 /** {@code true} indicating at least one data network exists. */ 286 private boolean mAnyDataNetworkExisting; 287 288 /** 289 * Contain the last 10 data networks that were connected. This is for debugging purposes only. 290 */ 291 private final @NonNull List<DataNetwork> mPreviousConnectedDataNetworkList = new ArrayList<>(); 292 293 /** 294 * The internet data network state. Note that this is the best effort if more than one 295 * data network supports internet. 296 */ 297 private @DataState int mInternetDataNetworkState = TelephonyManager.DATA_DISCONNECTED; 298 299 /** 300 * The IMS data network state. For now this is just for debugging purposes. 301 */ 302 private @DataState int mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED; 303 304 /** Overall aggregated link status from internet data networks. */ 305 private @LinkStatus int mInternetLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN; 306 307 /** Data network controller callbacks. */ 308 private final @NonNull Set<DataNetworkControllerCallback> mDataNetworkControllerCallbacks = 309 new ArraySet<>(); 310 311 /** Indicates if packet switch data is restricted by the cellular network. */ 312 private boolean mPsRestricted = false; 313 314 /** Indicates if NR advanced is allowed by PCO. */ 315 private boolean mNrAdvancedCapableByPco = false; 316 317 /** Indicates if srvcc is going on. */ 318 private boolean mIsSrvccHandoverInProcess = false; 319 320 /** 321 * Indicates if the data services are bound. Key if the transport type, and value is the boolean 322 * indicating service is bound or not. 323 */ 324 private final @NonNull SparseBooleanArray mDataServiceBound = new SparseBooleanArray(); 325 326 /** SIM state. */ 327 private @SimState int mSimState = TelephonyManager.SIM_STATE_UNKNOWN; 328 329 /** Data activity. */ 330 private @DataActivityType int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE; 331 332 /** 333 * IMS state callbacks. Key is the IMS feature, value is the callback. 334 */ 335 private final @NonNull SparseArray<ImsStateCallback> mImsStateCallbacks = new SparseArray<>(); 336 337 /** Registered IMS features. Unregistered IMS features are removed from the set. */ 338 private final @NonNull Set<Integer> mRegisteredImsFeatures = new ArraySet<>(); 339 340 /** IMS feature package names. Key is the IMS feature, value is the package name. */ 341 private final @NonNull SparseArray<String> mImsFeaturePackageName = new SparseArray<>(); 342 343 /** 344 * Networks that are pending IMS de-registration. Key is the data network, value is the function 345 * to tear down the network. 346 */ 347 private final @NonNull Map<DataNetwork, Runnable> mPendingImsDeregDataNetworks = 348 new ArrayMap<>(); 349 350 /** 351 * IMS feature registration callback. The key is the IMS feature, the value is the registration 352 * callback. When new SIM inserted, the old callbacks associated with the old subscription index 353 * will be unregistered. 354 */ 355 private final @NonNull SparseArray<RegistrationManager.RegistrationCallback> 356 mImsFeatureRegistrationCallbacks = new SparseArray<>(); 357 358 /** The counter to detect back to back release/request IMS network. */ 359 private @NonNull SlidingWindowEventCounter mImsThrottleCounter; 360 /** Event counter for unwanted network within time window, is used to trigger anomaly report. */ 361 private @NonNull SlidingWindowEventCounter mNetworkUnwantedCounter; 362 /** Event counter for WLAN setup data failure within time window to trigger anomaly report. */ 363 private @NonNull SlidingWindowEventCounter mSetupDataCallWlanFailureCounter; 364 /** Event counter for WWAN setup data failure within time window to trigger anomaly report. */ 365 private @NonNull SlidingWindowEventCounter mSetupDataCallWwanFailureCounter; 366 367 /** 368 * {@code true} if {@link #tearDownAllDataNetworks(int)} was invoked and waiting for all 369 * networks torn down. 370 */ 371 private boolean mPendingTearDownAllNetworks = false; 372 373 /** 374 * The capabilities of the latest released IMS request. To detect back to back release/request 375 * IMS network. 376 */ 377 private int[] mLastReleasedImsRequestCapabilities; 378 379 /** True after try to release an IMS network; False after try to request an IMS network. */ 380 private boolean mLastImsOperationIsRelease; 381 382 /** The broadcast receiver. */ 383 private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 384 @Override 385 public void onReceive(Context context, Intent intent) { 386 switch(intent.getAction()) { 387 case TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED: 388 case TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED: 389 if (mPhone.getPhoneId() == intent.getIntExtra( 390 SubscriptionManager.EXTRA_SLOT_INDEX, 391 SubscriptionManager.INVALID_SIM_SLOT_INDEX)) { 392 int simState = intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE, 393 TelephonyManager.SIM_STATE_UNKNOWN); 394 sendMessage(obtainMessage(EVENT_SIM_STATE_CHANGED, simState, 0)); 395 } 396 } 397 } 398 }; 399 400 /** 401 * The sorted network request list by priority. The highest priority network request stays at 402 * the head of the list. The highest priority is 100, the lowest is 0. 403 * 404 * Note this list is not thread-safe. Do not access the list from different threads. 405 */ 406 @VisibleForTesting 407 public static class NetworkRequestList extends LinkedList<TelephonyNetworkRequest> { 408 /** 409 * Constructor 410 */ NetworkRequestList()411 public NetworkRequestList() { 412 } 413 414 /** 415 * Copy constructor 416 * 417 * @param requestList The network request list. 418 */ NetworkRequestList(@onNull NetworkRequestList requestList)419 public NetworkRequestList(@NonNull NetworkRequestList requestList) { 420 addAll(requestList); 421 } 422 423 /** 424 * Constructor 425 * 426 * @param requestList The network request list. 427 */ NetworkRequestList(@onNull List<TelephonyNetworkRequest> requestList)428 public NetworkRequestList(@NonNull List<TelephonyNetworkRequest> requestList) { 429 addAll(requestList); 430 } 431 432 /** 433 * Constructor 434 * 435 * @param newRequest The initial request of the list. 436 */ NetworkRequestList(@onNull TelephonyNetworkRequest newRequest)437 public NetworkRequestList(@NonNull TelephonyNetworkRequest newRequest) { 438 this(); 439 add(newRequest); 440 } 441 442 /** 443 * Add the network request to the list. Note that the item will be inserted to the position 444 * based on the priority. 445 * 446 * @param newRequest The network request to be added. 447 * @return {@code true} if added successfully. {@code false} if the request already exists. 448 */ 449 @Override add(@onNull TelephonyNetworkRequest newRequest)450 public boolean add(@NonNull TelephonyNetworkRequest newRequest) { 451 int index = 0; 452 while (index < size()) { 453 TelephonyNetworkRequest networkRequest = get(index); 454 if (networkRequest.equals(newRequest)) { 455 return false; // Do not allow duplicate 456 } 457 if (newRequest.getPriority() > networkRequest.getPriority()) { 458 break; 459 } 460 index++; 461 } 462 super.add(index, newRequest); 463 return true; 464 } 465 466 @Override add(int index, @NonNull TelephonyNetworkRequest newRequest)467 public void add(int index, @NonNull TelephonyNetworkRequest newRequest) { 468 throw new UnsupportedOperationException("Insertion to certain position is illegal."); 469 } 470 471 @Override addAll(Collection<? extends TelephonyNetworkRequest> requests)472 public boolean addAll(Collection<? extends TelephonyNetworkRequest> requests) { 473 for (TelephonyNetworkRequest networkRequest : requests) { 474 add(networkRequest); 475 } 476 return true; 477 } 478 479 /** 480 * Get the first network request that contains all the provided network capabilities. 481 * 482 * @param netCaps The network capabilities. 483 * @return The first network request in the list that contains all the provided 484 * capabilities. 485 */ get(@onNull @etCapability int[] netCaps)486 public @Nullable TelephonyNetworkRequest get(@NonNull @NetCapability int[] netCaps) { 487 int index = 0; 488 while (index < size()) { 489 TelephonyNetworkRequest networkRequest = get(index); 490 // Check if any network requests contains all the provided capabilities. 491 if (Arrays.stream(networkRequest.getCapabilities()) 492 .boxed() 493 .collect(Collectors.toSet()) 494 .containsAll(Arrays.stream(netCaps).boxed() 495 .collect(Collectors.toList()))) { 496 return networkRequest; 497 } 498 index++; 499 } 500 return null; 501 } 502 503 /** 504 * Check if any network request is requested by the specified package. 505 * 506 * @param packageName The package name. 507 * @return {@code true} if any request is originated from the specified package. 508 */ hasNetworkRequestsFromPackage(@onNull String packageName)509 public boolean hasNetworkRequestsFromPackage(@NonNull String packageName) { 510 for (TelephonyNetworkRequest networkRequest : this) { 511 if (packageName.equals( 512 networkRequest.getNativeNetworkRequest().getRequestorPackageName())) { 513 return true; 514 } 515 } 516 return false; 517 } 518 519 @Override toString()520 public String toString() { 521 return "[NetworkRequestList: size=" + size() + (size() > 0 ? ", leading by " 522 + get(0) : "") + "]"; 523 } 524 525 /** 526 * Dump the network request list. 527 * 528 * @param pw print writer. 529 */ dump(IndentingPrintWriter pw)530 public void dump(IndentingPrintWriter pw) { 531 pw.increaseIndent(); 532 for (TelephonyNetworkRequest networkRequest : this) { 533 pw.println(networkRequest); 534 } 535 pw.decreaseIndent(); 536 } 537 } 538 539 /** 540 * The data network controller callback. Note this is only used for passing information 541 * internally in the data stack, should not be used externally. 542 */ 543 public static class DataNetworkControllerCallback extends DataCallback { 544 /** 545 * Constructor 546 * 547 * @param executor The executor of the callback. 548 */ DataNetworkControllerCallback(@onNull @allbackExecutor Executor executor)549 public DataNetworkControllerCallback(@NonNull @CallbackExecutor Executor executor) { 550 super(executor); 551 } 552 553 /** 554 * Called when internet data network validation status changed. 555 * 556 * @param validationStatus The validation status. 557 */ onInternetDataNetworkValidationStatusChanged( @alidationStatus int validationStatus)558 public void onInternetDataNetworkValidationStatusChanged( 559 @ValidationStatus int validationStatus) {} 560 561 /** 562 * Called when internet data network is connected. 563 * 564 * @param internetNetworks The connected internet data network. It should be only one in 565 * most of the cases. 566 */ onInternetDataNetworkConnected(@onNull List<DataNetwork> internetNetworks)567 public void onInternetDataNetworkConnected(@NonNull List<DataNetwork> internetNetworks) {} 568 569 /** 570 * Called when data network is connected. 571 * 572 * @param transport Transport for the connected network. 573 * @param dataProfile The data profile of the connected data network. 574 */ onDataNetworkConnected(@ransportType int transport, @NonNull DataProfile dataProfile)575 public void onDataNetworkConnected(@TransportType int transport, 576 @NonNull DataProfile dataProfile) {} 577 578 /** Called when internet data network is disconnected. */ onInternetDataNetworkDisconnected()579 public void onInternetDataNetworkDisconnected() {} 580 581 /** 582 * Called when any data network existing status changed. 583 * 584 * @param anyDataExisting {@code true} indicating there is at least one data network 585 * existing regardless of its state. {@code false} indicating all data networks are 586 * disconnected. 587 */ onAnyDataNetworkExistingChanged(boolean anyDataExisting)588 public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {} 589 590 /** 591 * Called when {@link SubscriptionPlan}s change or an unmetered or congested subscription 592 * override is set. 593 */ onSubscriptionPlanOverride()594 public void onSubscriptionPlanOverride() {} 595 596 /** 597 * Called when the physical link status changed. 598 * 599 * @param status The latest link status. 600 */ onPhysicalLinkStatusChanged(@inkStatus int status)601 public void onPhysicalLinkStatusChanged(@LinkStatus int status) {} 602 603 /** 604 * Called when NR advanced capable by PCO changed. 605 * 606 * @param nrAdvancedCapable {@code true} if at least one of the data network is NR advanced 607 * capable. 608 */ onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable)609 public void onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable) {} 610 611 /** 612 * Called when data service is bound. 613 * 614 * @param transport The transport of the data service. 615 */ onDataServiceBound(@ransportType int transport)616 public void onDataServiceBound(@TransportType int transport) {} 617 } 618 619 /** 620 * This class represent a rule allowing or disallowing handover between IWLAN and cellular 621 * networks. 622 * 623 * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY 624 */ 625 public static class HandoverRule { 626 @Retention(RetentionPolicy.SOURCE) 627 @IntDef(prefix = {"RULE_TYPE_"}, 628 value = { 629 RULE_TYPE_ALLOWED, 630 RULE_TYPE_DISALLOWED, 631 }) 632 public @interface HandoverRuleType {} 633 634 /** Indicating this rule is for allowing handover. */ 635 public static final int RULE_TYPE_ALLOWED = 1; 636 637 /** Indicating this rule is for disallowing handover. */ 638 public static final int RULE_TYPE_DISALLOWED = 2; 639 640 private static final String RULE_TAG_SOURCE_ACCESS_NETWORKS = "source"; 641 642 private static final String RULE_TAG_TARGET_ACCESS_NETWORKS = "target"; 643 644 private static final String RULE_TAG_TYPE = "type"; 645 646 private static final String RULE_TAG_CAPABILITIES = "capabilities"; 647 648 private static final String RULE_TAG_ROAMING = "roaming"; 649 650 /** Handover rule type. */ 651 public final @HandoverRuleType int type; 652 653 /** The applicable source access networks for handover. */ 654 public final @NonNull @RadioAccessNetworkType Set<Integer> sourceAccessNetworks; 655 656 /** The applicable target access networks for handover. */ 657 public final @NonNull @RadioAccessNetworkType Set<Integer> targetAccessNetworks; 658 659 /** 660 * The network capabilities to any of which this handover rule applies. 661 * If is empty, then capability is ignored as a rule matcher. 662 */ 663 public final @NonNull @NetCapability Set<Integer> networkCapabilities; 664 665 /** {@code true} indicates this policy is only applicable when the device is roaming. */ 666 public final boolean isOnlyForRoaming; 667 668 /** 669 * Constructor 670 * 671 * @param ruleString The rule in string format. 672 * 673 * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY 674 */ HandoverRule(@onNull String ruleString)675 public HandoverRule(@NonNull String ruleString) { 676 if (TextUtils.isEmpty(ruleString)) { 677 throw new IllegalArgumentException("illegal rule " + ruleString); 678 } 679 680 Set<Integer> source = null, target = null, capabilities = Collections.emptySet(); 681 int type = 0; 682 boolean roaming = false; 683 684 ruleString = ruleString.trim().toLowerCase(Locale.ROOT); 685 String[] expressions = ruleString.split("\\s*,\\s*"); 686 for (String expression : expressions) { 687 String[] tokens = expression.trim().split("\\s*=\\s*"); 688 if (tokens.length != 2) { 689 throw new IllegalArgumentException("illegal rule " + ruleString + ", tokens=" 690 + Arrays.toString(tokens)); 691 } 692 String key = tokens[0].trim(); 693 String value = tokens[1].trim(); 694 try { 695 switch (key) { 696 case RULE_TAG_SOURCE_ACCESS_NETWORKS: 697 source = Arrays.stream(value.split("\\s*\\|\\s*")) 698 .map(String::trim) 699 .map(AccessNetworkType::fromString) 700 .collect(Collectors.toSet()); 701 break; 702 case RULE_TAG_TARGET_ACCESS_NETWORKS: 703 target = Arrays.stream(value.split("\\s*\\|\\s*")) 704 .map(String::trim) 705 .map(AccessNetworkType::fromString) 706 .collect(Collectors.toSet()); 707 break; 708 case RULE_TAG_TYPE: 709 if (value.toLowerCase(Locale.ROOT).equals("allowed")) { 710 type = RULE_TYPE_ALLOWED; 711 } else if (value.toLowerCase(Locale.ROOT).equals("disallowed")) { 712 type = RULE_TYPE_DISALLOWED; 713 } else { 714 throw new IllegalArgumentException("unexpected rule type " + value); 715 } 716 break; 717 case RULE_TAG_CAPABILITIES: 718 capabilities = DataUtils.getNetworkCapabilitiesFromString(value); 719 break; 720 case RULE_TAG_ROAMING: 721 roaming = Boolean.parseBoolean(value); 722 break; 723 default: 724 throw new IllegalArgumentException("unexpected key " + key); 725 } 726 } catch (Exception e) { 727 e.printStackTrace(); 728 throw new IllegalArgumentException("illegal rule \"" + ruleString + "\", e=" 729 + e); 730 } 731 } 732 733 if (source == null || target == null || source.isEmpty() || target.isEmpty()) { 734 throw new IllegalArgumentException("Need to specify both source and target. " 735 + "\"" + ruleString + "\""); 736 } 737 738 if (source.contains(AccessNetworkType.UNKNOWN) && type != RULE_TYPE_DISALLOWED) { 739 throw new IllegalArgumentException("Unknown access network can be only specified in" 740 + " the disallowed rule. \"" + ruleString + "\""); 741 } 742 743 if (target.contains(AccessNetworkType.UNKNOWN)) { 744 throw new IllegalArgumentException("Target access networks contains unknown. " 745 + "\"" + ruleString + "\""); 746 } 747 748 if (type == 0) { 749 throw new IllegalArgumentException("Rule type is not specified correctly. " 750 + "\"" + ruleString + "\""); 751 } 752 753 if (capabilities != null && capabilities.contains(-1)) { 754 throw new IllegalArgumentException("Network capabilities contains unknown. " 755 + "\"" + ruleString + "\""); 756 } 757 758 if (!source.contains(AccessNetworkType.IWLAN) 759 && !target.contains(AccessNetworkType.IWLAN)) { 760 throw new IllegalArgumentException("IWLAN must be specified in either source or " 761 + "target access networks.\"" + ruleString + "\""); 762 } 763 764 sourceAccessNetworks = source; 765 targetAccessNetworks = target; 766 this.type = type; 767 networkCapabilities = capabilities; 768 isOnlyForRoaming = roaming; 769 } 770 771 @Override toString()772 public String toString() { 773 return "[HandoverRule: type=" + (type == RULE_TYPE_ALLOWED ? "allowed" 774 : "disallowed") + ", source=" + sourceAccessNetworks.stream() 775 .map(AccessNetworkType::toString).collect(Collectors.joining("|")) 776 + ", target=" + targetAccessNetworks.stream().map(AccessNetworkType::toString) 777 .collect(Collectors.joining("|")) + ", isRoaming=" + isOnlyForRoaming 778 + ", capabilities=" + DataUtils.networkCapabilitiesToString(networkCapabilities) 779 + "]"; 780 } 781 } 782 783 /** 784 * Constructor 785 * 786 * @param phone The phone instance. 787 * @param looper The looper to be used by the handler. Currently the handler thread is the 788 * phone process's main thread. 789 */ DataNetworkController(@onNull Phone phone, @NonNull Looper looper)790 public DataNetworkController(@NonNull Phone phone, @NonNull Looper looper) { 791 super(looper); 792 mPhone = phone; 793 mLogTag = "DNC-" + mPhone.getPhoneId(); 794 log("DataNetworkController created."); 795 796 mAccessNetworksManager = phone.getAccessNetworksManager(); 797 for (int transport : mAccessNetworksManager.getAvailableTransports()) { 798 mDataServiceManagers.put(transport, new DataServiceManager(mPhone, looper, transport)); 799 } 800 801 mDataConfigManager = new DataConfigManager(mPhone, looper); 802 803 // ========== Anomaly counters ========== 804 mImsThrottleCounter = new SlidingWindowEventCounter( 805 mDataConfigManager.getAnomalyImsReleaseRequestThreshold().timeWindow, 806 mDataConfigManager.getAnomalyImsReleaseRequestThreshold().eventNumOccurrence); 807 mNetworkUnwantedCounter = new SlidingWindowEventCounter( 808 mDataConfigManager.getAnomalyNetworkUnwantedThreshold().timeWindow, 809 mDataConfigManager.getAnomalyNetworkUnwantedThreshold().eventNumOccurrence); 810 mSetupDataCallWlanFailureCounter = new SlidingWindowEventCounter( 811 mDataConfigManager.getAnomalySetupDataCallThreshold().timeWindow, 812 mDataConfigManager.getAnomalySetupDataCallThreshold().eventNumOccurrence); 813 mSetupDataCallWwanFailureCounter = new SlidingWindowEventCounter( 814 mDataConfigManager.getAnomalySetupDataCallThreshold().timeWindow, 815 mDataConfigManager.getAnomalySetupDataCallThreshold().eventNumOccurrence); 816 // ======================================== 817 818 mDataSettingsManager = TelephonyComponentFactory.getInstance().inject( 819 DataSettingsManager.class.getName()) 820 .makeDataSettingsManager(mPhone, this, looper, 821 new DataSettingsManagerCallback(this::post) { 822 @Override 823 public void onDataEnabledChanged(boolean enabled, 824 @TelephonyManager.DataEnabledChangedReason int reason, 825 @NonNull String callingPackage) { 826 // If mobile data is enabled by the user, evaluate the unsatisfied 827 // network requests and then attempt to setup data networks to 828 // satisfy them. If mobile data is disabled, evaluate the existing 829 // data networks and see if they need to be torn down. 830 logl("onDataEnabledChanged: enabled=" + enabled); 831 sendMessage(obtainMessage(enabled 832 ? EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS 833 : EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 834 DataEvaluationReason.DATA_ENABLED_CHANGED)); 835 } 836 @Override 837 public void onDataEnabledOverrideChanged(boolean enabled, 838 @TelephonyManager.MobileDataPolicy int policy) { 839 // If data enabled override is enabled by the user, evaluate the 840 // unsatisfied network requests and then attempt to setup data 841 // networks to satisfy them. If data enabled override is disabled, 842 // evaluate the existing data networks and see if they need to be 843 // torn down. 844 logl("onDataEnabledOverrideChanged: enabled=" + enabled); 845 sendMessage(obtainMessage(enabled 846 ? EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS 847 : EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 848 DataEvaluationReason.DATA_ENABLED_OVERRIDE_CHANGED)); 849 } 850 @Override 851 public void onDataRoamingEnabledChanged(boolean enabled) { 852 // If data roaming is enabled by the user, evaluate the unsatisfied 853 // network requests and then attempt to setup data networks to 854 // satisfy them. If data roaming is disabled, evaluate the existing 855 // data networks and see if they need to be torn down. 856 logl("onDataRoamingEnabledChanged: enabled=" + enabled); 857 sendMessage(obtainMessage(enabled 858 ? EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS 859 : EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 860 DataEvaluationReason.ROAMING_ENABLED_CHANGED)); 861 } 862 }); 863 mDataProfileManager = TelephonyComponentFactory.getInstance().inject( 864 DataProfileManager.class.getName()) 865 .makeDataProfileManager(mPhone, this, mDataServiceManagers 866 .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), looper, 867 new DataProfileManagerCallback(this::post) { 868 @Override 869 public void onDataProfilesChanged() { 870 sendMessage( 871 obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 872 DataEvaluationReason.DATA_PROFILES_CHANGED)); 873 sendMessage( 874 obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 875 DataEvaluationReason.DATA_PROFILES_CHANGED)); 876 } 877 }); 878 mDataStallRecoveryManager = new DataStallRecoveryManager(mPhone, this, mDataServiceManagers 879 .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), looper, 880 new DataStallRecoveryManagerCallback(this::post) { 881 @Override 882 public void onDataStallReestablishInternet() { 883 DataNetworkController.this.onDataStallReestablishInternet(); 884 } 885 }); 886 mDataRetryManager = new DataRetryManager(mPhone, this, 887 mDataServiceManagers, looper, 888 new DataRetryManagerCallback(this::post) { 889 @Override 890 public void onDataNetworkSetupRetry( 891 @NonNull DataSetupRetryEntry dataSetupRetryEntry) { 892 Objects.requireNonNull(dataSetupRetryEntry); 893 DataNetworkController.this.onDataNetworkSetupRetry(dataSetupRetryEntry); 894 } 895 @Override 896 public void onDataNetworkHandoverRetry( 897 @NonNull DataHandoverRetryEntry dataHandoverRetryEntry) { 898 Objects.requireNonNull(dataHandoverRetryEntry); 899 DataNetworkController.this 900 .onDataNetworkHandoverRetry(dataHandoverRetryEntry); 901 } 902 @Override 903 public void onDataNetworkHandoverRetryStopped( 904 @NonNull DataNetwork dataNetwork) { 905 Objects.requireNonNull(dataNetwork); 906 DataNetworkController.this.onDataNetworkHandoverRetryStopped(dataNetwork); 907 } 908 }); 909 mImsManager = mPhone.getContext().getSystemService(ImsManager.class); 910 mNetworkPolicyManager = mPhone.getContext().getSystemService(NetworkPolicyManager.class); 911 mTelecomManager = mPhone.getContext().getSystemService(TelecomManager.class); 912 913 // Use the raw one from ServiceStateTracker instead of the combined one from 914 // mPhone.getServiceState(). 915 mServiceState = mPhone.getServiceStateTracker().getServiceState(); 916 917 // Instead of calling onRegisterAllEvents directly from the constructor, send the event. 918 // The reason is that getImsPhone is null when we are still in the constructor here. 919 sendEmptyMessage(EVENT_REGISTER_ALL_EVENTS); 920 } 921 922 /** 923 * Called when needed to register for all events that data network controller is interested. 924 */ onRegisterAllEvents()925 private void onRegisterAllEvents() { 926 IntentFilter filter = new IntentFilter(); 927 filter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED); 928 filter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED); 929 mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); 930 931 mAccessNetworksManager.registerCallback(new AccessNetworksManagerCallback(this::post) { 932 @Override 933 public void onPreferredTransportChanged(@NetCapability int capability) { 934 int preferredTransport = mAccessNetworksManager 935 .getPreferredTransportByNetworkCapability(capability); 936 logl("onPreferredTransportChanged: " 937 + DataUtils.networkCapabilityToString(capability) + " preferred on " 938 + AccessNetworkConstants.transportTypeToString(preferredTransport)); 939 DataNetworkController.this.onEvaluatePreferredTransport(capability); 940 if (!hasMessages(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS)) { 941 sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 942 DataEvaluationReason.PREFERRED_TRANSPORT_CHANGED)); 943 } else { 944 log("onPreferredTransportChanged: Skipped evaluating unsatisfied network " 945 + "requests because another evaluation was already scheduled."); 946 } 947 } 948 }); 949 950 mNetworkPolicyManager.registerSubscriptionCallback(new SubscriptionCallback() { 951 @Override 952 public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { 953 if (mSubId != subId) return; 954 obtainMessage(EVENT_SUBSCRIPTION_PLANS_CHANGED, plans).sendToTarget(); 955 } 956 957 @Override 958 public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, 959 int[] networkTypes) { 960 if (mSubId != subId) return; 961 obtainMessage(EVENT_SUBSCRIPTION_OVERRIDE, overrideMask, overrideValue, 962 networkTypes).sendToTarget(); 963 } 964 }); 965 966 mPhone.getServiceStateTracker().registerForServiceStateChanged(this, 967 EVENT_SERVICE_STATE_CHANGED, null); 968 mDataConfigManager.registerCallback(new DataConfigManagerCallback(this::post) { 969 @Override 970 public void onCarrierConfigChanged() { 971 DataNetworkController.this.onCarrierConfigUpdated(); 972 } 973 @Override 974 public void onDeviceConfigChanged() { 975 DataNetworkController.this.onDeviceConfigUpdated(); 976 } 977 }); 978 mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this, 979 EVENT_PS_RESTRICT_ENABLED, null); 980 mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this, 981 EVENT_PS_RESTRICT_DISABLED, null); 982 mPhone.getServiceStateTracker().registerForAreaCodeChanged(this, EVENT_TAC_CHANGED, null); 983 mPhone.registerForEmergencyCallToggle(this, EVENT_EMERGENCY_CALL_CHANGED, null); 984 mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 985 .registerForServiceBindingChanged(this, EVENT_DATA_SERVICE_BINDING_CHANGED); 986 987 mPhone.getServiceStateTracker().registerForServiceStateChanged(this, 988 EVENT_SERVICE_STATE_CHANGED, null); 989 mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) 990 .registerForServiceBindingChanged(this, EVENT_DATA_SERVICE_BINDING_CHANGED); 991 992 mPhone.getContext().getSystemService(TelephonyRegistryManager.class) 993 .addOnSubscriptionsChangedListener(new OnSubscriptionsChangedListener() { 994 @Override 995 public void onSubscriptionsChanged() { 996 sendEmptyMessage(EVENT_SUBSCRIPTION_CHANGED); 997 } 998 }, this::post); 999 1000 // Register for call ended event for voice/data concurrent not supported case. It is 1001 // intended to only listen for events from the same phone as most of the telephony modules 1002 // are designed as per-SIM basis. For DSDS call ended on non-DDS sub, the frameworks relies 1003 // on service state on DDS sub change from out-of-service to in-service to trigger data 1004 // retry. 1005 mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_VOICE_CALL_ENDED, null); 1006 // Check null for devices not supporting FEATURE_TELEPHONY_IMS. 1007 if (mPhone.getImsPhone() != null) { 1008 mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded( 1009 this, EVENT_VOICE_CALL_ENDED, null); 1010 } 1011 mPhone.mCi.registerForSlicingConfigChanged(this, EVENT_SLICE_CONFIG_CHANGED, null); 1012 mPhone.mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null); 1013 1014 mPhone.getLinkBandwidthEstimator().registerCallback( 1015 new LinkBandwidthEstimatorCallback(this::post) { 1016 @Override 1017 public void onDataActivityChanged(@DataActivityType int dataActivity) { 1018 DataNetworkController.this.updateDataActivity(); 1019 } 1020 } 1021 ); 1022 } 1023 1024 @Override handleMessage(@onNull Message msg)1025 public void handleMessage(@NonNull Message msg) { 1026 AsyncResult ar; 1027 switch (msg.what) { 1028 case EVENT_REGISTER_ALL_EVENTS: 1029 onRegisterAllEvents(); 1030 break; 1031 case EVENT_ADD_NETWORK_REQUEST: 1032 onAddNetworkRequest((TelephonyNetworkRequest) msg.obj); 1033 break; 1034 case EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS: 1035 DataEvaluationReason reason = (DataEvaluationReason) msg.obj; 1036 onReevaluateUnsatisfiedNetworkRequests(reason); 1037 break; 1038 case EVENT_REEVALUATE_EXISTING_DATA_NETWORKS: 1039 reason = (DataEvaluationReason) msg.obj; 1040 onReevaluateExistingDataNetworks(reason); 1041 break; 1042 case EVENT_REMOVE_NETWORK_REQUEST: 1043 onRemoveNetworkRequest((TelephonyNetworkRequest) msg.obj); 1044 break; 1045 case EVENT_VOICE_CALL_ENDED: 1046 // In some cases we need to tear down network after call ends. For example, when 1047 // delay IMS tear down until call ends is turned on. 1048 sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 1049 DataEvaluationReason.VOICE_CALL_ENDED)); 1050 // Delay evaluating unsatisfied network requests. In temporary DDS switch case, it 1051 // takes some time to switch DDS after call end. We do not want to bring up network 1052 // before switch completes. 1053 sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 1054 DataEvaluationReason.VOICE_CALL_ENDED), 1055 REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_AFTER_CALL_END_DELAY_MILLIS); 1056 break; 1057 case EVENT_SLICE_CONFIG_CHANGED: 1058 sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 1059 DataEvaluationReason.SLICE_CONFIG_CHANGED)); 1060 break; 1061 case EVENT_SRVCC_STATE_CHANGED: 1062 ar = (AsyncResult) msg.obj; 1063 if (ar.exception == null) { 1064 onSrvccStateChanged((int[]) ar.result); 1065 } 1066 break; 1067 case EVENT_PS_RESTRICT_ENABLED: 1068 mPsRestricted = true; 1069 break; 1070 case EVENT_PS_RESTRICT_DISABLED: 1071 mPsRestricted = false; 1072 sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 1073 DataEvaluationReason.DATA_RESTRICTED_CHANGED)); 1074 break; 1075 case EVENT_TAC_CHANGED: 1076 // Re-evaluate unsatisfied network requests with some delays to let DataRetryManager 1077 // clears the throttling record. 1078 sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 1079 DataEvaluationReason.TAC_CHANGED), 1080 REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_TAC_CHANGED_DELAY_MILLIS); 1081 break; 1082 case EVENT_DATA_SERVICE_BINDING_CHANGED: 1083 ar = (AsyncResult) msg.obj; 1084 int transport = (int) ar.userObj; 1085 boolean bound = (boolean) ar.result; 1086 onDataServiceBindingChanged(transport, bound); 1087 break; 1088 case EVENT_SIM_STATE_CHANGED: 1089 int simState = msg.arg1; 1090 onSimStateChanged(simState); 1091 break; 1092 case EVENT_TEAR_DOWN_ALL_DATA_NETWORKS: 1093 onTearDownAllDataNetworks(msg.arg1); 1094 break; 1095 case EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK: 1096 DataNetworkControllerCallback callback = (DataNetworkControllerCallback) msg.obj; 1097 mDataNetworkControllerCallbacks.add(callback); 1098 // Notify upon registering if no data networks currently exist. 1099 if (mDataNetworkList.isEmpty()) { 1100 callback.invokeFromExecutor( 1101 () -> callback.onAnyDataNetworkExistingChanged(false)); 1102 } 1103 break; 1104 case EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK: 1105 mDataNetworkControllerCallbacks.remove((DataNetworkControllerCallback) msg.obj); 1106 break; 1107 case EVENT_SUBSCRIPTION_CHANGED: 1108 onSubscriptionChanged(); 1109 break; 1110 case EVENT_SERVICE_STATE_CHANGED: 1111 onServiceStateChanged(); 1112 break; 1113 case EVENT_EMERGENCY_CALL_CHANGED: 1114 if (mPhone.isInEcm()) { 1115 sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 1116 DataEvaluationReason.EMERGENCY_CALL_CHANGED)); 1117 } else { 1118 sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 1119 DataEvaluationReason.EMERGENCY_CALL_CHANGED)); 1120 } 1121 break; 1122 case EVENT_EVALUATE_PREFERRED_TRANSPORT: 1123 onEvaluatePreferredTransport(msg.arg1); 1124 break; 1125 case EVENT_SUBSCRIPTION_PLANS_CHANGED: 1126 SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj; 1127 log("Subscription plans changed: " + Arrays.toString(plans)); 1128 mSubscriptionPlans.clear(); 1129 mSubscriptionPlans.addAll(Arrays.asList(plans)); 1130 mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor( 1131 () -> cb.onSubscriptionPlanOverride())); 1132 break; 1133 case EVENT_SUBSCRIPTION_OVERRIDE: 1134 int overrideMask = msg.arg1; 1135 boolean override = msg.arg2 != 0; 1136 int[] networkTypes = (int[]) msg.obj; 1137 1138 if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED) { 1139 log("Unmetered subscription override: override=" + override 1140 + ", networkTypes=" + Arrays.stream(networkTypes) 1141 .mapToObj(TelephonyManager::getNetworkTypeName) 1142 .collect(Collectors.joining(","))); 1143 for (int networkType : networkTypes) { 1144 if (override) { 1145 mUnmeteredOverrideNetworkTypes.add(networkType); 1146 } else { 1147 mUnmeteredOverrideNetworkTypes.remove(networkType); 1148 } 1149 } 1150 mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor( 1151 () -> cb.onSubscriptionPlanOverride())); 1152 } else if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED) { 1153 log("Congested subscription override: override=" + override 1154 + ", networkTypes=" + Arrays.stream(networkTypes) 1155 .mapToObj(TelephonyManager::getNetworkTypeName) 1156 .collect(Collectors.joining(","))); 1157 for (int networkType : networkTypes) { 1158 if (override) { 1159 mCongestedOverrideNetworkTypes.add(networkType); 1160 } else { 1161 mCongestedOverrideNetworkTypes.remove(networkType); 1162 } 1163 } 1164 mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor( 1165 () -> cb.onSubscriptionPlanOverride())); 1166 } else { 1167 loge("Unknown override mask: " + overrideMask); 1168 } 1169 break; 1170 default: 1171 loge("Unexpected event " + msg.what); 1172 } 1173 } 1174 1175 /** 1176 * Add a network request, which is originated from the apps. Note that add a network request 1177 * is not necessarily setting up a {@link DataNetwork}. 1178 * 1179 * @param networkRequest Network request 1180 * 1181 */ addNetworkRequest(@onNull TelephonyNetworkRequest networkRequest)1182 public void addNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) { 1183 sendMessage(obtainMessage(EVENT_ADD_NETWORK_REQUEST, networkRequest)); 1184 } 1185 1186 /** 1187 * Called when a network request arrives data network controller. 1188 * 1189 * @param networkRequest The network request. 1190 */ onAddNetworkRequest(@onNull TelephonyNetworkRequest networkRequest)1191 private void onAddNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) { 1192 // To detect IMS back-to-back release-request anomaly event 1193 if (mLastImsOperationIsRelease) { 1194 mLastImsOperationIsRelease = false; 1195 if (Arrays.equals( 1196 mLastReleasedImsRequestCapabilities, networkRequest.getCapabilities()) 1197 && mImsThrottleCounter.addOccurrence()) { 1198 reportAnomaly(networkRequest.getNativeNetworkRequest().getRequestorPackageName() 1199 + " requested with same capabilities " 1200 + mImsThrottleCounter.getFrequencyString(), 1201 "ead6f8db-d2f2-4ed3-8da5-1d8560fe7daf"); 1202 } 1203 } 1204 if (!mAllNetworkRequestList.add(networkRequest)) { 1205 loge("onAddNetworkRequest: Duplicate network request. " + networkRequest); 1206 return; 1207 } 1208 log("onAddNetworkRequest: added " + networkRequest); 1209 onSatisfyNetworkRequest(networkRequest); 1210 } 1211 1212 /** 1213 * Called when attempting to satisfy a network request. If after evaluation, the network 1214 * request is determined that can be satisfied, the data network controller will establish 1215 * the data network. If the network request can't be satisfied, it will remain in the 1216 * unsatisfied pool until the environment changes. 1217 * 1218 * @param networkRequest The network request to be satisfied. 1219 */ onSatisfyNetworkRequest(@onNull TelephonyNetworkRequest networkRequest)1220 private void onSatisfyNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) { 1221 if (networkRequest.getState() == TelephonyNetworkRequest.REQUEST_STATE_SATISFIED) { 1222 logv("Already satisfied. " + networkRequest); 1223 return; 1224 } 1225 1226 // Check if there is any existing data network that can satisfy the network request, and 1227 // attempt to attach if possible. 1228 if (findCompatibleDataNetworkAndAttach(networkRequest)) { 1229 return; 1230 } 1231 1232 // If no data network can satisfy the requests, then start the evaluation process. Since 1233 // all the requests in the list have the same capabilities, we can only evaluate one 1234 // of them. 1235 DataEvaluation evaluation = evaluateNetworkRequest(networkRequest, 1236 DataEvaluationReason.NEW_REQUEST); 1237 if (!evaluation.containsDisallowedReasons()) { 1238 DataProfile dataProfile = evaluation.getCandidateDataProfile(); 1239 if (dataProfile != null) { 1240 setupDataNetwork(dataProfile, null, 1241 evaluation.getDataAllowedReason()); 1242 } 1243 } else if (evaluation.contains(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK)) { 1244 // Re-evaluate the existing data networks. If this request's priority is higher than 1245 // the existing data network, the data network will be torn down so this request will 1246 // get a chance to be satisfied. 1247 sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 1248 DataEvaluationReason.SINGLE_DATA_NETWORK_ARBITRATION)); 1249 } 1250 } 1251 1252 /** 1253 * Attempt to attach a network request to an existing data network that can satisfy the 1254 * network request. 1255 * 1256 * @param networkRequest The network request to attach. 1257 * 1258 * @return {@code false} if can't find the data network to to satisfy the network request. 1259 * {@code true} if the network request has been scheduled to attach to the data network. 1260 * If attach succeeds, the network request's state will be set to 1261 * {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed, 1262 * {@link #onAttachNetworkRequestsFailed(DataNetwork, NetworkRequestList)} will be invoked. 1263 */ findCompatibleDataNetworkAndAttach( @onNull TelephonyNetworkRequest networkRequest)1264 private boolean findCompatibleDataNetworkAndAttach( 1265 @NonNull TelephonyNetworkRequest networkRequest) { 1266 return findCompatibleDataNetworkAndAttach(new NetworkRequestList(networkRequest)); 1267 } 1268 1269 /** 1270 * Attempt to attach a network request list to an existing data network that can satisfy all the 1271 * network requests. Note this method does not support partial attach (i.e. Only attach some 1272 * of the satisfiable requests to the network). All requests must be satisfied so they can be 1273 * attached. 1274 * 1275 * @param requestList The network request list to attach. It is expected that every network 1276 * request in this list has the same network capabilities. 1277 * 1278 * @return {@code false} if can't find the data network to to satisfy the network requests, even 1279 * if only one of network request can't be satisfied. {@code true} if the network request 1280 * has been scheduled to attach to the data network. If attach succeeds, the network request's 1281 * state will be set to 1282 * {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed, 1283 * {@link #onAttachNetworkRequestsFailed(DataNetwork, NetworkRequestList)} will be invoked. 1284 */ findCompatibleDataNetworkAndAttach(@onNull NetworkRequestList requestList)1285 private boolean findCompatibleDataNetworkAndAttach(@NonNull NetworkRequestList requestList) { 1286 // Try to find a data network that can satisfy all the network requests. 1287 for (DataNetwork dataNetwork : mDataNetworkList) { 1288 TelephonyNetworkRequest networkRequest = requestList.stream() 1289 .filter(request -> !request.canBeSatisfiedBy( 1290 dataNetwork.getNetworkCapabilities())) 1291 .findAny() 1292 .orElse(null); 1293 // If found any request that can't be satisfied by this data network, continue to try 1294 // next data network. We must find a data network that can satisfy all the provided 1295 // network requests. 1296 if (networkRequest != null) { 1297 continue; 1298 } 1299 1300 // When reaching here, it means this data network can satisfy all the network requests. 1301 logv("Found a compatible data network " + dataNetwork + ". Attaching " 1302 + requestList); 1303 return dataNetwork.attachNetworkRequests(requestList); 1304 } 1305 return false; 1306 } 1307 1308 /** 1309 * @param ss The service state to be checked 1310 * @param transport The transport is used to determine the data registration state 1311 * 1312 * @return {@code true} if data is in service or if voice is in service on legacy CS 1313 * connections (2G/3G) on the non-DDS. In those cases we attempt to attach PS. We don't try for 1314 * newer RAT because for those PS attach already occurred. 1315 */ serviceStateAllowsPSAttach(@onNull ServiceState ss, @TransportType int transport)1316 private boolean serviceStateAllowsPSAttach(@NonNull ServiceState ss, 1317 @TransportType int transport) { 1318 // Use the data registration state from the modem instead of the current data registration 1319 // state, which can be overridden. 1320 int nriRegState = getDataRegistrationState(ss, transport); 1321 if (nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME 1322 || nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) return true; 1323 1324 // If data is OOS as this device slot is not modem preferred(i.e. not active for internet), 1325 // attempt to attach PS on 2G/3G if CS connection is available. 1326 return ss.getVoiceRegState() == ServiceState.STATE_IN_SERVICE 1327 && mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId() 1328 && isLegacyCs(ss.getVoiceNetworkType()); 1329 } 1330 1331 /** 1332 * @param voiceNetworkType The voice network type to be checked. 1333 * @return {@code true} if the network type is on legacy CS connection. 1334 */ isLegacyCs(@etworkType int voiceNetworkType)1335 private boolean isLegacyCs(@NetworkType int voiceNetworkType) { 1336 int voiceAccessNetworkType = DataUtils.networkTypeToAccessNetworkType(voiceNetworkType); 1337 return voiceAccessNetworkType == AccessNetworkType.GERAN 1338 || voiceAccessNetworkType == AccessNetworkType.UTRAN 1339 || voiceAccessNetworkType == AccessNetworkType.CDMA2000; 1340 } 1341 1342 /** 1343 * @return {@code true} if the network only allows single data network at one time. 1344 */ isOnlySingleDataNetworkAllowed(@ransportType int transport)1345 private boolean isOnlySingleDataNetworkAllowed(@TransportType int transport) { 1346 if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) return false; 1347 1348 return mDataConfigManager.getNetworkTypesOnlySupportSingleDataNetwork() 1349 .contains(getDataNetworkType(transport)); 1350 } 1351 1352 /** 1353 * @param capabilities The Network Capabilities to be checked. 1354 * @return {@code true} if the capabilities contain any capability that's exempt from the single 1355 * PDN rule. 1356 */ hasCapabilityExemptsFromSinglePdnRule(@etCapability int[] capabilities)1357 private boolean hasCapabilityExemptsFromSinglePdnRule(@NetCapability int[] capabilities) { 1358 Set<Integer> exemptCapabilities = 1359 mDataConfigManager.getCapabilitiesExemptFromSingleDataNetwork(); 1360 return Arrays.stream(capabilities).anyMatch(exemptCapabilities::contains); 1361 } 1362 1363 /** 1364 * Evaluate if telephony frameworks would allow data setup for internet in current environment. 1365 * 1366 * @return {@code true} if the environment is allowed for internet data. {@code false} if not 1367 * allowed. For example, if SIM is absent, or airplane mode is on, then data is NOT allowed. 1368 * This API does not reflect the currently internet data network status. It's possible there is 1369 * no internet data due to weak cellular signal or network side issue, but internet data is 1370 * still allowed in this case. 1371 */ isInternetDataAllowed()1372 public boolean isInternetDataAllowed() { 1373 TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest( 1374 new NetworkRequest.Builder() 1375 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 1376 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) 1377 .build(), mPhone); 1378 // If one of the existing networks can satisfy the internet request, then internet is 1379 // allowed. 1380 if (mDataNetworkList.stream().anyMatch(dataNetwork -> internetRequest.canBeSatisfiedBy( 1381 dataNetwork.getNetworkCapabilities()))) { 1382 return true; 1383 } 1384 1385 // If no existing network can satisfy the request, then check if we can possibly setup 1386 // the internet network. 1387 1388 DataEvaluation evaluation = evaluateNetworkRequest(internetRequest, 1389 DataEvaluationReason.EXTERNAL_QUERY); 1390 if (evaluation.containsOnly(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK)) { 1391 // If the only failed reason is only single network allowed, then check if the request 1392 // can trump the current network. 1393 return internetRequest.getPriority() > mDataNetworkList.stream() 1394 .map(DataNetwork::getPriority) 1395 .max(Comparator.comparing(Integer::valueOf)) 1396 .orElse(0); 1397 } 1398 return !evaluation.containsDisallowedReasons(); 1399 } 1400 1401 /** 1402 * @return {@code true} if internet is unmetered. 1403 */ isInternetUnmetered()1404 public boolean isInternetUnmetered() { 1405 return mDataNetworkList.stream() 1406 .filter(dataNetwork -> !dataNetwork.isConnecting() && !dataNetwork.isDisconnected()) 1407 .filter(DataNetwork::isInternetSupported) 1408 .allMatch(dataNetwork -> dataNetwork.getNetworkCapabilities() 1409 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) 1410 || dataNetwork.getNetworkCapabilities() 1411 .hasCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 1412 } 1413 1414 /** 1415 * @return {@code true} if all data networks are disconnected. 1416 */ areAllDataDisconnected()1417 public boolean areAllDataDisconnected() { 1418 if (!mDataNetworkList.isEmpty()) { 1419 log("areAllDataDisconnected false due to: " + mDataNetworkList.stream() 1420 .map(DataNetwork::name).collect(Collectors.joining(", "))); 1421 } 1422 return mDataNetworkList.isEmpty(); 1423 } 1424 1425 /** 1426 * @return List of the reasons why internet data is not allowed. An empty list if internet 1427 * is allowed. 1428 */ getInternetDataDisallowedReasons()1429 public @NonNull List<DataDisallowedReason> getInternetDataDisallowedReasons() { 1430 TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest( 1431 new NetworkRequest.Builder() 1432 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 1433 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) 1434 .build(), mPhone); 1435 DataEvaluation evaluation = evaluateNetworkRequest(internetRequest, 1436 DataEvaluationReason.EXTERNAL_QUERY); 1437 return evaluation.getDataDisallowedReasons(); 1438 } 1439 1440 /** 1441 * Evaluate a network request. The goal is to find a suitable {@link DataProfile} that can be 1442 * used to setup the data network. 1443 * 1444 * @param networkRequest The network request to evaluate. 1445 * @param reason The reason for evaluation. 1446 * @return The data evaluation result. 1447 */ evaluateNetworkRequest( @onNull TelephonyNetworkRequest networkRequest, DataEvaluationReason reason)1448 private @NonNull DataEvaluation evaluateNetworkRequest( 1449 @NonNull TelephonyNetworkRequest networkRequest, DataEvaluationReason reason) { 1450 DataEvaluation evaluation = new DataEvaluation(reason); 1451 int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability( 1452 networkRequest.getApnTypeNetworkCapability()); 1453 1454 // Bypass all checks for emergency network request. 1455 if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) { 1456 evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST); 1457 evaluation.setCandidateDataProfile(mDataProfileManager.getDataProfileForNetworkRequest( 1458 networkRequest, getDataNetworkType(transport), true)); 1459 networkRequest.setEvaluation(evaluation); 1460 log(evaluation.toString()); 1461 return evaluation; 1462 } 1463 1464 if (!serviceStateAllowsPSAttach(mServiceState, transport)) { 1465 evaluation.addDataDisallowedReason(DataDisallowedReason.NOT_IN_SERVICE); 1466 } 1467 1468 // Check SIM state 1469 if (mSimState != TelephonyManager.SIM_STATE_LOADED) { 1470 evaluation.addDataDisallowedReason(DataDisallowedReason.SIM_NOT_READY); 1471 } 1472 1473 // Check if carrier specific config is loaded or not. 1474 if (!mDataConfigManager.isConfigCarrierSpecific()) { 1475 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_CONFIG_NOT_READY); 1476 } 1477 1478 // Check CS call state and see if concurrent voice/data is allowed. 1479 if (mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE 1480 && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { 1481 evaluation.addDataDisallowedReason( 1482 DataDisallowedReason.CONCURRENT_VOICE_DATA_NOT_ALLOWED); 1483 } 1484 1485 // Check VoPS support 1486 if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1487 && networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) { 1488 NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo( 1489 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1490 if (nri != null) { 1491 DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); 1492 if (dsri != null && dsri.getVopsSupportInfo() != null 1493 && !dsri.getVopsSupportInfo().isVopsSupported()) { 1494 evaluation.addDataDisallowedReason(DataDisallowedReason.VOPS_NOT_SUPPORTED); 1495 } 1496 } 1497 } 1498 1499 // Check if default data is selected. 1500 if (!SubscriptionManager.isValidSubscriptionId( 1501 SubscriptionManager.getDefaultDataSubscriptionId())) { 1502 evaluation.addDataDisallowedReason(DataDisallowedReason.DEFAULT_DATA_UNSELECTED); 1503 } 1504 1505 // Check if data roaming is disabled. 1506 if (mServiceState.getDataRoaming() && !mDataSettingsManager.isDataRoamingEnabled()) { 1507 evaluation.addDataDisallowedReason(DataDisallowedReason.ROAMING_DISABLED); 1508 } 1509 1510 // Check if data is restricted by the cellular network. 1511 if (mPsRestricted && transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1512 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_RESTRICTED_BY_NETWORK); 1513 } 1514 1515 // Check if there are pending tear down all networks request. 1516 if (mPendingTearDownAllNetworks) { 1517 evaluation.addDataDisallowedReason(DataDisallowedReason.PENDING_TEAR_DOWN_ALL); 1518 } 1519 1520 // Check if the request is preferred on cellular and radio is/will be turned off. 1521 // We are using getDesiredPowerState() instead of isRadioOn() because we also don't want 1522 // to setup data network when radio power is about to be turned off. 1523 if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1524 && (!mPhone.getServiceStateTracker().getDesiredPowerState() 1525 || mPhone.mCi.getRadioState() != TelephonyManager.RADIO_POWER_ON)) { 1526 evaluation.addDataDisallowedReason(DataDisallowedReason.RADIO_POWER_OFF); 1527 } 1528 1529 // Check if radio is/will be turned off by carrier. 1530 if (!mPhone.getServiceStateTracker().getPowerStateFromCarrier()) { 1531 evaluation.addDataDisallowedReason(DataDisallowedReason.RADIO_DISABLED_BY_CARRIER); 1532 } 1533 1534 // Check if the underlying data service is bound. 1535 if (!mDataServiceBound.get(transport)) { 1536 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_SERVICE_NOT_READY); 1537 } 1538 1539 // Check if device is in CDMA ECBM 1540 if (mPhone.isInCdmaEcm()) { 1541 evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE); 1542 } 1543 1544 // Check if only one data network is allowed. 1545 if (isOnlySingleDataNetworkAllowed(transport) 1546 && !hasCapabilityExemptsFromSinglePdnRule(networkRequest.getCapabilities())) { 1547 // if exists not-exempt network. 1548 if (mDataNetworkList.stream() 1549 .anyMatch(dataNetwork -> !hasCapabilityExemptsFromSinglePdnRule( 1550 dataNetwork.getNetworkCapabilities().getCapabilities()))) { 1551 evaluation.addDataDisallowedReason( 1552 DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK); 1553 } 1554 } 1555 1556 if (mDataSettingsManager.isDataInitialized()) { 1557 if (!mDataSettingsManager.isDataEnabled(DataUtils.networkCapabilityToApnType( 1558 networkRequest.getApnTypeNetworkCapability()))) { 1559 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_DISABLED); 1560 } 1561 } else { 1562 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_SETTINGS_NOT_READY); 1563 } 1564 1565 // Check whether to allow data in certain situations if data is disallowed for soft reasons 1566 if (!evaluation.containsDisallowedReasons()) { 1567 evaluation.addDataAllowedReason(DataAllowedReason.NORMAL); 1568 1569 if (!mDataSettingsManager.isDataEnabled() 1570 && networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS) 1571 && mDataSettingsManager.isMobileDataPolicyEnabled(TelephonyManager 1572 .MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED)) { 1573 // We reach here when data is disabled, but MMS always-allowed is enabled. 1574 // (Note that isDataEnabled(ApnSetting.TYPE_MMS) returns true in this case, so it 1575 // would not generate any soft disallowed reason. We need to explicitly handle it.) 1576 evaluation.addDataAllowedReason(DataAllowedReason.MMS_REQUEST); 1577 } 1578 } else if (!evaluation.containsHardDisallowedReasons()) { 1579 if ((mTelecomManager.isInEmergencyCall() || mPhone.isInEcm()) 1580 && networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { 1581 // Check if it's SUPL during emergency call. 1582 evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_SUPL); 1583 } else if (!networkRequest.hasCapability( 1584 NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 1585 && isValidRestrictedRequest(networkRequest)) { 1586 // Check if request is restricted and not for tethering, which always comes with 1587 // a restricted network request. 1588 evaluation.addDataAllowedReason(DataAllowedReason.RESTRICTED_REQUEST); 1589 } else if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1590 // Check if request is unmetered (WiFi or unmetered APN). 1591 evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE); 1592 } else if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1593 if (!networkRequest.isMeteredRequest()) { 1594 evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE); 1595 } 1596 } 1597 } 1598 1599 // Check if there is any compatible data profile 1600 int networkType = getDataNetworkType(transport); 1601 if (networkType == TelephonyManager.NETWORK_TYPE_UNKNOWN 1602 && transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1603 // reach here when data is OOS but serviceStateAllowsPSAttach == true, so we adopt the 1604 // voice RAT to select data profile 1605 networkType = mServiceState.getVoiceNetworkType(); 1606 } 1607 DataProfile dataProfile = mDataProfileManager 1608 .getDataProfileForNetworkRequest(networkRequest, networkType, 1609 // If the evaluation is due to environmental changes, then we should ignore 1610 // the permanent failure reached earlier. 1611 reason.isConditionBased()); 1612 if (dataProfile == null) { 1613 evaluation.addDataDisallowedReason(DataDisallowedReason.NO_SUITABLE_DATA_PROFILE); 1614 } else if (// Check for new requests if we already self-scheduled(as opposed to modem 1615 // demanded) retry for similar requests. 1616 reason == DataEvaluationReason.NEW_REQUEST 1617 && mDataRetryManager.isSimilarNetworkRequestRetryScheduled( 1618 networkRequest, transport)) { 1619 evaluation.addDataDisallowedReason(DataDisallowedReason.RETRY_SCHEDULED); 1620 } else if (mDataRetryManager.isDataProfileThrottled(dataProfile, transport)) { 1621 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_THROTTLED); 1622 } 1623 1624 if (!evaluation.containsDisallowedReasons()) { 1625 evaluation.setCandidateDataProfile(dataProfile); 1626 } 1627 1628 networkRequest.setEvaluation(evaluation); 1629 // EXTERNAL_QUERY generates too many log spam. 1630 if (reason != DataEvaluationReason.EXTERNAL_QUERY) { 1631 log(evaluation.toString() + ", network type=" 1632 + TelephonyManager.getNetworkTypeName(getDataNetworkType(transport)) 1633 + ", reg state=" 1634 + NetworkRegistrationInfo.registrationStateToString( 1635 getDataRegistrationState(mServiceState, transport)) 1636 + ", " + networkRequest); 1637 } 1638 return evaluation; 1639 } 1640 1641 /** 1642 * @return The grouped unsatisfied network requests. The network requests that have the same 1643 * network capabilities is grouped into one {@link NetworkRequestList}. 1644 */ getGroupedUnsatisfiedNetworkRequests()1645 private @NonNull List<NetworkRequestList> getGroupedUnsatisfiedNetworkRequests() { 1646 NetworkRequestList networkRequestList = new NetworkRequestList(); 1647 for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) { 1648 if (networkRequest.getState() == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED) { 1649 networkRequestList.add(networkRequest); 1650 } 1651 } 1652 return DataUtils.getGroupedNetworkRequestList(networkRequestList); 1653 } 1654 1655 /** 1656 * Called when it's needed to evaluate all unsatisfied network requests. 1657 * 1658 * @param reason The reason for evaluation. 1659 */ onReevaluateUnsatisfiedNetworkRequests(@onNull DataEvaluationReason reason)1660 private void onReevaluateUnsatisfiedNetworkRequests(@NonNull DataEvaluationReason reason) { 1661 // First, try to group similar network request together. 1662 List<NetworkRequestList> networkRequestLists = getGroupedUnsatisfiedNetworkRequests(); 1663 log("Re-evaluating " + networkRequestLists.stream().mapToInt(List::size).sum() 1664 + " unsatisfied network requests in " + networkRequestLists.size() 1665 + " groups, " + networkRequestLists.stream().map( 1666 requestList -> DataUtils.networkCapabilitiesToString( 1667 requestList.get(0).getCapabilities())) 1668 .collect(Collectors.joining(", ")) + " due to " + reason); 1669 1670 // Second, see if any existing network can satisfy those network requests. 1671 for (NetworkRequestList requestList : networkRequestLists) { 1672 if (findCompatibleDataNetworkAndAttach(requestList)) { 1673 continue; 1674 } 1675 1676 // If no data network can satisfy the requests, then start the evaluation process. Since 1677 // all the requests in the list have the same capabilities, we can only evaluate one 1678 // of them. 1679 DataEvaluation evaluation = evaluateNetworkRequest(requestList.get(0), reason); 1680 if (!evaluation.containsDisallowedReasons()) { 1681 DataProfile dataProfile = evaluation.getCandidateDataProfile(); 1682 if (dataProfile != null) { 1683 setupDataNetwork(dataProfile, null, 1684 evaluation.getDataAllowedReason()); 1685 } 1686 } 1687 } 1688 } 1689 1690 /** 1691 * Evaluate an existing data network to see if it is still allowed to exist. For example, if 1692 * RAT changes from LTE to UMTS, an IMS data network is not allowed anymore. Or when SIM is 1693 * removal, all data networks (except emergency) should be torn down. 1694 * 1695 * @param dataNetwork The data network to evaluate. 1696 * @param reason The reason for evaluation. 1697 * 1698 * @return The data evaluation result. 1699 */ evaluateDataNetwork(@onNull DataNetwork dataNetwork, @NonNull DataEvaluationReason reason)1700 private @NonNull DataEvaluation evaluateDataNetwork(@NonNull DataNetwork dataNetwork, 1701 @NonNull DataEvaluationReason reason) { 1702 DataEvaluation evaluation = new DataEvaluation(reason); 1703 // Bypass all checks for emergency data network. 1704 if (dataNetwork.getNetworkCapabilities().hasCapability( 1705 NetworkCapabilities.NET_CAPABILITY_EIMS)) { 1706 evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST); 1707 log(evaluation.toString()); 1708 return evaluation; 1709 } 1710 1711 // Check SIM state 1712 if (mSimState != TelephonyManager.SIM_STATE_LOADED) { 1713 evaluation.addDataDisallowedReason(DataDisallowedReason.SIM_NOT_READY); 1714 } 1715 1716 // Check if device is in CDMA ECBM 1717 if (mPhone.isInCdmaEcm()) { 1718 evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE); 1719 } 1720 1721 // Check if there are other network that has higher priority, and only single data network 1722 // is allowed. 1723 if (isOnlySingleDataNetworkAllowed(dataNetwork.getTransport()) 1724 && !hasCapabilityExemptsFromSinglePdnRule( 1725 dataNetwork.getNetworkCapabilities().getCapabilities())) { 1726 // If there is network request that has higher priority than this data network, then 1727 // tear down the network, regardless that network request is satisfied or not. 1728 if (mAllNetworkRequestList.stream() 1729 .filter(request -> dataNetwork.getTransport() 1730 == mAccessNetworksManager.getPreferredTransportByNetworkCapability( 1731 request.getApnTypeNetworkCapability())) 1732 .filter(request 1733 -> !hasCapabilityExemptsFromSinglePdnRule(request.getCapabilities())) 1734 .anyMatch(request -> request.getPriority() > dataNetwork.getPriority())) { 1735 evaluation.addDataDisallowedReason( 1736 DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK); 1737 } else { 1738 log("evaluateDataNetwork: " + dataNetwork + " has the highest priority. " 1739 + "No need to tear down"); 1740 } 1741 } 1742 1743 boolean vopsIsRequired = dataNetwork.hasNetworkCapabilityInNetworkRequests( 1744 NetworkCapabilities.NET_CAPABILITY_MMTEL); 1745 1746 // Check an active call relying on this network and config for "delay tear down due to vops 1747 // call" is enabled. 1748 if (dataNetwork.shouldDelayImsTearDownDueToInCall()) { 1749 if (vopsIsRequired) { 1750 log("Ignored VoPS check due to delay IMS tear down until call ends."); 1751 } 1752 } else { 1753 // Reach here means we should ignore active calls even if there are any. 1754 1755 // Check if VoPS requirement is met. 1756 if (vopsIsRequired) { 1757 if (dataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1758 NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo( 1759 NetworkRegistrationInfo.DOMAIN_PS, 1760 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1761 if (nri != null) { 1762 DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); 1763 if (dsri != null && dsri.getVopsSupportInfo() != null 1764 && !dsri.getVopsSupportInfo().isVopsSupported() 1765 && !mDataConfigManager.shouldKeepNetworkUpInNonVops()) { 1766 evaluation.addDataDisallowedReason( 1767 DataDisallowedReason.VOPS_NOT_SUPPORTED); 1768 } 1769 } 1770 } 1771 } 1772 1773 // Check if handover retry stopped and preferred transport still not matched. 1774 int preferredTransport = mAccessNetworksManager 1775 .getPreferredTransportByNetworkCapability( 1776 dataNetwork.getApnTypeNetworkCapability()); 1777 if (preferredTransport != dataNetwork.getTransport() 1778 && mDataRetryManager.isDataNetworkHandoverRetryStopped(dataNetwork)) { 1779 evaluation.addDataDisallowedReason(DataDisallowedReason.HANDOVER_RETRY_STOPPED); 1780 } 1781 } 1782 1783 // Check if data is disabled 1784 boolean dataDisabled = !mDataSettingsManager.isDataEnabled(); 1785 1786 // Check if data roaming is disabled 1787 if (mServiceState.getDataRoaming() && !mDataSettingsManager.isDataRoamingEnabled()) { 1788 evaluation.addDataDisallowedReason(DataDisallowedReason.ROAMING_DISABLED); 1789 } 1790 1791 // Check if current data network type is allowed by the data profile. Use the lingering 1792 // network type. Some data network is allowed to create on certain RATs, but can linger 1793 // to extended RATs. For example, IMS is allowed to be created on LTE only, but can 1794 // extend its life cycle to 3G. 1795 int networkType = getDataNetworkType(dataNetwork.getTransport()); 1796 DataProfile dataProfile = dataNetwork.getDataProfile(); 1797 if (dataProfile.getApnSetting() != null) { 1798 // Check if data is disabled for the APN type 1799 dataDisabled = !mDataSettingsManager.isDataEnabled( 1800 DataUtils.networkCapabilityToApnType( 1801 dataNetwork.getApnTypeNetworkCapability())); 1802 1803 // Sometimes network temporarily OOS and network type becomes UNKNOWN. We don't 1804 // tear down network in that case. 1805 if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN 1806 && !dataProfile.getApnSetting().canSupportLingeringNetworkType(networkType)) { 1807 log("networkType=" + TelephonyManager.getNetworkTypeName(networkType) 1808 + ", networkTypeBitmask=" 1809 + TelephonyManager.convertNetworkTypeBitmaskToString( 1810 dataProfile.getApnSetting().getNetworkTypeBitmask()) 1811 + ", lingeringNetworkTypeBitmask=" 1812 + TelephonyManager.convertNetworkTypeBitmaskToString( 1813 dataProfile.getApnSetting().getLingeringNetworkTypeBitmask())); 1814 evaluation.addDataDisallowedReason( 1815 DataDisallowedReason.DATA_NETWORK_TYPE_NOT_ALLOWED); 1816 } 1817 } 1818 1819 if (dataDisabled) { 1820 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_DISABLED); 1821 } 1822 1823 // Check if the data profile is still compatible, sometimes the users can remove it from the 1824 // APN editor. If some of the important fields are changed in APN settings, we need to 1825 // tear down the network. Note traffic descriptor from the data profile will not be checked. 1826 if (!mDataProfileManager.isDataProfileCompatible(dataProfile)) { 1827 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_PROFILE_INVALID); 1828 } 1829 1830 // If users switch preferred profile in APN editor, we need to tear down network. 1831 if (dataNetwork.isInternetSupported() 1832 && !mDataProfileManager.isDataProfilePreferred(dataProfile) 1833 && mDataProfileManager.canPreferredDataProfileSatisfy( 1834 dataNetwork.getAttachedNetworkRequestList())) { 1835 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_PROFILE_NOT_PREFERRED); 1836 } 1837 1838 // Check whether if there are any reason we should tear down the network. 1839 if (!evaluation.containsDisallowedReasons()) { 1840 // The data is allowed in the current condition. 1841 evaluation.addDataAllowedReason(DataAllowedReason.NORMAL); 1842 } else if (!evaluation.containsHardDisallowedReasons()) { 1843 // If there are reasons we should tear down the network, check if those are hard reasons 1844 // or soft reasons. In some scenarios, we can make exceptions if they are soft 1845 // disallowed reasons. 1846 if ((mTelecomManager.isInEmergencyCall() || mPhone.isInEcm()) 1847 && dataNetwork.isEmergencySupl()) { 1848 // Check if it's SUPL during emergency call. 1849 evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_SUPL); 1850 } else if (!dataNetwork.getNetworkCapabilities().hasCapability( 1851 NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 1852 && dataNetwork.getAttachedNetworkRequestList().stream() 1853 .allMatch(this::isValidRestrictedRequest)) { 1854 // Check if request is restricted and there are no exceptional requests attached to 1855 // the network. 1856 evaluation.addDataAllowedReason(DataAllowedReason.RESTRICTED_REQUEST); 1857 } else if (dataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1858 // Check if request is unmetered (WiFi or unmetered APN) 1859 evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE); 1860 } else { 1861 boolean unmeteredNetwork = !mDataConfigManager.isAnyMeteredCapability( 1862 dataNetwork.getNetworkCapabilities() 1863 .getCapabilities(), mServiceState.getDataRoaming()); 1864 if (unmeteredNetwork) { 1865 evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE); 1866 } 1867 } 1868 } 1869 1870 // Check if we allow additional lingering for active VoPS call network if 1871 // a. this network is SRVCC handover in progress 1872 // or b. "delay tear down due to active VoPS call" is enabled 1873 boolean isInSrvcc = vopsIsRequired && mIsSrvccHandoverInProcess; 1874 if (evaluation.containsOnly(DataDisallowedReason.DATA_NETWORK_TYPE_NOT_ALLOWED) 1875 && (dataNetwork.shouldDelayImsTearDownDueToInCall() || isInSrvcc)) { 1876 evaluation.addDataAllowedReason(DataAllowedReason.IN_VOICE_CALL); 1877 } 1878 1879 log("Evaluated " + dataNetwork + ", " + evaluation); 1880 return evaluation; 1881 } 1882 1883 /** 1884 * tethering and enterprise capabilities are not respected as restricted requests. For a request 1885 * with these capabilities, any soft disallowed reasons are honored. 1886 * @param networkRequest The network request to evaluate. 1887 * @return {@code true} if the request doesn't contain any exceptional capabilities, its 1888 * restricted capability, if any, is respected. 1889 */ isValidRestrictedRequest(@onNull TelephonyNetworkRequest networkRequest)1890 private boolean isValidRestrictedRequest(@NonNull TelephonyNetworkRequest networkRequest) { 1891 return !(networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN) 1892 || networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)); 1893 } 1894 1895 /** 1896 * Called when needed to re-evaluate existing data networks and tear down networks if needed. 1897 * 1898 * @param reason The reason for this data evaluation. 1899 */ onReevaluateExistingDataNetworks(@onNull DataEvaluationReason reason)1900 private void onReevaluateExistingDataNetworks(@NonNull DataEvaluationReason reason) { 1901 if (mDataNetworkList.isEmpty()) { 1902 log("onReevaluateExistingDataNetworks: No existing data networks to re-evaluate."); 1903 return; 1904 } 1905 log("Re-evaluating " + mDataNetworkList.size() + " existing data networks due to " 1906 + reason); 1907 for (DataNetwork dataNetwork : mDataNetworkList) { 1908 if (dataNetwork.isConnecting() || dataNetwork.isConnected()) { 1909 DataEvaluation dataEvaluation = evaluateDataNetwork(dataNetwork, reason); 1910 if (dataEvaluation.containsDisallowedReasons()) { 1911 tearDownGracefully(dataNetwork, getTearDownReason(dataEvaluation)); 1912 } 1913 } 1914 } 1915 } 1916 1917 /** 1918 * Evaluate if it is allowed to handover the data network between IWLAN and cellular. Some 1919 * carriers do not allow handover in certain conditions. 1920 * 1921 * @param dataNetwork The data network to be handover. 1922 * @return The evaluation result. 1923 * 1924 * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY 1925 */ evaluateDataNetworkHandover(@onNull DataNetwork dataNetwork)1926 private @NonNull DataEvaluation evaluateDataNetworkHandover(@NonNull DataNetwork dataNetwork) { 1927 DataEvaluation dataEvaluation = new DataEvaluation(DataEvaluationReason.DATA_HANDOVER); 1928 if (!dataNetwork.isConnecting() && !dataNetwork.isConnected()) { 1929 dataEvaluation.addDataDisallowedReason(DataDisallowedReason.ILLEGAL_STATE); 1930 return dataEvaluation; 1931 } 1932 1933 // If enhanced handover check is enabled, perform extra checks. 1934 if (mDataConfigManager.isEnhancedIwlanHandoverCheckEnabled()) { 1935 int targetTransport = DataUtils.getTargetTransport(dataNetwork.getTransport()); 1936 NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo( 1937 NetworkRegistrationInfo.DOMAIN_PS, targetTransport); 1938 if (nri != null) { 1939 // Check if OOS on target transport. 1940 if (!nri.isInService()) { 1941 dataEvaluation.addDataDisallowedReason(DataDisallowedReason.NOT_IN_SERVICE); 1942 } 1943 1944 // Check if VoPS is required, but the target transport is non-VoPS. 1945 NetworkRequestList networkRequestList = 1946 dataNetwork.getAttachedNetworkRequestList(); 1947 if (networkRequestList.stream().anyMatch(request 1948 -> request.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL))) { 1949 DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); 1950 // Check if the network is non-VoPS. 1951 if (dsri != null && dsri.getVopsSupportInfo() != null 1952 && !dsri.getVopsSupportInfo().isVopsSupported() 1953 && !mDataConfigManager.shouldKeepNetworkUpInNonVops()) { 1954 dataEvaluation.addDataDisallowedReason( 1955 DataDisallowedReason.VOPS_NOT_SUPPORTED); 1956 } 1957 } 1958 1959 if (dataEvaluation.containsDisallowedReasons()) { 1960 return dataEvaluation; 1961 } 1962 } 1963 } 1964 1965 if (mDataConfigManager.isIwlanHandoverPolicyEnabled()) { 1966 List<HandoverRule> handoverRules = mDataConfigManager.getHandoverRules(); 1967 1968 int sourceNetworkType = getDataNetworkType(dataNetwork.getTransport()); 1969 if (sourceNetworkType == TelephonyManager.NETWORK_TYPE_UNKNOWN) { 1970 // Using the data network type stored in the data network. We 1971 // cache the last known network type in data network controller 1972 // because data network has much shorter life cycle. It can prevent 1973 // the obsolete last known network type cached in data network 1974 // type controller. 1975 sourceNetworkType = dataNetwork.getLastKnownDataNetworkType(); 1976 } 1977 int sourceAccessNetwork = DataUtils.networkTypeToAccessNetworkType( 1978 sourceNetworkType); 1979 NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo( 1980 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1981 boolean isWwanInService = false; 1982 if (nri != null && nri.isInService()) { 1983 isWwanInService = true; 1984 } 1985 // If WWAN is inService, use the real roaming state reported by modem instead of 1986 // using the overridden roaming state, otherwise get last known roaming state stored 1987 // in data network. 1988 boolean isRoaming = isWwanInService ? mServiceState.getDataRoamingFromRegistration() 1989 : dataNetwork.getLastKnownRoamingState(); 1990 int targetAccessNetwork = DataUtils.networkTypeToAccessNetworkType( 1991 getDataNetworkType(DataUtils.getTargetTransport(dataNetwork.getTransport()))); 1992 NetworkCapabilities capabilities = dataNetwork.getNetworkCapabilities(); 1993 log("evaluateDataNetworkHandover: " 1994 + "source=" + AccessNetworkType.toString(sourceAccessNetwork) 1995 + ", target=" + AccessNetworkType.toString(targetAccessNetwork) 1996 + ", roaming=" + isRoaming 1997 + ", ServiceState=" + mServiceState 1998 + ", capabilities=" + capabilities); 1999 2000 // Matching the rules by the configured order. Bail out if find first matching rule. 2001 for (HandoverRule rule : handoverRules) { 2002 // Check if the rule is only for roaming and we are not roaming. 2003 if (rule.isOnlyForRoaming && !isRoaming) { 2004 // If the rule is for roaming only, and the device is not roaming, then bypass 2005 // this rule. 2006 continue; 2007 } 2008 2009 if (rule.sourceAccessNetworks.contains(sourceAccessNetwork) 2010 && rule.targetAccessNetworks.contains(targetAccessNetwork)) { 2011 // if no capability rule specified, 2012 // data network capability is considered matched. 2013 // otherwise, any capabilities overlap is also considered matched. 2014 if (rule.networkCapabilities.isEmpty() 2015 || rule.networkCapabilities.stream() 2016 .anyMatch(capabilities::hasCapability)) { 2017 log("evaluateDataNetworkHandover: Matched " + rule); 2018 if (rule.type == HandoverRule.RULE_TYPE_DISALLOWED) { 2019 dataEvaluation.addDataDisallowedReason( 2020 DataDisallowedReason.NOT_ALLOWED_BY_POLICY); 2021 } else { 2022 dataEvaluation.addDataAllowedReason(DataAllowedReason.NORMAL); 2023 } 2024 log("evaluateDataNetworkHandover: " + dataEvaluation); 2025 return dataEvaluation; 2026 } 2027 } 2028 } 2029 log("evaluateDataNetworkHandover: Did not find matching rule."); 2030 } else { 2031 log("evaluateDataNetworkHandover: IWLAN handover policy not enabled."); 2032 } 2033 2034 // Allow handover by default if no rule is found/not enabled by config. 2035 dataEvaluation.addDataAllowedReason(DataAllowedReason.NORMAL); 2036 return dataEvaluation; 2037 } 2038 2039 /** 2040 * Get tear down reason from the evaluation result. 2041 * 2042 * @param dataEvaluation The evaluation result from 2043 * {@link #evaluateDataNetwork(DataNetwork, DataEvaluationReason)}. 2044 * @return The tear down reason. 2045 */ getTearDownReason(@onNull DataEvaluation dataEvaluation)2046 private static @TearDownReason int getTearDownReason(@NonNull DataEvaluation dataEvaluation) { 2047 if (dataEvaluation.containsDisallowedReasons()) { 2048 switch (dataEvaluation.getDataDisallowedReasons().get(0)) { 2049 case DATA_DISABLED: 2050 return DataNetwork.TEAR_DOWN_REASON_DATA_DISABLED; 2051 case ROAMING_DISABLED: 2052 return DataNetwork.TEAR_DOWN_REASON_ROAMING_DISABLED; 2053 case DEFAULT_DATA_UNSELECTED: 2054 return DataNetwork.TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED; 2055 case NOT_IN_SERVICE: 2056 return DataNetwork.TEAR_DOWN_REASON_NOT_IN_SERVICE; 2057 case DATA_CONFIG_NOT_READY: 2058 return DataNetwork.TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY; 2059 case SIM_NOT_READY: 2060 return DataNetwork.TEAR_DOWN_REASON_SIM_REMOVAL; 2061 case CONCURRENT_VOICE_DATA_NOT_ALLOWED: 2062 return DataNetwork.TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED; 2063 case RADIO_POWER_OFF: 2064 return DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON; 2065 case PENDING_TEAR_DOWN_ALL: 2066 return DataNetwork.TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL; 2067 case RADIO_DISABLED_BY_CARRIER: 2068 return DataNetwork.TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER; 2069 case DATA_SERVICE_NOT_READY: 2070 return DataNetwork.TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY; 2071 case NO_SUITABLE_DATA_PROFILE: 2072 return DataNetwork.TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE; 2073 case DATA_NETWORK_TYPE_NOT_ALLOWED: 2074 return DataNetwork.TEAR_DOWN_REASON_RAT_NOT_ALLOWED; 2075 case CDMA_EMERGENCY_CALLBACK_MODE: 2076 return DataNetwork.TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE; 2077 case RETRY_SCHEDULED: 2078 return DataNetwork.TEAR_DOWN_REASON_RETRY_SCHEDULED; 2079 case DATA_THROTTLED: 2080 return DataNetwork.TEAR_DOWN_REASON_DATA_THROTTLED; 2081 case DATA_PROFILE_INVALID: 2082 return DataNetwork.TEAR_DOWN_REASON_DATA_PROFILE_INVALID; 2083 case DATA_PROFILE_NOT_PREFERRED: 2084 return DataNetwork.TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED; 2085 case NOT_ALLOWED_BY_POLICY: 2086 return DataNetwork.TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY; 2087 case ILLEGAL_STATE: 2088 return DataNetwork.TEAR_DOWN_REASON_ILLEGAL_STATE; 2089 case VOPS_NOT_SUPPORTED: 2090 return DataNetwork.TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED; 2091 case ONLY_ALLOWED_SINGLE_NETWORK: 2092 return DataNetwork.TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK; 2093 case HANDOVER_RETRY_STOPPED: 2094 return DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED; 2095 } 2096 } 2097 return DataNetwork.TEAR_DOWN_REASON_NONE; 2098 } 2099 2100 /** 2101 * Check whether a dataNetwork is actively capable of internet connection 2102 * @param cid dataNetwork unique identifier 2103 * @return true if the dataNetwork is connected and capable of internet connection 2104 */ isInternetNetwork(int cid)2105 public boolean isInternetNetwork(int cid) { 2106 for (DataNetwork dataNetwork : mDataNetworkList) { 2107 if (dataNetwork.getId() == cid 2108 && dataNetwork.isConnected() 2109 && dataNetwork.getNetworkCapabilities() 2110 .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) { 2111 return true; 2112 } 2113 } 2114 return false; 2115 } 2116 2117 /** 2118 * @return {@code true} if data is dormant. 2119 */ isDataDormant()2120 private boolean isDataDormant() { 2121 return mDataNetworkList.stream().anyMatch( 2122 dataNetwork -> dataNetwork.getLinkStatus() 2123 == DataCallResponse.LINK_STATUS_DORMANT) 2124 && mDataNetworkList.stream().noneMatch( 2125 dataNetwork -> dataNetwork.getLinkStatus() 2126 == DataCallResponse.LINK_STATUS_ACTIVE); 2127 } 2128 2129 /** 2130 * Update data activity. 2131 */ updateDataActivity()2132 private void updateDataActivity() { 2133 int dataActivity = TelephonyManager.DATA_ACTIVITY_NONE; 2134 if (isDataDormant()) { 2135 dataActivity = TelephonyManager.DATA_ACTIVITY_DORMANT; 2136 } else if (mPhone.getLinkBandwidthEstimator() != null) { 2137 dataActivity = mPhone.getLinkBandwidthEstimator().getDataActivity(); 2138 } 2139 2140 if (mDataActivity != dataActivity) { 2141 logv("updateDataActivity: dataActivity=" 2142 + DataUtils.dataActivityToString(dataActivity)); 2143 mDataActivity = dataActivity; 2144 mPhone.notifyDataActivity(); 2145 } 2146 } 2147 2148 /** 2149 * Remove a network request, which is originated from the apps. Note that remove a network 2150 * will not result in tearing down the network. The tear down request directly comes from 2151 * {@link com.android.server.ConnectivityService} through 2152 * {@link NetworkAgent#onNetworkUnwanted()}. 2153 * 2154 * @param networkRequest Network request 2155 */ removeNetworkRequest(@onNull TelephonyNetworkRequest networkRequest)2156 public void removeNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) { 2157 sendMessage(obtainMessage(EVENT_REMOVE_NETWORK_REQUEST, networkRequest)); 2158 } 2159 onRemoveNetworkRequest(@onNull TelephonyNetworkRequest request)2160 private void onRemoveNetworkRequest(@NonNull TelephonyNetworkRequest request) { 2161 // The request generated from telephony network factory does not contain the information 2162 // the original request has, for example, attached data network. We need to find the 2163 // original one. 2164 TelephonyNetworkRequest networkRequest = mAllNetworkRequestList.stream() 2165 .filter(r -> r.equals(request)) 2166 .findFirst() 2167 .orElse(null); 2168 if (networkRequest == null || !mAllNetworkRequestList.remove(networkRequest)) { 2169 loge("onRemoveNetworkRequest: Network request does not exist. " + networkRequest); 2170 return; 2171 } 2172 2173 if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) { 2174 mImsThrottleCounter.addOccurrence(); 2175 mLastReleasedImsRequestCapabilities = networkRequest.getCapabilities(); 2176 mLastImsOperationIsRelease = true; 2177 } 2178 2179 if (networkRequest.getAttachedNetwork() != null) { 2180 networkRequest.getAttachedNetwork().detachNetworkRequest( 2181 networkRequest, false /* shouldRetry */); 2182 } 2183 log("onRemoveNetworkRequest: Removed " + networkRequest); 2184 } 2185 2186 /** 2187 * Check if the network request is existing. Note this method is not thread safe so can be only 2188 * called within the modules in {@link com.android.internal.telephony.data}. 2189 * 2190 * @param networkRequest Telephony network request to check. 2191 * @return {@code true} if the network request exists. 2192 */ isNetworkRequestExisting(@onNull TelephonyNetworkRequest networkRequest)2193 public boolean isNetworkRequestExisting(@NonNull TelephonyNetworkRequest networkRequest) { 2194 return mAllNetworkRequestList.contains(networkRequest); 2195 } 2196 2197 /** 2198 * Get data network by interface name. 2199 * 2200 * @param interfaceName The network interface name. 2201 * @return The data network if found. 2202 */ 2203 @Nullable getDataNetworkByInterface(@onNull String interfaceName)2204 public DataNetwork getDataNetworkByInterface(@NonNull String interfaceName) { 2205 return mDataNetworkList.stream() 2206 .filter(dataNetwork -> !dataNetwork.isDisconnecting()) 2207 .filter(dataNetwork -> interfaceName.equals( 2208 dataNetwork.getLinkProperties().getInterfaceName())) 2209 .findFirst() 2210 .orElse(null); 2211 } 2212 2213 /** 2214 * Register for IMS feature registration state. 2215 * 2216 * @param subId The subscription index. 2217 * @param imsFeature The IMS feature. Only {@link ImsFeature#FEATURE_MMTEL} and 2218 * {@link ImsFeature#FEATURE_RCS} are supported at this point. 2219 */ registerImsFeatureRegistrationState(int subId, @ImsFeature.FeatureType int imsFeature)2220 private void registerImsFeatureRegistrationState(int subId, 2221 @ImsFeature.FeatureType int imsFeature) { 2222 RegistrationManager.RegistrationCallback callback = 2223 new RegistrationManager.RegistrationCallback() { 2224 @Override 2225 public void onRegistered(ImsRegistrationAttributes attributes) { 2226 log("IMS " + DataUtils.imsFeatureToString(imsFeature) 2227 + " registered. Attributes=" + attributes); 2228 mRegisteredImsFeatures.add(imsFeature); 2229 } 2230 2231 @Override 2232 public void onUnregistered(ImsReasonInfo info) { 2233 log("IMS " + DataUtils.imsFeatureToString(imsFeature) 2234 + " deregistered. Info=" + info); 2235 mRegisteredImsFeatures.remove(imsFeature); 2236 evaluatePendingImsDeregDataNetworks(); 2237 } 2238 }; 2239 2240 try { 2241 // Use switch here as we can't make a generic callback registration logic because 2242 // RcsManager does not implement RegistrationManager. 2243 switch (imsFeature) { 2244 case ImsFeature.FEATURE_MMTEL: 2245 mImsManager.getImsMmTelManager(subId).registerImsRegistrationCallback( 2246 DataNetworkController.this::post, callback); 2247 break; 2248 case ImsFeature.FEATURE_RCS: 2249 mImsManager.getImsRcsManager(subId).registerImsRegistrationCallback( 2250 DataNetworkController.this::post, callback); 2251 break; 2252 } 2253 2254 // Store the callback so that we can unregister in the future. 2255 mImsFeatureRegistrationCallbacks.put(imsFeature, callback); 2256 log("Successfully register " + DataUtils.imsFeatureToString(imsFeature) 2257 + " registration state. subId=" + subId); 2258 } catch (ImsException e) { 2259 loge("updateImsFeatureRegistrationStateListening: subId=" + subId 2260 + ", imsFeature=" + DataUtils.imsFeatureToString(imsFeature) + ", " + e); 2261 } 2262 } 2263 2264 /** 2265 * Unregister IMS feature callback. 2266 * 2267 * @param subId The subscription index. 2268 * @param imsFeature The IMS feature. Only {@link ImsFeature#FEATURE_MMTEL} and 2269 * {@link ImsFeature#FEATURE_RCS} are supported at this point. 2270 */ unregisterImsFeatureRegistrationState(int subId, @ImsFeature.FeatureType int imsFeature)2271 private void unregisterImsFeatureRegistrationState(int subId, 2272 @ImsFeature.FeatureType int imsFeature) { 2273 RegistrationManager.RegistrationCallback oldCallback = 2274 mImsFeatureRegistrationCallbacks.get(imsFeature); 2275 if (oldCallback != null) { 2276 if (imsFeature == ImsFeature.FEATURE_MMTEL) { 2277 mImsManager.getImsMmTelManager(subId) 2278 .unregisterImsRegistrationCallback(oldCallback); 2279 } else if (imsFeature == ImsFeature.FEATURE_RCS) { 2280 mImsManager.getImsRcsManager(subId) 2281 .unregisterImsRegistrationCallback(oldCallback); 2282 } 2283 log("Successfully unregistered " + DataUtils.imsFeatureToString(imsFeature) 2284 + " registration state. sudId=" + subId); 2285 mImsFeatureRegistrationCallbacks.remove(imsFeature); 2286 } 2287 } 2288 2289 /** 2290 * Register IMS state callback. 2291 * 2292 * @param subId Subscription index. 2293 */ registerImsStateCallback(int subId)2294 private void registerImsStateCallback(int subId) { 2295 Function<Integer, ImsStateCallback> imsFeatureStateCallbackFactory = 2296 imsFeature -> new ImsStateCallback() { 2297 @Override 2298 public void onUnavailable(int reason) { 2299 // Unregister registration state update when IMS service is unbound. 2300 unregisterImsFeatureRegistrationState(subId, imsFeature); 2301 } 2302 2303 @Override 2304 public void onAvailable() { 2305 mImsFeaturePackageName.put(imsFeature, ImsResolver.getInstance() 2306 .getConfiguredImsServicePackageName(mPhone.getPhoneId(), 2307 imsFeature)); 2308 // Once IMS service is bound, register for registration state update. 2309 registerImsFeatureRegistrationState(subId, imsFeature); 2310 } 2311 2312 @Override 2313 public void onError() { 2314 } 2315 }; 2316 2317 try { 2318 ImsStateCallback callback = imsFeatureStateCallbackFactory 2319 .apply(ImsFeature.FEATURE_MMTEL); 2320 mImsManager.getImsMmTelManager(subId).registerImsStateCallback(this::post, 2321 callback); 2322 mImsStateCallbacks.put(ImsFeature.FEATURE_MMTEL, callback); 2323 log("Successfully register MMTEL state on sub " + subId); 2324 2325 callback = imsFeatureStateCallbackFactory.apply(ImsFeature.FEATURE_RCS); 2326 mImsManager.getImsRcsManager(subId).registerImsStateCallback(this::post, callback); 2327 mImsStateCallbacks.put(ImsFeature.FEATURE_RCS, callback); 2328 log("Successfully register RCS state on sub " + subId); 2329 } catch (ImsException e) { 2330 loge("Exception when registering IMS state callback. " + e); 2331 } 2332 } 2333 2334 /** 2335 * Unregister IMS feature state callbacks. 2336 * 2337 * @param subId Subscription index. 2338 */ unregisterImsStateCallbacks(int subId)2339 private void unregisterImsStateCallbacks(int subId) { 2340 ImsStateCallback callback = mImsStateCallbacks.get(ImsFeature.FEATURE_MMTEL); 2341 if (callback != null) { 2342 mImsManager.getImsMmTelManager(subId).unregisterImsStateCallback(callback); 2343 mImsStateCallbacks.remove(ImsFeature.FEATURE_MMTEL); 2344 log("Unregister MMTEL state on sub " + subId); 2345 } 2346 2347 callback = mImsStateCallbacks.get(ImsFeature.FEATURE_RCS); 2348 if (callback != null) { 2349 mImsManager.getImsRcsManager(subId).unregisterImsStateCallback(callback); 2350 mImsStateCallbacks.remove(ImsFeature.FEATURE_RCS); 2351 log("Unregister RCS state on sub " + subId); 2352 } 2353 } 2354 2355 /** Called when subscription info changed. */ onSubscriptionChanged()2356 private void onSubscriptionChanged() { 2357 if (mSubId != mPhone.getSubId()) { 2358 log("onDataConfigUpdated: mSubId changed from " + mSubId + " to " 2359 + mPhone.getSubId()); 2360 if (isImsGracefulTearDownSupported()) { 2361 if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) { 2362 registerImsStateCallback(mPhone.getSubId()); 2363 } else { 2364 unregisterImsStateCallbacks(mSubId); 2365 } 2366 } 2367 mSubId = mPhone.getSubId(); 2368 updateSubscriptionPlans(); 2369 } 2370 } 2371 2372 /** 2373 * Called when carrier config was updated. 2374 */ onCarrierConfigUpdated()2375 private void onCarrierConfigUpdated() { 2376 log("onCarrierConfigUpdated: config is " 2377 + (mDataConfigManager.isConfigCarrierSpecific() ? "" : "not ") 2378 + "carrier specific. mSimState=" 2379 + TelephonyManager.simStateToString(mSimState)); 2380 updateNetworkRequestsPriority(); 2381 onReevaluateUnsatisfiedNetworkRequests(DataEvaluationReason.DATA_CONFIG_CHANGED); 2382 } 2383 2384 /** 2385 * Called when device config was updated. 2386 */ onDeviceConfigUpdated()2387 private void onDeviceConfigUpdated() { 2388 log("onDeviceConfigUpdated: DeviceConfig updated."); 2389 updateAnomalySlidingWindowCounters(); 2390 } 2391 2392 /** 2393 * Update each network request's priority. 2394 */ updateNetworkRequestsPriority()2395 private void updateNetworkRequestsPriority() { 2396 for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) { 2397 networkRequest.updatePriority(); 2398 } 2399 } 2400 2401 /** 2402 * Update the threshold of anomaly report counters 2403 */ updateAnomalySlidingWindowCounters()2404 private void updateAnomalySlidingWindowCounters() { 2405 mImsThrottleCounter = new SlidingWindowEventCounter( 2406 mDataConfigManager.getAnomalyImsReleaseRequestThreshold().timeWindow, 2407 mDataConfigManager.getAnomalyImsReleaseRequestThreshold().eventNumOccurrence); 2408 mNetworkUnwantedCounter = new SlidingWindowEventCounter( 2409 mDataConfigManager.getAnomalyNetworkUnwantedThreshold().timeWindow, 2410 mDataConfigManager.getAnomalyNetworkUnwantedThreshold().eventNumOccurrence); 2411 mSetupDataCallWwanFailureCounter = new SlidingWindowEventCounter( 2412 mDataConfigManager.getAnomalySetupDataCallThreshold().timeWindow, 2413 mDataConfigManager.getAnomalySetupDataCallThreshold().eventNumOccurrence); 2414 mSetupDataCallWlanFailureCounter = new SlidingWindowEventCounter( 2415 mDataConfigManager.getAnomalySetupDataCallThreshold().timeWindow, 2416 mDataConfigManager.getAnomalySetupDataCallThreshold().eventNumOccurrence); 2417 } 2418 2419 /** 2420 * There have been several bugs where a RECONNECT loop kicks off where a data network 2421 * is brought up, but connectivity service indicates that the network is unwanted so telephony 2422 * tears down the network. But later telephony bring up the data network again and becomes an 2423 * infinite loop. By the time we get the bug report it's too late because there have already 2424 * been hundreds of bring up/tear down. This is meant to capture the issue when it first starts. 2425 */ onTrackNetworkUnwanted()2426 private void onTrackNetworkUnwanted() { 2427 if (mNetworkUnwantedCounter.addOccurrence()) { 2428 reportAnomaly("Network Unwanted called " 2429 + mNetworkUnwantedCounter.getFrequencyString(), 2430 "9f3bc55b-bfa6-4e26-afaa-5031426a66d3"); 2431 } 2432 } 2433 2434 /** 2435 * Find unsatisfied network requests that can be satisfied by the given data profile. 2436 * 2437 * @param dataProfile The data profile. 2438 * @return The network requests list. 2439 */ findSatisfiableNetworkRequests( @onNull DataProfile dataProfile)2440 private @NonNull NetworkRequestList findSatisfiableNetworkRequests( 2441 @NonNull DataProfile dataProfile) { 2442 return new NetworkRequestList(mAllNetworkRequestList.stream() 2443 .filter(request -> request.getState() 2444 == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED) 2445 .filter(request -> request.canBeSatisfiedBy(dataProfile)) 2446 .collect(Collectors.toList())); 2447 } 2448 2449 /** 2450 * Setup data network. 2451 * 2452 * @param dataProfile The data profile to setup the data network. 2453 * @param dataSetupRetryEntry Data retry entry. {@code null} if this data network setup is not 2454 * initiated by a data retry. 2455 * @param allowedReason The reason that why setting up this data network is allowed. 2456 */ setupDataNetwork(@onNull DataProfile dataProfile, @Nullable DataSetupRetryEntry dataSetupRetryEntry, @NonNull DataAllowedReason allowedReason)2457 private void setupDataNetwork(@NonNull DataProfile dataProfile, 2458 @Nullable DataSetupRetryEntry dataSetupRetryEntry, 2459 @NonNull DataAllowedReason allowedReason) { 2460 log("onSetupDataNetwork: dataProfile=" + dataProfile + ", retryEntry=" 2461 + dataSetupRetryEntry + ", allowed reason=" + allowedReason + ", service state=" 2462 + mServiceState); 2463 for (DataNetwork dataNetwork : mDataNetworkList) { 2464 DataProfile currentDataProfile = dataNetwork.getDataProfile(); 2465 if (dataProfile.equals(currentDataProfile) 2466 || mDataProfileManager.areDataProfilesSharingApn( 2467 dataProfile, currentDataProfile)) { 2468 log("onSetupDataNetwork: Found existing data network " + dataNetwork 2469 + " using the same or a similar data profile."); 2470 if (dataSetupRetryEntry != null) { 2471 dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 2472 } 2473 return; 2474 } 2475 } 2476 2477 NetworkRequestList networkRequestList = findSatisfiableNetworkRequests(dataProfile); 2478 2479 if (networkRequestList.isEmpty()) { 2480 log("Can't find any unsatisfied network requests that can be satisfied by this data " 2481 + "profile."); 2482 if (dataSetupRetryEntry != null) { 2483 dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 2484 } 2485 2486 return; 2487 } 2488 2489 int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability( 2490 networkRequestList.get(0).getApnTypeNetworkCapability()); 2491 logl("Creating data network on " 2492 + AccessNetworkConstants.transportTypeToString(transport) + " with " + dataProfile 2493 + ", and attaching " + networkRequestList.size() + " network requests to it."); 2494 2495 mDataNetworkList.add(new DataNetwork(mPhone, getLooper(), mDataServiceManagers, 2496 dataProfile, networkRequestList, transport, allowedReason, 2497 new DataNetworkCallback(this::post) { 2498 @Override 2499 public void onSetupDataFailed(@NonNull DataNetwork dataNetwork, 2500 @NonNull NetworkRequestList requestList, @DataFailureCause int cause, 2501 long retryDelayMillis) { 2502 if (dataSetupRetryEntry != null) { 2503 dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED); 2504 } 2505 DataNetworkController.this.onDataNetworkSetupFailed( 2506 dataNetwork, requestList, cause, retryDelayMillis); 2507 } 2508 2509 @Override 2510 public void onConnected(@NonNull DataNetwork dataNetwork) { 2511 if (dataSetupRetryEntry != null) { 2512 dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_SUCCEEDED); 2513 } 2514 DataNetworkController.this.onDataNetworkConnected(dataNetwork); 2515 } 2516 2517 @Override 2518 public void onAttachFailed(@NonNull DataNetwork dataNetwork, 2519 @NonNull NetworkRequestList requestList) { 2520 DataNetworkController.this.onAttachNetworkRequestsFailed( 2521 dataNetwork, requestList); 2522 } 2523 2524 @Override 2525 public void onValidationStatusChanged(@NonNull DataNetwork dataNetwork, 2526 @ValidationStatus int status, @Nullable Uri redirectUri) { 2527 DataNetworkController.this.onDataNetworkValidationStatusChanged( 2528 dataNetwork, status, redirectUri); 2529 } 2530 2531 @Override 2532 public void onSuspendedStateChanged(@NonNull DataNetwork dataNetwork, 2533 boolean suspended) { 2534 DataNetworkController.this.onDataNetworkSuspendedStateChanged( 2535 dataNetwork, suspended); 2536 } 2537 2538 @Override 2539 public void onDisconnected(@NonNull DataNetwork dataNetwork, 2540 @DataFailureCause int cause, @TearDownReason int tearDownReason) { 2541 DataNetworkController.this.onDataNetworkDisconnected( 2542 dataNetwork, cause, tearDownReason); 2543 } 2544 2545 @Override 2546 public void onHandoverSucceeded(@NonNull DataNetwork dataNetwork) { 2547 DataNetworkController.this.onDataNetworkHandoverSucceeded(dataNetwork); 2548 } 2549 2550 @Override 2551 public void onHandoverFailed(@NonNull DataNetwork dataNetwork, 2552 @DataFailureCause int cause, long retryDelayMillis, 2553 @HandoverFailureMode int handoverFailureMode) { 2554 DataNetworkController.this.onDataNetworkHandoverFailed( 2555 dataNetwork, cause, retryDelayMillis, handoverFailureMode); 2556 } 2557 2558 @Override 2559 public void onLinkStatusChanged(@NonNull DataNetwork dataNetwork, 2560 @LinkStatus int linkStatus) { 2561 DataNetworkController.this.onLinkStatusChanged(dataNetwork, linkStatus); 2562 } 2563 2564 @Override 2565 public void onPcoDataChanged(@NonNull DataNetwork dataNetwork) { 2566 DataNetworkController.this.onPcoDataChanged(dataNetwork); 2567 } 2568 2569 @Override 2570 public void onNetworkCapabilitiesChanged(@NonNull DataNetwork dataNetwork) { 2571 DataNetworkController.this.onNetworkCapabilitiesChanged(dataNetwork); 2572 } 2573 2574 @Override 2575 public void onTrackNetworkUnwanted(@NonNull DataNetwork dataNetwork) { 2576 DataNetworkController.this.onTrackNetworkUnwanted(); 2577 } 2578 2579 @Override 2580 public void onRetryUnsatisfiedNetworkRequest( 2581 @NonNull TelephonyNetworkRequest networkRequest) { 2582 DataNetworkController.this.onRetryUnsatisfiedNetworkRequest( 2583 networkRequest); 2584 } 2585 } 2586 )); 2587 if (!mAnyDataNetworkExisting) { 2588 mAnyDataNetworkExisting = true; 2589 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 2590 () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); 2591 } 2592 } 2593 2594 /** 2595 * Called when setup data network failed. 2596 * 2597 * @param dataNetwork The data network. 2598 * @param requestList The network requests attached to the data network. 2599 * @param cause The fail cause 2600 * @param retryDelayMillis The retry timer suggested by the network/data service. 2601 */ onDataNetworkSetupFailed(@onNull DataNetwork dataNetwork, @NonNull NetworkRequestList requestList, @DataFailureCause int cause, long retryDelayMillis)2602 private void onDataNetworkSetupFailed(@NonNull DataNetwork dataNetwork, 2603 @NonNull NetworkRequestList requestList, @DataFailureCause int cause, 2604 long retryDelayMillis) { 2605 logl("onDataNetworkSetupDataFailed: " + dataNetwork + ", cause=" 2606 + DataFailCause.toString(cause) + ", retryDelayMillis=" + retryDelayMillis + "ms."); 2607 mDataNetworkList.remove(dataNetwork); 2608 trackSetupDataCallFailure(dataNetwork.getTransport(), cause); 2609 if (mAnyDataNetworkExisting && mDataNetworkList.isEmpty()) { 2610 mPendingTearDownAllNetworks = false; 2611 mAnyDataNetworkExisting = false; 2612 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 2613 () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); 2614 } 2615 2616 requestList.removeIf(request -> !mAllNetworkRequestList.contains(request)); 2617 if (requestList.isEmpty()) { 2618 log("onDataNetworkSetupFailed: All requests have been released. " 2619 + "Will not evaluate retry."); 2620 return; 2621 } 2622 2623 // Data retry manager will determine if retry is needed. If needed, retry will be scheduled. 2624 mDataRetryManager.evaluateDataSetupRetry(dataNetwork.getDataProfile(), 2625 dataNetwork.getTransport(), requestList, cause, retryDelayMillis); 2626 } 2627 2628 /** 2629 * Track the frequency of setup data failure on each 2630 * {@link AccessNetworkConstants.TransportType} data service. 2631 * 2632 * @param transport The transport of the data service. 2633 * @param cause The fail cause 2634 */ trackSetupDataCallFailure(@ransportType int transport, @DataFailureCause int cause)2635 private void trackSetupDataCallFailure(@TransportType int transport, 2636 @DataFailureCause int cause) { 2637 switch (transport) { 2638 case AccessNetworkConstants.TRANSPORT_TYPE_WWAN: 2639 // Skip when poor signal strength 2640 if (mPhone.getSignalStrength().getLevel() 2641 <= CellSignalStrength.SIGNAL_STRENGTH_POOR) { 2642 return; 2643 } 2644 if (cause == DataFailCause.ERROR_UNSPECIFIED || cause == DataFailCause.UNKNOWN) { 2645 reportAnomaly("RIL set up data call fails: unknown/unspecified error", 2646 "ce7d1465-d8e4-404a-b76f-de2c60bee843"); 2647 } 2648 if (mSetupDataCallWwanFailureCounter.addOccurrence()) { 2649 reportAnomaly("RIL fails setup data call request " 2650 + mSetupDataCallWwanFailureCounter.getFrequencyString(), 2651 "e6a98b97-9e34-4977-9a92-01d52a6691f6"); 2652 } 2653 break; 2654 case AccessNetworkConstants.TRANSPORT_TYPE_WLAN: 2655 if (cause == DataFailCause.ERROR_UNSPECIFIED || cause == DataFailCause.UNKNOWN) { 2656 reportAnomaly("IWLAN set up data call fails: unknown/unspecified error", 2657 "a16fc15c-815b-4908-b8e6-5f3bc7cbc20b"); 2658 } 2659 if (mSetupDataCallWlanFailureCounter.addOccurrence()) { 2660 reportAnomaly("IWLAN data service fails setup data call request " 2661 + mSetupDataCallWlanFailureCounter.getFrequencyString(), 2662 "e2248d8b-d55f-42bd-871c-0cfd80c3ddd1"); 2663 } 2664 break; 2665 default: 2666 loge("trackSetupDataCallFailure: INVALID transport."); 2667 } 2668 } 2669 2670 /** 2671 * Trigger the anomaly report with the specified UUID. 2672 * 2673 * @param anomalyMsg Description of the event 2674 * @param uuid UUID associated with that event 2675 */ reportAnomaly(@onNull String anomalyMsg, @NonNull String uuid)2676 private void reportAnomaly(@NonNull String anomalyMsg, @NonNull String uuid) { 2677 logl(anomalyMsg); 2678 AnomalyReporter.reportAnomaly(UUID.fromString(uuid), anomalyMsg, mPhone.getCarrierId()); 2679 } 2680 2681 /** 2682 * Called when data network is connected. 2683 * 2684 * @param dataNetwork The data network. 2685 */ onDataNetworkConnected(@onNull DataNetwork dataNetwork)2686 private void onDataNetworkConnected(@NonNull DataNetwork dataNetwork) { 2687 logl("onDataNetworkConnected: " + dataNetwork); 2688 2689 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 2690 () -> callback.onDataNetworkConnected(dataNetwork.getTransport(), 2691 dataNetwork.getDataProfile()))); 2692 2693 mPreviousConnectedDataNetworkList.add(0, dataNetwork); 2694 // Preserve the connected data networks for debugging purposes. 2695 if (mPreviousConnectedDataNetworkList.size() > MAX_HISTORICAL_CONNECTED_DATA_NETWORKS) { 2696 mPreviousConnectedDataNetworkList.remove(MAX_HISTORICAL_CONNECTED_DATA_NETWORKS); 2697 } 2698 2699 updateOverallInternetDataState(); 2700 2701 if (dataNetwork.getNetworkCapabilities().hasCapability( 2702 NetworkCapabilities.NET_CAPABILITY_IMS)) { 2703 logl("IMS data state changed from " 2704 + TelephonyUtils.dataStateToString(mImsDataNetworkState) + " to CONNECTED."); 2705 mImsDataNetworkState = TelephonyManager.DATA_CONNECTED; 2706 } 2707 } 2708 2709 /** 2710 * Called when needed to retry data setup. 2711 * 2712 * @param dataSetupRetryEntry The data setup retry entry scheduled by {@link DataRetryManager}. 2713 */ onDataNetworkSetupRetry(@onNull DataSetupRetryEntry dataSetupRetryEntry)2714 private void onDataNetworkSetupRetry(@NonNull DataSetupRetryEntry dataSetupRetryEntry) { 2715 // The request might be already removed before retry happens. Remove them from the list 2716 // if that's the case. Copy the list first. We don't want to remove the requests from 2717 // the retry entry. They can be later used to determine what kind of retry it is. 2718 NetworkRequestList requestList = new NetworkRequestList( 2719 dataSetupRetryEntry.networkRequestList); 2720 requestList.removeIf(request -> !mAllNetworkRequestList.contains(request)); 2721 // Retrieves the newly added unsatisfied NetworkRequest if all NetworkRequests in the 2722 // DataSetupRetryEntry have already been removed. 2723 if (requestList.isEmpty()) { 2724 List<NetworkRequestList> groupRequestLists = getGroupedUnsatisfiedNetworkRequests(); 2725 dataSetupRetryEntry.networkRequestList.stream() 2726 .filter(request -> groupRequestLists.stream() 2727 .anyMatch(groupRequestList -> groupRequestList 2728 .get(request.getCapabilities()) != null)) 2729 .forEach(requestList::add); 2730 } 2731 if (requestList.isEmpty()) { 2732 loge("onDataNetworkSetupRetry: Request list is empty. Abort retry."); 2733 dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 2734 return; 2735 } 2736 log("onDataNetworkSetupRetry: Request list:" + requestList); 2737 TelephonyNetworkRequest telephonyNetworkRequest = requestList.get(0); 2738 2739 int networkCapability = telephonyNetworkRequest.getApnTypeNetworkCapability(); 2740 int preferredTransport = mAccessNetworksManager.getPreferredTransportByNetworkCapability( 2741 networkCapability); 2742 if (preferredTransport != dataSetupRetryEntry.transport) { 2743 log("Cannot re-satisfy " + telephonyNetworkRequest + " on " 2744 + AccessNetworkConstants.transportTypeToString(dataSetupRetryEntry.transport) 2745 + ". The preferred transport has switched to " 2746 + AccessNetworkConstants.transportTypeToString(preferredTransport) 2747 + ". " + dataSetupRetryEntry); 2748 // Cancel the retry since the preferred transport has already changed, but then 2749 // re-evaluate the unsatisfied network requests again so the new network can be brought 2750 // up on the new target transport later. 2751 dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 2752 sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 2753 DataEvaluationReason.PREFERRED_TRANSPORT_CHANGED)); 2754 return; 2755 } 2756 2757 DataEvaluation evaluation = evaluateNetworkRequest( 2758 telephonyNetworkRequest, DataEvaluationReason.DATA_RETRY); 2759 if (!evaluation.containsDisallowedReasons()) { 2760 DataProfile dataProfile = dataSetupRetryEntry.dataProfile; 2761 if (dataProfile == null) { 2762 dataProfile = evaluation.getCandidateDataProfile(); 2763 } 2764 if (dataProfile != null) { 2765 setupDataNetwork(dataProfile, dataSetupRetryEntry, 2766 evaluation.getDataAllowedReason()); 2767 } else { 2768 loge("onDataNetworkSetupRetry: Not able to find a suitable data profile to retry."); 2769 dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED); 2770 } 2771 } else { 2772 dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED); 2773 } 2774 } 2775 2776 /** 2777 * Called when needed to retry data network handover. 2778 * 2779 * @param dataHandoverRetryEntry The handover entry. 2780 */ onDataNetworkHandoverRetry( @onNull DataHandoverRetryEntry dataHandoverRetryEntry)2781 private void onDataNetworkHandoverRetry( 2782 @NonNull DataHandoverRetryEntry dataHandoverRetryEntry) { 2783 DataNetwork dataNetwork = dataHandoverRetryEntry.dataNetwork; 2784 if (!mDataNetworkList.contains(dataNetwork)) { 2785 log("onDataNetworkHandoverRetry: " + dataNetwork + " no longer exists."); 2786 dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 2787 return; 2788 } 2789 2790 if (!dataNetwork.isConnected()) { 2791 log("onDataNetworkHandoverRetry: " + dataNetwork + " is not in the right state."); 2792 dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 2793 return; 2794 } 2795 2796 int preferredTransport = mAccessNetworksManager.getPreferredTransportByNetworkCapability( 2797 dataNetwork.getApnTypeNetworkCapability()); 2798 if (dataNetwork.getTransport() == preferredTransport) { 2799 log("onDataNetworkHandoverRetry: " + dataNetwork + " is already on the preferred " 2800 + "transport " + AccessNetworkConstants.transportTypeToString( 2801 preferredTransport) + "."); 2802 dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED); 2803 return; 2804 } 2805 2806 logl("onDataNetworkHandoverRetry: Start handover " + dataNetwork + " to " 2807 + AccessNetworkConstants.transportTypeToString(preferredTransport) 2808 + ", " + dataHandoverRetryEntry); 2809 tryHandoverDataNetwork(dataNetwork, preferredTransport, dataHandoverRetryEntry); 2810 } 2811 2812 /** 2813 * Called when data network reached max handover retry count. 2814 * 2815 * @param dataNetwork The data network. 2816 */ onDataNetworkHandoverRetryStopped(@onNull DataNetwork dataNetwork)2817 private void onDataNetworkHandoverRetryStopped(@NonNull DataNetwork dataNetwork) { 2818 int preferredTransport = mAccessNetworksManager 2819 .getPreferredTransportByNetworkCapability( 2820 dataNetwork.getApnTypeNetworkCapability()); 2821 if (dataNetwork.getTransport() == preferredTransport) { 2822 log("onDataNetworkHandoverRetryStopped: " + dataNetwork + " is already " 2823 + "on the preferred transport " 2824 + AccessNetworkConstants.transportTypeToString( 2825 preferredTransport)); 2826 return; 2827 } 2828 if (dataNetwork.shouldDelayImsTearDownDueToInCall()) { 2829 log("onDataNetworkHandoverRetryStopped: Delay IMS tear down until call " 2830 + "ends. " + dataNetwork); 2831 return; 2832 } 2833 2834 tearDownGracefully(dataNetwork, 2835 DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED); 2836 } 2837 2838 /** 2839 * Called when data network validation status changed. 2840 * 2841 * @param status one of {@link NetworkAgent#VALIDATION_STATUS_VALID} or 2842 * {@link NetworkAgent#VALIDATION_STATUS_NOT_VALID}. 2843 * @param redirectUri If internet connectivity is being redirected (e.g., on a captive portal), 2844 * this is the destination the probes are being redirected to, otherwise {@code null}. 2845 * 2846 * @param dataNetwork The data network. 2847 */ onDataNetworkValidationStatusChanged(@onNull DataNetwork dataNetwork, @ValidationStatus int status, @Nullable Uri redirectUri)2848 private void onDataNetworkValidationStatusChanged(@NonNull DataNetwork dataNetwork, 2849 @ValidationStatus int status, @Nullable Uri redirectUri) { 2850 log("onDataNetworkValidationStatusChanged: " + dataNetwork + ", validation status=" 2851 + DataUtils.validationStatusToString(status) 2852 + (redirectUri != null ? ", " + redirectUri : "")); 2853 if (!TextUtils.isEmpty(redirectUri.toString())) { 2854 Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED); 2855 intent.putExtra(TelephonyManager.EXTRA_REDIRECTION_URL, redirectUri); 2856 mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent); 2857 log("Notify carrier signal receivers with redirectUri: " + redirectUri); 2858 } 2859 2860 if (status != NetworkAgent.VALIDATION_STATUS_VALID 2861 && status != NetworkAgent.VALIDATION_STATUS_NOT_VALID) { 2862 loge("Invalid validation status " + status + " received."); 2863 return; 2864 } 2865 2866 if (!mDataSettingsManager.isRecoveryOnBadNetworkEnabled()) { 2867 log("Ignore data network validation status changed because " 2868 + "data stall recovery is disabled."); 2869 return; 2870 } 2871 2872 if (dataNetwork.isInternetSupported()) { 2873 if (status == NetworkAgent.VALIDATION_STATUS_NOT_VALID 2874 && (dataNetwork.getCurrentState() == null || dataNetwork.isDisconnected())) { 2875 log("Ignoring invalid validation status for disconnected DataNetwork"); 2876 return; 2877 } 2878 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 2879 () -> callback.onInternetDataNetworkValidationStatusChanged(status))); 2880 } 2881 } 2882 2883 /** 2884 * Called when data network suspended state changed. 2885 * 2886 * @param dataNetwork The data network. 2887 * @param suspended {@code true} if data is suspended. 2888 */ onDataNetworkSuspendedStateChanged(@onNull DataNetwork dataNetwork, boolean suspended)2889 private void onDataNetworkSuspendedStateChanged(@NonNull DataNetwork dataNetwork, 2890 boolean suspended) { 2891 updateOverallInternetDataState(); 2892 2893 if (dataNetwork.getNetworkCapabilities().hasCapability( 2894 NetworkCapabilities.NET_CAPABILITY_IMS)) { 2895 logl("IMS data state changed from " 2896 + TelephonyUtils.dataStateToString(mImsDataNetworkState) + " to " 2897 + (suspended ? "SUSPENDED" : "CONNECTED")); 2898 mImsDataNetworkState = suspended 2899 ? TelephonyManager.DATA_SUSPENDED : TelephonyManager.DATA_CONNECTED; 2900 } 2901 } 2902 2903 /** 2904 * Called when data network disconnected. 2905 * 2906 * @param dataNetwork The data network. 2907 * @param cause The disconnect cause. 2908 * @param tearDownReason The reason the network was torn down 2909 */ onDataNetworkDisconnected(@onNull DataNetwork dataNetwork, @DataFailureCause int cause, @TearDownReason int tearDownReason)2910 private void onDataNetworkDisconnected(@NonNull DataNetwork dataNetwork, 2911 @DataFailureCause int cause, @TearDownReason int tearDownReason) { 2912 logl("onDataNetworkDisconnected: " + dataNetwork + ", cause=" 2913 + DataFailCause.toString(cause) + "(" + cause + "), tearDownReason=" 2914 + DataNetwork.tearDownReasonToString(tearDownReason)); 2915 mDataNetworkList.remove(dataNetwork); 2916 mPendingImsDeregDataNetworks.remove(dataNetwork); 2917 mDataRetryManager.cancelPendingHandoverRetry(dataNetwork); 2918 updateOverallInternetDataState(); 2919 2920 if (dataNetwork.getNetworkCapabilities().hasCapability( 2921 NetworkCapabilities.NET_CAPABILITY_IMS)) { 2922 logl("IMS data state changed from " 2923 + TelephonyUtils.dataStateToString(mImsDataNetworkState) + " to DISCONNECTED."); 2924 mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED; 2925 } 2926 2927 if (mAnyDataNetworkExisting && mDataNetworkList.isEmpty()) { 2928 log("All data networks disconnected now."); 2929 mPendingTearDownAllNetworks = false; 2930 mAnyDataNetworkExisting = false; 2931 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 2932 () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); 2933 } 2934 2935 // Immediately reestablish on target transport if network was torn down due to policy 2936 long delayMillis = tearDownReason == DataNetwork.TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED 2937 ? 0 : mDataConfigManager.getRetrySetupAfterDisconnectMillis(); 2938 // Sometimes network was unsolicitedly reported lost for reasons. We should re-evaluate 2939 // and see if data network can be re-established again. 2940 sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 2941 DataEvaluationReason.RETRY_AFTER_DISCONNECTED), delayMillis); 2942 } 2943 2944 /** 2945 * Called when handover between IWLAN and cellular network succeeded. 2946 * 2947 * @param dataNetwork The data network. 2948 */ onDataNetworkHandoverSucceeded(@onNull DataNetwork dataNetwork)2949 private void onDataNetworkHandoverSucceeded(@NonNull DataNetwork dataNetwork) { 2950 logl("Handover successfully. " + dataNetwork + " to " + AccessNetworkConstants 2951 .transportTypeToString(dataNetwork.getTransport())); 2952 // The preferred transport might be changed when handover was in progress. We need to 2953 // evaluate again to make sure we are not out-of-sync with the input from access network 2954 // manager. 2955 sendMessage(obtainMessage(EVENT_EVALUATE_PREFERRED_TRANSPORT, 2956 dataNetwork.getApnTypeNetworkCapability(), 0)); 2957 2958 // There might be network we didn't tear down in the last evaluation due to handover in 2959 // progress. We should evaluate again. 2960 sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 2961 DataEvaluationReason.DATA_HANDOVER)); 2962 } 2963 2964 /** 2965 * Called when data network handover between IWLAN and cellular network failed. 2966 * 2967 * @param dataNetwork The data network. 2968 * @param cause The fail cause. 2969 * @param retryDelayMillis Network suggested retry time in milliseconds. 2970 * {@link Long#MAX_VALUE} indicates data retry should not occur. 2971 * {@link DataCallResponse#RETRY_DURATION_UNDEFINED} indicates network did not suggest any 2972 * retry duration. 2973 * @param handoverFailureMode The handover failure mode that determine the behavior of 2974 * how frameworks should handle the handover failure. 2975 */ onDataNetworkHandoverFailed(@onNull DataNetwork dataNetwork, @DataFailureCause int cause, long retryDelayMillis, @HandoverFailureMode int handoverFailureMode)2976 private void onDataNetworkHandoverFailed(@NonNull DataNetwork dataNetwork, 2977 @DataFailureCause int cause, long retryDelayMillis, 2978 @HandoverFailureMode int handoverFailureMode) { 2979 logl("Handover failed. " + dataNetwork + ", cause=" + DataFailCause.toString(cause) 2980 + ", retryDelayMillis=" + retryDelayMillis + "ms, handoverFailureMode=" 2981 + DataCallResponse.failureModeToString(handoverFailureMode)); 2982 // There might be network we didn't tear down in the last evaluation due to handover in 2983 // progress. We should evaluate again. 2984 sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 2985 DataEvaluationReason.DATA_HANDOVER)); 2986 2987 if (dataNetwork.getAttachedNetworkRequestList().isEmpty()) { 2988 log("onDataNetworkHandoverFailed: No network requests attached to " + dataNetwork 2989 + ". No need to retry since the network will be torn down soon."); 2990 return; 2991 } 2992 2993 if (handoverFailureMode == DataCallResponse.HANDOVER_FAILURE_MODE_DO_FALLBACK 2994 || (handoverFailureMode == DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY 2995 && cause == DataFailCause.HANDOFF_PREFERENCE_CHANGED)) { 2996 // Don't retry handover anymore. Give QNS some time to switch the preferred transport 2997 // to the original one, but we should re-evaluate the preferred transport again to 2998 // make sure QNS does change it back, if not, we still need to perform handover at that 2999 // time. 3000 sendMessageDelayed(obtainMessage(EVENT_EVALUATE_PREFERRED_TRANSPORT, 3001 dataNetwork.getApnTypeNetworkCapability(), 0), 3002 REEVALUATE_PREFERRED_TRANSPORT_DELAY_MILLIS); 3003 } else if (handoverFailureMode == DataCallResponse 3004 .HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL || handoverFailureMode 3005 == DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY) { 3006 int preferredTransport = mAccessNetworksManager 3007 .getPreferredTransportByNetworkCapability( 3008 dataNetwork.getApnTypeNetworkCapability()); 3009 if (dataNetwork.getTransport() == preferredTransport) { 3010 log("onDataNetworkHandoverFailed: Already on preferred transport " 3011 + AccessNetworkConstants.transportTypeToString(preferredTransport) 3012 + ". No further actions needed."); 3013 return; 3014 } 3015 3016 int targetTransport = DataUtils.getTargetTransport(dataNetwork.getTransport()); 3017 mDataRetryManager.evaluateDataSetupRetry(dataNetwork.getDataProfile(), targetTransport, 3018 dataNetwork.getAttachedNetworkRequestList(), cause, retryDelayMillis); 3019 // Tear down the data network on source transport. Retry manager will schedule 3020 // setup a new data network on the target transport. 3021 tearDownGracefully(dataNetwork, DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED); 3022 } else { 3023 mDataRetryManager.evaluateDataHandoverRetry(dataNetwork, cause, retryDelayMillis); 3024 } 3025 } 3026 3027 /** 3028 * Called when network requests failed to attach to the data network. 3029 * 3030 * @param dataNetwork The data network that can't be attached. 3031 * @param requestList The requests failed to attach to the network. 3032 */ onAttachNetworkRequestsFailed(@onNull DataNetwork dataNetwork, @NonNull NetworkRequestList requestList)3033 private void onAttachNetworkRequestsFailed(@NonNull DataNetwork dataNetwork, 3034 @NonNull NetworkRequestList requestList) { 3035 log("Failed to attach " + requestList + " to " + dataNetwork); 3036 } 3037 3038 /** 3039 * Called when a network request is detached from the data network and should be retried. 3040 * 3041 * @param networkRequest The detached network request. 3042 */ onRetryUnsatisfiedNetworkRequest( @onNull TelephonyNetworkRequest networkRequest)3043 private void onRetryUnsatisfiedNetworkRequest( 3044 @NonNull TelephonyNetworkRequest networkRequest) { 3045 if (!mAllNetworkRequestList.contains(networkRequest)) return; 3046 3047 sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 3048 DataEvaluationReason.UNSATISFIED_REQUEST_DETACHED), 3049 REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_AFTER_DETACHED_DELAY_MILLIS); 3050 } 3051 3052 /** 3053 * Called when data stall occurs and needed to tear down / setup a new data network for 3054 * internet. This event is from {@link DataStallRecoveryManager}. 3055 */ onDataStallReestablishInternet()3056 private void onDataStallReestablishInternet() { 3057 log("onDataStallReestablishInternet: Tear down data networks that support internet."); 3058 // Tear down all data networks that support internet. After data disconnected, unsatisfied 3059 // network requests will be re-evaluate again and data network controller will attempt to 3060 // setup data networks to satisfy them. 3061 mDataNetworkList.stream() 3062 .filter(DataNetwork::isInternetSupported) 3063 .forEach(dataNetwork -> dataNetwork.tearDown( 3064 DataNetwork.TEAR_DOWN_REASON_DATA_STALL)); 3065 } 3066 3067 /** 3068 * Called when SRVCC handover state changes. To preserve the voice call, we don't tear down the 3069 * IMS network while handover in process. We reevaluate the network when handover ends. 3070 * 3071 * @param state The handover state of SRVCC 3072 */ onSrvccStateChanged(@onNull int[] state)3073 private void onSrvccStateChanged(@NonNull int[] state) { 3074 if (state != null && state.length != 0) { 3075 log("onSrvccStateChanged: " + TelephonyManager.srvccStateToString(state[0])); 3076 mIsSrvccHandoverInProcess = state[0] == TelephonyManager.SRVCC_STATE_HANDOVER_STARTED; 3077 // Reevaluate networks if SRVCC ends. 3078 if (!mIsSrvccHandoverInProcess 3079 && !hasMessages(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)) { 3080 sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 3081 DataEvaluationReason.SRVCC_STATE_CHANGED)); 3082 } 3083 } 3084 } 3085 3086 /** 3087 * Called when data service binding changed. 3088 * 3089 * @param transport The transport of the changed data service. 3090 * @param bound {@code true} if data service is bound. 3091 */ onDataServiceBindingChanged(@ransportType int transport, boolean bound)3092 private void onDataServiceBindingChanged(@TransportType int transport, boolean bound) { 3093 log("onDataServiceBindingChanged: " + AccessNetworkConstants 3094 .transportTypeToString(transport) + " data service is " 3095 + (bound ? "bound." : "unbound.")); 3096 if (bound) { 3097 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 3098 () -> callback.onDataServiceBound(transport))); 3099 } 3100 mDataServiceBound.put(transport, bound); 3101 } 3102 3103 /** 3104 * Called when SIM is absent. 3105 */ onSimAbsent()3106 private void onSimAbsent() { 3107 log("onSimAbsent"); 3108 sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 3109 DataEvaluationReason.SIM_REMOVAL)); 3110 } 3111 3112 /** 3113 * Called when SIM state changes. 3114 * 3115 * @param simState SIM state. (Note this is mixed with card state and application state.) 3116 */ onSimStateChanged(@imState int simState)3117 private void onSimStateChanged(@SimState int simState) { 3118 log("onSimStateChanged: state=" + TelephonyManager.simStateToString(simState)); 3119 if (mSimState != simState) { 3120 mSimState = simState; 3121 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 3122 onSimAbsent(); 3123 } else if (simState == TelephonyManager.SIM_STATE_LOADED) { 3124 sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 3125 DataEvaluationReason.SIM_LOADED)); 3126 } 3127 } 3128 } 3129 3130 /** 3131 * Called when needed to evaluate the preferred transport for certain capability. 3132 * 3133 * @param capability The network capability to evaluate. 3134 */ onEvaluatePreferredTransport(@etCapability int capability)3135 private void onEvaluatePreferredTransport(@NetCapability int capability) { 3136 int preferredTransport = mAccessNetworksManager 3137 .getPreferredTransportByNetworkCapability(capability); 3138 log("onEvaluatePreferredTransport: " + DataUtils.networkCapabilityToString(capability) 3139 + " preferred on " 3140 + AccessNetworkConstants.transportTypeToString(preferredTransport)); 3141 for (DataNetwork dataNetwork : mDataNetworkList) { 3142 if (dataNetwork.getApnTypeNetworkCapability() == capability) { 3143 // Check if the data network's current transport is different than from the 3144 // preferred transport. If it's different, then handover is needed. 3145 if (dataNetwork.getTransport() == preferredTransport) { 3146 log("onEvaluatePreferredTransport:" + dataNetwork + " already on " 3147 + AccessNetworkConstants.transportTypeToString(preferredTransport)); 3148 continue; 3149 } 3150 3151 // If handover is ongoing, ignore the preference change for now. After handover 3152 // succeeds or fails, preferred transport will be re-evaluate again. Handover will 3153 // be performed at that time if needed. 3154 if (dataNetwork.isHandoverInProgress()) { 3155 log("onEvaluatePreferredTransport: " + dataNetwork + " handover in progress."); 3156 continue; 3157 } 3158 3159 tryHandoverDataNetwork(dataNetwork, preferredTransport, null/*handoverRetryEntry*/); 3160 } 3161 } 3162 } 3163 3164 /** 3165 * Perform data network handover if condition allows, otherwise tear down the network to allow 3166 * new network setup on the target transport. 3167 * 3168 * @param dataNetwork The network on which the handover occurs 3169 * @param targetTransport The target transport of the handover 3170 * @param dataHandoverRetryEntry {@code null} if the handover attempt is not due to scheduled 3171 * retry 3172 */ tryHandoverDataNetwork(@onNull DataNetwork dataNetwork, @TransportType int targetTransport, @Nullable DataHandoverRetryEntry dataHandoverRetryEntry)3173 private void tryHandoverDataNetwork(@NonNull DataNetwork dataNetwork, 3174 @TransportType int targetTransport, 3175 @Nullable DataHandoverRetryEntry dataHandoverRetryEntry) { 3176 if (dataHandoverRetryEntry == null // This handover is a new request 3177 && mDataRetryManager.isAnyHandoverRetryScheduled(dataNetwork)) { 3178 log("tryHandoverDataNetwork: retry scheduled for" + dataNetwork 3179 + ", ignore this attempt"); 3180 return; 3181 } 3182 DataEvaluation dataEvaluation = evaluateDataNetworkHandover(dataNetwork); 3183 log("tryHandoverDataNetwork: " + dataEvaluation + ", " + dataNetwork); 3184 if (!dataEvaluation.containsDisallowedReasons()) { 3185 logl("Start handover " + dataNetwork + " to " 3186 + AccessNetworkConstants.transportTypeToString(targetTransport)); 3187 dataNetwork.startHandover(targetTransport, dataHandoverRetryEntry); 3188 } else if (dataEvaluation.containsOnly(DataDisallowedReason.NOT_IN_SERVICE) 3189 && dataNetwork.shouldDelayImsTearDownDueToInCall()) { 3190 // We try to preserve voice call in the case of temporary preferred transport mismatch 3191 if (dataHandoverRetryEntry != null) { 3192 dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED); 3193 } 3194 mDataRetryManager.evaluateDataHandoverRetry(dataNetwork, 3195 DataFailCause.HANDOVER_FAILED, 3196 DataCallResponse.RETRY_DURATION_UNDEFINED /* retry mills */); 3197 logl("tryHandoverDataNetwork: Scheduled retry due to in voice call and target OOS"); 3198 } else if (dataEvaluation.containsAny(DataDisallowedReason.NOT_ALLOWED_BY_POLICY, 3199 DataDisallowedReason.NOT_IN_SERVICE, 3200 DataDisallowedReason.VOPS_NOT_SUPPORTED)) { 3201 logl("tryHandoverDataNetwork: Handover not allowed. Tear down" 3202 + dataNetwork + " so a new network can be setup on " 3203 + AccessNetworkConstants.transportTypeToString(targetTransport)); 3204 tearDownGracefully(dataNetwork, 3205 DataNetwork.TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED); 3206 } else if (dataEvaluation.containsAny(DataDisallowedReason.ILLEGAL_STATE, 3207 DataDisallowedReason.RETRY_SCHEDULED)) { 3208 logl("tryHandoverDataNetwork: Handover not allowed. " + dataNetwork 3209 + " will remain on " + AccessNetworkConstants.transportTypeToString( 3210 dataNetwork.getTransport())); 3211 } else { 3212 loge("tryHandoverDataNetwork: Unexpected handover evaluation result."); 3213 } 3214 } 3215 3216 /** 3217 * Update {@link SubscriptionPlan}s from {@link NetworkPolicyManager}. 3218 */ updateSubscriptionPlans()3219 private void updateSubscriptionPlans() { 3220 SubscriptionPlan[] plans = mNetworkPolicyManager.getSubscriptionPlans( 3221 mSubId, mPhone.getContext().getOpPackageName()); 3222 mSubscriptionPlans.clear(); 3223 mSubscriptionPlans.addAll(plans != null ? Arrays.asList(plans) : Collections.emptyList()); 3224 mCongestedOverrideNetworkTypes.clear(); 3225 mUnmeteredOverrideNetworkTypes.clear(); 3226 log("Subscription plans initialized: " + mSubscriptionPlans); 3227 } 3228 3229 /** 3230 * Called when data network's link status changed. 3231 * 3232 * @param dataNetwork The data network that has link status changed. 3233 * @param linkStatus The link status (i.e. RRC state). 3234 */ onLinkStatusChanged(@onNull DataNetwork dataNetwork, @LinkStatus int linkStatus)3235 private void onLinkStatusChanged(@NonNull DataNetwork dataNetwork, @LinkStatus int linkStatus) { 3236 // TODO: Since this is only used for 5G icon display logic, so we only use internet data 3237 // data network's link status. Consider expanding to all data networks if needed, and 3238 // should use CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL 3239 // to determine if using all data networks or only internet data networks. 3240 int status = DataCallResponse.LINK_STATUS_INACTIVE; 3241 boolean anyInternet = mDataNetworkList.stream() 3242 .anyMatch(network -> network.isInternetSupported() && network.isConnected()); 3243 if (anyInternet) { 3244 status = mDataNetworkList.stream() 3245 .anyMatch(network -> network.isInternetSupported() 3246 && network.isConnected() && network.getLinkStatus() 3247 == DataCallResponse.LINK_STATUS_ACTIVE) 3248 ? DataCallResponse.LINK_STATUS_ACTIVE 3249 : DataCallResponse.LINK_STATUS_DORMANT; 3250 } 3251 3252 if (mInternetLinkStatus != status) { 3253 log("Internet link status changed to " + DataUtils.linkStatusToString(status)); 3254 mInternetLinkStatus = status; 3255 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 3256 () -> callback.onPhysicalLinkStatusChanged(mInternetLinkStatus))); 3257 } 3258 3259 updateDataActivity(); 3260 } 3261 3262 /** 3263 * Called when PCO data changed. 3264 * 3265 * @param dataNetwork The data network. 3266 */ onPcoDataChanged(@onNull DataNetwork dataNetwork)3267 private void onPcoDataChanged(@NonNull DataNetwork dataNetwork) { 3268 // Check if any data network is using NR advanced bands. 3269 int nrAdvancedPcoId = mDataConfigManager.getNrAdvancedCapablePcoId(); 3270 if (nrAdvancedPcoId != 0) { 3271 boolean nrAdvancedCapableByPco = false; 3272 for (DataNetwork network : mDataNetworkList) { 3273 PcoData pcoData = network.getPcoData().get(nrAdvancedPcoId); 3274 if (pcoData != null && pcoData.contents.length > 0 3275 && pcoData.contents[pcoData.contents.length - 1] == 1) { 3276 nrAdvancedCapableByPco = true; 3277 break; 3278 } 3279 } 3280 3281 if (nrAdvancedCapableByPco != mNrAdvancedCapableByPco) { 3282 log("onPcoDataChanged: mNrAdvancedCapableByPco = " + nrAdvancedCapableByPco); 3283 mNrAdvancedCapableByPco = nrAdvancedCapableByPco; 3284 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 3285 () -> callback.onNrAdvancedCapableByPcoChanged(mNrAdvancedCapableByPco))); 3286 } 3287 } 3288 } 3289 3290 /** 3291 * Called when network capabilities changed. 3292 * 3293 * @param dataNetwork The data network. 3294 */ onNetworkCapabilitiesChanged(@onNull DataNetwork dataNetwork)3295 private void onNetworkCapabilitiesChanged(@NonNull DataNetwork dataNetwork) { 3296 // The network capabilities changed. See if there are unsatisfied network requests that 3297 // become satisfiable. 3298 NetworkRequestList networkRequestList = new NetworkRequestList(); 3299 for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) { 3300 if (networkRequest.getState() == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED) { 3301 if (networkRequest.canBeSatisfiedBy(dataNetwork.getNetworkCapabilities())) { 3302 networkRequestList.add(networkRequest); 3303 } 3304 } 3305 } 3306 3307 if (!networkRequestList.isEmpty()) { 3308 log("Found more network requests that can be satisfied. " + networkRequestList); 3309 dataNetwork.attachNetworkRequests(networkRequestList); 3310 } 3311 3312 if (dataNetwork.getNetworkCapabilities().hasCapability( 3313 NetworkCapabilities.NET_CAPABILITY_INTERNET)) { 3314 // Update because DataNetwork#isInternetSupported might have changed with capabilities. 3315 updateOverallInternetDataState(); 3316 } 3317 } 3318 3319 /** 3320 * Check if needed to re-evaluate the existing data networks. 3321 * 3322 * @param oldNri Previous network registration info. 3323 * @param newNri Current network registration info. 3324 * @return {@code true} if needed to re-evaluate the existing data networks. 3325 */ shouldReevaluateDataNetworks(@ullable NetworkRegistrationInfo oldNri, @Nullable NetworkRegistrationInfo newNri)3326 private boolean shouldReevaluateDataNetworks(@Nullable NetworkRegistrationInfo oldNri, 3327 @Nullable NetworkRegistrationInfo newNri) { 3328 if (oldNri == null || newNri == null) return false; 3329 if (newNri.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_UNKNOWN) { 3330 // Sometimes devices temporarily lose signal and RAT becomes unknown. We don't tear 3331 // down data network in this case. 3332 return false; 3333 } 3334 3335 if (oldNri.getAccessNetworkTechnology() != newNri.getAccessNetworkTechnology() 3336 || (!oldNri.isRoaming() && newNri.isRoaming())) { 3337 return true; 3338 } 3339 3340 DataSpecificRegistrationInfo oldDsri = oldNri.getDataSpecificInfo(); 3341 DataSpecificRegistrationInfo newDsri = newNri.getDataSpecificInfo(); 3342 3343 if (newDsri == null) return false; 3344 if ((oldDsri == null || oldDsri.getVopsSupportInfo() == null 3345 || oldDsri.getVopsSupportInfo().isVopsSupported()) 3346 && (newDsri.getVopsSupportInfo() != null && !newDsri.getVopsSupportInfo() 3347 .isVopsSupported())) { 3348 // If previously VoPS was supported (or does not exist), and now the network reports 3349 // VoPS not supported, we should evaluate existing data networks to see if they need 3350 // to be torn down. 3351 return true; 3352 } 3353 3354 return false; 3355 } 3356 3357 /** 3358 * Check if needed to re-evaluate the unsatisfied network requests. 3359 * 3360 * @param oldSS Previous raw service state. 3361 * @param newSS Current raw service state. 3362 * @param transport The network transport to be checked. 3363 * @return {@code true} if needed to re-evaluate the unsatisfied network requests. 3364 */ shouldReevaluateNetworkRequests(@onNull ServiceState oldSS, @NonNull ServiceState newSS, @TransportType int transport)3365 private boolean shouldReevaluateNetworkRequests(@NonNull ServiceState oldSS, 3366 @NonNull ServiceState newSS, @TransportType int transport) { 3367 NetworkRegistrationInfo oldPsNri = oldSS.getNetworkRegistrationInfo( 3368 NetworkRegistrationInfo.DOMAIN_PS, transport); 3369 NetworkRegistrationInfo newPsNri = newSS.getNetworkRegistrationInfo( 3370 NetworkRegistrationInfo.DOMAIN_PS, transport); 3371 3372 if (newPsNri == null) return false; 3373 if (newPsNri.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_UNKNOWN) { 3374 // Sometimes devices temporarily lose signal and RAT becomes unknown. We don't setup 3375 // data in this case. 3376 return false; 3377 } 3378 3379 if (oldPsNri == null 3380 || oldPsNri.getAccessNetworkTechnology() != newPsNri.getAccessNetworkTechnology() 3381 || (!oldPsNri.isInService() && newPsNri.isInService()) 3382 || (oldPsNri.isRoaming() && !newPsNri.isRoaming())) { 3383 return true; 3384 } 3385 3386 // If CS connection is back to service on non-DDS, reevaluate for potential PS 3387 if (!serviceStateAllowsPSAttach(oldSS, transport) 3388 && serviceStateAllowsPSAttach(newSS, transport)) { 3389 return true; 3390 } 3391 3392 DataSpecificRegistrationInfo oldDsri = oldPsNri.getDataSpecificInfo(); 3393 DataSpecificRegistrationInfo newDsri = newPsNri.getDataSpecificInfo(); 3394 3395 if (oldDsri == null) return false; 3396 if ((newDsri == null || newDsri.getVopsSupportInfo() == null 3397 || newDsri.getVopsSupportInfo().isVopsSupported()) 3398 && (oldDsri.getVopsSupportInfo() != null && !oldDsri.getVopsSupportInfo() 3399 .isVopsSupported())) { 3400 // If previously VoPS was not supported, and now the network reports 3401 // VoPS supported (or does not report), we should evaluate the unsatisfied network 3402 // request to see if the can be satisfied again. 3403 return true; 3404 } 3405 3406 return false; 3407 } 3408 3409 /** 3410 * Called when service state changed. 3411 */ 3412 // Note that this is only called when data RAT or data registration changed. If we need to know 3413 // more "changed" events other than data RAT and data registration state, we should add 3414 // a new listening ServiceStateTracker.registerForServiceStateChanged(). onServiceStateChanged()3415 private void onServiceStateChanged() { 3416 // Use the raw service state instead of the mPhone.getServiceState(). 3417 ServiceState newServiceState = mPhone.getServiceStateTracker().getServiceState(); 3418 StringBuilder debugMessage = new StringBuilder("onServiceStateChanged: "); 3419 boolean evaluateNetworkRequests = false, evaluateDataNetworks = false; 3420 3421 if (!mServiceState.equals(newServiceState)) { 3422 log("onServiceStateChanged: changed to " + newServiceState); 3423 for (int transport : mAccessNetworksManager.getAvailableTransports()) { 3424 NetworkRegistrationInfo oldNri = mServiceState.getNetworkRegistrationInfo( 3425 NetworkRegistrationInfo.DOMAIN_PS, transport); 3426 NetworkRegistrationInfo newNri = newServiceState.getNetworkRegistrationInfo( 3427 NetworkRegistrationInfo.DOMAIN_PS, transport); 3428 debugMessage.append("[").append( 3429 AccessNetworkConstants.transportTypeToString(transport)).append(": "); 3430 debugMessage.append(oldNri != null ? TelephonyManager.getNetworkTypeName( 3431 oldNri.getAccessNetworkTechnology()) : null); 3432 debugMessage.append("->").append( 3433 newNri != null ? TelephonyManager.getNetworkTypeName( 3434 newNri.getAccessNetworkTechnology()) : null).append(", "); 3435 debugMessage.append( 3436 oldNri != null ? NetworkRegistrationInfo.registrationStateToString( 3437 oldNri.getRegistrationState()) : null); 3438 debugMessage.append("->").append(newNri != null 3439 ? NetworkRegistrationInfo.registrationStateToString( 3440 newNri.getRegistrationState()) : null).append("] "); 3441 if (shouldReevaluateDataNetworks(oldNri, newNri)) { 3442 if (!hasMessages(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)) { 3443 sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, 3444 DataEvaluationReason.DATA_SERVICE_STATE_CHANGED)); 3445 evaluateDataNetworks = true; 3446 } 3447 } 3448 if (shouldReevaluateNetworkRequests(mServiceState, newServiceState, transport)) { 3449 if (!hasMessages(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS)) { 3450 sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, 3451 DataEvaluationReason.DATA_SERVICE_STATE_CHANGED)); 3452 evaluateNetworkRequests = true; 3453 } 3454 } 3455 } 3456 mServiceState = newServiceState; 3457 } else { 3458 debugMessage.append("not changed"); 3459 } 3460 debugMessage.append(". Evaluating network requests is ").append( 3461 evaluateNetworkRequests ? "" : "not ").append( 3462 "needed, evaluating existing data networks is ").append( 3463 evaluateDataNetworks ? "" : "not ").append("needed."); 3464 log(debugMessage.toString()); 3465 } 3466 3467 /** 3468 * Update the internet data network state. For now only {@link TelephonyManager#DATA_CONNECTED}, 3469 * {@link TelephonyManager#DATA_SUSPENDED}, and {@link TelephonyManager#DATA_DISCONNECTED} 3470 * are supported. 3471 */ updateOverallInternetDataState()3472 private void updateOverallInternetDataState() { 3473 boolean anyInternetConnected = mDataNetworkList.stream() 3474 .anyMatch(dataNetwork -> dataNetwork.isInternetSupported() 3475 && (dataNetwork.isConnected() || dataNetwork.isHandoverInProgress())); 3476 // If any one is not suspended, then the overall is not suspended. 3477 List<DataNetwork> allConnectedInternetDataNetworks = mDataNetworkList.stream() 3478 .filter(DataNetwork::isInternetSupported) 3479 .filter(dataNetwork -> dataNetwork.isConnected() 3480 || dataNetwork.isHandoverInProgress()) 3481 .collect(Collectors.toList()); 3482 boolean isSuspended = !allConnectedInternetDataNetworks.isEmpty() 3483 && allConnectedInternetDataNetworks.stream().allMatch(DataNetwork::isSuspended); 3484 logv("isSuspended=" + isSuspended + ", anyInternetConnected=" + anyInternetConnected 3485 + ", mDataNetworkList=" + mDataNetworkList); 3486 3487 int dataNetworkState = TelephonyManager.DATA_DISCONNECTED; 3488 if (isSuspended) { 3489 dataNetworkState = TelephonyManager.DATA_SUSPENDED; 3490 } else if (anyInternetConnected) { 3491 dataNetworkState = TelephonyManager.DATA_CONNECTED; 3492 } 3493 3494 if (mInternetDataNetworkState != dataNetworkState) { 3495 logl("Internet data state changed from " 3496 + TelephonyUtils.dataStateToString(mInternetDataNetworkState) + " to " 3497 + TelephonyUtils.dataStateToString(dataNetworkState) + "."); 3498 // TODO: Create a new route to notify TelephonyRegistry. 3499 if (dataNetworkState == TelephonyManager.DATA_CONNECTED 3500 && mInternetDataNetworkState == TelephonyManager.DATA_DISCONNECTED) { 3501 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 3502 () -> callback.onInternetDataNetworkConnected( 3503 allConnectedInternetDataNetworks))); 3504 } else if (dataNetworkState == TelephonyManager.DATA_DISCONNECTED 3505 && mInternetDataNetworkState == TelephonyManager.DATA_CONNECTED) { 3506 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( 3507 callback::onInternetDataNetworkDisconnected)); 3508 } // TODO: Add suspended callback if needed. 3509 mInternetDataNetworkState = dataNetworkState; 3510 } 3511 } 3512 3513 /** 3514 * @return Data config manager instance. 3515 */ getDataConfigManager()3516 public @NonNull DataConfigManager getDataConfigManager() { 3517 return mDataConfigManager; 3518 } 3519 3520 /** 3521 * @return Data profile manager instance. 3522 */ getDataProfileManager()3523 public @NonNull DataProfileManager getDataProfileManager() { 3524 return mDataProfileManager; 3525 } 3526 3527 /** 3528 * @return Data settings manager instance. 3529 */ getDataSettingsManager()3530 public @NonNull DataSettingsManager getDataSettingsManager() { 3531 return mDataSettingsManager; 3532 } 3533 3534 /** 3535 * @return Data retry manager instance. 3536 */ getDataRetryManager()3537 public @NonNull DataRetryManager getDataRetryManager() { 3538 return mDataRetryManager; 3539 } 3540 3541 /** 3542 * @return The list of SubscriptionPlans 3543 */ 3544 @VisibleForTesting getSubscriptionPlans()3545 public @NonNull List<SubscriptionPlan> getSubscriptionPlans() { 3546 return mSubscriptionPlans; 3547 } 3548 3549 /** 3550 * @return The set of network types an unmetered override applies to 3551 */ 3552 @VisibleForTesting getUnmeteredOverrideNetworkTypes()3553 public @NonNull @NetworkType Set<Integer> getUnmeteredOverrideNetworkTypes() { 3554 return mUnmeteredOverrideNetworkTypes; 3555 } 3556 3557 /** 3558 * @return The set of network types a congested override applies to 3559 */ 3560 @VisibleForTesting getCongestedOverrideNetworkTypes()3561 public @NonNull @NetworkType Set<Integer> getCongestedOverrideNetworkTypes() { 3562 return mCongestedOverrideNetworkTypes; 3563 } 3564 3565 /** 3566 * Get data network type based on transport. 3567 * 3568 * @param transport The transport. 3569 * @return The current network type. 3570 */ getDataNetworkType(@ransportType int transport)3571 private @NetworkType int getDataNetworkType(@TransportType int transport) { 3572 NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo( 3573 NetworkRegistrationInfo.DOMAIN_PS, transport); 3574 if (nri != null) { 3575 return nri.getAccessNetworkTechnology(); 3576 } 3577 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 3578 } 3579 3580 /** 3581 * Get data registration state based on transport. 3582 * 3583 * @param ss The service state from which to extract the data registration state. 3584 * @param transport The transport. 3585 * @return The registration state. 3586 */ getDataRegistrationState(@onNull ServiceState ss, @TransportType int transport)3587 private @RegistrationState int getDataRegistrationState(@NonNull ServiceState ss, 3588 @TransportType int transport) { 3589 NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo( 3590 NetworkRegistrationInfo.DOMAIN_PS, transport); 3591 if (nri != null) { 3592 return nri.getRegistrationState(); 3593 } 3594 return NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN; 3595 } 3596 3597 /** 3598 * @return The data activity. Note this is only updated when screen is on. 3599 */ getDataActivity()3600 public @DataActivityType int getDataActivity() { 3601 return mDataActivity; 3602 } 3603 3604 /** 3605 * Register data network controller callback. 3606 * 3607 * @param callback The callback. 3608 */ registerDataNetworkControllerCallback( @onNull DataNetworkControllerCallback callback)3609 public void registerDataNetworkControllerCallback( 3610 @NonNull DataNetworkControllerCallback callback) { 3611 sendMessage(obtainMessage(EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK, callback)); 3612 } 3613 3614 /** 3615 * Unregister data network controller callback. 3616 * 3617 * @param callback The callback. 3618 */ unregisterDataNetworkControllerCallback( @onNull DataNetworkControllerCallback callback)3619 public void unregisterDataNetworkControllerCallback( 3620 @NonNull DataNetworkControllerCallback callback) { 3621 sendMessage(obtainMessage(EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK, callback)); 3622 } 3623 3624 /** 3625 * Tear down all data networks. 3626 * 3627 * @param reason The reason to tear down. 3628 */ tearDownAllDataNetworks(@earDownReason int reason)3629 public void tearDownAllDataNetworks(@TearDownReason int reason) { 3630 sendMessage(obtainMessage(EVENT_TEAR_DOWN_ALL_DATA_NETWORKS, reason, 0)); 3631 } 3632 3633 /** 3634 * Called when needed to tear down all data networks. 3635 * 3636 * @param reason The reason to tear down. 3637 */ onTearDownAllDataNetworks(@earDownReason int reason)3638 public void onTearDownAllDataNetworks(@TearDownReason int reason) { 3639 log("onTearDownAllDataNetworks: reason=" + DataNetwork.tearDownReasonToString(reason)); 3640 if (mDataNetworkList.isEmpty()) { 3641 log("tearDownAllDataNetworks: No pending networks. All disconnected now."); 3642 return; 3643 } 3644 3645 mPendingTearDownAllNetworks = true; 3646 for (DataNetwork dataNetwork : mDataNetworkList) { 3647 if (!dataNetwork.isDisconnecting()) { 3648 tearDownGracefully(dataNetwork, reason); 3649 } 3650 } 3651 } 3652 3653 /** 3654 * Evaluate the pending IMS de-registration networks and tear it down if it is safe to do that. 3655 */ evaluatePendingImsDeregDataNetworks()3656 private void evaluatePendingImsDeregDataNetworks() { 3657 Iterator<Map.Entry<DataNetwork, Runnable>> it = 3658 mPendingImsDeregDataNetworks.entrySet().iterator(); 3659 while (it.hasNext()) { 3660 Map.Entry<DataNetwork, Runnable> entry = it.next(); 3661 if (isSafeToTearDown(entry.getKey())) { 3662 // Now tear down the network. 3663 log("evaluatePendingImsDeregDataNetworks: Safe to tear down data network " 3664 + entry.getKey() + " now."); 3665 entry.getValue().run(); 3666 it.remove(); 3667 } else { 3668 log("Still not safe to tear down " + entry.getKey() + "."); 3669 } 3670 } 3671 } 3672 3673 /** 3674 * Check if the data network is safe to tear down at this moment. 3675 * 3676 * @param dataNetwork The data network. 3677 * @return {@code true} if the data network is safe to tear down. {@code false} indicates this 3678 * data network has requests originated from the IMS/RCS service and IMS/RCS is not 3679 * de-registered yet. 3680 */ isSafeToTearDown(@onNull DataNetwork dataNetwork)3681 private boolean isSafeToTearDown(@NonNull DataNetwork dataNetwork) { 3682 for (int imsFeature : SUPPORTED_IMS_FEATURES) { 3683 String imsFeaturePackage = mImsFeaturePackageName.get(imsFeature); 3684 if (imsFeaturePackage != null) { 3685 if (dataNetwork.getAttachedNetworkRequestList() 3686 .hasNetworkRequestsFromPackage(imsFeaturePackage)) { 3687 if (mRegisteredImsFeatures.contains(imsFeature)) { 3688 return false; 3689 } 3690 } 3691 } 3692 } 3693 // All IMS features are de-registered (or this data network has no requests from IMS feature 3694 // packages. 3695 return true; 3696 } 3697 3698 /** 3699 * @return {@code true} if IMS graceful tear down is supported by frameworks. 3700 */ isImsGracefulTearDownSupported()3701 private boolean isImsGracefulTearDownSupported() { 3702 return mDataConfigManager.getImsDeregistrationDelay() > 0; 3703 } 3704 3705 /** 3706 * Tear down the data network gracefully. 3707 * 3708 * @param dataNetwork The data network. 3709 */ tearDownGracefully(@onNull DataNetwork dataNetwork, @TearDownReason int reason)3710 private void tearDownGracefully(@NonNull DataNetwork dataNetwork, @TearDownReason int reason) { 3711 long deregDelay = mDataConfigManager.getImsDeregistrationDelay(); 3712 if (isImsGracefulTearDownSupported() && !isSafeToTearDown(dataNetwork)) { 3713 log("tearDownGracefully: Not safe to tear down " + dataNetwork 3714 + " at this point. Wait for IMS de-registration or timeout. MMTEL=" 3715 + (mRegisteredImsFeatures.contains(ImsFeature.FEATURE_MMTEL) 3716 ? "registered" : "not registered") 3717 + ", RCS=" 3718 + (mRegisteredImsFeatures.contains(ImsFeature.FEATURE_RCS) 3719 ? "registered" : "not registered") 3720 ); 3721 Runnable runnable = dataNetwork.tearDownWhenConditionMet(reason, deregDelay); 3722 if (runnable != null) { 3723 mPendingImsDeregDataNetworks.put(dataNetwork, runnable); 3724 } else { 3725 log(dataNetwork + " is being torn down already."); 3726 } 3727 } else { 3728 // Graceful tear down is not turned on. Tear down the network immediately. 3729 log("tearDownGracefully: Safe to tear down " + dataNetwork); 3730 dataNetwork.tearDown(reason); 3731 } 3732 } 3733 3734 /** 3735 * Get the internet data network state. Note that this is the best effort if more than one 3736 * data network supports internet. For now only {@link TelephonyManager#DATA_CONNECTED}, 3737 * {@link TelephonyManager#DATA_SUSPENDED}, and {@link TelephonyManager#DATA_DISCONNECTED} 3738 * are supported. 3739 * 3740 * @return The data network state. 3741 */ getInternetDataNetworkState()3742 public @DataState int getInternetDataNetworkState() { 3743 return mInternetDataNetworkState; 3744 } 3745 3746 /** 3747 * @return List of bound data service packages name on WWAN and WLAN. 3748 */ getDataServicePackages()3749 public @NonNull List<String> getDataServicePackages() { 3750 List<String> packages = new ArrayList<>(); 3751 for (int i = 0; i < mDataServiceManagers.size(); i++) { 3752 packages.add(mDataServiceManagers.valueAt(i).getDataServicePackageName()); 3753 } 3754 return packages; 3755 } 3756 3757 /** 3758 * Log debug messages. 3759 * @param s debug messages 3760 */ log(@onNull String s)3761 private void log(@NonNull String s) { 3762 Rlog.d(mLogTag, s); 3763 } 3764 3765 /** 3766 * Log error messages. 3767 * @param s error messages 3768 */ loge(@onNull String s)3769 private void loge(@NonNull String s) { 3770 Rlog.e(mLogTag, s); 3771 } 3772 3773 /** 3774 * Log verbose messages. 3775 * @param s debug messages. 3776 */ logv(@onNull String s)3777 private void logv(@NonNull String s) { 3778 if (VDBG) Rlog.v(mLogTag, s); 3779 } 3780 3781 /** 3782 * Log debug messages and also log into the local log. 3783 * @param s debug messages 3784 */ logl(@onNull String s)3785 private void logl(@NonNull String s) { 3786 log(s); 3787 mLocalLog.log(s); 3788 } 3789 3790 /** 3791 * Dump the state of DataNetworkController 3792 * 3793 * @param fd File descriptor 3794 * @param printWriter Print writer 3795 * @param args Arguments 3796 */ dump(FileDescriptor fd, PrintWriter printWriter, String[] args)3797 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 3798 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 3799 pw.println(DataNetworkController.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":"); 3800 pw.increaseIndent(); 3801 pw.println("Current data networks:"); 3802 pw.increaseIndent(); 3803 for (DataNetwork dn : mDataNetworkList) { 3804 dn.dump(fd, pw, args); 3805 } 3806 pw.decreaseIndent(); 3807 3808 pw.println("Pending tear down data networks:"); 3809 pw.increaseIndent(); 3810 for (DataNetwork dn : mPendingImsDeregDataNetworks.keySet()) { 3811 dn.dump(fd, pw, args); 3812 } 3813 pw.decreaseIndent(); 3814 3815 pw.println("Previously connected data networks: (up to " 3816 + MAX_HISTORICAL_CONNECTED_DATA_NETWORKS + ")"); 3817 pw.increaseIndent(); 3818 for (DataNetwork dn: mPreviousConnectedDataNetworkList) { 3819 // Do not print networks which is already in current network list. 3820 if (!mDataNetworkList.contains(dn)) { 3821 dn.dump(fd, pw, args); 3822 } 3823 } 3824 pw.decreaseIndent(); 3825 3826 pw.println("All telephony network requests:"); 3827 pw.increaseIndent(); 3828 for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) { 3829 pw.println(networkRequest); 3830 } 3831 pw.decreaseIndent(); 3832 3833 pw.println("IMS features registration state: MMTEL=" 3834 + (mRegisteredImsFeatures.contains(ImsFeature.FEATURE_MMTEL) 3835 ? "registered" : "not registered") 3836 + ", RCS=" 3837 + (mRegisteredImsFeatures.contains(ImsFeature.FEATURE_RCS) 3838 ? "registered" : "not registered")); 3839 pw.println("mServiceState=" + mServiceState); 3840 pw.println("mPsRestricted=" + mPsRestricted); 3841 pw.println("mAnyDataNetworkExisting=" + mAnyDataNetworkExisting); 3842 pw.println("mInternetDataNetworkState=" 3843 + TelephonyUtils.dataStateToString(mInternetDataNetworkState)); 3844 pw.println("mImsDataNetworkState=" 3845 + TelephonyUtils.dataStateToString(mImsDataNetworkState)); 3846 pw.println("mDataServiceBound=" + mDataServiceBound); 3847 pw.println("mIsSrvccHandoverInProcess=" + mIsSrvccHandoverInProcess); 3848 pw.println("mSimState=" + TelephonyManager.simStateToString(mSimState)); 3849 pw.println("mDataNetworkControllerCallbacks=" + mDataNetworkControllerCallbacks); 3850 pw.println("Subscription plans:"); 3851 pw.increaseIndent(); 3852 mSubscriptionPlans.forEach(pw::println); 3853 pw.decreaseIndent(); 3854 pw.println("Unmetered override network types=" + mUnmeteredOverrideNetworkTypes.stream() 3855 .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(","))); 3856 pw.println("Congested override network types=" + mCongestedOverrideNetworkTypes.stream() 3857 .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(","))); 3858 pw.println("mImsThrottleCounter=" + mImsThrottleCounter); 3859 pw.println("mNetworkUnwantedCounter=" + mNetworkUnwantedCounter); 3860 pw.println("Local logs:"); 3861 pw.increaseIndent(); 3862 mLocalLog.dump(fd, pw, args); 3863 pw.decreaseIndent(); 3864 3865 pw.println("-------------------------------------"); 3866 mDataProfileManager.dump(fd, pw, args); 3867 pw.println("-------------------------------------"); 3868 mDataRetryManager.dump(fd, pw, args); 3869 pw.println("-------------------------------------"); 3870 mDataSettingsManager.dump(fd, pw, args); 3871 pw.println("-------------------------------------"); 3872 mDataStallRecoveryManager.dump(fd, pw, args); 3873 pw.println("-------------------------------------"); 3874 mDataConfigManager.dump(fd, pw, args); 3875 3876 pw.decreaseIndent(); 3877 } 3878 } 3879