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