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