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