1 /*
2  * Copyright (C) 2008 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.server;
18 
19 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
20 import static android.content.pm.PackageManager.FEATURE_BLUETOOTH;
21 import static android.content.pm.PackageManager.FEATURE_WATCH;
22 import static android.content.pm.PackageManager.FEATURE_WIFI;
23 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT;
24 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
25 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
26 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
27 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT;
28 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS;
29 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS;
30 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
31 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
32 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
33 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
34 import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
35 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
36 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
37 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
38 import static android.net.ConnectivityManager.TYPE_ETHERNET;
39 import static android.net.ConnectivityManager.TYPE_MOBILE;
40 import static android.net.ConnectivityManager.TYPE_MOBILE_CBS;
41 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
42 import static android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY;
43 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
44 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
45 import static android.net.ConnectivityManager.TYPE_MOBILE_IA;
46 import static android.net.ConnectivityManager.TYPE_MOBILE_IMS;
47 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
48 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
49 import static android.net.ConnectivityManager.TYPE_NONE;
50 import static android.net.ConnectivityManager.TYPE_PROXY;
51 import static android.net.ConnectivityManager.TYPE_VPN;
52 import static android.net.ConnectivityManager.TYPE_WIFI;
53 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
54 import static android.net.ConnectivityManager.getNetworkTypeName;
55 import static android.net.ConnectivityManager.isNetworkTypeValid;
56 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
57 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
58 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
59 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
60 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
61 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
62 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
63 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
64 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
65 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
66 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
67 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
68 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
69 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
70 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
71 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
72 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
73 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
74 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
75 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
76 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
77 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
78 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
79 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
80 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
81 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
82 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
83 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST;
84 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY;
85 import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
86 import static android.os.Process.INVALID_UID;
87 import static android.os.Process.VPN_UID;
88 import static android.system.OsConstants.IPPROTO_TCP;
89 import static android.system.OsConstants.IPPROTO_UDP;
90 
91 import static java.util.Map.Entry;
92 
93 import android.Manifest;
94 import android.annotation.NonNull;
95 import android.annotation.Nullable;
96 import android.app.AppOpsManager;
97 import android.app.BroadcastOptions;
98 import android.app.PendingIntent;
99 import android.app.usage.NetworkStatsManager;
100 import android.content.BroadcastReceiver;
101 import android.content.ComponentName;
102 import android.content.ContentResolver;
103 import android.content.Context;
104 import android.content.Intent;
105 import android.content.IntentFilter;
106 import android.content.pm.PackageManager;
107 import android.database.ContentObserver;
108 import android.net.CaptivePortal;
109 import android.net.CaptivePortalData;
110 import android.net.ConnectionInfo;
111 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
112 import android.net.ConnectivityDiagnosticsManager.DataStallReport;
113 import android.net.ConnectivityManager;
114 import android.net.ConnectivityManager.BlockedReason;
115 import android.net.ConnectivityManager.NetworkCallback;
116 import android.net.ConnectivityManager.RestrictBackgroundStatus;
117 import android.net.ConnectivityResources;
118 import android.net.ConnectivitySettingsManager;
119 import android.net.DataStallReportParcelable;
120 import android.net.DnsResolverServiceManager;
121 import android.net.ICaptivePortal;
122 import android.net.IConnectivityDiagnosticsCallback;
123 import android.net.IConnectivityManager;
124 import android.net.IDnsResolver;
125 import android.net.INetd;
126 import android.net.INetworkActivityListener;
127 import android.net.INetworkAgent;
128 import android.net.INetworkMonitor;
129 import android.net.INetworkMonitorCallbacks;
130 import android.net.INetworkOfferCallback;
131 import android.net.IOnCompleteListener;
132 import android.net.IQosCallback;
133 import android.net.ISocketKeepaliveCallback;
134 import android.net.InetAddresses;
135 import android.net.IpMemoryStore;
136 import android.net.IpPrefix;
137 import android.net.LinkProperties;
138 import android.net.MatchAllNetworkSpecifier;
139 import android.net.NativeNetworkConfig;
140 import android.net.NativeNetworkType;
141 import android.net.NattSocketKeepalive;
142 import android.net.Network;
143 import android.net.NetworkAgent;
144 import android.net.NetworkAgentConfig;
145 import android.net.NetworkCapabilities;
146 import android.net.NetworkInfo;
147 import android.net.NetworkInfo.DetailedState;
148 import android.net.NetworkMonitorManager;
149 import android.net.NetworkPolicyManager;
150 import android.net.NetworkPolicyManager.NetworkPolicyCallback;
151 import android.net.NetworkProvider;
152 import android.net.NetworkRequest;
153 import android.net.NetworkScore;
154 import android.net.NetworkSpecifier;
155 import android.net.NetworkStack;
156 import android.net.NetworkState;
157 import android.net.NetworkStateSnapshot;
158 import android.net.NetworkTestResultParcelable;
159 import android.net.NetworkUtils;
160 import android.net.NetworkWatchlistManager;
161 import android.net.OemNetworkPreferences;
162 import android.net.PrivateDnsConfigParcel;
163 import android.net.ProxyInfo;
164 import android.net.QosCallbackException;
165 import android.net.QosFilter;
166 import android.net.QosSocketFilter;
167 import android.net.QosSocketInfo;
168 import android.net.RouteInfo;
169 import android.net.RouteInfoParcel;
170 import android.net.SocketKeepalive;
171 import android.net.TetheringManager;
172 import android.net.TransportInfo;
173 import android.net.UidRange;
174 import android.net.UidRangeParcel;
175 import android.net.UnderlyingNetworkInfo;
176 import android.net.Uri;
177 import android.net.VpnManager;
178 import android.net.VpnTransportInfo;
179 import android.net.metrics.IpConnectivityLog;
180 import android.net.metrics.NetworkEvent;
181 import android.net.netd.aidl.NativeUidRangeConfig;
182 import android.net.netlink.InetDiagMessage;
183 import android.net.networkstack.ModuleNetworkStackClient;
184 import android.net.networkstack.NetworkStackClientBase;
185 import android.net.resolv.aidl.DnsHealthEventParcel;
186 import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener;
187 import android.net.resolv.aidl.Nat64PrefixEventParcel;
188 import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
189 import android.net.shared.PrivateDnsConfig;
190 import android.net.util.MultinetworkPolicyTracker;
191 import android.os.BatteryStatsManager;
192 import android.os.Binder;
193 import android.os.Build;
194 import android.os.Bundle;
195 import android.os.Handler;
196 import android.os.HandlerThread;
197 import android.os.IBinder;
198 import android.os.Looper;
199 import android.os.Message;
200 import android.os.Messenger;
201 import android.os.ParcelFileDescriptor;
202 import android.os.Parcelable;
203 import android.os.PersistableBundle;
204 import android.os.PowerManager;
205 import android.os.Process;
206 import android.os.RemoteCallbackList;
207 import android.os.RemoteException;
208 import android.os.ServiceSpecificException;
209 import android.os.SystemClock;
210 import android.os.SystemProperties;
211 import android.os.UserHandle;
212 import android.os.UserManager;
213 import android.provider.Settings;
214 import android.sysprop.NetworkProperties;
215 import android.telephony.TelephonyManager;
216 import android.text.TextUtils;
217 import android.util.ArrayMap;
218 import android.util.ArraySet;
219 import android.util.LocalLog;
220 import android.util.Log;
221 import android.util.Pair;
222 import android.util.SparseArray;
223 import android.util.SparseIntArray;
224 
225 import com.android.connectivity.resources.R;
226 import com.android.internal.annotations.GuardedBy;
227 import com.android.internal.annotations.VisibleForTesting;
228 import com.android.internal.util.IndentingPrintWriter;
229 import com.android.internal.util.MessageUtils;
230 import com.android.modules.utils.BasicShellCommandHandler;
231 import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
232 import com.android.net.module.util.CollectionUtils;
233 import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
234 import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
235 import com.android.net.module.util.LocationPermissionChecker;
236 import com.android.net.module.util.NetworkCapabilitiesUtils;
237 import com.android.net.module.util.PermissionUtils;
238 import com.android.server.connectivity.AutodestructReference;
239 import com.android.server.connectivity.DnsManager;
240 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
241 import com.android.server.connectivity.FullScore;
242 import com.android.server.connectivity.KeepaliveTracker;
243 import com.android.server.connectivity.LingerMonitor;
244 import com.android.server.connectivity.MockableSystemProperties;
245 import com.android.server.connectivity.NetworkAgentInfo;
246 import com.android.server.connectivity.NetworkDiagnostics;
247 import com.android.server.connectivity.NetworkNotificationManager;
248 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
249 import com.android.server.connectivity.NetworkOffer;
250 import com.android.server.connectivity.NetworkRanker;
251 import com.android.server.connectivity.PermissionMonitor;
252 import com.android.server.connectivity.ProfileNetworkPreferences;
253 import com.android.server.connectivity.ProxyTracker;
254 import com.android.server.connectivity.QosCallbackTracker;
255 
256 import libcore.io.IoUtils;
257 
258 import java.io.FileDescriptor;
259 import java.io.PrintWriter;
260 import java.net.Inet4Address;
261 import java.net.InetAddress;
262 import java.net.InetSocketAddress;
263 import java.net.UnknownHostException;
264 import java.util.ArrayList;
265 import java.util.Arrays;
266 import java.util.Collection;
267 import java.util.Collections;
268 import java.util.Comparator;
269 import java.util.ConcurrentModificationException;
270 import java.util.HashMap;
271 import java.util.HashSet;
272 import java.util.List;
273 import java.util.Map;
274 import java.util.Objects;
275 import java.util.Set;
276 import java.util.SortedSet;
277 import java.util.StringJoiner;
278 import java.util.TreeSet;
279 import java.util.concurrent.atomic.AtomicInteger;
280 
281 /**
282  * @hide
283  */
284 public class ConnectivityService extends IConnectivityManager.Stub
285         implements PendingIntent.OnFinished {
286     private static final String TAG = ConnectivityService.class.getSimpleName();
287 
288     private static final String DIAG_ARG = "--diag";
289     public static final String SHORT_ARG = "--short";
290     private static final String NETWORK_ARG = "networks";
291     private static final String REQUEST_ARG = "requests";
292 
293     private static final boolean DBG = true;
294     private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
295     private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
296 
297     private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
298 
299     /**
300      * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed
301      * by OEMs for configuration purposes, as this value is overridden by
302      * ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL.
303      * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose
304      * (preferably via runtime resource overlays).
305      */
306     private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL =
307             "http://connectivitycheck.gstatic.com/generate_204";
308 
309     // TODO: create better separation between radio types and network types
310 
311     // how long to wait before switching back to a radio's default network
312     private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
313     // system property that can override the above value
314     private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
315             "android.telephony.apn-restore";
316 
317     // How long to wait before putting up a "This network doesn't have an Internet connection,
318     // connect anyway?" dialog after the user selects a network that doesn't validate.
319     private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
320 
321     // Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing.
322     private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
323     private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
324     private static final int DEFAULT_NASCENT_DELAY_MS = 5_000;
325 
326     // The maximum number of network request allowed per uid before an exception is thrown.
327     @VisibleForTesting
328     static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
329 
330     // The maximum number of network request allowed for system UIDs before an exception is thrown.
331     @VisibleForTesting
332     static final int MAX_NETWORK_REQUESTS_PER_SYSTEM_UID = 250;
333 
334     @VisibleForTesting
335     protected int mLingerDelayMs;  // Can't be final, or test subclass constructors can't change it.
336     @VisibleForTesting
337     protected int mNascentDelayMs;
338 
339     // How long to delay to removal of a pending intent based request.
340     // See ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
341     private final int mReleasePendingIntentDelayMs;
342 
343     private MockableSystemProperties mSystemProperties;
344 
345     @VisibleForTesting
346     protected final PermissionMonitor mPermissionMonitor;
347 
348     @VisibleForTesting
349     final PerUidCounter mNetworkRequestCounter;
350     @VisibleForTesting
351     final PerUidCounter mSystemNetworkRequestCounter;
352 
353     private volatile boolean mLockdownEnabled;
354 
355     /**
356      * Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in
357      * internal handler thread, they don't need a lock.
358      */
359     private SparseIntArray mUidBlockedReasons = new SparseIntArray();
360 
361     private final Context mContext;
362     private final ConnectivityResources mResources;
363     // The Context is created for UserHandle.ALL.
364     private final Context mUserAllContext;
365     private final Dependencies mDeps;
366     // 0 is full bad, 100 is full good
367     private int mDefaultInetConditionPublished = 0;
368 
369     @VisibleForTesting
370     protected IDnsResolver mDnsResolver;
371     @VisibleForTesting
372     protected INetd mNetd;
373     private NetworkStatsManager mStatsManager;
374     private NetworkPolicyManager mPolicyManager;
375     private final NetdCallback mNetdCallback;
376 
377     /**
378      * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
379      * instances.
380      */
381     @GuardedBy("mTNSLock")
382     private TestNetworkService mTNS;
383 
384     private final Object mTNSLock = new Object();
385 
386     private String mCurrentTcpBufferSizes;
387 
388     private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
389             new Class[] { ConnectivityService.class, NetworkAgent.class, NetworkAgentInfo.class });
390 
391     private enum ReapUnvalidatedNetworks {
392         // Tear down networks that have no chance (e.g. even if validated) of becoming
393         // the highest scoring network satisfying a NetworkRequest.  This should be passed when
394         // all networks have been rematched against all NetworkRequests.
395         REAP,
396         // Don't reap networks.  This should be passed when some networks have not yet been
397         // rematched against all NetworkRequests.
398         DONT_REAP
399     }
400 
401     private enum UnneededFor {
402         LINGER,    // Determine whether this network is unneeded and should be lingered.
403         TEARDOWN,  // Determine whether this network is unneeded and should be torn down.
404     }
405 
406     /**
407      * For per-app preferences, requests contain an int to signify which request
408      * should have priority. The priority is passed to netd which will use it
409      * together with UID ranges to generate the corresponding IP rule. This serves
410      * to direct device-originated data traffic of the specific UIDs to the correct
411      * default network for each app.
412      * Priorities passed to netd must be in the 0~999 range. Larger values code for
413      * a lower priority, {@see NativeUidRangeConfig}
414      *
415      * Requests that don't code for a per-app preference use PREFERENCE_PRIORITY_INVALID.
416      * The default request uses PREFERENCE_PRIORITY_DEFAULT.
417      */
418     // Bound for the lowest valid priority.
419     static final int PREFERENCE_PRIORITY_LOWEST = 999;
420     // Used when sending to netd to code for "no priority".
421     static final int PREFERENCE_PRIORITY_NONE = 0;
422     // Priority for requests that don't code for a per-app preference. As it is
423     // out of the valid range, the corresponding priority should be
424     // PREFERENCE_PRIORITY_NONE when sending to netd.
425     @VisibleForTesting
426     static final int PREFERENCE_PRIORITY_INVALID = Integer.MAX_VALUE;
427     // Priority for the default internet request. Since this must always have the
428     // lowest priority, its value is larger than the largest acceptable value. As
429     // it is out of the valid range, the corresponding priority should be
430     // PREFERENCE_PRIORITY_NONE when sending to netd.
431     static final int PREFERENCE_PRIORITY_DEFAULT = 1000;
432     // As a security feature, VPNs have the top priority.
433     static final int PREFERENCE_PRIORITY_VPN = 0; // Netd supports only 0 for VPN.
434     // Priority of per-app OEM preference. See {@link #setOemNetworkPreference}.
435     @VisibleForTesting
436     static final int PREFERENCE_PRIORITY_OEM = 10;
437     // Priority of per-profile preference, such as used by enterprise networks.
438     // See {@link #setProfileNetworkPreference}.
439     @VisibleForTesting
440     static final int PREFERENCE_PRIORITY_PROFILE = 20;
441     // Priority of user setting to prefer mobile data even when networks with
442     // better scores are connected.
443     // See {@link ConnectivitySettingsManager#setMobileDataPreferredUids}
444     @VisibleForTesting
445     static final int PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED = 30;
446 
447     /**
448      * used internally to clear a wakelock when transitioning
449      * from one net to another.  Clear happens when we get a new
450      * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens
451      * after a timeout if no network is found (typically 1 min).
452      */
453     private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
454 
455     /**
456      * used internally to reload global proxy settings
457      */
458     private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
459 
460     /**
461      * PAC manager has received new port.
462      */
463     private static final int EVENT_PROXY_HAS_CHANGED = 16;
464 
465     /**
466      * used internally when registering NetworkProviders
467      * obj = NetworkProviderInfo
468      */
469     private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17;
470 
471     /**
472      * used internally when registering NetworkAgents
473      * obj = Messenger
474      */
475     private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
476 
477     /**
478      * used to add a network request
479      * includes a NetworkRequestInfo
480      */
481     private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
482 
483     /**
484      * indicates a timeout period is over - check if we had a network yet or not
485      * and if not, call the timeout callback (but leave the request live until they
486      * cancel it.
487      * includes a NetworkRequestInfo
488      */
489     private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
490 
491     /**
492      * used to add a network listener - no request
493      * includes a NetworkRequestInfo
494      */
495     private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
496 
497     /**
498      * used to remove a network request, either a listener or a real request
499      * arg1 = UID of caller
500      * obj  = NetworkRequest
501      */
502     private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
503 
504     /**
505      * used internally when registering NetworkProviders
506      * obj = Messenger
507      */
508     private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23;
509 
510     /**
511      * used internally to expire a wakelock when transitioning
512      * from one net to another.  Expire happens when we fail to find
513      * a new network (typically after 1 minute) -
514      * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found
515      * a replacement network.
516      */
517     private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
518 
519     /**
520      * used to add a network request with a pending intent
521      * obj = NetworkRequestInfo
522      */
523     private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
524 
525     /**
526      * used to remove a pending intent and its associated network request.
527      * arg1 = UID of caller
528      * obj  = PendingIntent
529      */
530     private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
531 
532     /**
533      * used to specify whether a network should be used even if unvalidated.
534      * arg1 = whether to accept the network if it's unvalidated (1 or 0)
535      * arg2 = whether to remember this choice in the future (1 or 0)
536      * obj  = network
537      */
538     private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
539 
540     /**
541      * used to ask the user to confirm a connection to an unvalidated network.
542      * obj  = network
543      */
544     private static final int EVENT_PROMPT_UNVALIDATED = 29;
545 
546     /**
547      * used internally to (re)configure always-on networks.
548      */
549     private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
550 
551     /**
552      * used to add a network listener with a pending intent
553      * obj = NetworkRequestInfo
554      */
555     private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
556 
557     /**
558      * used to specify whether a network should not be penalized when it becomes unvalidated.
559      */
560     private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
561 
562     /**
563      * used to trigger revalidation of a network.
564      */
565     private static final int EVENT_REVALIDATE_NETWORK = 36;
566 
567     // Handle changes in Private DNS settings.
568     private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37;
569 
570     // Handle private DNS validation status updates.
571     private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
572 
573      /**
574       * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
575       * been tested.
576       * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor.
577       * data = PersistableBundle of extras passed from NetworkMonitor. If {@link
578       * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null.
579       */
580     private static final int EVENT_NETWORK_TESTED = 41;
581 
582     /**
583      * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS
584      * config was resolved.
585      * obj = PrivateDnsConfig
586      * arg2 = netid
587      */
588     private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42;
589 
590     /**
591      * Request ConnectivityService display provisioning notification.
592      * arg1    = Whether to make the notification visible.
593      * arg2    = NetID.
594      * obj     = Intent to be launched when notification selected by user, null if !arg1.
595      */
596     private static final int EVENT_PROVISIONING_NOTIFICATION = 43;
597 
598     /**
599      * Used to specify whether a network should be used even if connectivity is partial.
600      * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for
601      * false)
602      * arg2 = whether to remember this choice in the future (1 for true or 0 for false)
603      * obj  = network
604      */
605     private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44;
606 
607     /**
608      * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
609      * Both of the arguments are bitmasks, and the value of bits come from
610      * INetworkMonitor.NETWORK_VALIDATION_PROBE_*.
611      * arg1 = A bitmask to describe which probes are completed.
612      * arg2 = A bitmask to describe which probes are successful.
613      */
614     public static final int EVENT_PROBE_STATUS_CHANGED = 45;
615 
616     /**
617      * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
618      * arg1 = unused
619      * arg2 = netId
620      * obj = captive portal data
621      */
622     private static final int EVENT_CAPPORT_DATA_CHANGED = 46;
623 
624     /**
625      * Used by setRequireVpnForUids.
626      * arg1 = whether the specified UID ranges are required to use a VPN.
627      * obj  = Array of UidRange objects.
628      */
629     private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47;
630 
631     /**
632      * Used internally when setting the default networks for OemNetworkPreferences.
633      * obj = Pair<OemNetworkPreferences, listener>
634      */
635     private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48;
636 
637     /**
638      * Used to indicate the system default network becomes active.
639      */
640     private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49;
641 
642     /**
643      * Used internally when setting a network preference for a user profile.
644      * obj = Pair<ProfileNetworkPreference, Listener>
645      */
646     private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50;
647 
648     /**
649      * Event to specify that reasons for why an uid is blocked changed.
650      * arg1 = uid
651      * arg2 = blockedReasons
652      */
653     private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51;
654 
655     /**
656      * Event to register a new network offer
657      * obj = NetworkOffer
658      */
659     private static final int EVENT_REGISTER_NETWORK_OFFER = 52;
660 
661     /**
662      * Event to unregister an existing network offer
663      * obj = INetworkOfferCallback
664      */
665     private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53;
666 
667     /**
668      * Used internally when MOBILE_DATA_PREFERRED_UIDS setting changed.
669      */
670     private static final int EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED = 54;
671 
672     /**
673      * Event to set temporary allow bad wifi within a limited time to override
674      * {@code config_networkAvoidBadWifi}.
675      */
676     private static final int EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL = 55;
677 
678     /**
679      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
680      * should be shown.
681      */
682     private static final int PROVISIONING_NOTIFICATION_SHOW = 1;
683 
684     /**
685      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
686      * should be hidden.
687      */
688     private static final int PROVISIONING_NOTIFICATION_HIDE = 0;
689 
690     /**
691      * The maximum alive time to allow bad wifi configuration for testing.
692      */
693     private static final long MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS = 5 * 60 * 1000L;
694 
eventName(int what)695     private static String eventName(int what) {
696         return sMagicDecoderRing.get(what, Integer.toString(what));
697     }
698 
getDnsResolver(Context context)699     private static IDnsResolver getDnsResolver(Context context) {
700         final DnsResolverServiceManager dsm = context.getSystemService(
701                 DnsResolverServiceManager.class);
702         return IDnsResolver.Stub.asInterface(dsm.getService());
703     }
704 
705     /** Handler thread used for all of the handlers below. */
706     @VisibleForTesting
707     protected final HandlerThread mHandlerThread;
708     /** Handler used for internal events. */
709     final private InternalHandler mHandler;
710     /** Handler used for incoming {@link NetworkStateTracker} events. */
711     final private NetworkStateTrackerHandler mTrackerHandler;
712     /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */
713     @VisibleForTesting
714     final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler;
715 
716     private final DnsManager mDnsManager;
717     private final NetworkRanker mNetworkRanker;
718 
719     private boolean mSystemReady;
720     private Intent mInitialBroadcast;
721 
722     private PowerManager.WakeLock mNetTransitionWakeLock;
723     private final PowerManager.WakeLock mPendingIntentWakeLock;
724 
725     // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell
726     // the world when it changes.
727     @VisibleForTesting
728     protected final ProxyTracker mProxyTracker;
729 
730     final private SettingsObserver mSettingsObserver;
731 
732     private UserManager mUserManager;
733 
734     // the set of network types that can only be enabled by system/sig apps
735     private List<Integer> mProtectedNetworks;
736 
737     private Set<String> mWolSupportedInterfaces;
738 
739     private final TelephonyManager mTelephonyManager;
740     private final AppOpsManager mAppOpsManager;
741 
742     private final LocationPermissionChecker mLocationPermissionChecker;
743 
744     private KeepaliveTracker mKeepaliveTracker;
745     private QosCallbackTracker mQosCallbackTracker;
746     private NetworkNotificationManager mNotifier;
747     private LingerMonitor mLingerMonitor;
748 
749     // sequence number of NetworkRequests
750     private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID;
751 
752     // Sequence number for NetworkProvider IDs.
753     private final AtomicInteger mNextNetworkProviderId = new AtomicInteger(
754             NetworkProvider.FIRST_PROVIDER_ID);
755 
756     // NetworkRequest activity String log entries.
757     private static final int MAX_NETWORK_REQUEST_LOGS = 20;
758     private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS);
759 
760     // NetworkInfo blocked and unblocked String log entries
761     private static final int MAX_NETWORK_INFO_LOGS = 40;
762     private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS);
763 
764     private static final int MAX_WAKELOCK_LOGS = 20;
765     private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS);
766     private int mTotalWakelockAcquisitions = 0;
767     private int mTotalWakelockReleases = 0;
768     private long mTotalWakelockDurationMs = 0;
769     private long mMaxWakelockDurationMs = 0;
770     private long mLastWakeLockAcquireTimestamp = 0;
771 
772     private final IpConnectivityLog mMetricsLog;
773 
774     @GuardedBy("mBandwidthRequests")
775     private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10);
776 
777     @VisibleForTesting
778     final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
779 
780     @VisibleForTesting
781     final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks =
782             new HashMap<>();
783 
784     /**
785      * Implements support for the legacy "one network per network type" model.
786      *
787      * We used to have a static array of NetworkStateTrackers, one for each
788      * network type, but that doesn't work any more now that we can have,
789      * for example, more that one wifi network. This class stores all the
790      * NetworkAgentInfo objects that support a given type, but the legacy
791      * API will only see the first one.
792      *
793      * It serves two main purposes:
794      *
795      * 1. Provide information about "the network for a given type" (since this
796      *    API only supports one).
797      * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
798      *    the first network for a given type changes, or if the default network
799      *    changes.
800      */
801     @VisibleForTesting
802     static class LegacyTypeTracker {
803 
804         private static final boolean DBG = true;
805         private static final boolean VDBG = false;
806 
807         /**
808          * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
809          * Each list holds references to all NetworkAgentInfos that are used to
810          * satisfy requests for that network type.
811          *
812          * This array is built out at startup such that an unsupported network
813          * doesn't get an ArrayList instance, making this a tristate:
814          * unsupported, supported but not active and active.
815          *
816          * The actual lists are populated when we scan the network types that
817          * are supported on this device.
818          *
819          * Threading model:
820          *  - addSupportedType() is only called in the constructor
821          *  - add(), update(), remove() are only called from the ConnectivityService handler thread.
822          *    They are therefore not thread-safe with respect to each other.
823          *  - getNetworkForType() can be called at any time on binder threads. It is synchronized
824          *    on mTypeLists to be thread-safe with respect to a concurrent remove call.
825          *  - getRestoreTimerForType(type) is also synchronized on mTypeLists.
826          *  - dump is thread-safe with respect to concurrent add and remove calls.
827          */
828         private final ArrayList<NetworkAgentInfo> mTypeLists[];
829         @NonNull
830         private final ConnectivityService mService;
831 
832         // Restore timers for requestNetworkForFeature (network type -> timer in ms). Types without
833         // an entry have no timer (equivalent to -1). Lazily loaded.
834         @NonNull
835         private ArrayMap<Integer, Integer> mRestoreTimers = new ArrayMap<>();
836 
LegacyTypeTracker(@onNull ConnectivityService service)837         LegacyTypeTracker(@NonNull ConnectivityService service) {
838             mService = service;
839             mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
840         }
841 
loadSupportedTypes(@onNull Context ctx, @NonNull TelephonyManager tm)842         public void loadSupportedTypes(@NonNull Context ctx, @NonNull TelephonyManager tm) {
843             final PackageManager pm = ctx.getPackageManager();
844             if (pm.hasSystemFeature(FEATURE_WIFI)) {
845                 addSupportedType(TYPE_WIFI);
846             }
847             if (pm.hasSystemFeature(FEATURE_WIFI_DIRECT)) {
848                 addSupportedType(TYPE_WIFI_P2P);
849             }
850             if (tm.isDataCapable()) {
851                 // Telephony does not have granular support for these types: they are either all
852                 // supported, or none is supported
853                 addSupportedType(TYPE_MOBILE);
854                 addSupportedType(TYPE_MOBILE_MMS);
855                 addSupportedType(TYPE_MOBILE_SUPL);
856                 addSupportedType(TYPE_MOBILE_DUN);
857                 addSupportedType(TYPE_MOBILE_HIPRI);
858                 addSupportedType(TYPE_MOBILE_FOTA);
859                 addSupportedType(TYPE_MOBILE_IMS);
860                 addSupportedType(TYPE_MOBILE_CBS);
861                 addSupportedType(TYPE_MOBILE_IA);
862                 addSupportedType(TYPE_MOBILE_EMERGENCY);
863             }
864             if (pm.hasSystemFeature(FEATURE_BLUETOOTH)) {
865                 addSupportedType(TYPE_BLUETOOTH);
866             }
867             if (pm.hasSystemFeature(FEATURE_WATCH)) {
868                 // TYPE_PROXY is only used on Wear
869                 addSupportedType(TYPE_PROXY);
870             }
871             // Ethernet is often not specified in the configs, although many devices can use it via
872             // USB host adapters. Add it as long as the ethernet service is here.
873             if (ctx.getSystemService(Context.ETHERNET_SERVICE) != null) {
874                 addSupportedType(TYPE_ETHERNET);
875             }
876 
877             // Always add TYPE_VPN as a supported type
878             addSupportedType(TYPE_VPN);
879         }
880 
addSupportedType(int type)881         private void addSupportedType(int type) {
882             if (mTypeLists[type] != null) {
883                 throw new IllegalStateException(
884                         "legacy list for type " + type + "already initialized");
885             }
886             mTypeLists[type] = new ArrayList<>();
887         }
888 
isTypeSupported(int type)889         public boolean isTypeSupported(int type) {
890             return isNetworkTypeValid(type) && mTypeLists[type] != null;
891         }
892 
getNetworkForType(int type)893         public NetworkAgentInfo getNetworkForType(int type) {
894             synchronized (mTypeLists) {
895                 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
896                     return mTypeLists[type].get(0);
897                 }
898             }
899             return null;
900         }
901 
getRestoreTimerForType(int type)902         public int getRestoreTimerForType(int type) {
903             synchronized (mTypeLists) {
904                 if (mRestoreTimers == null) {
905                     mRestoreTimers = loadRestoreTimers();
906                 }
907                 return mRestoreTimers.getOrDefault(type, -1);
908             }
909         }
910 
loadRestoreTimers()911         private ArrayMap<Integer, Integer> loadRestoreTimers() {
912             final String[] configs = mService.mResources.get().getStringArray(
913                     R.array.config_legacy_networktype_restore_timers);
914             final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length);
915             for (final String config : configs) {
916                 final String[] splits = TextUtils.split(config, ",");
917                 if (splits.length != 2) {
918                     logwtf("Invalid restore timer token count: " + config);
919                     continue;
920                 }
921                 try {
922                     ret.put(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
923                 } catch (NumberFormatException e) {
924                     logwtf("Invalid restore timer number format: " + config, e);
925                 }
926             }
927             return ret;
928         }
929 
maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)930         private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
931                 boolean isDefaultNetwork) {
932             if (DBG) {
933                 log("Sending " + state
934                         + " broadcast for type " + type + " " + nai.toShortString()
935                         + " isDefaultNetwork=" + isDefaultNetwork);
936             }
937         }
938 
939         // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying
940         // network type, to preserve previous behaviour.
maybeSendLegacyLockdownBroadcast(@onNull NetworkAgentInfo vpnNai)941         private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) {
942             if (vpnNai != mService.getLegacyLockdownNai()) return;
943 
944             if (vpnNai.declaredUnderlyingNetworks == null
945                     || vpnNai.declaredUnderlyingNetworks.length != 1) {
946                 Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: "
947                         + Arrays.toString(vpnNai.declaredUnderlyingNetworks));
948                 return;
949             }
950             final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork(
951                     vpnNai.declaredUnderlyingNetworks[0]);
952             if (underlyingNai == null) return;
953 
954             final int type = underlyingNai.networkInfo.getType();
955             final DetailedState state = DetailedState.CONNECTED;
956             maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */);
957             mService.sendLegacyNetworkBroadcast(underlyingNai, state, type);
958         }
959 
960         /** Adds the given network to the specified legacy type list. */
add(int type, NetworkAgentInfo nai)961         public void add(int type, NetworkAgentInfo nai) {
962             if (!isTypeSupported(type)) {
963                 return;  // Invalid network type.
964             }
965             if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
966 
967             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
968             if (list.contains(nai)) {
969                 return;
970             }
971             synchronized (mTypeLists) {
972                 list.add(nai);
973             }
974 
975             // Send a broadcast if this is the first network of its type or if it's the default.
976             final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
977 
978             // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts
979             // to preserve previous behaviour.
980             final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED);
981             if ((list.size() == 1) || isDefaultNetwork) {
982                 maybeLogBroadcast(nai, state, type, isDefaultNetwork);
983                 mService.sendLegacyNetworkBroadcast(nai, state, type);
984             }
985 
986             if (type == TYPE_VPN && state == DetailedState.CONNECTED) {
987                 maybeSendLegacyLockdownBroadcast(nai);
988             }
989         }
990 
991         /** Removes the given network from the specified legacy type list. */
remove(int type, NetworkAgentInfo nai, boolean wasDefault)992         public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) {
993             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
994             if (list == null || list.isEmpty()) {
995                 return;
996             }
997             final boolean wasFirstNetwork = list.get(0).equals(nai);
998 
999             synchronized (mTypeLists) {
1000                 if (!list.remove(nai)) {
1001                     return;
1002                 }
1003             }
1004 
1005             if (wasFirstNetwork || wasDefault) {
1006                 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault);
1007                 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type);
1008             }
1009 
1010             if (!list.isEmpty() && wasFirstNetwork) {
1011                 if (DBG) log("Other network available for type " + type +
1012                               ", sending connected broadcast");
1013                 final NetworkAgentInfo replacement = list.get(0);
1014                 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
1015                         mService.isDefaultNetwork(replacement));
1016                 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
1017             }
1018         }
1019 
1020         /** Removes the given network from all legacy type lists. */
remove(NetworkAgentInfo nai, boolean wasDefault)1021         public void remove(NetworkAgentInfo nai, boolean wasDefault) {
1022             if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault);
1023             for (int type = 0; type < mTypeLists.length; type++) {
1024                 remove(type, nai, wasDefault);
1025             }
1026         }
1027 
1028         // send out another legacy broadcast - currently only used for suspend/unsuspend
1029         // toggle
update(NetworkAgentInfo nai)1030         public void update(NetworkAgentInfo nai) {
1031             final boolean isDefault = mService.isDefaultNetwork(nai);
1032             final DetailedState state = nai.networkInfo.getDetailedState();
1033             for (int type = 0; type < mTypeLists.length; type++) {
1034                 final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
1035                 final boolean contains = (list != null && list.contains(nai));
1036                 final boolean isFirst = contains && (nai == list.get(0));
1037                 if (isFirst || contains && isDefault) {
1038                     maybeLogBroadcast(nai, state, type, isDefault);
1039                     mService.sendLegacyNetworkBroadcast(nai, state, type);
1040                 }
1041             }
1042         }
1043 
dump(IndentingPrintWriter pw)1044         public void dump(IndentingPrintWriter pw) {
1045             pw.println("mLegacyTypeTracker:");
1046             pw.increaseIndent();
1047             pw.print("Supported types:");
1048             for (int type = 0; type < mTypeLists.length; type++) {
1049                 if (mTypeLists[type] != null) pw.print(" " + type);
1050             }
1051             pw.println();
1052             pw.println("Current state:");
1053             pw.increaseIndent();
1054             synchronized (mTypeLists) {
1055                 for (int type = 0; type < mTypeLists.length; type++) {
1056                     if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue;
1057                     for (NetworkAgentInfo nai : mTypeLists[type]) {
1058                         pw.println(type + " " + nai.toShortString());
1059                     }
1060                 }
1061             }
1062             pw.decreaseIndent();
1063             pw.decreaseIndent();
1064             pw.println();
1065         }
1066     }
1067     private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
1068 
1069     final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
1070     /**
1071      * Helper class which parses out priority arguments and dumps sections according to their
1072      * priority. If priority arguments are omitted, function calls the legacy dump command.
1073      */
1074     private class LocalPriorityDump {
1075         private static final String PRIORITY_ARG = "--dump-priority";
1076         private static final String PRIORITY_ARG_HIGH = "HIGH";
1077         private static final String PRIORITY_ARG_NORMAL = "NORMAL";
1078 
LocalPriorityDump()1079         LocalPriorityDump() {}
1080 
dumpHigh(FileDescriptor fd, PrintWriter pw)1081         private void dumpHigh(FileDescriptor fd, PrintWriter pw) {
1082             doDump(fd, pw, new String[] {DIAG_ARG});
1083             doDump(fd, pw, new String[] {SHORT_ARG});
1084         }
1085 
dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args)1086         private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
1087             doDump(fd, pw, args);
1088         }
1089 
dump(FileDescriptor fd, PrintWriter pw, String[] args)1090         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1091             if (args == null) {
1092                 dumpNormal(fd, pw, args);
1093                 return;
1094             }
1095 
1096             String priority = null;
1097             for (int argIndex = 0; argIndex < args.length; argIndex++) {
1098                 if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) {
1099                     argIndex++;
1100                     priority = args[argIndex];
1101                 }
1102             }
1103 
1104             if (PRIORITY_ARG_HIGH.equals(priority)) {
1105                 dumpHigh(fd, pw);
1106             } else if (PRIORITY_ARG_NORMAL.equals(priority)) {
1107                 dumpNormal(fd, pw, args);
1108             } else {
1109                 // ConnectivityService publishes binder service using publishBinderService() with
1110                 // no priority assigned will be treated as NORMAL priority. Dumpsys does not send
1111                 // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the
1112                 // legacy output for dumpsys connectivity.
1113                 // TODO: Integrate into signal dump.
1114                 dumpNormal(fd, pw, args);
1115             }
1116         }
1117     }
1118 
1119     /**
1120      * Keeps track of the number of requests made under different uids.
1121      */
1122     public static class PerUidCounter {
1123         private final int mMaxCountPerUid;
1124 
1125         // Map from UID to number of NetworkRequests that UID has filed.
1126         @VisibleForTesting
1127         @GuardedBy("mUidToNetworkRequestCount")
1128         final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
1129 
1130         /**
1131          * Constructor
1132          *
1133          * @param maxCountPerUid the maximum count per uid allowed
1134          */
PerUidCounter(final int maxCountPerUid)1135         public PerUidCounter(final int maxCountPerUid) {
1136             mMaxCountPerUid = maxCountPerUid;
1137         }
1138 
1139         /**
1140          * Increments the request count of the given uid.  Throws an exception if the number
1141          * of open requests for the uid exceeds the value of maxCounterPerUid which is the value
1142          * passed into the constructor. see: {@link #PerUidCounter(int)}.
1143          *
1144          * @throws ServiceSpecificException with
1145          * {@link ConnectivityManager.Errors.TOO_MANY_REQUESTS} if the number of requests for
1146          * the uid exceed the allowed number.
1147          *
1148          * @param uid the uid that the request was made under
1149          */
incrementCountOrThrow(final int uid)1150         public void incrementCountOrThrow(final int uid) {
1151             synchronized (mUidToNetworkRequestCount) {
1152                 incrementCountOrThrow(uid, 1 /* numToIncrement */);
1153             }
1154         }
1155 
incrementCountOrThrow(final int uid, final int numToIncrement)1156         private void incrementCountOrThrow(final int uid, final int numToIncrement) {
1157             final int newRequestCount =
1158                     mUidToNetworkRequestCount.get(uid, 0) + numToIncrement;
1159             if (newRequestCount >= mMaxCountPerUid
1160                     // HACK : the system server is allowed to go over the request count limit
1161                     // when it is creating requests on behalf of another app (but not itself,
1162                     // so it can still detect its own request leaks). This only happens in the
1163                     // per-app API flows in which case the old requests for that particular
1164                     // UID will be removed soon.
1165                     // TODO : instead of this hack, addPerAppDefaultNetworkRequests and other
1166                     // users of transact() should unregister the requests to decrease the count
1167                     // before they increase it again by creating a new NRI. Then remove the
1168                     // transact() method.
1169                     && (Process.myUid() == uid || Process.myUid() != Binder.getCallingUid())) {
1170                 throw new ServiceSpecificException(
1171                         ConnectivityManager.Errors.TOO_MANY_REQUESTS,
1172                         "Uid " + uid + " exceeded its allotted requests limit");
1173             }
1174             mUidToNetworkRequestCount.put(uid, newRequestCount);
1175         }
1176 
1177         /**
1178          * Decrements the request count of the given uid.
1179          *
1180          * @param uid the uid that the request was made under
1181          */
decrementCount(final int uid)1182         public void decrementCount(final int uid) {
1183             synchronized (mUidToNetworkRequestCount) {
1184                 decrementCount(uid, 1 /* numToDecrement */);
1185             }
1186         }
1187 
decrementCount(final int uid, final int numToDecrement)1188         private void decrementCount(final int uid, final int numToDecrement) {
1189             final int newRequestCount =
1190                     mUidToNetworkRequestCount.get(uid, 0) - numToDecrement;
1191             if (newRequestCount < 0) {
1192                 logwtf("BUG: too small request count " + newRequestCount + " for UID " + uid);
1193             } else if (newRequestCount == 0) {
1194                 mUidToNetworkRequestCount.delete(uid);
1195             } else {
1196                 mUidToNetworkRequestCount.put(uid, newRequestCount);
1197             }
1198         }
1199 
1200         /**
1201          * Used to adjust the request counter for the per-app API flows. Directly adjusting the
1202          * counter is not ideal however in the per-app flows, the nris can't be removed until they
1203          * are used to create the new nris upon set. Therefore the request count limit can be
1204          * artificially hit. This method is used as a workaround for this particular case so that
1205          * the request counts are accounted for correctly.
1206          * @param uid the uid to adjust counts for
1207          * @param numOfNewRequests the new request count to account for
1208          * @param r the runnable to execute
1209          */
transact(final int uid, final int numOfNewRequests, @NonNull final Runnable r)1210         public void transact(final int uid, final int numOfNewRequests, @NonNull final Runnable r) {
1211             // This should only be used on the handler thread as per all current and foreseen
1212             // use-cases. ensureRunningOnConnectivityServiceThread() can't be used because there is
1213             // no ref to the outer ConnectivityService.
1214             synchronized (mUidToNetworkRequestCount) {
1215                 final int reqCountOverage = getCallingUidRequestCountOverage(uid, numOfNewRequests);
1216                 decrementCount(uid, reqCountOverage);
1217                 r.run();
1218                 incrementCountOrThrow(uid, reqCountOverage);
1219             }
1220         }
1221 
getCallingUidRequestCountOverage(final int uid, final int numOfNewRequests)1222         private int getCallingUidRequestCountOverage(final int uid, final int numOfNewRequests) {
1223             final int newUidRequestCount = mUidToNetworkRequestCount.get(uid, 0)
1224                     + numOfNewRequests;
1225             return newUidRequestCount >= MAX_NETWORK_REQUESTS_PER_SYSTEM_UID
1226                     ? newUidRequestCount - (MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1) : 0;
1227         }
1228     }
1229 
1230     /**
1231      * Dependencies of ConnectivityService, for injection in tests.
1232      */
1233     @VisibleForTesting
1234     public static class Dependencies {
getCallingUid()1235         public int getCallingUid() {
1236             return Binder.getCallingUid();
1237         }
1238 
1239         /**
1240          * Get system properties to use in ConnectivityService.
1241          */
getSystemProperties()1242         public MockableSystemProperties getSystemProperties() {
1243             return new MockableSystemProperties();
1244         }
1245 
1246         /**
1247          * Get the {@link ConnectivityResources} to use in ConnectivityService.
1248          */
getResources(@onNull Context ctx)1249         public ConnectivityResources getResources(@NonNull Context ctx) {
1250             return new ConnectivityResources(ctx);
1251         }
1252 
1253         /**
1254          * Create a HandlerThread to use in ConnectivityService.
1255          */
makeHandlerThread()1256         public HandlerThread makeHandlerThread() {
1257             return new HandlerThread("ConnectivityServiceThread");
1258         }
1259 
1260         /**
1261          * Get a reference to the ModuleNetworkStackClient.
1262          */
getNetworkStack()1263         public NetworkStackClientBase getNetworkStack() {
1264             return ModuleNetworkStackClient.getInstance(null);
1265         }
1266 
1267         /**
1268          * @see ProxyTracker
1269          */
makeProxyTracker(@onNull Context context, @NonNull Handler connServiceHandler)1270         public ProxyTracker makeProxyTracker(@NonNull Context context,
1271                 @NonNull Handler connServiceHandler) {
1272             return new ProxyTracker(context, connServiceHandler, EVENT_PROXY_HAS_CHANGED);
1273         }
1274 
1275         /**
1276          * @see NetIdManager
1277          */
makeNetIdManager()1278         public NetIdManager makeNetIdManager() {
1279             return new NetIdManager();
1280         }
1281 
1282         /**
1283          * @see NetworkUtils#queryUserAccess(int, int)
1284          */
queryUserAccess(int uid, Network network, ConnectivityService cs)1285         public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) {
1286             return cs.queryUserAccess(uid, network);
1287         }
1288 
1289         /**
1290          * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets
1291          * requires CAP_NET_ADMIN, which the unit tests do not have.
1292          */
getConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote)1293         public int getConnectionOwnerUid(int protocol, InetSocketAddress local,
1294                 InetSocketAddress remote) {
1295             return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote);
1296         }
1297 
1298         /**
1299          * @see MultinetworkPolicyTracker
1300          */
makeMultinetworkPolicyTracker( @onNull Context c, @NonNull Handler h, @NonNull Runnable r)1301         public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(
1302                 @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) {
1303             return new MultinetworkPolicyTracker(c, h, r);
1304         }
1305 
1306         /**
1307          * @see BatteryStatsManager
1308          */
reportNetworkInterfaceForTransports(Context context, String iface, int[] transportTypes)1309         public void reportNetworkInterfaceForTransports(Context context, String iface,
1310                 int[] transportTypes) {
1311             final BatteryStatsManager batteryStats =
1312                     context.getSystemService(BatteryStatsManager.class);
1313             batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes);
1314         }
1315 
getCellular464XlatEnabled()1316         public boolean getCellular464XlatEnabled() {
1317             return NetworkProperties.isCellular464XlatEnabled().orElse(true);
1318         }
1319 
1320         /**
1321          * @see PendingIntent#intentFilterEquals
1322          */
intentFilterEquals(PendingIntent a, PendingIntent b)1323         public boolean intentFilterEquals(PendingIntent a, PendingIntent b) {
1324             return a.intentFilterEquals(b);
1325         }
1326 
1327         /**
1328          * @see LocationPermissionChecker
1329          */
makeLocationPermissionChecker(Context context)1330         public LocationPermissionChecker makeLocationPermissionChecker(Context context) {
1331             return new LocationPermissionChecker(context);
1332         }
1333     }
1334 
ConnectivityService(Context context)1335     public ConnectivityService(Context context) {
1336         this(context, getDnsResolver(context), new IpConnectivityLog(),
1337                 INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
1338                 new Dependencies());
1339     }
1340 
1341     @VisibleForTesting
ConnectivityService(Context context, IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps)1342     protected ConnectivityService(Context context, IDnsResolver dnsresolver,
1343             IpConnectivityLog logger, INetd netd, Dependencies deps) {
1344         if (DBG) log("ConnectivityService starting up");
1345 
1346         mDeps = Objects.requireNonNull(deps, "missing Dependencies");
1347         mSystemProperties = mDeps.getSystemProperties();
1348         mNetIdManager = mDeps.makeNetIdManager();
1349         mContext = Objects.requireNonNull(context, "missing Context");
1350         mResources = deps.getResources(mContext);
1351         mNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_UID);
1352         mSystemNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID);
1353 
1354         mMetricsLog = logger;
1355         mNetworkRanker = new NetworkRanker();
1356         final NetworkRequest defaultInternetRequest = createDefaultRequest();
1357         mDefaultRequest = new NetworkRequestInfo(
1358                 Process.myUid(), defaultInternetRequest, null,
1359                 new Binder(), NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
1360                 null /* attributionTags */);
1361         mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
1362         mDefaultNetworkRequests.add(mDefaultRequest);
1363         mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest);
1364 
1365         mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
1366                 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
1367 
1368         // The default WiFi request is a background request so that apps using WiFi are
1369         // migrated to a better network (typically ethernet) when one comes up, instead
1370         // of staying on WiFi forever.
1371         mDefaultWifiRequest = createDefaultInternetRequestForTransport(
1372                 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
1373 
1374         mDefaultVehicleRequest = createAlwaysOnRequestForCapability(
1375                 NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL,
1376                 NetworkRequest.Type.BACKGROUND_REQUEST);
1377 
1378         mHandlerThread = mDeps.makeHandlerThread();
1379         mHandlerThread.start();
1380         mHandler = new InternalHandler(mHandlerThread.getLooper());
1381         mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
1382         mConnectivityDiagnosticsHandler =
1383                 new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper());
1384 
1385         mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
1386                 ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
1387 
1388         mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
1389         // TODO: Consider making the timer customizable.
1390         mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS;
1391 
1392         mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
1393         mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
1394         mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
1395         mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
1396 
1397         mNetd = netd;
1398         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
1399         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
1400         mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
1401 
1402         // To ensure uid state is synchronized with Network Policy, register for
1403         // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
1404         // reading existing policy from disk.
1405         mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback);
1406 
1407         final PowerManager powerManager = (PowerManager) context.getSystemService(
1408                 Context.POWER_SERVICE);
1409         mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
1410         mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
1411 
1412         mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager);
1413         mProtectedNetworks = new ArrayList<>();
1414         int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks);
1415         for (int p : protectedNetworks) {
1416             if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) {
1417                 mProtectedNetworks.add(p);
1418             } else {
1419                 if (DBG) loge("Ignoring protectedNetwork " + p);
1420             }
1421         }
1422 
1423         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
1424 
1425         mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
1426 
1427         mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
1428         // Listen for user add/removes to inform PermissionMonitor.
1429         // Should run on mHandler to avoid any races.
1430         final IntentFilter userIntentFilter = new IntentFilter();
1431         userIntentFilter.addAction(Intent.ACTION_USER_ADDED);
1432         userIntentFilter.addAction(Intent.ACTION_USER_REMOVED);
1433         mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter,
1434                 null /* broadcastPermission */, mHandler);
1435 
1436         // Listen to package add/removes for netd
1437         final IntentFilter packageIntentFilter = new IntentFilter();
1438         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
1439         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1440         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
1441         packageIntentFilter.addDataScheme("package");
1442         mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter,
1443                 null /* broadcastPermission */, mHandler);
1444 
1445         mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNetd);
1446 
1447         mNetdCallback = new NetdCallback();
1448         try {
1449             mNetd.registerUnsolicitedEventListener(mNetdCallback);
1450         } catch (RemoteException | ServiceSpecificException e) {
1451             loge("Error registering event listener :" + e);
1452         }
1453 
1454         mSettingsObserver = new SettingsObserver(mContext, mHandler);
1455         registerSettingsCallbacks();
1456 
1457         mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
1458         mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager);
1459         mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter);
1460 
1461         final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
1462                 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
1463                 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT);
1464         final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(),
1465                 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
1466                 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
1467         mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
1468 
1469         mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker(
1470                 mContext, mHandler, () -> updateAvoidBadWifi());
1471         mMultinetworkPolicyTracker.start();
1472 
1473         mDnsManager = new DnsManager(mContext, mDnsResolver);
1474         registerPrivateDnsSettingsCallbacks();
1475 
1476         // This NAI is a sentinel used to offer no service to apps that are on a multi-layer
1477         // request that doesn't allow fallback to the default network. It should never be visible
1478         // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal
1479         // arguments like the handler or the DnsResolver.
1480         // TODO : remove this ; it is probably better handled with a sentinel request.
1481         mNoServiceNetwork = new NetworkAgentInfo(null,
1482                 new Network(INetd.UNREACHABLE_NET_ID),
1483                 new NetworkInfo(TYPE_NONE, 0, "", ""),
1484                 new LinkProperties(), new NetworkCapabilities(),
1485                 new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null,
1486                 new NetworkAgentConfig(), this, null, null, 0, INVALID_UID,
1487                 mLingerDelayMs, mQosCallbackTracker, mDeps);
1488     }
1489 
createDefaultNetworkCapabilitiesForUid(int uid)1490     private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
1491         return createDefaultNetworkCapabilitiesForUidRange(new UidRange(uid, uid));
1492     }
1493 
createDefaultNetworkCapabilitiesForUidRange( @onNull final UidRange uids)1494     private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRange(
1495             @NonNull final UidRange uids) {
1496         final NetworkCapabilities netCap = new NetworkCapabilities();
1497         netCap.addCapability(NET_CAPABILITY_INTERNET);
1498         netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
1499         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
1500         netCap.setUids(UidRange.toIntRanges(Collections.singleton(uids)));
1501         return netCap;
1502     }
1503 
createDefaultRequest()1504     private NetworkRequest createDefaultRequest() {
1505         return createDefaultInternetRequestForTransport(
1506                 TYPE_NONE, NetworkRequest.Type.REQUEST);
1507     }
1508 
createDefaultInternetRequestForTransport( int transportType, NetworkRequest.Type type)1509     private NetworkRequest createDefaultInternetRequestForTransport(
1510             int transportType, NetworkRequest.Type type) {
1511         final NetworkCapabilities netCap = new NetworkCapabilities();
1512         netCap.addCapability(NET_CAPABILITY_INTERNET);
1513         netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
1514         netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
1515         if (transportType > TYPE_NONE) {
1516             netCap.addTransportType(transportType);
1517         }
1518         return createNetworkRequest(type, netCap);
1519     }
1520 
createNetworkRequest( NetworkRequest.Type type, NetworkCapabilities netCap)1521     private NetworkRequest createNetworkRequest(
1522             NetworkRequest.Type type, NetworkCapabilities netCap) {
1523         return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
1524     }
1525 
createAlwaysOnRequestForCapability(int capability, NetworkRequest.Type type)1526     private NetworkRequest createAlwaysOnRequestForCapability(int capability,
1527             NetworkRequest.Type type) {
1528         final NetworkCapabilities netCap = new NetworkCapabilities();
1529         netCap.clearAll();
1530         netCap.addCapability(capability);
1531         netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
1532         return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
1533     }
1534 
1535     // Used only for testing.
1536     // TODO: Delete this and either:
1537     // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires
1538     //    changing ContentResolver to make registerContentObserver non-final).
1539     // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
1540     //    by subclassing SettingsObserver.
1541     @VisibleForTesting
updateAlwaysOnNetworks()1542     void updateAlwaysOnNetworks() {
1543         mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
1544     }
1545 
1546     // See FakeSettingsProvider comment above.
1547     @VisibleForTesting
updatePrivateDnsSettings()1548     void updatePrivateDnsSettings() {
1549         mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
1550     }
1551 
1552     @VisibleForTesting
updateMobileDataPreferredUids()1553     void updateMobileDataPreferredUids() {
1554         mHandler.sendEmptyMessage(EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED);
1555     }
1556 
handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, int id)1557     private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, int id) {
1558         final boolean enable = mContext.getResources().getBoolean(id);
1559         handleAlwaysOnNetworkRequest(networkRequest, enable);
1560     }
1561 
handleAlwaysOnNetworkRequest( NetworkRequest networkRequest, String settingName, boolean defaultValue)1562     private void handleAlwaysOnNetworkRequest(
1563             NetworkRequest networkRequest, String settingName, boolean defaultValue) {
1564         final boolean enable = toBool(Settings.Global.getInt(
1565                 mContext.getContentResolver(), settingName, encodeBool(defaultValue)));
1566         handleAlwaysOnNetworkRequest(networkRequest, enable);
1567     }
1568 
handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable)1569     private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable) {
1570         final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null);
1571         if (enable == isEnabled) {
1572             return;  // Nothing to do.
1573         }
1574 
1575         if (enable) {
1576             handleRegisterNetworkRequest(new NetworkRequestInfo(
1577                     Process.myUid(), networkRequest, null, new Binder(),
1578                     NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
1579                     null /* attributionTags */));
1580         } else {
1581             handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
1582                     /* callOnUnavailable */ false);
1583         }
1584     }
1585 
handleConfigureAlwaysOnNetworks()1586     private void handleConfigureAlwaysOnNetworks() {
1587         handleAlwaysOnNetworkRequest(mDefaultMobileDataRequest,
1588                 ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */);
1589         handleAlwaysOnNetworkRequest(mDefaultWifiRequest,
1590                 ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */);
1591         final boolean vehicleAlwaysRequested = mResources.get().getBoolean(
1592                 R.bool.config_vehicleInternalNetworkAlwaysRequested);
1593         handleAlwaysOnNetworkRequest(mDefaultVehicleRequest, vehicleAlwaysRequested);
1594     }
1595 
1596     // Note that registering observer for setting do not get initial callback when registering,
1597     // callers must fetch the initial value of the setting themselves if needed.
registerSettingsCallbacks()1598     private void registerSettingsCallbacks() {
1599         // Watch for global HTTP proxy changes.
1600         mSettingsObserver.observe(
1601                 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY),
1602                 EVENT_APPLY_GLOBAL_HTTP_PROXY);
1603 
1604         // Watch for whether or not to keep mobile data always on.
1605         mSettingsObserver.observe(
1606                 Settings.Global.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON),
1607                 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
1608 
1609         // Watch for whether or not to keep wifi always on.
1610         mSettingsObserver.observe(
1611                 Settings.Global.getUriFor(ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED),
1612                 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
1613 
1614         // Watch for mobile data preferred uids changes.
1615         mSettingsObserver.observe(
1616                 Settings.Secure.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_PREFERRED_UIDS),
1617                 EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED);
1618     }
1619 
registerPrivateDnsSettingsCallbacks()1620     private void registerPrivateDnsSettingsCallbacks() {
1621         for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) {
1622             mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
1623         }
1624     }
1625 
nextNetworkRequestId()1626     private synchronized int nextNetworkRequestId() {
1627         // TODO: Consider handle wrapping and exclude {@link NetworkRequest#REQUEST_ID_NONE} if
1628         //  doing that.
1629         return mNextNetworkRequestId++;
1630     }
1631 
1632     @VisibleForTesting
getNetworkAgentInfoForNetwork(Network network)1633     protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
1634         if (network == null) {
1635             return null;
1636         }
1637         return getNetworkAgentInfoForNetId(network.getNetId());
1638     }
1639 
getNetworkAgentInfoForNetId(int netId)1640     private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) {
1641         synchronized (mNetworkForNetId) {
1642             return mNetworkForNetId.get(netId);
1643         }
1644     }
1645 
1646     // TODO: determine what to do when more than one VPN applies to |uid|.
getVpnForUid(int uid)1647     private NetworkAgentInfo getVpnForUid(int uid) {
1648         synchronized (mNetworkForNetId) {
1649             for (int i = 0; i < mNetworkForNetId.size(); i++) {
1650                 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
1651                 if (nai.isVPN() && nai.everConnected && nai.networkCapabilities.appliesToUid(uid)) {
1652                     return nai;
1653                 }
1654             }
1655         }
1656         return null;
1657     }
1658 
getVpnUnderlyingNetworks(int uid)1659     private Network[] getVpnUnderlyingNetworks(int uid) {
1660         if (mLockdownEnabled) return null;
1661         final NetworkAgentInfo nai = getVpnForUid(uid);
1662         if (nai != null) return nai.declaredUnderlyingNetworks;
1663         return null;
1664     }
1665 
getNetworkAgentInfoForUid(int uid)1666     private NetworkAgentInfo getNetworkAgentInfoForUid(int uid) {
1667         NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
1668 
1669         final Network[] networks = getVpnUnderlyingNetworks(uid);
1670         if (networks != null) {
1671             // getUnderlyingNetworks() returns:
1672             // null => there was no VPN, or the VPN didn't specify anything, so we use the default.
1673             // empty array => the VPN explicitly said "no default network".
1674             // non-empty array => the VPN specified one or more default networks; we use the
1675             //                    first one.
1676             if (networks.length > 0) {
1677                 nai = getNetworkAgentInfoForNetwork(networks[0]);
1678             } else {
1679                 nai = null;
1680             }
1681         }
1682         return nai;
1683     }
1684 
1685     /**
1686      * Check if UID should be blocked from using the specified network.
1687      */
isNetworkWithCapabilitiesBlocked(@ullable final NetworkCapabilities nc, final int uid, final boolean ignoreBlocked)1688     private boolean isNetworkWithCapabilitiesBlocked(@Nullable final NetworkCapabilities nc,
1689             final int uid, final boolean ignoreBlocked) {
1690         // Networks aren't blocked when ignoring blocked status
1691         if (ignoreBlocked) {
1692             return false;
1693         }
1694         if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true;
1695         final long ident = Binder.clearCallingIdentity();
1696         try {
1697             final boolean metered = nc == null ? true : nc.isMetered();
1698             return mPolicyManager.isUidNetworkingBlocked(uid, metered);
1699         } finally {
1700             Binder.restoreCallingIdentity(ident);
1701         }
1702     }
1703 
maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid)1704     private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
1705         if (ni == null || !LOGD_BLOCKED_NETWORKINFO) {
1706             return;
1707         }
1708         final boolean blocked;
1709         synchronized (mBlockedAppUids) {
1710             if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
1711                 blocked = true;
1712             } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
1713                 blocked = false;
1714             } else {
1715                 return;
1716             }
1717         }
1718         String action = blocked ? "BLOCKED" : "UNBLOCKED";
1719         log(String.format("Returning %s NetworkInfo to uid=%d", action, uid));
1720         mNetworkInfoBlockingLogs.log(action + " " + uid);
1721     }
1722 
maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked)1723     private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) {
1724         if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
1725             return;
1726         }
1727         final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED";
1728         final int requestId = nri.getActiveRequest() != null
1729                 ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId;
1730         mNetworkInfoBlockingLogs.log(String.format(
1731                 "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(),
1732                 Integer.toHexString(blocked)));
1733     }
1734 
1735     /**
1736      * Apply any relevant filters to the specified {@link NetworkInfo} for the given UID. For
1737      * example, this may mark the network as {@link DetailedState#BLOCKED} based
1738      * on {@link #isNetworkWithCapabilitiesBlocked}.
1739      */
1740     @NonNull
filterNetworkInfo(@onNull NetworkInfo networkInfo, int type, @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked)1741     private NetworkInfo filterNetworkInfo(@NonNull NetworkInfo networkInfo, int type,
1742             @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) {
1743         final NetworkInfo filtered = new NetworkInfo(networkInfo);
1744         // Many legacy types (e.g,. TYPE_MOBILE_HIPRI) are not actually a property of the network
1745         // but only exists if an app asks about them or requests them. Ensure the requesting app
1746         // gets the type it asks for.
1747         filtered.setType(type);
1748         if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
1749             filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */,
1750                     null /* extraInfo */);
1751         }
1752         filterForLegacyLockdown(filtered);
1753         return filtered;
1754     }
1755 
getFilteredNetworkInfo(NetworkAgentInfo nai, int uid, boolean ignoreBlocked)1756     private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid,
1757             boolean ignoreBlocked) {
1758         return filterNetworkInfo(nai.networkInfo, nai.networkInfo.getType(),
1759                 nai.networkCapabilities, uid, ignoreBlocked);
1760     }
1761 
1762     /**
1763      * Return NetworkInfo for the active (i.e., connected) network interface.
1764      * It is assumed that at most one network is active at a time. If more
1765      * than one is active, it is indeterminate which will be returned.
1766      * @return the info for the active network, or {@code null} if none is
1767      * active
1768      */
1769     @Override
getActiveNetworkInfo()1770     public NetworkInfo getActiveNetworkInfo() {
1771         enforceAccessPermission();
1772         final int uid = mDeps.getCallingUid();
1773         final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
1774         if (nai == null) return null;
1775         final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false);
1776         maybeLogBlockedNetworkInfo(networkInfo, uid);
1777         return networkInfo;
1778     }
1779 
1780     @Override
getActiveNetwork()1781     public Network getActiveNetwork() {
1782         enforceAccessPermission();
1783         return getActiveNetworkForUidInternal(mDeps.getCallingUid(), false);
1784     }
1785 
1786     @Override
getActiveNetworkForUid(int uid, boolean ignoreBlocked)1787     public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
1788         PermissionUtils.enforceNetworkStackPermission(mContext);
1789         return getActiveNetworkForUidInternal(uid, ignoreBlocked);
1790     }
1791 
getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked)1792     private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
1793         final NetworkAgentInfo vpnNai = getVpnForUid(uid);
1794         if (vpnNai != null) {
1795             final NetworkCapabilities requiredCaps = createDefaultNetworkCapabilitiesForUid(uid);
1796             if (requiredCaps.satisfiedByNetworkCapabilities(vpnNai.networkCapabilities)) {
1797                 return vpnNai.network;
1798             }
1799         }
1800 
1801         NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
1802         if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid,
1803                 ignoreBlocked)) {
1804             return null;
1805         }
1806         return nai.network;
1807     }
1808 
1809     @Override
getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked)1810     public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
1811         PermissionUtils.enforceNetworkStackPermission(mContext);
1812         final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
1813         if (nai == null) return null;
1814         return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
1815     }
1816 
1817     /** Returns a NetworkInfo object for a network that doesn't exist. */
makeFakeNetworkInfo(int networkType, int uid)1818     private NetworkInfo makeFakeNetworkInfo(int networkType, int uid) {
1819         final NetworkInfo info = new NetworkInfo(networkType, 0 /* subtype */,
1820                 getNetworkTypeName(networkType), "" /* subtypeName */);
1821         info.setIsAvailable(true);
1822         // For compatibility with legacy code, return BLOCKED instead of DISCONNECTED when
1823         // background data is restricted.
1824         final NetworkCapabilities nc = new NetworkCapabilities();  // Metered.
1825         final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false)
1826                 ? DetailedState.BLOCKED
1827                 : DetailedState.DISCONNECTED;
1828         info.setDetailedState(state, null /* reason */, null /* extraInfo */);
1829         filterForLegacyLockdown(info);
1830         return info;
1831     }
1832 
getFilteredNetworkInfoForType(int networkType, int uid)1833     private NetworkInfo getFilteredNetworkInfoForType(int networkType, int uid) {
1834         if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
1835             return null;
1836         }
1837         final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
1838         if (nai == null) {
1839             return makeFakeNetworkInfo(networkType, uid);
1840         }
1841         return filterNetworkInfo(nai.networkInfo, networkType, nai.networkCapabilities, uid,
1842                 false);
1843     }
1844 
1845     @Override
getNetworkInfo(int networkType)1846     public NetworkInfo getNetworkInfo(int networkType) {
1847         enforceAccessPermission();
1848         final int uid = mDeps.getCallingUid();
1849         if (getVpnUnderlyingNetworks(uid) != null) {
1850             // A VPN is active, so we may need to return one of its underlying networks. This
1851             // information is not available in LegacyTypeTracker, so we have to get it from
1852             // getNetworkAgentInfoForUid.
1853             final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
1854             if (nai == null) return null;
1855             final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false);
1856             if (networkInfo.getType() == networkType) {
1857                 return networkInfo;
1858             }
1859         }
1860         return getFilteredNetworkInfoForType(networkType, uid);
1861     }
1862 
1863     @Override
getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked)1864     public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
1865         enforceAccessPermission();
1866         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
1867         if (nai == null) return null;
1868         return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
1869     }
1870 
1871     @Override
getAllNetworkInfo()1872     public NetworkInfo[] getAllNetworkInfo() {
1873         enforceAccessPermission();
1874         final ArrayList<NetworkInfo> result = new ArrayList<>();
1875         for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
1876                 networkType++) {
1877             NetworkInfo info = getNetworkInfo(networkType);
1878             if (info != null) {
1879                 result.add(info);
1880             }
1881         }
1882         return result.toArray(new NetworkInfo[result.size()]);
1883     }
1884 
1885     @Override
getNetworkForType(int networkType)1886     public Network getNetworkForType(int networkType) {
1887         enforceAccessPermission();
1888         if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
1889             return null;
1890         }
1891         final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
1892         if (nai == null) {
1893             return null;
1894         }
1895         final int uid = mDeps.getCallingUid();
1896         if (isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) {
1897             return null;
1898         }
1899         return nai.network;
1900     }
1901 
1902     @Override
getAllNetworks()1903     public Network[] getAllNetworks() {
1904         enforceAccessPermission();
1905         synchronized (mNetworkForNetId) {
1906             final Network[] result = new Network[mNetworkForNetId.size()];
1907             for (int i = 0; i < mNetworkForNetId.size(); i++) {
1908                 result[i] = mNetworkForNetId.valueAt(i).network;
1909             }
1910             return result;
1911         }
1912     }
1913 
1914     @Override
getDefaultNetworkCapabilitiesForUser( int userId, String callingPackageName, @Nullable String callingAttributionTag)1915     public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(
1916                 int userId, String callingPackageName, @Nullable String callingAttributionTag) {
1917         // The basic principle is: if an app's traffic could possibly go over a
1918         // network, without the app doing anything multinetwork-specific,
1919         // (hence, by "default"), then include that network's capabilities in
1920         // the array.
1921         //
1922         // In the normal case, app traffic only goes over the system's default
1923         // network connection, so that's the only network returned.
1924         //
1925         // With a VPN in force, some app traffic may go into the VPN, and thus
1926         // over whatever underlying networks the VPN specifies, while other app
1927         // traffic may go over the system default network (e.g.: a split-tunnel
1928         // VPN, or an app disallowed by the VPN), so the set of networks
1929         // returned includes the VPN's underlying networks and the system
1930         // default.
1931         enforceAccessPermission();
1932 
1933         HashMap<Network, NetworkCapabilities> result = new HashMap<>();
1934 
1935         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
1936             if (!nri.isBeingSatisfied()) {
1937                 continue;
1938             }
1939             final NetworkAgentInfo nai = nri.getSatisfier();
1940             final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
1941             if (null != nc
1942                     && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
1943                     && !result.containsKey(nai.network)) {
1944                 result.put(
1945                         nai.network,
1946                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
1947                                 nc, false /* includeLocationSensitiveInfo */,
1948                                 getCallingPid(), mDeps.getCallingUid(), callingPackageName,
1949                                 callingAttributionTag));
1950             }
1951         }
1952 
1953         // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null.
1954         final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid());
1955         if (null != networks) {
1956             for (final Network network : networks) {
1957                 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
1958                 if (null != nc) {
1959                     result.put(
1960                             network,
1961                             createWithLocationInfoSanitizedIfNecessaryWhenParceled(
1962                                     nc,
1963                                     false /* includeLocationSensitiveInfo */,
1964                                     getCallingPid(), mDeps.getCallingUid(), callingPackageName,
1965                                     callingAttributionTag));
1966                 }
1967             }
1968         }
1969 
1970         NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
1971         out = result.values().toArray(out);
1972         return out;
1973     }
1974 
1975     @Override
isNetworkSupported(int networkType)1976     public boolean isNetworkSupported(int networkType) {
1977         enforceAccessPermission();
1978         return mLegacyTypeTracker.isTypeSupported(networkType);
1979     }
1980 
1981     /**
1982      * Return LinkProperties for the active (i.e., connected) default
1983      * network interface for the calling uid.
1984      * @return the ip properties for the active network, or {@code null} if
1985      * none is active
1986      */
1987     @Override
getActiveLinkProperties()1988     public LinkProperties getActiveLinkProperties() {
1989         enforceAccessPermission();
1990         final int uid = mDeps.getCallingUid();
1991         NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
1992         if (nai == null) return null;
1993         return linkPropertiesRestrictedForCallerPermissions(nai.linkProperties,
1994                 Binder.getCallingPid(), uid);
1995     }
1996 
1997     @Override
getLinkPropertiesForType(int networkType)1998     public LinkProperties getLinkPropertiesForType(int networkType) {
1999         enforceAccessPermission();
2000         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
2001         final LinkProperties lp = getLinkProperties(nai);
2002         if (lp == null) return null;
2003         return linkPropertiesRestrictedForCallerPermissions(
2004                 lp, Binder.getCallingPid(), mDeps.getCallingUid());
2005     }
2006 
2007     // TODO - this should be ALL networks
2008     @Override
getLinkProperties(Network network)2009     public LinkProperties getLinkProperties(Network network) {
2010         enforceAccessPermission();
2011         final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network));
2012         if (lp == null) return null;
2013         return linkPropertiesRestrictedForCallerPermissions(
2014                 lp, Binder.getCallingPid(), mDeps.getCallingUid());
2015     }
2016 
2017     @Nullable
getLinkProperties(@ullable NetworkAgentInfo nai)2018     private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) {
2019         if (nai == null) {
2020             return null;
2021         }
2022         synchronized (nai) {
2023             return nai.linkProperties;
2024         }
2025     }
2026 
getNetworkCapabilitiesInternal(Network network)2027     private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) {
2028         return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
2029     }
2030 
getNetworkCapabilitiesInternal(NetworkAgentInfo nai)2031     private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) {
2032         if (nai == null) return null;
2033         synchronized (nai) {
2034             return networkCapabilitiesRestrictedForCallerPermissions(
2035                     nai.networkCapabilities, Binder.getCallingPid(), mDeps.getCallingUid());
2036         }
2037     }
2038 
2039     @Override
getNetworkCapabilities(Network network, String callingPackageName, @Nullable String callingAttributionTag)2040     public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName,
2041             @Nullable String callingAttributionTag) {
2042         mAppOpsManager.checkPackage(mDeps.getCallingUid(), callingPackageName);
2043         enforceAccessPermission();
2044         return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
2045                 getNetworkCapabilitiesInternal(network),
2046                 false /* includeLocationSensitiveInfo */,
2047                 getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
2048     }
2049 
2050     @VisibleForTesting
networkCapabilitiesRestrictedForCallerPermissions( NetworkCapabilities nc, int callerPid, int callerUid)2051     NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
2052             NetworkCapabilities nc, int callerPid, int callerUid) {
2053         final NetworkCapabilities newNc = new NetworkCapabilities(nc);
2054         if (!checkSettingsPermission(callerPid, callerUid)) {
2055             newNc.setUids(null);
2056             newNc.setSSID(null);
2057         }
2058         if (newNc.getNetworkSpecifier() != null) {
2059             newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
2060         }
2061         newNc.setAdministratorUids(new int[0]);
2062         if (!checkAnyPermissionOf(
2063                 callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) {
2064             newNc.setSubscriptionIds(Collections.emptySet());
2065         }
2066 
2067         return newNc;
2068     }
2069 
2070     /**
2071      * Wrapper used to cache the permission check results performed for the corresponding
2072      * app. This avoid performing multiple permission checks for different fields in
2073      * NetworkCapabilities.
2074      * Note: This wrapper does not support any sort of invalidation and thus must not be
2075      * persistent or long-lived. It may only be used for the time necessary to
2076      * compute the redactions required by one particular NetworkCallback or
2077      * synchronous call.
2078      */
2079     private class RedactionPermissionChecker {
2080         private final int mCallingPid;
2081         private final int mCallingUid;
2082         @NonNull private final String mCallingPackageName;
2083         @Nullable private final String mCallingAttributionTag;
2084 
2085         private Boolean mHasLocationPermission = null;
2086         private Boolean mHasLocalMacAddressPermission = null;
2087         private Boolean mHasSettingsPermission = null;
2088 
RedactionPermissionChecker(int callingPid, int callingUid, @NonNull String callingPackageName, @Nullable String callingAttributionTag)2089         RedactionPermissionChecker(int callingPid, int callingUid,
2090                 @NonNull String callingPackageName, @Nullable String callingAttributionTag) {
2091             mCallingPid = callingPid;
2092             mCallingUid = callingUid;
2093             mCallingPackageName = callingPackageName;
2094             mCallingAttributionTag = callingAttributionTag;
2095         }
2096 
hasLocationPermissionInternal()2097         private boolean hasLocationPermissionInternal() {
2098             final long token = Binder.clearCallingIdentity();
2099             try {
2100                 return mLocationPermissionChecker.checkLocationPermission(
2101                         mCallingPackageName, mCallingAttributionTag, mCallingUid,
2102                         null /* message */);
2103             } finally {
2104                 Binder.restoreCallingIdentity(token);
2105             }
2106         }
2107 
2108         /**
2109          * Returns whether the app holds location permission or not (might return cached result
2110          * if the permission was already checked before).
2111          */
hasLocationPermission()2112         public boolean hasLocationPermission() {
2113             if (mHasLocationPermission == null) {
2114                 // If there is no cached result, perform the check now.
2115                 mHasLocationPermission = hasLocationPermissionInternal();
2116             }
2117             return mHasLocationPermission;
2118         }
2119 
2120         /**
2121          * Returns whether the app holds local mac address permission or not (might return cached
2122          * result if the permission was already checked before).
2123          */
hasLocalMacAddressPermission()2124         public boolean hasLocalMacAddressPermission() {
2125             if (mHasLocalMacAddressPermission == null) {
2126                 // If there is no cached result, perform the check now.
2127                 mHasLocalMacAddressPermission =
2128                         checkLocalMacAddressPermission(mCallingPid, mCallingUid);
2129             }
2130             return mHasLocalMacAddressPermission;
2131         }
2132 
2133         /**
2134          * Returns whether the app holds settings permission or not (might return cached
2135          * result if the permission was already checked before).
2136          */
hasSettingsPermission()2137         public boolean hasSettingsPermission() {
2138             if (mHasSettingsPermission == null) {
2139                 // If there is no cached result, perform the check now.
2140                 mHasSettingsPermission = checkSettingsPermission(mCallingPid, mCallingUid);
2141             }
2142             return mHasSettingsPermission;
2143         }
2144     }
2145 
shouldRedact(@etworkCapabilities.RedactionType long redactions, @NetworkCapabilities.NetCapability long redaction)2146     private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions,
2147             @NetworkCapabilities.NetCapability long redaction) {
2148         return (redactions & redaction) != 0;
2149     }
2150 
2151     /**
2152      * Use the provided |applicableRedactions| to check the receiving app's
2153      * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask
2154      * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities
2155      * before being sent to the corresponding app.
2156      */
retrieveRequiredRedactions( @etworkCapabilities.RedactionType long applicableRedactions, @NonNull RedactionPermissionChecker redactionPermissionChecker, boolean includeLocationSensitiveInfo)2157     private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions(
2158             @NetworkCapabilities.RedactionType long applicableRedactions,
2159             @NonNull RedactionPermissionChecker redactionPermissionChecker,
2160             boolean includeLocationSensitiveInfo) {
2161         long redactions = applicableRedactions;
2162         if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) {
2163             if (includeLocationSensitiveInfo
2164                     && redactionPermissionChecker.hasLocationPermission()) {
2165                 redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION;
2166             }
2167         }
2168         if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) {
2169             if (redactionPermissionChecker.hasLocalMacAddressPermission()) {
2170                 redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS;
2171             }
2172         }
2173         if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) {
2174             if (redactionPermissionChecker.hasSettingsPermission()) {
2175                 redactions &= ~REDACT_FOR_NETWORK_SETTINGS;
2176             }
2177         }
2178         return redactions;
2179     }
2180 
2181     @VisibleForTesting
2182     @Nullable
createWithLocationInfoSanitizedIfNecessaryWhenParceled( @ullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo, int callingPid, int callingUid, @NonNull String callingPkgName, @Nullable String callingAttributionTag)2183     NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
2184             @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
2185             int callingPid, int callingUid, @NonNull String callingPkgName,
2186             @Nullable String callingAttributionTag) {
2187         if (nc == null) {
2188             return null;
2189         }
2190         // Avoid doing location permission check if the transport info has no location sensitive
2191         // data.
2192         final RedactionPermissionChecker redactionPermissionChecker =
2193                 new RedactionPermissionChecker(callingPid, callingUid, callingPkgName,
2194                         callingAttributionTag);
2195         final long redactions = retrieveRequiredRedactions(
2196                 nc.getApplicableRedactions(), redactionPermissionChecker,
2197                 includeLocationSensitiveInfo);
2198         final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
2199         // Reset owner uid if not destined for the owner app.
2200         if (callingUid != nc.getOwnerUid()) {
2201             newNc.setOwnerUid(INVALID_UID);
2202             return newNc;
2203         }
2204         // Allow VPNs to see ownership of their own VPN networks - not location sensitive.
2205         if (nc.hasTransport(TRANSPORT_VPN)) {
2206             // Owner UIDs already checked above. No need to re-check.
2207             return newNc;
2208         }
2209         // If the calling does not want location sensitive data & target SDK >= S, then mask info.
2210         // Else include the owner UID iff the calling has location permission to provide backwards
2211         // compatibility for older apps.
2212         if (!includeLocationSensitiveInfo
2213                 && isTargetSdkAtleast(
2214                         Build.VERSION_CODES.S, callingUid, callingPkgName)) {
2215             newNc.setOwnerUid(INVALID_UID);
2216             return newNc;
2217         }
2218         // Reset owner uid if the app has no location permission.
2219         if (!redactionPermissionChecker.hasLocationPermission()) {
2220             newNc.setOwnerUid(INVALID_UID);
2221         }
2222         return newNc;
2223     }
2224 
linkPropertiesRestrictedForCallerPermissions( LinkProperties lp, int callerPid, int callerUid)2225     private LinkProperties linkPropertiesRestrictedForCallerPermissions(
2226             LinkProperties lp, int callerPid, int callerUid) {
2227         if (lp == null) return new LinkProperties();
2228 
2229         // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls.
2230         final boolean needsSanitization =
2231                 (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null);
2232         if (!needsSanitization) {
2233             return new LinkProperties(lp);
2234         }
2235 
2236         if (checkSettingsPermission(callerPid, callerUid)) {
2237             return new LinkProperties(lp, true /* parcelSensitiveFields */);
2238         }
2239 
2240         final LinkProperties newLp = new LinkProperties(lp);
2241         // Sensitive fields would not be parceled anyway, but sanitize for consistency before the
2242         // object gets parceled.
2243         newLp.setCaptivePortalApiUrl(null);
2244         newLp.setCaptivePortalData(null);
2245         return newLp;
2246     }
2247 
restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc, int callerUid, String callerPackageName)2248     private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc,
2249             int callerUid, String callerPackageName) {
2250         // There is no need to track the effective UID of the request here. If the caller
2251         // lacks the settings permission, the effective UID is the same as the calling ID.
2252         if (!checkSettingsPermission()) {
2253             // Unprivileged apps can only pass in null or their own UID.
2254             if (nc.getUids() == null) {
2255                 // If the caller passes in null, the callback will also match networks that do not
2256                 // apply to its UID, similarly to what it would see if it called getAllNetworks.
2257                 // In this case, redact everything in the request immediately. This ensures that the
2258                 // app is not able to get any redacted information by filing an unredacted request
2259                 // and observing whether the request matches something.
2260                 if (nc.getNetworkSpecifier() != null) {
2261                     nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact());
2262                 }
2263             } else {
2264                 nc.setSingleUid(callerUid);
2265             }
2266         }
2267         nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
2268         nc.setAdministratorUids(new int[0]);
2269 
2270         // Clear owner UID; this can never come from an app.
2271         nc.setOwnerUid(INVALID_UID);
2272     }
2273 
restrictBackgroundRequestForCaller(NetworkCapabilities nc)2274     private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) {
2275         if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(mDeps.getCallingUid())) {
2276             nc.addCapability(NET_CAPABILITY_FOREGROUND);
2277         }
2278     }
2279 
2280     @Override
getRestrictBackgroundStatusByCaller()2281     public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() {
2282         enforceAccessPermission();
2283         final int callerUid = Binder.getCallingUid();
2284         final long token = Binder.clearCallingIdentity();
2285         try {
2286             return mPolicyManager.getRestrictBackgroundStatus(callerUid);
2287         } finally {
2288             Binder.restoreCallingIdentity(token);
2289         }
2290     }
2291 
2292     // TODO: Consider delete this function or turn it into a no-op method.
2293     @Override
getAllNetworkState()2294     public NetworkState[] getAllNetworkState() {
2295         // This contains IMSI details, so make sure the caller is privileged.
2296         PermissionUtils.enforceNetworkStackPermission(mContext);
2297 
2298         final ArrayList<NetworkState> result = new ArrayList<>();
2299         for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) {
2300             // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the
2301             // NetworkAgentInfo.
2302             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork());
2303             if (nai != null && nai.networkInfo.isConnected()) {
2304                 result.add(new NetworkState(new NetworkInfo(nai.networkInfo),
2305                         snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(),
2306                         snapshot.getNetwork(), snapshot.getSubscriberId()));
2307             }
2308         }
2309         return result.toArray(new NetworkState[result.size()]);
2310     }
2311 
2312     @Override
2313     @NonNull
getAllNetworkStateSnapshots()2314     public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
2315         // This contains IMSI details, so make sure the caller is privileged.
2316         enforceNetworkStackOrSettingsPermission();
2317 
2318         final ArrayList<NetworkStateSnapshot> result = new ArrayList<>();
2319         for (Network network : getAllNetworks()) {
2320             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
2321             // TODO: Consider include SUSPENDED networks, which should be considered as
2322             //  temporary shortage of connectivity of a connected network.
2323             if (nai != null && nai.networkInfo.isConnected()) {
2324                 // TODO (b/73321673) : NetworkStateSnapshot contains a copy of the
2325                 // NetworkCapabilities, which may contain UIDs of apps to which the
2326                 // network applies. Should the UIDs be cleared so as not to leak or
2327                 // interfere ?
2328                 result.add(nai.getNetworkStateSnapshot());
2329             }
2330         }
2331         return result;
2332     }
2333 
2334     @Override
isActiveNetworkMetered()2335     public boolean isActiveNetworkMetered() {
2336         enforceAccessPermission();
2337 
2338         final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork());
2339         if (caps != null) {
2340             return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
2341         } else {
2342             // Always return the most conservative value
2343             return true;
2344         }
2345     }
2346 
2347     /**
2348      * Ensures that the system cannot call a particular method.
2349      */
disallowedBecauseSystemCaller()2350     private boolean disallowedBecauseSystemCaller() {
2351         // TODO: start throwing a SecurityException when GnssLocationProvider stops calling
2352         // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost
2353         // for devices launched with Q and above. However, existing devices upgrading to Q and
2354         // above must continued to be supported for few more releases.
2355         if (isSystem(mDeps.getCallingUid()) && SystemProperties.getInt(
2356                 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) {
2357             log("This method exists only for app backwards compatibility"
2358                     + " and must not be called by system services.");
2359             return true;
2360         }
2361         return false;
2362     }
2363 
getAppUid(final String app, final UserHandle user)2364     private int getAppUid(final String app, final UserHandle user) {
2365         final PackageManager pm =
2366                 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
2367         final long token = Binder.clearCallingIdentity();
2368         try {
2369             return pm.getPackageUid(app, 0 /* flags */);
2370         } catch (PackageManager.NameNotFoundException e) {
2371             return -1;
2372         } finally {
2373             Binder.restoreCallingIdentity(token);
2374         }
2375     }
2376 
verifyCallingUidAndPackage(String packageName, int callingUid)2377     private void verifyCallingUidAndPackage(String packageName, int callingUid) {
2378         final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
2379         if (getAppUid(packageName, user) != callingUid) {
2380             throw new SecurityException(packageName + " does not belong to uid " + callingUid);
2381         }
2382     }
2383 
2384     /**
2385      * Ensure that a network route exists to deliver traffic to the specified
2386      * host via the specified network interface.
2387      * @param networkType the type of the network over which traffic to the
2388      * specified host is to be routed
2389      * @param hostAddress the IP address of the host to which the route is
2390      * desired
2391      * @return {@code true} on success, {@code false} on failure
2392      */
2393     @Override
requestRouteToHostAddress(int networkType, byte[] hostAddress, String callingPackageName, String callingAttributionTag)2394     public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
2395             String callingPackageName, String callingAttributionTag) {
2396         if (disallowedBecauseSystemCaller()) {
2397             return false;
2398         }
2399         verifyCallingUidAndPackage(callingPackageName, mDeps.getCallingUid());
2400         enforceChangePermission(callingPackageName, callingAttributionTag);
2401         if (mProtectedNetworks.contains(networkType)) {
2402             enforceConnectivityRestrictedNetworksPermission();
2403         }
2404 
2405         InetAddress addr;
2406         try {
2407             addr = InetAddress.getByAddress(hostAddress);
2408         } catch (UnknownHostException e) {
2409             if (DBG) log("requestRouteToHostAddress got " + e.toString());
2410             return false;
2411         }
2412 
2413         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
2414             if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
2415             return false;
2416         }
2417 
2418         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
2419         if (nai == null) {
2420             if (mLegacyTypeTracker.isTypeSupported(networkType) == false) {
2421                 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
2422             } else {
2423                 if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
2424             }
2425             return false;
2426         }
2427 
2428         DetailedState netState;
2429         synchronized (nai) {
2430             netState = nai.networkInfo.getDetailedState();
2431         }
2432 
2433         if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) {
2434             if (VDBG) {
2435                 log("requestRouteToHostAddress on down network "
2436                         + "(" + networkType + ") - dropped"
2437                         + " netState=" + netState);
2438             }
2439             return false;
2440         }
2441 
2442         final int uid = mDeps.getCallingUid();
2443         final long token = Binder.clearCallingIdentity();
2444         try {
2445             LinkProperties lp;
2446             int netId;
2447             synchronized (nai) {
2448                 lp = nai.linkProperties;
2449                 netId = nai.network.getNetId();
2450             }
2451             boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
2452             if (DBG) {
2453                 log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok);
2454             }
2455             return ok;
2456         } finally {
2457             Binder.restoreCallingIdentity(token);
2458         }
2459     }
2460 
addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid)2461     private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) {
2462         RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
2463         if (bestRoute == null) {
2464             bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
2465         } else {
2466             String iface = bestRoute.getInterface();
2467             if (bestRoute.getGateway().equals(addr)) {
2468                 // if there is no better route, add the implied hostroute for our gateway
2469                 bestRoute = RouteInfo.makeHostRoute(addr, iface);
2470             } else {
2471                 // if we will connect to this through another route, add a direct route
2472                 // to it's gateway
2473                 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
2474             }
2475         }
2476         if (DBG) log("Adding legacy route " + bestRoute +
2477                 " for UID/PID " + uid + "/" + Binder.getCallingPid());
2478 
2479         final String dst = bestRoute.getDestinationLinkAddress().toString();
2480         final String nextHop = bestRoute.hasGateway()
2481                 ? bestRoute.getGateway().getHostAddress() : "";
2482         try {
2483             mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid);
2484         } catch (RemoteException | ServiceSpecificException e) {
2485             if (DBG) loge("Exception trying to add a route: " + e);
2486             return false;
2487         }
2488         return true;
2489     }
2490 
2491     class DnsResolverUnsolicitedEventCallback extends
2492             IDnsResolverUnsolicitedEventListener.Stub {
2493         @Override
onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event)2494         public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) {
2495             try {
2496                 mHandler.sendMessage(mHandler.obtainMessage(
2497                         EVENT_PRIVATE_DNS_VALIDATION_UPDATE,
2498                         new PrivateDnsValidationUpdate(event.netId,
2499                                 InetAddresses.parseNumericAddress(event.ipAddress),
2500                                 event.hostname, event.validation)));
2501             } catch (IllegalArgumentException e) {
2502                 loge("Error parsing ip address in validation event");
2503             }
2504         }
2505 
2506         @Override
onDnsHealthEvent(final DnsHealthEventParcel event)2507         public void onDnsHealthEvent(final DnsHealthEventParcel event) {
2508             NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId);
2509             // Netd event only allow registrants from system. Each NetworkMonitor thread is under
2510             // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd
2511             // event callback for certain nai. e.g. cellular. Register here to pass to
2512             // NetworkMonitor instead.
2513             // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allow one
2514             // callback from each caller type. Need to re-factor NetdEventListenerService to allow
2515             // multiple NetworkMonitor registrants.
2516             if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) {
2517                 nai.networkMonitor().notifyDnsResponse(event.healthResult);
2518             }
2519         }
2520 
2521         @Override
onNat64PrefixEvent(final Nat64PrefixEventParcel event)2522         public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) {
2523             mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation,
2524                     event.prefixAddress, event.prefixLength));
2525         }
2526 
2527         @Override
getInterfaceVersion()2528         public int getInterfaceVersion() {
2529             return this.VERSION;
2530         }
2531 
2532         @Override
getInterfaceHash()2533         public String getInterfaceHash() {
2534             return this.HASH;
2535         }
2536     }
2537 
2538     @VisibleForTesting
2539     protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback =
2540             new DnsResolverUnsolicitedEventCallback();
2541 
registerDnsResolverUnsolicitedEventListener()2542     private void registerDnsResolverUnsolicitedEventListener() {
2543         try {
2544             mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback);
2545         } catch (Exception e) {
2546             loge("Error registering DnsResolver unsolicited event callback: " + e);
2547         }
2548     }
2549 
2550     private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
2551         @Override
2552         public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
2553             mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
2554                     uid, blockedReasons));
2555         }
2556     };
2557 
handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons)2558     private void handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
2559         maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
2560         setUidBlockedReasons(uid, blockedReasons);
2561     }
2562 
checkAnyPermissionOf(String... permissions)2563     private boolean checkAnyPermissionOf(String... permissions) {
2564         for (String permission : permissions) {
2565             if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
2566                 return true;
2567             }
2568         }
2569         return false;
2570     }
2571 
checkAnyPermissionOf(int pid, int uid, String... permissions)2572     private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) {
2573         for (String permission : permissions) {
2574             if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) {
2575                 return true;
2576             }
2577         }
2578         return false;
2579     }
2580 
enforceAnyPermissionOf(String... permissions)2581     private void enforceAnyPermissionOf(String... permissions) {
2582         if (!checkAnyPermissionOf(permissions)) {
2583             throw new SecurityException("Requires one of the following permissions: "
2584                     + String.join(", ", permissions) + ".");
2585         }
2586     }
2587 
enforceInternetPermission()2588     private void enforceInternetPermission() {
2589         mContext.enforceCallingOrSelfPermission(
2590                 android.Manifest.permission.INTERNET,
2591                 "ConnectivityService");
2592     }
2593 
enforceAccessPermission()2594     private void enforceAccessPermission() {
2595         mContext.enforceCallingOrSelfPermission(
2596                 android.Manifest.permission.ACCESS_NETWORK_STATE,
2597                 "ConnectivityService");
2598     }
2599 
2600     /**
2601      * Performs a strict and comprehensive check of whether a calling package is allowed to
2602      * change the state of network, as the condition differs for pre-M, M+, and
2603      * privileged/preinstalled apps. The caller is expected to have either the
2604      * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
2605      * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
2606      * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
2607      * permission and cannot be revoked. See http://b/23597341
2608      *
2609      * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
2610      * of this app will be updated to the current time.
2611      */
enforceChangePermission(String callingPkg, String callingAttributionTag)2612     private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
2613         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
2614                 == PackageManager.PERMISSION_GRANTED) {
2615             return;
2616         }
2617 
2618         if (callingPkg == null) {
2619             throw new SecurityException("Calling package name is null.");
2620         }
2621 
2622         final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class);
2623         final int uid = mDeps.getCallingUid();
2624         final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid,
2625                 callingPkg, callingAttributionTag, null /* message */);
2626 
2627         if (mode == AppOpsManager.MODE_ALLOWED) {
2628             return;
2629         }
2630 
2631         if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission(
2632                 android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) {
2633             return;
2634         }
2635 
2636         throw new SecurityException(callingPkg + " was not granted either of these permissions:"
2637                 + android.Manifest.permission.CHANGE_NETWORK_STATE + ","
2638                 + android.Manifest.permission.WRITE_SETTINGS + ".");
2639     }
2640 
enforceSettingsPermission()2641     private void enforceSettingsPermission() {
2642         enforceAnyPermissionOf(
2643                 android.Manifest.permission.NETWORK_SETTINGS,
2644                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2645     }
2646 
enforceNetworkFactoryPermission()2647     private void enforceNetworkFactoryPermission() {
2648         enforceAnyPermissionOf(
2649                 android.Manifest.permission.NETWORK_FACTORY,
2650                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2651     }
2652 
enforceNetworkFactoryOrSettingsPermission()2653     private void enforceNetworkFactoryOrSettingsPermission() {
2654         enforceAnyPermissionOf(
2655                 android.Manifest.permission.NETWORK_SETTINGS,
2656                 android.Manifest.permission.NETWORK_FACTORY,
2657                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2658     }
2659 
enforceNetworkFactoryOrTestNetworksPermission()2660     private void enforceNetworkFactoryOrTestNetworksPermission() {
2661         enforceAnyPermissionOf(
2662                 android.Manifest.permission.MANAGE_TEST_NETWORKS,
2663                 android.Manifest.permission.NETWORK_FACTORY,
2664                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2665     }
2666 
checkSettingsPermission()2667     private boolean checkSettingsPermission() {
2668         return checkAnyPermissionOf(
2669                 android.Manifest.permission.NETWORK_SETTINGS,
2670                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2671     }
2672 
checkSettingsPermission(int pid, int uid)2673     private boolean checkSettingsPermission(int pid, int uid) {
2674         return PERMISSION_GRANTED == mContext.checkPermission(
2675                 android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
2676                 || PERMISSION_GRANTED == mContext.checkPermission(
2677                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
2678     }
2679 
enforceNetworkStackOrSettingsPermission()2680     private void enforceNetworkStackOrSettingsPermission() {
2681         enforceAnyPermissionOf(
2682                 android.Manifest.permission.NETWORK_SETTINGS,
2683                 android.Manifest.permission.NETWORK_STACK,
2684                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2685     }
2686 
enforceNetworkStackSettingsOrSetup()2687     private void enforceNetworkStackSettingsOrSetup() {
2688         enforceAnyPermissionOf(
2689                 android.Manifest.permission.NETWORK_SETTINGS,
2690                 android.Manifest.permission.NETWORK_SETUP_WIZARD,
2691                 android.Manifest.permission.NETWORK_STACK,
2692                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2693     }
2694 
enforceAirplaneModePermission()2695     private void enforceAirplaneModePermission() {
2696         enforceAnyPermissionOf(
2697                 android.Manifest.permission.NETWORK_AIRPLANE_MODE,
2698                 android.Manifest.permission.NETWORK_SETTINGS,
2699                 android.Manifest.permission.NETWORK_SETUP_WIZARD,
2700                 android.Manifest.permission.NETWORK_STACK,
2701                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2702     }
2703 
enforceOemNetworkPreferencesPermission()2704     private void enforceOemNetworkPreferencesPermission() {
2705         mContext.enforceCallingOrSelfPermission(
2706                 android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE,
2707                 "ConnectivityService");
2708     }
2709 
enforceManageTestNetworksPermission()2710     private void enforceManageTestNetworksPermission() {
2711         mContext.enforceCallingOrSelfPermission(
2712                 android.Manifest.permission.MANAGE_TEST_NETWORKS,
2713                 "ConnectivityService");
2714     }
2715 
checkNetworkStackPermission()2716     private boolean checkNetworkStackPermission() {
2717         return checkAnyPermissionOf(
2718                 android.Manifest.permission.NETWORK_STACK,
2719                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2720     }
2721 
checkNetworkStackPermission(int pid, int uid)2722     private boolean checkNetworkStackPermission(int pid, int uid) {
2723         return checkAnyPermissionOf(pid, uid,
2724                 android.Manifest.permission.NETWORK_STACK,
2725                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2726     }
2727 
checkNetworkSignalStrengthWakeupPermission(int pid, int uid)2728     private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) {
2729         return checkAnyPermissionOf(pid, uid,
2730                 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP,
2731                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
2732                 android.Manifest.permission.NETWORK_SETTINGS);
2733     }
2734 
enforceConnectivityRestrictedNetworksPermission()2735     private void enforceConnectivityRestrictedNetworksPermission() {
2736         try {
2737             mContext.enforceCallingOrSelfPermission(
2738                     android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS,
2739                     "ConnectivityService");
2740             return;
2741         } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ }
2742         //  TODO: Remove this fallback check after all apps have declared
2743         //   CONNECTIVITY_USE_RESTRICTED_NETWORKS.
2744         mContext.enforceCallingOrSelfPermission(
2745                 android.Manifest.permission.CONNECTIVITY_INTERNAL,
2746                 "ConnectivityService");
2747     }
2748 
enforceKeepalivePermission()2749     private void enforceKeepalivePermission() {
2750         mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
2751     }
2752 
checkLocalMacAddressPermission(int pid, int uid)2753     private boolean checkLocalMacAddressPermission(int pid, int uid) {
2754         return PERMISSION_GRANTED == mContext.checkPermission(
2755                 Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid);
2756     }
2757 
sendConnectedBroadcast(NetworkInfo info)2758     private void sendConnectedBroadcast(NetworkInfo info) {
2759         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
2760     }
2761 
sendInetConditionBroadcast(NetworkInfo info)2762     private void sendInetConditionBroadcast(NetworkInfo info) {
2763         sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
2764     }
2765 
makeGeneralIntent(NetworkInfo info, String bcastType)2766     private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
2767         Intent intent = new Intent(bcastType);
2768         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
2769         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
2770         if (info.isFailover()) {
2771             intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
2772             info.setFailover(false);
2773         }
2774         if (info.getReason() != null) {
2775             intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
2776         }
2777         if (info.getExtraInfo() != null) {
2778             intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
2779                     info.getExtraInfo());
2780         }
2781         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
2782         return intent;
2783     }
2784 
sendGeneralBroadcast(NetworkInfo info, String bcastType)2785     private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
2786         sendStickyBroadcast(makeGeneralIntent(info, bcastType));
2787     }
2788 
sendStickyBroadcast(Intent intent)2789     private void sendStickyBroadcast(Intent intent) {
2790         synchronized (this) {
2791             if (!mSystemReady
2792                     && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
2793                 mInitialBroadcast = new Intent(intent);
2794             }
2795             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2796             if (VDBG) {
2797                 log("sendStickyBroadcast: action=" + intent.getAction());
2798             }
2799 
2800             Bundle options = null;
2801             final long ident = Binder.clearCallingIdentity();
2802             if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
2803                 final NetworkInfo ni = intent.getParcelableExtra(
2804                         ConnectivityManager.EXTRA_NETWORK_INFO);
2805                 final BroadcastOptions opts = BroadcastOptions.makeBasic();
2806                 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
2807                 options = opts.toBundle();
2808                 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
2809             }
2810             try {
2811                 mUserAllContext.sendStickyBroadcast(intent, options);
2812             } finally {
2813                 Binder.restoreCallingIdentity(ident);
2814             }
2815         }
2816     }
2817 
2818     /**
2819      * Called by SystemServer through ConnectivityManager when the system is ready.
2820      */
2821     @Override
systemReady()2822     public void systemReady() {
2823         if (mDeps.getCallingUid() != Process.SYSTEM_UID) {
2824             throw new SecurityException("Calling Uid is not system uid.");
2825         }
2826         systemReadyInternal();
2827     }
2828 
2829     /**
2830      * Called when ConnectivityService can initialize remaining components.
2831      */
2832     @VisibleForTesting
systemReadyInternal()2833     public void systemReadyInternal() {
2834         // Since mApps in PermissionMonitor needs to be populated first to ensure that
2835         // listening network request which is sent by MultipathPolicyTracker won't be added
2836         // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must
2837         // be called after PermissionMonitor#startMonitoring().
2838         // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the
2839         // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady()
2840         // to ensure the tracking will be initialized correctly.
2841         mPermissionMonitor.startMonitoring();
2842         mProxyTracker.loadGlobalProxy();
2843         registerDnsResolverUnsolicitedEventListener();
2844 
2845         synchronized (this) {
2846             mSystemReady = true;
2847             if (mInitialBroadcast != null) {
2848                 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
2849                 mInitialBroadcast = null;
2850             }
2851         }
2852 
2853         // Create network requests for always-on networks.
2854         mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
2855 
2856         // Update mobile data preference if necessary.
2857         // Note that empty uid list can be skip here only because no uid rules applied before system
2858         // ready. Normally, the empty uid list means to clear the uids rules on netd.
2859         if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) {
2860             updateMobileDataPreferredUids();
2861         }
2862     }
2863 
2864     /**
2865      * Start listening for default data network activity state changes.
2866      */
2867     @Override
registerNetworkActivityListener(@onNull INetworkActivityListener l)2868     public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
2869         mNetworkActivityTracker.registerNetworkActivityListener(l);
2870     }
2871 
2872     /**
2873      * Stop listening for default data network activity state changes.
2874      */
2875     @Override
unregisterNetworkActivityListener(@onNull INetworkActivityListener l)2876     public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
2877         mNetworkActivityTracker.unregisterNetworkActivityListener(l);
2878     }
2879 
2880     /**
2881      * Check whether the default network radio is currently active.
2882      */
2883     @Override
isDefaultNetworkActive()2884     public boolean isDefaultNetworkActive() {
2885         return mNetworkActivityTracker.isDefaultNetworkActive();
2886     }
2887 
2888     /**
2889      * Reads the network specific MTU size from resources.
2890      * and set it on it's iface.
2891      */
updateMtu(LinkProperties newLp, LinkProperties oldLp)2892     private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
2893         final String iface = newLp.getInterfaceName();
2894         final int mtu = newLp.getMtu();
2895         if (oldLp == null && mtu == 0) {
2896             // Silently ignore unset MTU value.
2897             return;
2898         }
2899         if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
2900             if (VDBG) log("identical MTU - not setting");
2901             return;
2902         }
2903         if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) {
2904             if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface);
2905             return;
2906         }
2907 
2908         // Cannot set MTU without interface name
2909         if (TextUtils.isEmpty(iface)) {
2910             loge("Setting MTU size with null iface.");
2911             return;
2912         }
2913 
2914         try {
2915             if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu);
2916             mNetd.interfaceSetMtu(iface, mtu);
2917         } catch (RemoteException | ServiceSpecificException e) {
2918             loge("exception in interfaceSetMtu()" + e);
2919         }
2920     }
2921 
2922     @VisibleForTesting
2923     protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
2924 
updateTcpBufferSizes(String tcpBufferSizes)2925     private void updateTcpBufferSizes(String tcpBufferSizes) {
2926         String[] values = null;
2927         if (tcpBufferSizes != null) {
2928             values = tcpBufferSizes.split(",");
2929         }
2930 
2931         if (values == null || values.length != 6) {
2932             if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults");
2933             tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES;
2934             values = tcpBufferSizes.split(",");
2935         }
2936 
2937         if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return;
2938 
2939         try {
2940             if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes);
2941 
2942             String rmemValues = String.join(" ", values[0], values[1], values[2]);
2943             String wmemValues = String.join(" ", values[3], values[4], values[5]);
2944             mNetd.setTcpRWmemorySize(rmemValues, wmemValues);
2945             mCurrentTcpBufferSizes = tcpBufferSizes;
2946         } catch (RemoteException | ServiceSpecificException e) {
2947             loge("Can't set TCP buffer sizes:" + e);
2948         }
2949     }
2950 
2951     @Override
getRestoreDefaultNetworkDelay(int networkType)2952     public int getRestoreDefaultNetworkDelay(int networkType) {
2953         String restoreDefaultNetworkDelayStr = mSystemProperties.get(
2954                 NETWORK_RESTORE_DELAY_PROP_NAME);
2955         if(restoreDefaultNetworkDelayStr != null &&
2956                 restoreDefaultNetworkDelayStr.length() != 0) {
2957             try {
2958                 return Integer.parseInt(restoreDefaultNetworkDelayStr);
2959             } catch (NumberFormatException e) {
2960             }
2961         }
2962         // if the system property isn't set, use the value for the apn type
2963         int ret = RESTORE_DEFAULT_NETWORK_DELAY;
2964 
2965         if (mLegacyTypeTracker.isTypeSupported(networkType)) {
2966             ret = mLegacyTypeTracker.getRestoreTimerForType(networkType);
2967         }
2968         return ret;
2969     }
2970 
dumpNetworkDiagnostics(IndentingPrintWriter pw)2971     private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
2972         final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
2973         final long DIAG_TIME_MS = 5000;
2974         for (NetworkAgentInfo nai : networksSortedById()) {
2975             PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network);
2976             // Start gathering diagnostic information.
2977             netDiags.add(new NetworkDiagnostics(
2978                     nai.network,
2979                     new LinkProperties(nai.linkProperties),  // Must be a copy.
2980                     privateDnsCfg,
2981                     DIAG_TIME_MS));
2982         }
2983 
2984         for (NetworkDiagnostics netDiag : netDiags) {
2985             pw.println();
2986             netDiag.waitForMeasurements();
2987             netDiag.dump(pw);
2988         }
2989     }
2990 
2991     @Override
dump(@onNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args)2992     protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
2993             @Nullable String[] args) {
2994         if (!checkDumpPermission(mContext, TAG, writer)) return;
2995 
2996         mPriorityDumper.dump(fd, writer, args);
2997     }
2998 
checkDumpPermission(Context context, String tag, PrintWriter pw)2999     private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
3000         if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
3001                 != PackageManager.PERMISSION_GRANTED) {
3002             pw.println("Permission Denial: can't dump " + tag + " from from pid="
3003                     + Binder.getCallingPid() + ", uid=" + mDeps.getCallingUid()
3004                     + " due to missing android.permission.DUMP permission");
3005             return false;
3006         } else {
3007             return true;
3008         }
3009     }
3010 
doDump(FileDescriptor fd, PrintWriter writer, String[] args)3011     private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
3012         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
3013 
3014         if (CollectionUtils.contains(args, DIAG_ARG)) {
3015             dumpNetworkDiagnostics(pw);
3016             return;
3017         } else if (CollectionUtils.contains(args, NETWORK_ARG)) {
3018             dumpNetworks(pw);
3019             return;
3020         } else if (CollectionUtils.contains(args, REQUEST_ARG)) {
3021             dumpNetworkRequests(pw);
3022             return;
3023         }
3024 
3025         pw.print("NetworkProviders for:");
3026         for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
3027             pw.print(" " + npi.name);
3028         }
3029         pw.println();
3030         pw.println();
3031 
3032         final NetworkAgentInfo defaultNai = getDefaultNetwork();
3033         pw.print("Active default network: ");
3034         if (defaultNai == null) {
3035             pw.println("none");
3036         } else {
3037             pw.println(defaultNai.network.getNetId());
3038         }
3039         pw.println();
3040 
3041         pw.print("Current per-app default networks: ");
3042         pw.increaseIndent();
3043         dumpPerAppNetworkPreferences(pw);
3044         pw.decreaseIndent();
3045         pw.println();
3046 
3047         pw.println("Current Networks:");
3048         pw.increaseIndent();
3049         dumpNetworks(pw);
3050         pw.decreaseIndent();
3051         pw.println();
3052 
3053         pw.println("Status for known UIDs:");
3054         pw.increaseIndent();
3055         final int size = mUidBlockedReasons.size();
3056         for (int i = 0; i < size; i++) {
3057             // Don't crash if the array is modified while dumping in bugreports.
3058             try {
3059                 final int uid = mUidBlockedReasons.keyAt(i);
3060                 final int blockedReasons = mUidBlockedReasons.valueAt(i);
3061                 pw.println("UID=" + uid + " blockedReasons="
3062                         + Integer.toHexString(blockedReasons));
3063             } catch (ArrayIndexOutOfBoundsException e) {
3064                 pw.println("  ArrayIndexOutOfBoundsException");
3065             } catch (ConcurrentModificationException e) {
3066                 pw.println("  ConcurrentModificationException");
3067             }
3068         }
3069         pw.println();
3070         pw.decreaseIndent();
3071 
3072         pw.println("Network Requests:");
3073         pw.increaseIndent();
3074         dumpNetworkRequests(pw);
3075         pw.decreaseIndent();
3076         pw.println();
3077 
3078         mLegacyTypeTracker.dump(pw);
3079 
3080         pw.println();
3081         mKeepaliveTracker.dump(pw);
3082 
3083         pw.println();
3084         dumpAvoidBadWifiSettings(pw);
3085 
3086         pw.println();
3087 
3088         if (!CollectionUtils.contains(args, SHORT_ARG)) {
3089             pw.println();
3090             pw.println("mNetworkRequestInfoLogs (most recent first):");
3091             pw.increaseIndent();
3092             mNetworkRequestInfoLogs.reverseDump(pw);
3093             pw.decreaseIndent();
3094 
3095             pw.println();
3096             pw.println("mNetworkInfoBlockingLogs (most recent first):");
3097             pw.increaseIndent();
3098             mNetworkInfoBlockingLogs.reverseDump(pw);
3099             pw.decreaseIndent();
3100 
3101             pw.println();
3102             pw.println("NetTransition WakeLock activity (most recent first):");
3103             pw.increaseIndent();
3104             pw.println("total acquisitions: " + mTotalWakelockAcquisitions);
3105             pw.println("total releases: " + mTotalWakelockReleases);
3106             pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s");
3107             pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s");
3108             if (mTotalWakelockAcquisitions > mTotalWakelockReleases) {
3109                 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
3110                 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
3111             }
3112             mWakelockLogs.reverseDump(pw);
3113 
3114             pw.println();
3115             pw.println("bandwidth update requests (by uid):");
3116             pw.increaseIndent();
3117             synchronized (mBandwidthRequests) {
3118                 for (int i = 0; i < mBandwidthRequests.size(); i++) {
3119                     pw.println("[" + mBandwidthRequests.keyAt(i)
3120                             + "]: " + mBandwidthRequests.valueAt(i));
3121                 }
3122             }
3123             pw.decreaseIndent();
3124             pw.decreaseIndent();
3125 
3126             pw.println();
3127             pw.println("mOemNetworkPreferencesLogs (most recent first):");
3128             pw.increaseIndent();
3129             mOemNetworkPreferencesLogs.reverseDump(pw);
3130             pw.decreaseIndent();
3131         }
3132 
3133         pw.println();
3134 
3135         pw.println();
3136         pw.println("Permission Monitor:");
3137         pw.increaseIndent();
3138         mPermissionMonitor.dump(pw);
3139         pw.decreaseIndent();
3140 
3141         pw.println();
3142         pw.println("Legacy network activity:");
3143         pw.increaseIndent();
3144         mNetworkActivityTracker.dump(pw);
3145         pw.decreaseIndent();
3146     }
3147 
dumpNetworks(IndentingPrintWriter pw)3148     private void dumpNetworks(IndentingPrintWriter pw) {
3149         for (NetworkAgentInfo nai : networksSortedById()) {
3150             pw.println(nai.toString());
3151             pw.increaseIndent();
3152             pw.println(String.format(
3153                     "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d",
3154                     nai.numForegroundNetworkRequests(),
3155                     nai.numNetworkRequests() - nai.numRequestNetworkRequests(),
3156                     nai.numBackgroundNetworkRequests(),
3157                     nai.numNetworkRequests()));
3158             pw.increaseIndent();
3159             for (int i = 0; i < nai.numNetworkRequests(); i++) {
3160                 pw.println(nai.requestAt(i).toString());
3161             }
3162             pw.decreaseIndent();
3163             pw.println("Inactivity Timers:");
3164             pw.increaseIndent();
3165             nai.dumpInactivityTimers(pw);
3166             pw.decreaseIndent();
3167             pw.decreaseIndent();
3168         }
3169     }
3170 
dumpPerAppNetworkPreferences(IndentingPrintWriter pw)3171     private void dumpPerAppNetworkPreferences(IndentingPrintWriter pw) {
3172         pw.println("Per-App Network Preference:");
3173         pw.increaseIndent();
3174         if (0 == mOemNetworkPreferences.getNetworkPreferences().size()) {
3175             pw.println("none");
3176         } else {
3177             pw.println(mOemNetworkPreferences.toString());
3178         }
3179         pw.decreaseIndent();
3180 
3181         for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) {
3182             if (mDefaultRequest == defaultRequest) {
3183                 continue;
3184             }
3185 
3186             final boolean isActive = null != defaultRequest.getSatisfier();
3187             pw.println("Is per-app network active:");
3188             pw.increaseIndent();
3189             pw.println(isActive);
3190             if (isActive) {
3191                 pw.println("Active network: " + defaultRequest.getSatisfier().network.netId);
3192             }
3193             pw.println("Tracked UIDs:");
3194             pw.increaseIndent();
3195             if (0 == defaultRequest.mRequests.size()) {
3196                 pw.println("none, this should never occur.");
3197             } else {
3198                 pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUidRanges());
3199             }
3200             pw.decreaseIndent();
3201             pw.decreaseIndent();
3202         }
3203     }
3204 
dumpNetworkRequests(IndentingPrintWriter pw)3205     private void dumpNetworkRequests(IndentingPrintWriter pw) {
3206         for (NetworkRequestInfo nri : requestsSortedById()) {
3207             pw.println(nri.toString());
3208         }
3209     }
3210 
3211     /**
3212      * Return an array of all current NetworkAgentInfos sorted by network id.
3213      */
networksSortedById()3214     private NetworkAgentInfo[] networksSortedById() {
3215         NetworkAgentInfo[] networks = new NetworkAgentInfo[0];
3216         networks = mNetworkAgentInfos.toArray(networks);
3217         Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId()));
3218         return networks;
3219     }
3220 
3221     /**
3222      * Return an array of all current NetworkRequest sorted by request id.
3223      */
3224     @VisibleForTesting
requestsSortedById()3225     NetworkRequestInfo[] requestsSortedById() {
3226         NetworkRequestInfo[] requests = new NetworkRequestInfo[0];
3227         requests = getNrisFromGlobalRequests().toArray(requests);
3228         // Sort the array based off the NRI containing the min requestId in its requests.
3229         Arrays.sort(requests,
3230                 Comparator.comparingInt(nri -> Collections.min(nri.mRequests,
3231                         Comparator.comparingInt(req -> req.requestId)).requestId
3232                 )
3233         );
3234         return requests;
3235     }
3236 
isLiveNetworkAgent(NetworkAgentInfo nai, int what)3237     private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) {
3238         final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network);
3239         if (officialNai != null && officialNai.equals(nai)) return true;
3240         if (officialNai != null || VDBG) {
3241             loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai +
3242                 " - " + nai);
3243         }
3244         return false;
3245     }
3246 
3247     // must be stateless - things change under us.
3248     private class NetworkStateTrackerHandler extends Handler {
NetworkStateTrackerHandler(Looper looper)3249         public NetworkStateTrackerHandler(Looper looper) {
3250             super(looper);
3251         }
3252 
maybeHandleNetworkAgentMessage(Message msg)3253         private void maybeHandleNetworkAgentMessage(Message msg) {
3254             final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
3255             final NetworkAgentInfo nai = arg.first;
3256             if (!mNetworkAgentInfos.contains(nai)) {
3257                 if (VDBG) {
3258                     log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
3259                 }
3260                 return;
3261             }
3262 
3263             switch (msg.what) {
3264                 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
3265                     NetworkCapabilities networkCapabilities = (NetworkCapabilities) arg.second;
3266                     if (networkCapabilities.hasConnectivityManagedCapability()) {
3267                         Log.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
3268                     }
3269                     if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
3270                         // Make sure the original object is not mutated. NetworkAgent normally
3271                         // makes a copy of the capabilities when sending the message through
3272                         // the Messenger, but if this ever changes, not making a defensive copy
3273                         // here will give attack vectors to clients using this code path.
3274                         networkCapabilities = new NetworkCapabilities(networkCapabilities);
3275                         networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
3276                     }
3277                     processCapabilitiesFromAgent(nai, networkCapabilities);
3278                     updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
3279                     break;
3280                 }
3281                 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
3282                     LinkProperties newLp = (LinkProperties) arg.second;
3283                     processLinkPropertiesFromAgent(nai, newLp);
3284                     handleUpdateLinkProperties(nai, newLp);
3285                     break;
3286                 }
3287                 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
3288                     NetworkInfo info = (NetworkInfo) arg.second;
3289                     updateNetworkInfo(nai, info);
3290                     break;
3291                 }
3292                 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
3293                     updateNetworkScore(nai, (NetworkScore) arg.second);
3294                     break;
3295                 }
3296                 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
3297                     if (nai.everConnected) {
3298                         loge("ERROR: cannot call explicitlySelected on already-connected network");
3299                         // Note that if the NAI had been connected, this would affect the
3300                         // score, and therefore would require re-mixing the score and performing
3301                         // a rematch.
3302                     }
3303                     nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1);
3304                     nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
3305                     // Mark the network as temporarily accepting partial connectivity so that it
3306                     // will be validated (and possibly become default) even if it only provides
3307                     // partial internet access. Note that if user connects to partial connectivity
3308                     // and choose "don't ask again", then wifi disconnected by some reasons(maybe
3309                     // out of wifi coverage) and if the same wifi is available again, the device
3310                     // will auto connect to this wifi even though the wifi has "no internet".
3311                     // TODO: Evaluate using a separate setting in IpMemoryStore.
3312                     nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2);
3313                     break;
3314                 }
3315                 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
3316                     mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2);
3317                     break;
3318                 }
3319                 case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: {
3320                     // TODO: prevent loops, e.g., if a network declares itself as underlying.
3321                     final List<Network> underlying = (List<Network>) arg.second;
3322 
3323                     if (isLegacyLockdownNai(nai)
3324                             && (underlying == null || underlying.size() != 1)) {
3325                         Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString()
3326                                 + " must have exactly one underlying network: " + underlying);
3327                     }
3328 
3329                     final Network[] oldUnderlying = nai.declaredUnderlyingNetworks;
3330                     nai.declaredUnderlyingNetworks = (underlying != null)
3331                             ? underlying.toArray(new Network[0]) : null;
3332 
3333                     if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) {
3334                         if (DBG) {
3335                             log(nai.toShortString() + " changed underlying networks to "
3336                                     + Arrays.toString(nai.declaredUnderlyingNetworks));
3337                         }
3338                         updateCapabilitiesForNetwork(nai);
3339                         notifyIfacesChangedForNetworkStats();
3340                     }
3341                     break;
3342                 }
3343                 case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: {
3344                     if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
3345                         nai.teardownDelayMs = msg.arg1;
3346                     } else {
3347                         logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1);
3348                     }
3349                     break;
3350                 }
3351                 case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: {
3352                     nai.setLingerDuration((int) arg.second);
3353                     break;
3354                 }
3355             }
3356         }
3357 
maybeHandleNetworkMonitorMessage(Message msg)3358         private boolean maybeHandleNetworkMonitorMessage(Message msg) {
3359             switch (msg.what) {
3360                 default:
3361                     return false;
3362                 case EVENT_PROBE_STATUS_CHANGED: {
3363                     final Integer netId = (Integer) msg.obj;
3364                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
3365                     if (nai == null) {
3366                         break;
3367                     }
3368                     final boolean probePrivateDnsCompleted =
3369                             ((msg.arg1 & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
3370                     final boolean privateDnsBroken =
3371                             ((msg.arg2 & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
3372                     if (probePrivateDnsCompleted) {
3373                         if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) {
3374                             nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken);
3375                             updateCapabilitiesForNetwork(nai);
3376                         }
3377                         // Only show the notification when the private DNS is broken and the
3378                         // PRIVATE_DNS_BROKEN notification hasn't shown since last valid.
3379                         if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) {
3380                             showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN);
3381                         }
3382                         nai.networkAgentConfig.hasShownBroken = privateDnsBroken;
3383                     } else if (nai.networkCapabilities.isPrivateDnsBroken()) {
3384                         // If probePrivateDnsCompleted is false but nai.networkCapabilities says
3385                         // private DNS is broken, it means this network is being reevaluated.
3386                         // Either probing private DNS is not necessary any more or it hasn't been
3387                         // done yet. In either case, the networkCapabilities should be updated to
3388                         // reflect the new status.
3389                         nai.networkCapabilities.setPrivateDnsBroken(false);
3390                         updateCapabilitiesForNetwork(nai);
3391                         nai.networkAgentConfig.hasShownBroken = false;
3392                     }
3393                     break;
3394                 }
3395                 case EVENT_NETWORK_TESTED: {
3396                     final NetworkTestedResults results = (NetworkTestedResults) msg.obj;
3397 
3398                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(results.mNetId);
3399                     if (nai == null) break;
3400 
3401                     handleNetworkTested(nai, results.mTestResult,
3402                             (results.mRedirectUrl == null) ? "" : results.mRedirectUrl);
3403                     break;
3404                 }
3405                 case EVENT_PROVISIONING_NOTIFICATION: {
3406                     final int netId = msg.arg2;
3407                     final boolean visible = toBool(msg.arg1);
3408                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
3409                     // If captive portal status has changed, update capabilities or disconnect.
3410                     if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
3411                         nai.lastCaptivePortalDetected = visible;
3412                         nai.everCaptivePortalDetected |= visible;
3413                         if (nai.lastCaptivePortalDetected &&
3414                                 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
3415                                         == getCaptivePortalMode()) {
3416                             if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
3417                             nai.onPreventAutomaticReconnect();
3418                             teardownUnneededNetwork(nai);
3419                             break;
3420                         }
3421                         updateCapabilitiesForNetwork(nai);
3422                     }
3423                     if (!visible) {
3424                         // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other
3425                         // notifications belong to the same network may be cleared unexpectedly.
3426                         mNotifier.clearNotification(netId, NotificationType.SIGN_IN);
3427                         mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH);
3428                     } else {
3429                         if (nai == null) {
3430                             loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
3431                             break;
3432                         }
3433                         if (!nai.networkAgentConfig.provisioningNotificationDisabled) {
3434                             mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null,
3435                                     (PendingIntent) msg.obj,
3436                                     nai.networkAgentConfig.explicitlySelected);
3437                         }
3438                     }
3439                     break;
3440                 }
3441                 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: {
3442                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
3443                     if (nai == null) break;
3444 
3445                     updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
3446                     break;
3447                 }
3448                 case EVENT_CAPPORT_DATA_CHANGED: {
3449                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
3450                     if (nai == null) break;
3451                     handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj);
3452                     break;
3453                 }
3454             }
3455             return true;
3456         }
3457 
handleNetworkTested( @onNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl)3458         private void handleNetworkTested(
3459                 @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) {
3460             final boolean wasPartial = nai.partialConnectivity;
3461             nai.partialConnectivity = ((testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
3462             final boolean partialConnectivityChanged =
3463                     (wasPartial != nai.partialConnectivity);
3464 
3465             final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0);
3466             final boolean wasValidated = nai.lastValidated;
3467             final boolean wasDefault = isDefaultNetwork(nai);
3468 
3469             if (DBG) {
3470                 final String logMsg = !TextUtils.isEmpty(redirectUrl)
3471                         ? " with redirect to " + redirectUrl
3472                         : "";
3473                 log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg);
3474             }
3475             if (valid != nai.lastValidated) {
3476                 final int oldScore = nai.getCurrentScore();
3477                 nai.lastValidated = valid;
3478                 nai.everValidated |= valid;
3479                 updateCapabilities(oldScore, nai, nai.networkCapabilities);
3480                 if (valid) {
3481                     handleFreshlyValidatedNetwork(nai);
3482                     // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and
3483                     // LOST_INTERNET notifications if network becomes valid.
3484                     mNotifier.clearNotification(nai.network.getNetId(),
3485                             NotificationType.NO_INTERNET);
3486                     mNotifier.clearNotification(nai.network.getNetId(),
3487                             NotificationType.LOST_INTERNET);
3488                     mNotifier.clearNotification(nai.network.getNetId(),
3489                             NotificationType.PARTIAL_CONNECTIVITY);
3490                     mNotifier.clearNotification(nai.network.getNetId(),
3491                             NotificationType.PRIVATE_DNS_BROKEN);
3492                     // If network becomes valid, the hasShownBroken should be reset for
3493                     // that network so that the notification will be fired when the private
3494                     // DNS is broken again.
3495                     nai.networkAgentConfig.hasShownBroken = false;
3496                 }
3497             } else if (partialConnectivityChanged) {
3498                 updateCapabilitiesForNetwork(nai);
3499             }
3500             updateInetCondition(nai);
3501             // Let the NetworkAgent know the state of its network
3502             // TODO: Evaluate to update partial connectivity to status to NetworkAgent.
3503             nai.onValidationStatusChanged(
3504                     valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK,
3505                     redirectUrl);
3506 
3507             // If NetworkMonitor detects partial connectivity before
3508             // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
3509             // immediately. Re-notify partial connectivity silently if no internet
3510             // notification already there.
3511             if (!wasPartial && nai.partialConnectivity) {
3512                 // Remove delayed message if there is a pending message.
3513                 mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
3514                 handlePromptUnvalidated(nai.network);
3515             }
3516 
3517             if (wasValidated && !nai.lastValidated) {
3518                 handleNetworkUnvalidated(nai);
3519             }
3520         }
3521 
getCaptivePortalMode()3522         private int getCaptivePortalMode() {
3523             return Settings.Global.getInt(mContext.getContentResolver(),
3524                     ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE,
3525                     ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT);
3526         }
3527 
maybeHandleNetworkAgentInfoMessage(Message msg)3528         private boolean maybeHandleNetworkAgentInfoMessage(Message msg) {
3529             switch (msg.what) {
3530                 default:
3531                     return false;
3532                 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: {
3533                     NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
3534                     if (nai != null && isLiveNetworkAgent(nai, msg.what)) {
3535                         handleLingerComplete(nai);
3536                     }
3537                     break;
3538                 }
3539                 case NetworkAgentInfo.EVENT_AGENT_REGISTERED: {
3540                     handleNetworkAgentRegistered(msg);
3541                     break;
3542                 }
3543                 case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: {
3544                     handleNetworkAgentDisconnected(msg);
3545                     break;
3546                 }
3547             }
3548             return true;
3549         }
3550 
3551         @Override
handleMessage(Message msg)3552         public void handleMessage(Message msg) {
3553             if (!maybeHandleNetworkMonitorMessage(msg)
3554                     && !maybeHandleNetworkAgentInfoMessage(msg)) {
3555                 maybeHandleNetworkAgentMessage(msg);
3556             }
3557         }
3558     }
3559 
3560     private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub {
3561         private final int mNetId;
3562         private final AutodestructReference<NetworkAgentInfo> mNai;
3563 
NetworkMonitorCallbacks(NetworkAgentInfo nai)3564         private NetworkMonitorCallbacks(NetworkAgentInfo nai) {
3565             mNetId = nai.network.getNetId();
3566             mNai = new AutodestructReference<>(nai);
3567         }
3568 
3569         @Override
onNetworkMonitorCreated(INetworkMonitor networkMonitor)3570         public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
3571             mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT,
3572                     new Pair<>(mNai.getAndDestroy(), networkMonitor)));
3573         }
3574 
3575         @Override
notifyNetworkTested(int testResult, @Nullable String redirectUrl)3576         public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) {
3577             // Legacy version of notifyNetworkTestedWithExtras.
3578             // Would only be called if the system has a NetworkStack module older than the
3579             // framework, which does not happen in practice.
3580             Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken");
3581         }
3582 
3583         @Override
notifyNetworkTestedWithExtras(NetworkTestResultParcelable p)3584         public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) {
3585             // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use
3586             // the same looper so messages will be processed in sequence.
3587             final Message msg = mTrackerHandler.obtainMessage(
3588                     EVENT_NETWORK_TESTED,
3589                     new NetworkTestedResults(
3590                             mNetId, p.result, p.timestampMillis, p.redirectUrl));
3591             mTrackerHandler.sendMessage(msg);
3592 
3593             // Invoke ConnectivityReport generation for this Network test event.
3594             final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId);
3595             if (nai == null) return;
3596 
3597             final PersistableBundle extras = new PersistableBundle();
3598             extras.putInt(KEY_NETWORK_VALIDATION_RESULT, p.result);
3599             extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded);
3600             extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted);
3601 
3602             ConnectivityReportEvent reportEvent =
3603                     new ConnectivityReportEvent(p.timestampMillis, nai, extras);
3604             final Message m = mConnectivityDiagnosticsHandler.obtainMessage(
3605                     ConnectivityDiagnosticsHandler.EVENT_NETWORK_TESTED, reportEvent);
3606             mConnectivityDiagnosticsHandler.sendMessage(m);
3607         }
3608 
3609         @Override
notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config)3610         public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) {
3611             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3612                     EVENT_PRIVATE_DNS_CONFIG_RESOLVED,
3613                     0, mNetId, PrivateDnsConfig.fromParcel(config)));
3614         }
3615 
3616         @Override
notifyProbeStatusChanged(int probesCompleted, int probesSucceeded)3617         public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) {
3618             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3619                     EVENT_PROBE_STATUS_CHANGED,
3620                     probesCompleted, probesSucceeded, new Integer(mNetId)));
3621         }
3622 
3623         @Override
notifyCaptivePortalDataChanged(CaptivePortalData data)3624         public void notifyCaptivePortalDataChanged(CaptivePortalData data) {
3625             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3626                     EVENT_CAPPORT_DATA_CHANGED,
3627                     0, mNetId, data));
3628         }
3629 
3630         @Override
showProvisioningNotification(String action, String packageName)3631         public void showProvisioningNotification(String action, String packageName) {
3632             final Intent intent = new Intent(action);
3633             intent.setPackage(packageName);
3634 
3635             final PendingIntent pendingIntent;
3636             // Only the system server can register notifications with package "android"
3637             final long token = Binder.clearCallingIdentity();
3638             try {
3639                 pendingIntent = PendingIntent.getBroadcast(
3640                         mContext,
3641                         0 /* requestCode */,
3642                         intent,
3643                         PendingIntent.FLAG_IMMUTABLE);
3644             } finally {
3645                 Binder.restoreCallingIdentity(token);
3646             }
3647             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3648                     EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW,
3649                     mNetId, pendingIntent));
3650         }
3651 
3652         @Override
hideProvisioningNotification()3653         public void hideProvisioningNotification() {
3654             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3655                     EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId));
3656         }
3657 
3658         @Override
notifyDataStallSuspected(DataStallReportParcelable p)3659         public void notifyDataStallSuspected(DataStallReportParcelable p) {
3660             ConnectivityService.this.notifyDataStallSuspected(p, mNetId);
3661         }
3662 
3663         @Override
getInterfaceVersion()3664         public int getInterfaceVersion() {
3665             return this.VERSION;
3666         }
3667 
3668         @Override
getInterfaceHash()3669         public String getInterfaceHash() {
3670             return this.HASH;
3671         }
3672     }
3673 
notifyDataStallSuspected(DataStallReportParcelable p, int netId)3674     private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) {
3675         log("Data stall detected with methods: " + p.detectionMethod);
3676 
3677         final PersistableBundle extras = new PersistableBundle();
3678         int detectionMethod = 0;
3679         if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
3680             extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
3681             detectionMethod |= DETECTION_METHOD_DNS_EVENTS;
3682         }
3683         if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
3684             extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
3685             extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
3686                     p.tcpMetricsCollectionPeriodMillis);
3687             detectionMethod |= DETECTION_METHOD_TCP_METRICS;
3688         }
3689 
3690         final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
3691                 ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId,
3692                 new Pair<>(p.timestampMillis, extras));
3693 
3694         // NetworkStateTrackerHandler currently doesn't take any actions based on data
3695         // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
3696         // the cost of going through two handlers.
3697         mConnectivityDiagnosticsHandler.sendMessage(msg);
3698     }
3699 
hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod)3700     private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) {
3701         return (p.detectionMethod & detectionMethod) != 0;
3702     }
3703 
networkRequiresPrivateDnsValidation(NetworkAgentInfo nai)3704     private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
3705         return isPrivateDnsValidationRequired(nai.networkCapabilities);
3706     }
3707 
handleFreshlyValidatedNetwork(NetworkAgentInfo nai)3708     private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) {
3709         if (nai == null) return;
3710         // If the Private DNS mode is opportunistic, reprogram the DNS servers
3711         // in order to restart a validation pass from within netd.
3712         final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
3713         if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) {
3714             updateDnses(nai.linkProperties, null, nai.network.getNetId());
3715         }
3716     }
3717 
handlePrivateDnsSettingsChanged()3718     private void handlePrivateDnsSettingsChanged() {
3719         final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
3720 
3721         for (NetworkAgentInfo nai : mNetworkAgentInfos) {
3722             handlePerNetworkPrivateDnsConfig(nai, cfg);
3723             if (networkRequiresPrivateDnsValidation(nai)) {
3724                 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
3725             }
3726         }
3727     }
3728 
handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg)3729     private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) {
3730         // Private DNS only ever applies to networks that might provide
3731         // Internet access and therefore also require validation.
3732         if (!networkRequiresPrivateDnsValidation(nai)) return;
3733 
3734         // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
3735         // schedule DNS resolutions. If a DNS resolution is required the
3736         // result will be sent back to us.
3737         nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
3738 
3739         // With Private DNS bypass support, we can proceed to update the
3740         // Private DNS config immediately, even if we're in strict mode
3741         // and have not yet resolved the provider name into a set of IPs.
3742         updatePrivateDns(nai, cfg);
3743     }
3744 
updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg)3745     private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) {
3746         mDnsManager.updatePrivateDns(nai.network, newCfg);
3747         updateDnses(nai.linkProperties, null, nai.network.getNetId());
3748     }
3749 
handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update)3750     private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) {
3751         NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId);
3752         if (nai == null) {
3753             return;
3754         }
3755         mDnsManager.updatePrivateDnsValidation(update);
3756         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
3757     }
3758 
handleNat64PrefixEvent(int netId, int operation, String prefixAddress, int prefixLength)3759     private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress,
3760             int prefixLength) {
3761         NetworkAgentInfo nai = mNetworkForNetId.get(netId);
3762         if (nai == null) return;
3763 
3764         log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d",
3765                 netId, operation, prefixAddress, prefixLength));
3766 
3767         IpPrefix prefix = null;
3768         if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) {
3769             try {
3770                 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress),
3771                         prefixLength);
3772             } catch (IllegalArgumentException e) {
3773                 loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength);
3774                 return;
3775             }
3776         }
3777 
3778         nai.clatd.setNat64PrefixFromDns(prefix);
3779         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
3780     }
3781 
handleCapportApiDataUpdate(@onNull final NetworkAgentInfo nai, @Nullable final CaptivePortalData data)3782     private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai,
3783             @Nullable final CaptivePortalData data) {
3784         nai.capportApiData = data;
3785         // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
3786         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
3787     }
3788 
3789     /**
3790      * Updates the inactivity state from the network requests inside the NAI.
3791      * @param nai the agent info to update
3792      * @param now the timestamp of the event causing this update
3793      * @return whether the network was inactive as a result of this update
3794      */
updateInactivityState(@onNull final NetworkAgentInfo nai, final long now)3795     private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) {
3796         // 1. Update the inactivity timer. If it's changed, reschedule or cancel the alarm.
3797         // 2. If the network was inactive and there are now requests, unset inactive.
3798         // 3. If this network is unneeded (which implies it is not lingering), and there is at least
3799         //    one lingered request, set inactive.
3800         nai.updateInactivityTimer();
3801         if (nai.isInactive() && nai.numForegroundNetworkRequests() > 0) {
3802             if (DBG) log("Unsetting inactive " + nai.toShortString());
3803             nai.unsetInactive();
3804             logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER);
3805         } else if (unneeded(nai, UnneededFor.LINGER) && nai.getInactivityExpiry() > 0) {
3806             if (DBG) {
3807                 final int lingerTime = (int) (nai.getInactivityExpiry() - now);
3808                 log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms");
3809             }
3810             nai.setInactive();
3811             logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
3812             return true;
3813         }
3814         return false;
3815     }
3816 
handleNetworkAgentRegistered(Message msg)3817     private void handleNetworkAgentRegistered(Message msg) {
3818         final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
3819         if (!mNetworkAgentInfos.contains(nai)) {
3820             return;
3821         }
3822 
3823         if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) {
3824             if (VDBG) log("NetworkAgent registered");
3825         } else {
3826             loge("Error connecting NetworkAgent");
3827             mNetworkAgentInfos.remove(nai);
3828             if (nai != null) {
3829                 final boolean wasDefault = isDefaultNetwork(nai);
3830                 synchronized (mNetworkForNetId) {
3831                     mNetworkForNetId.remove(nai.network.getNetId());
3832                 }
3833                 mNetIdManager.releaseNetId(nai.network.getNetId());
3834                 // Just in case.
3835                 mLegacyTypeTracker.remove(nai, wasDefault);
3836             }
3837         }
3838     }
3839 
handleNetworkAgentDisconnected(Message msg)3840     private void handleNetworkAgentDisconnected(Message msg) {
3841         NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
3842         if (mNetworkAgentInfos.contains(nai)) {
3843             disconnectAndDestroyNetwork(nai);
3844         }
3845     }
3846 
3847     // Destroys a network, remove references to it from the internal state managed by
3848     // ConnectivityService, free its interfaces and clean up.
3849     // Must be called on the Handler thread.
disconnectAndDestroyNetwork(NetworkAgentInfo nai)3850     private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
3851         ensureRunningOnConnectivityServiceThread();
3852         if (DBG) {
3853             log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests());
3854         }
3855         // Clear all notifications of this network.
3856         mNotifier.clearNotification(nai.network.getNetId());
3857         // A network agent has disconnected.
3858         // TODO - if we move the logic to the network agent (have them disconnect
3859         // because they lost all their requests or because their score isn't good)
3860         // then they would disconnect organically, report their new state and then
3861         // disconnect the channel.
3862         if (nai.networkInfo.isConnected()) {
3863             nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
3864                     null, null);
3865         }
3866         final boolean wasDefault = isDefaultNetwork(nai);
3867         if (wasDefault) {
3868             mDefaultInetConditionPublished = 0;
3869         }
3870         notifyIfacesChangedForNetworkStats();
3871         // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
3872         // by other networks that are already connected. Perhaps that can be done by
3873         // sending all CALLBACK_LOST messages (for requests, not listens) at the end
3874         // of rematchAllNetworksAndRequests
3875         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
3876         mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK);
3877 
3878         mQosCallbackTracker.handleNetworkReleased(nai.network);
3879         for (String iface : nai.linkProperties.getAllInterfaceNames()) {
3880             // Disable wakeup packet monitoring for each interface.
3881             wakeupModifyInterface(iface, nai.networkCapabilities, false);
3882         }
3883         nai.networkMonitor().notifyNetworkDisconnected();
3884         mNetworkAgentInfos.remove(nai);
3885         nai.clatd.update();
3886         synchronized (mNetworkForNetId) {
3887             // Remove the NetworkAgent, but don't mark the netId as
3888             // available until we've told netd to delete it below.
3889             mNetworkForNetId.remove(nai.network.getNetId());
3890         }
3891         propagateUnderlyingNetworkCapabilities(nai.network);
3892         // Remove all previously satisfied requests.
3893         for (int i = 0; i < nai.numNetworkRequests(); i++) {
3894             final NetworkRequest request = nai.requestAt(i);
3895             final NetworkRequestInfo nri = mNetworkRequests.get(request);
3896             final NetworkAgentInfo currentNetwork = nri.getSatisfier();
3897             if (currentNetwork != null
3898                     && currentNetwork.network.getNetId() == nai.network.getNetId()) {
3899                 // uid rules for this network will be removed in destroyNativeNetwork(nai).
3900                 // TODO : setting the satisfier is in fact the job of the rematch. Teach the
3901                 // rematch not to keep disconnected agents instead of setting it here ; this
3902                 // will also allow removing updating the offers below.
3903                 nri.setSatisfier(null, null);
3904                 for (final NetworkOfferInfo noi : mNetworkOffers) {
3905                     informOffer(nri, noi.offer, mNetworkRanker);
3906                 }
3907 
3908                 if (mDefaultRequest == nri) {
3909                     // TODO : make battery stats aware that since 2013 multiple interfaces may be
3910                     //  active at the same time. For now keep calling this with the default
3911                     //  network, because while incorrect this is the closest to the old (also
3912                     //  incorrect) behavior.
3913                     mNetworkActivityTracker.updateDataActivityTracking(
3914                             null /* newNetwork */, nai);
3915                     ensureNetworkTransitionWakelock(nai.toShortString());
3916                 }
3917             }
3918         }
3919         nai.clearInactivityState();
3920         // TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after.
3921         //  Currently, deleting it breaks tests that check for the default network disconnecting.
3922         //  Find out why, fix the rematch code, and delete this.
3923         mLegacyTypeTracker.remove(nai, wasDefault);
3924         rematchAllNetworksAndRequests();
3925         mLingerMonitor.noteDisconnect(nai);
3926 
3927         // Immediate teardown.
3928         if (nai.teardownDelayMs == 0) {
3929             destroyNetwork(nai);
3930             return;
3931         }
3932 
3933         // Delayed teardown.
3934         try {
3935             mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
3936         } catch (RemoteException e) {
3937             Log.d(TAG, "Error marking network restricted during teardown: " + e);
3938         }
3939         mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs);
3940     }
3941 
destroyNetwork(NetworkAgentInfo nai)3942     private void destroyNetwork(NetworkAgentInfo nai) {
3943         if (nai.created) {
3944             // Tell netd to clean up the configuration for this network
3945             // (routing rules, DNS, etc).
3946             // This may be slow as it requires a lot of netd shelling out to ip and
3947             // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
3948             // after we've rematched networks with requests (which might change the default
3949             // network or service a new request from an app), so network traffic isn't interrupted
3950             // for an unnecessarily long time.
3951             destroyNativeNetwork(nai);
3952             mDnsManager.removeNetwork(nai.network);
3953         }
3954         mNetIdManager.releaseNetId(nai.network.getNetId());
3955         nai.onNetworkDestroyed();
3956     }
3957 
createNativeNetwork(@onNull NetworkAgentInfo nai)3958     private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) {
3959         try {
3960             // This should never fail.  Specifying an already in use NetID will cause failure.
3961             final NativeNetworkConfig config;
3962             if (nai.isVPN()) {
3963                 if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) {
3964                     Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString());
3965                     return false;
3966                 }
3967                 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL,
3968                         INetd.PERMISSION_NONE,
3969                         (nai.networkAgentConfig == null || !nai.networkAgentConfig.allowBypass),
3970                         getVpnType(nai));
3971             } else {
3972                 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.PHYSICAL,
3973                         getNetworkPermission(nai.networkCapabilities), /*secure=*/ false,
3974                         VpnManager.TYPE_VPN_NONE);
3975             }
3976             mNetd.networkCreate(config);
3977             mDnsResolver.createNetworkCache(nai.network.getNetId());
3978             mDnsManager.updateTransportsForNetwork(nai.network.getNetId(),
3979                     nai.networkCapabilities.getTransportTypes());
3980             return true;
3981         } catch (RemoteException | ServiceSpecificException e) {
3982             loge("Error creating network " + nai.toShortString() + ": " + e.getMessage());
3983             return false;
3984         }
3985     }
3986 
destroyNativeNetwork(@onNull NetworkAgentInfo nai)3987     private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
3988         try {
3989             mNetd.networkDestroy(nai.network.getNetId());
3990         } catch (RemoteException | ServiceSpecificException e) {
3991             loge("Exception destroying network(networkDestroy): " + e);
3992         }
3993         try {
3994             mDnsResolver.destroyNetworkCache(nai.network.getNetId());
3995         } catch (RemoteException | ServiceSpecificException e) {
3996             loge("Exception destroying network: " + e);
3997         }
3998     }
3999 
4000     // If this method proves to be too slow then we can maintain a separate
4001     // pendingIntent => NetworkRequestInfo map.
4002     // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
findExistingNetworkRequestInfo(PendingIntent pendingIntent)4003     private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
4004         for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
4005             PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
4006             if (existingPendingIntent != null &&
4007                     mDeps.intentFilterEquals(existingPendingIntent, pendingIntent)) {
4008                 return entry.getValue();
4009             }
4010         }
4011         return null;
4012     }
4013 
handleRegisterNetworkRequestWithIntent(@onNull final Message msg)4014     private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) {
4015         final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
4016         // handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests.
4017         ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent");
4018         final NetworkRequestInfo existingRequest =
4019                 findExistingNetworkRequestInfo(nri.mPendingIntent);
4020         if (existingRequest != null) { // remove the existing request.
4021             if (DBG) {
4022                 log("Replacing " + existingRequest.mRequests.get(0) + " with "
4023                         + nri.mRequests.get(0) + " because their intents matched.");
4024             }
4025             handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(),
4026                     /* callOnUnavailable */ false);
4027         }
4028         handleRegisterNetworkRequest(nri);
4029     }
4030 
handleRegisterNetworkRequest(@onNull final NetworkRequestInfo nri)4031     private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) {
4032         handleRegisterNetworkRequests(Collections.singleton(nri));
4033     }
4034 
handleRegisterNetworkRequests(@onNull final Set<NetworkRequestInfo> nris)4035     private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
4036         ensureRunningOnConnectivityServiceThread();
4037         for (final NetworkRequestInfo nri : nris) {
4038             mNetworkRequestInfoLogs.log("REGISTER " + nri);
4039             for (final NetworkRequest req : nri.mRequests) {
4040                 mNetworkRequests.put(req, nri);
4041                 // TODO: Consider update signal strength for other types.
4042                 if (req.isListen()) {
4043                     for (final NetworkAgentInfo network : mNetworkAgentInfos) {
4044                         if (req.networkCapabilities.hasSignalStrength()
4045                                 && network.satisfiesImmutableCapabilitiesOf(req)) {
4046                             updateSignalStrengthThresholds(network, "REGISTER", req);
4047                         }
4048                     }
4049                 }
4050             }
4051             // If this NRI has a satisfier already, it is replacing an older request that
4052             // has been removed. Track it.
4053             final NetworkRequest activeRequest = nri.getActiveRequest();
4054             if (null != activeRequest) {
4055                 // If there is an active request, then for sure there is a satisfier.
4056                 nri.getSatisfier().addRequest(activeRequest);
4057             }
4058         }
4059 
4060         rematchAllNetworksAndRequests();
4061 
4062         // Requests that have not been matched to a network will not have been sent to the
4063         // providers, because the old satisfier and the new satisfier are the same (null in this
4064         // case). Send these requests to the providers.
4065         for (final NetworkRequestInfo nri : nris) {
4066             for (final NetworkOfferInfo noi : mNetworkOffers) {
4067                 informOffer(nri, noi.offer, mNetworkRanker);
4068             }
4069         }
4070     }
4071 
handleReleaseNetworkRequestWithIntent(@onNull final PendingIntent pendingIntent, final int callingUid)4072     private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent,
4073             final int callingUid) {
4074         final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
4075         if (nri != null) {
4076             // handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests.
4077             ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent");
4078             handleReleaseNetworkRequest(
4079                     nri.mRequests.get(0),
4080                     callingUid,
4081                     /* callOnUnavailable */ false);
4082         }
4083     }
4084 
4085     // Determines whether the network is the best (or could become the best, if it validated), for
4086     // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends
4087     // on the value of reason:
4088     //
4089     // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason,
4090     //   then it should be torn down.
4091     // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
4092     //   then it should be lingered.
unneeded(NetworkAgentInfo nai, UnneededFor reason)4093     private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
4094         ensureRunningOnConnectivityServiceThread();
4095 
4096         if (!nai.everConnected || nai.isVPN() || nai.isInactive()
4097                 || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
4098             return false;
4099         }
4100 
4101         final int numRequests;
4102         switch (reason) {
4103             case TEARDOWN:
4104                 numRequests = nai.numRequestNetworkRequests();
4105                 break;
4106             case LINGER:
4107                 numRequests = nai.numForegroundNetworkRequests();
4108                 break;
4109             default:
4110                 Log.wtf(TAG, "Invalid reason. Cannot happen.");
4111                 return true;
4112         }
4113 
4114         if (numRequests > 0) return false;
4115 
4116         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
4117             if (reason == UnneededFor.LINGER
4118                     && !nri.isMultilayerRequest()
4119                     && nri.mRequests.get(0).isBackgroundRequest()) {
4120                 // Background requests don't affect lingering.
4121                 continue;
4122             }
4123 
4124             if (isNetworkPotentialSatisfier(nai, nri)) {
4125                 return false;
4126             }
4127         }
4128         return true;
4129     }
4130 
isNetworkPotentialSatisfier( @onNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri)4131     private boolean isNetworkPotentialSatisfier(
4132             @NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) {
4133         // listen requests won't keep up a network satisfying it. If this is not a multilayer
4134         // request, return immediately. For multilayer requests, check to see if any of the
4135         // multilayer requests may have a potential satisfier.
4136         if (!nri.isMultilayerRequest() && (nri.mRequests.get(0).isListen()
4137                 || nri.mRequests.get(0).isListenForBest())) {
4138             return false;
4139         }
4140         for (final NetworkRequest req : nri.mRequests) {
4141             // This multilayer listen request is satisfied therefore no further requests need to be
4142             // evaluated deeming this network not a potential satisfier.
4143             if ((req.isListen() || req.isListenForBest()) && nri.getActiveRequest() == req) {
4144                 return false;
4145             }
4146             // As non-multilayer listen requests have already returned, the below would only happen
4147             // for a multilayer request therefore continue to the next request if available.
4148             if (req.isListen() || req.isListenForBest()) {
4149                 continue;
4150             }
4151             // If this Network is already the highest scoring Network for a request, or if
4152             // there is hope for it to become one if it validated, then it is needed.
4153             if (candidate.satisfies(req)) {
4154                 // As soon as a network is found that satisfies a request, return. Specifically for
4155                 // multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request
4156                 // is important so as to not evaluate lower priority requests further in
4157                 // nri.mRequests.
4158                 final NetworkAgentInfo champion = req.equals(nri.getActiveRequest())
4159                         ? nri.getSatisfier() : null;
4160                 // Note that this catches two important cases:
4161                 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
4162                 //    is currently satisfying the request.  This is desirable when
4163                 //    cellular ends up validating but WiFi does not.
4164                 // 2. Unvalidated WiFi will not be reaped when validated cellular
4165                 //    is currently satisfying the request.  This is desirable when
4166                 //    WiFi ends up validating and out scoring cellular.
4167                 return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable());
4168             }
4169         }
4170 
4171         return false;
4172     }
4173 
getNriForAppRequest( NetworkRequest request, int callingUid, String requestedOperation)4174     private NetworkRequestInfo getNriForAppRequest(
4175             NetworkRequest request, int callingUid, String requestedOperation) {
4176         // Looking up the app passed param request in mRequests isn't possible since it may return
4177         // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to
4178         // do the lookup since that will also find per-app default managed requests.
4179         // Additionally, this lookup needs to be relatively fast (hence the lookup optimization)
4180         // to avoid potential race conditions when validating a package->uid mapping when sending
4181         // the callback on the very low-chance that an application shuts down prior to the callback
4182         // being sent.
4183         final NetworkRequestInfo nri = mNetworkRequests.get(request) != null
4184                 ? mNetworkRequests.get(request) : getNriForAppRequest(request);
4185 
4186         if (nri != null) {
4187             if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
4188                 log(String.format("UID %d attempted to %s for unowned request %s",
4189                         callingUid, requestedOperation, nri));
4190                 return null;
4191             }
4192         }
4193 
4194         return nri;
4195     }
4196 
ensureNotMultilayerRequest(@onNull final NetworkRequestInfo nri, final String callingMethod)4197     private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri,
4198             final String callingMethod) {
4199         if (nri.isMultilayerRequest()) {
4200             throw new IllegalStateException(
4201                     callingMethod + " does not support multilayer requests.");
4202         }
4203     }
4204 
handleTimedOutNetworkRequest(@onNull final NetworkRequestInfo nri)4205     private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) {
4206         ensureRunningOnConnectivityServiceThread();
4207         // handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a
4208         // single NetworkRequest and thus does not apply to multilayer requests.
4209         ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest");
4210         if (mNetworkRequests.get(nri.mRequests.get(0)) == null) {
4211             return;
4212         }
4213         if (nri.isBeingSatisfied()) {
4214             return;
4215         }
4216         if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) {
4217             log("releasing " + nri.mRequests.get(0) + " (timeout)");
4218         }
4219         handleRemoveNetworkRequest(nri);
4220         callCallbackForRequest(
4221                 nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
4222     }
4223 
handleReleaseNetworkRequest(@onNull final NetworkRequest request, final int callingUid, final boolean callOnUnavailable)4224     private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request,
4225             final int callingUid,
4226             final boolean callOnUnavailable) {
4227         final NetworkRequestInfo nri =
4228                 getNriForAppRequest(request, callingUid, "release NetworkRequest");
4229         if (nri == null) {
4230             return;
4231         }
4232         if (VDBG || (DBG && request.isRequest())) {
4233             log("releasing " + request + " (release request)");
4234         }
4235         handleRemoveNetworkRequest(nri);
4236         if (callOnUnavailable) {
4237             callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
4238         }
4239     }
4240 
handleRemoveNetworkRequest(@onNull final NetworkRequestInfo nri)4241     private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri) {
4242         ensureRunningOnConnectivityServiceThread();
4243         for (final NetworkRequest req : nri.mRequests) {
4244             if (null == mNetworkRequests.remove(req)) {
4245                 logw("Attempted removal of untracked request " + req + " for nri " + nri);
4246                 continue;
4247             }
4248             if (req.isListen()) {
4249                 removeListenRequestFromNetworks(req);
4250             }
4251         }
4252         nri.unlinkDeathRecipient();
4253         if (mDefaultNetworkRequests.remove(nri)) {
4254             // If this request was one of the defaults, then the UID rules need to be updated
4255             // WARNING : if the app(s) for which this network request is the default are doing
4256             // traffic, this will kill their connected sockets, even if an equivalent request
4257             // is going to be reinstated right away ; unconnected traffic will go on the default
4258             // until the new default is set, which will happen very soon.
4259             // TODO : The only way out of this is to diff old defaults and new defaults, and only
4260             // remove ranges for those requests that won't have a replacement
4261             final NetworkAgentInfo satisfier = nri.getSatisfier();
4262             if (null != satisfier) {
4263                 try {
4264                     mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
4265                             satisfier.network.getNetId(),
4266                             toUidRangeStableParcels(nri.getUids()),
4267                             nri.getPriorityForNetd()));
4268                 } catch (RemoteException e) {
4269                     loge("Exception setting network preference default network", e);
4270                 }
4271             }
4272         }
4273         nri.decrementRequestCount();
4274         mNetworkRequestInfoLogs.log("RELEASE " + nri);
4275 
4276         if (null != nri.getActiveRequest()) {
4277             if (!nri.getActiveRequest().isListen()) {
4278                 removeSatisfiedNetworkRequestFromNetwork(nri);
4279             } else {
4280                 nri.setSatisfier(null, null);
4281             }
4282         }
4283 
4284         // For all outstanding offers, cancel any of the layers of this NRI that used to be
4285         // needed for this offer.
4286         for (final NetworkOfferInfo noi : mNetworkOffers) {
4287             for (final NetworkRequest req : nri.mRequests) {
4288                 if (req.isRequest() && noi.offer.neededFor(req)) {
4289                     noi.offer.onNetworkUnneeded(req);
4290                 }
4291             }
4292         }
4293     }
4294 
handleRemoveNetworkRequests(@onNull final Set<NetworkRequestInfo> nris)4295     private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
4296         for (final NetworkRequestInfo nri : nris) {
4297             if (mDefaultRequest == nri) {
4298                 // Make sure we never remove the default request.
4299                 continue;
4300             }
4301             handleRemoveNetworkRequest(nri);
4302         }
4303     }
4304 
removeListenRequestFromNetworks(@onNull final NetworkRequest req)4305     private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) {
4306         // listens don't have a singular affected Network. Check all networks to see
4307         // if this listen request applies and remove it.
4308         for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
4309             nai.removeRequest(req.requestId);
4310             if (req.networkCapabilities.hasSignalStrength()
4311                     && nai.satisfiesImmutableCapabilitiesOf(req)) {
4312                 updateSignalStrengthThresholds(nai, "RELEASE", req);
4313             }
4314         }
4315     }
4316 
4317     /**
4318      * Remove a NetworkRequestInfo's satisfied request from its 'satisfier' (NetworkAgentInfo) and
4319      * manage the necessary upkeep (linger, teardown networks, etc.) when doing so.
4320      * @param nri the NetworkRequestInfo to disassociate from its current NetworkAgentInfo
4321      */
removeSatisfiedNetworkRequestFromNetwork(@onNull final NetworkRequestInfo nri)4322     private void removeSatisfiedNetworkRequestFromNetwork(@NonNull final NetworkRequestInfo nri) {
4323         boolean wasKept = false;
4324         final NetworkAgentInfo nai = nri.getSatisfier();
4325         if (nai != null) {
4326             final int requestLegacyType = nri.getActiveRequest().legacyType;
4327             final boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
4328             nai.removeRequest(nri.getActiveRequest().requestId);
4329             if (VDBG || DDBG) {
4330                 log(" Removing from current network " + nai.toShortString()
4331                         + ", leaving " + nai.numNetworkRequests() + " requests.");
4332             }
4333             // If there are still lingered requests on this network, don't tear it down,
4334             // but resume lingering instead.
4335             final long now = SystemClock.elapsedRealtime();
4336             if (updateInactivityState(nai, now)) {
4337                 notifyNetworkLosing(nai, now);
4338             }
4339             if (unneeded(nai, UnneededFor.TEARDOWN)) {
4340                 if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting");
4341                 teardownUnneededNetwork(nai);
4342             } else {
4343                 wasKept = true;
4344             }
4345             nri.setSatisfier(null, null);
4346             if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
4347                 // Went from foreground to background.
4348                 updateCapabilitiesForNetwork(nai);
4349             }
4350 
4351             // Maintain the illusion.  When this request arrived, we might have pretended
4352             // that a network connected to serve it, even though the network was already
4353             // connected.  Now that this request has gone away, we might have to pretend
4354             // that the network disconnected.  LegacyTypeTracker will generate that
4355             // phantom disconnect for this type.
4356             if (requestLegacyType != TYPE_NONE) {
4357                 boolean doRemove = true;
4358                 if (wasKept) {
4359                     // check if any of the remaining requests for this network are for the
4360                     // same legacy type - if so, don't remove the nai
4361                     for (int i = 0; i < nai.numNetworkRequests(); i++) {
4362                         NetworkRequest otherRequest = nai.requestAt(i);
4363                         if (otherRequest.legacyType == requestLegacyType
4364                                 && otherRequest.isRequest()) {
4365                             if (DBG) log(" still have other legacy request - leaving");
4366                             doRemove = false;
4367                         }
4368                     }
4369                 }
4370 
4371                 if (doRemove) {
4372                     mLegacyTypeTracker.remove(requestLegacyType, nai, false);
4373                 }
4374             }
4375         }
4376     }
4377 
getRequestCounter(NetworkRequestInfo nri)4378     private PerUidCounter getRequestCounter(NetworkRequestInfo nri) {
4379         return checkAnyPermissionOf(
4380                 nri.mPid, nri.mUid, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
4381                 ? mSystemNetworkRequestCounter : mNetworkRequestCounter;
4382     }
4383 
4384     @Override
setAcceptUnvalidated(Network network, boolean accept, boolean always)4385     public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
4386         enforceNetworkStackSettingsOrSetup();
4387         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED,
4388                 encodeBool(accept), encodeBool(always), network));
4389     }
4390 
4391     @Override
setAcceptPartialConnectivity(Network network, boolean accept, boolean always)4392     public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) {
4393         enforceNetworkStackSettingsOrSetup();
4394         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY,
4395                 encodeBool(accept), encodeBool(always), network));
4396     }
4397 
4398     @Override
setAvoidUnvalidated(Network network)4399     public void setAvoidUnvalidated(Network network) {
4400         enforceNetworkStackSettingsOrSetup();
4401         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network));
4402     }
4403 
4404     @Override
setTestAllowBadWifiUntil(long timeMs)4405     public void setTestAllowBadWifiUntil(long timeMs) {
4406         enforceSettingsPermission();
4407         if (!Build.isDebuggable()) {
4408             throw new IllegalStateException("Does not support in non-debuggable build");
4409         }
4410 
4411         if (timeMs > System.currentTimeMillis() + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS) {
4412             throw new IllegalArgumentException("It should not exceed "
4413                     + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS + "ms from now");
4414         }
4415 
4416         mHandler.sendMessage(
4417                 mHandler.obtainMessage(EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL, timeMs));
4418     }
4419 
handleSetAcceptUnvalidated(Network network, boolean accept, boolean always)4420     private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
4421         if (DBG) log("handleSetAcceptUnvalidated network=" + network +
4422                 " accept=" + accept + " always=" + always);
4423 
4424         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4425         if (nai == null) {
4426             // Nothing to do.
4427             return;
4428         }
4429 
4430         if (nai.everValidated) {
4431             // The network validated while the dialog box was up. Take no action.
4432             return;
4433         }
4434 
4435         if (!nai.networkAgentConfig.explicitlySelected) {
4436             Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
4437         }
4438 
4439         if (accept != nai.networkAgentConfig.acceptUnvalidated) {
4440             nai.networkAgentConfig.acceptUnvalidated = accept;
4441             // If network becomes partial connectivity and user already accepted to use this
4442             // network, we should respect the user's option and don't need to popup the
4443             // PARTIAL_CONNECTIVITY notification to user again.
4444             nai.networkAgentConfig.acceptPartialConnectivity = accept;
4445             nai.updateScoreForNetworkAgentUpdate();
4446             rematchAllNetworksAndRequests();
4447         }
4448 
4449         if (always) {
4450             nai.onSaveAcceptUnvalidated(accept);
4451         }
4452 
4453         if (!accept) {
4454             // Tell the NetworkAgent to not automatically reconnect to the network.
4455             nai.onPreventAutomaticReconnect();
4456             // Teardown the network.
4457             teardownUnneededNetwork(nai);
4458         }
4459 
4460     }
4461 
handleSetAcceptPartialConnectivity(Network network, boolean accept, boolean always)4462     private void handleSetAcceptPartialConnectivity(Network network, boolean accept,
4463             boolean always) {
4464         if (DBG) {
4465             log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept
4466                     + " always=" + always);
4467         }
4468 
4469         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4470         if (nai == null) {
4471             // Nothing to do.
4472             return;
4473         }
4474 
4475         if (nai.lastValidated) {
4476             // The network validated while the dialog box was up. Take no action.
4477             return;
4478         }
4479 
4480         if (accept != nai.networkAgentConfig.acceptPartialConnectivity) {
4481             nai.networkAgentConfig.acceptPartialConnectivity = accept;
4482         }
4483 
4484         // TODO: Use the current design or save the user choice into IpMemoryStore.
4485         if (always) {
4486             nai.onSaveAcceptUnvalidated(accept);
4487         }
4488 
4489         if (!accept) {
4490             // Tell the NetworkAgent to not automatically reconnect to the network.
4491             nai.onPreventAutomaticReconnect();
4492             // Tear down the network.
4493             teardownUnneededNetwork(nai);
4494         } else {
4495             // Inform NetworkMonitor that partial connectivity is acceptable. This will likely
4496             // result in a partial connectivity result which will be processed by
4497             // maybeHandleNetworkMonitorMessage.
4498             //
4499             // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
4500             // per network. Therefore, NetworkMonitor may still do https probe.
4501             nai.networkMonitor().setAcceptPartialConnectivity();
4502         }
4503     }
4504 
handleSetAvoidUnvalidated(Network network)4505     private void handleSetAvoidUnvalidated(Network network) {
4506         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4507         if (nai == null || nai.lastValidated) {
4508             // Nothing to do. The network either disconnected or revalidated.
4509             return;
4510         }
4511         if (!nai.avoidUnvalidated) {
4512             nai.avoidUnvalidated = true;
4513             nai.updateScoreForNetworkAgentUpdate();
4514             rematchAllNetworksAndRequests();
4515         }
4516     }
4517 
scheduleUnvalidatedPrompt(NetworkAgentInfo nai)4518     private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) {
4519         if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network);
4520         mHandler.sendMessageDelayed(
4521                 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network),
4522                 PROMPT_UNVALIDATED_DELAY_MS);
4523     }
4524 
4525     @Override
startCaptivePortalApp(Network network)4526     public void startCaptivePortalApp(Network network) {
4527         enforceNetworkStackOrSettingsPermission();
4528         mHandler.post(() -> {
4529             NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4530             if (nai == null) return;
4531             if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
4532             nai.networkMonitor().launchCaptivePortalApp();
4533         });
4534     }
4535 
4536     /**
4537      * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this
4538      * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself.
4539      * @param network Network on which the captive portal was detected.
4540      * @param appExtras Bundle to use as intent extras for the captive portal application.
4541      *                  Must be treated as opaque to avoid preventing the captive portal app to
4542      *                  update its arguments.
4543      */
4544     @Override
startCaptivePortalAppInternal(Network network, Bundle appExtras)4545     public void startCaptivePortalAppInternal(Network network, Bundle appExtras) {
4546         mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
4547                 "ConnectivityService");
4548 
4549         final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
4550         appIntent.putExtras(appExtras);
4551         appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
4552                 new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
4553         appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
4554 
4555         final long token = Binder.clearCallingIdentity();
4556         try {
4557             mContext.startActivityAsUser(appIntent, UserHandle.CURRENT);
4558         } finally {
4559             Binder.restoreCallingIdentity(token);
4560         }
4561     }
4562 
4563     private class CaptivePortalImpl extends ICaptivePortal.Stub {
4564         private final Network mNetwork;
4565 
CaptivePortalImpl(Network network)4566         private CaptivePortalImpl(Network network) {
4567             mNetwork = network;
4568         }
4569 
4570         @Override
appResponse(final int response)4571         public void appResponse(final int response) {
4572             if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
4573                 enforceSettingsPermission();
4574             }
4575 
4576             final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
4577             if (nm == null) return;
4578             nm.notifyCaptivePortalAppFinished(response);
4579         }
4580 
4581         @Override
appRequest(final int request)4582         public void appRequest(final int request) {
4583             final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
4584             if (nm == null) return;
4585 
4586             if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) {
4587                 checkNetworkStackPermission();
4588                 nm.forceReevaluation(mDeps.getCallingUid());
4589             }
4590         }
4591 
4592         @Nullable
getNetworkMonitorManager(final Network network)4593         private NetworkMonitorManager getNetworkMonitorManager(final Network network) {
4594             // getNetworkAgentInfoForNetwork is thread-safe
4595             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4596             if (nai == null) return null;
4597 
4598             // nai.networkMonitor() is thread-safe
4599             return nai.networkMonitor();
4600         }
4601     }
4602 
avoidBadWifi()4603     public boolean avoidBadWifi() {
4604         return mMultinetworkPolicyTracker.getAvoidBadWifi();
4605     }
4606 
4607     /**
4608      * Return whether the device should maintain continuous, working connectivity by switching away
4609      * from WiFi networks having no connectivity.
4610      * @see MultinetworkPolicyTracker#getAvoidBadWifi()
4611      */
shouldAvoidBadWifi()4612     public boolean shouldAvoidBadWifi() {
4613         if (!checkNetworkStackPermission()) {
4614             throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission");
4615         }
4616         return avoidBadWifi();
4617     }
4618 
updateAvoidBadWifi()4619     private void updateAvoidBadWifi() {
4620         for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
4621             nai.updateScoreForNetworkAgentUpdate();
4622         }
4623         rematchAllNetworksAndRequests();
4624     }
4625 
4626     // TODO: Evaluate whether this is of interest to other consumers of
4627     // MultinetworkPolicyTracker and worth moving out of here.
dumpAvoidBadWifiSettings(IndentingPrintWriter pw)4628     private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
4629         final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
4630         if (!configRestrict) {
4631             pw.println("Bad Wi-Fi avoidance: unrestricted");
4632             return;
4633         }
4634 
4635         pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi());
4636         pw.increaseIndent();
4637         pw.println("Config restrict:   " + configRestrict);
4638 
4639         final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
4640         String description;
4641         // Can't use a switch statement because strings are legal case labels, but null is not.
4642         if ("0".equals(value)) {
4643             description = "get stuck";
4644         } else if (value == null) {
4645             description = "prompt";
4646         } else if ("1".equals(value)) {
4647             description = "avoid";
4648         } else {
4649             description = value + " (?)";
4650         }
4651         pw.println("User setting:      " + description);
4652         pw.println("Network overrides:");
4653         pw.increaseIndent();
4654         for (NetworkAgentInfo nai : networksSortedById()) {
4655             if (nai.avoidUnvalidated) {
4656                 pw.println(nai.toShortString());
4657             }
4658         }
4659         pw.decreaseIndent();
4660         pw.decreaseIndent();
4661     }
4662 
4663     // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to
4664     // unify the method.
getSettingsPackageName(@onNull final PackageManager pm)4665     private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) {
4666         final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
4667         final ComponentName settingsComponent = settingsIntent.resolveActivity(pm);
4668         return settingsComponent != null
4669                 ? settingsComponent.getPackageName() : "com.android.settings";
4670     }
4671 
showNetworkNotification(NetworkAgentInfo nai, NotificationType type)4672     private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
4673         final String action;
4674         final boolean highPriority;
4675         switch (type) {
4676             case NO_INTERNET:
4677                 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
4678                 // High priority because it is only displayed for explicitly selected networks.
4679                 highPriority = true;
4680                 break;
4681             case PRIVATE_DNS_BROKEN:
4682                 action = Settings.ACTION_WIRELESS_SETTINGS;
4683                 // High priority because we should let user know why there is no internet.
4684                 highPriority = true;
4685                 break;
4686             case LOST_INTERNET:
4687                 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
4688                 // High priority because it could help the user avoid unexpected data usage.
4689                 highPriority = true;
4690                 break;
4691             case PARTIAL_CONNECTIVITY:
4692                 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
4693                 // Don't bother the user with a high-priority notification if the network was not
4694                 // explicitly selected by the user.
4695                 highPriority = nai.networkAgentConfig.explicitlySelected;
4696                 break;
4697             default:
4698                 Log.wtf(TAG, "Unknown notification type " + type);
4699                 return;
4700         }
4701 
4702         Intent intent = new Intent(action);
4703         if (type != NotificationType.PRIVATE_DNS_BROKEN) {
4704             intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network);
4705             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4706             // Some OEMs have their own Settings package. Thus, need to get the current using
4707             // Settings package name instead of just use default name "com.android.settings".
4708             final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager());
4709             intent.setClassName(settingsPkgName,
4710                     settingsPkgName + ".wifi.WifiNoInternetDialog");
4711         }
4712 
4713         PendingIntent pendingIntent = PendingIntent.getActivity(
4714                 mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
4715                 0 /* requestCode */,
4716                 intent,
4717                 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
4718 
4719         mNotifier.showNotification(
4720                 nai.network.getNetId(), type, nai, null, pendingIntent, highPriority);
4721     }
4722 
shouldPromptUnvalidated(NetworkAgentInfo nai)4723     private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
4724         // Don't prompt if the network is validated, and don't prompt on captive portals
4725         // because we're already prompting the user to sign in.
4726         if (nai.everValidated || nai.everCaptivePortalDetected) {
4727             return false;
4728         }
4729 
4730         // If a network has partial connectivity, always prompt unless the user has already accepted
4731         // partial connectivity and selected don't ask again. This ensures that if the device
4732         // automatically connects to a network that has partial Internet access, the user will
4733         // always be able to use it, either because they've already chosen "don't ask again" or
4734         // because we have prompt them.
4735         if (nai.partialConnectivity && !nai.networkAgentConfig.acceptPartialConnectivity) {
4736             return true;
4737         }
4738 
4739         // If a network has no Internet access, only prompt if the network was explicitly selected
4740         // and if the user has not already told us to use the network regardless of whether it
4741         // validated or not.
4742         if (nai.networkAgentConfig.explicitlySelected
4743                 && !nai.networkAgentConfig.acceptUnvalidated) {
4744             return true;
4745         }
4746 
4747         return false;
4748     }
4749 
handlePromptUnvalidated(Network network)4750     private void handlePromptUnvalidated(Network network) {
4751         if (VDBG || DDBG) log("handlePromptUnvalidated " + network);
4752         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4753 
4754         if (nai == null || !shouldPromptUnvalidated(nai)) {
4755             return;
4756         }
4757 
4758         // Stop automatically reconnecting to this network in the future. Automatically connecting
4759         // to a network that provides no or limited connectivity is not useful, because the user
4760         // cannot use that network except through the notification shown by this method, and the
4761         // notification is only shown if the network is explicitly selected by the user.
4762         nai.onPreventAutomaticReconnect();
4763 
4764         // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
4765         // NetworkMonitor detects the network is partial connectivity. Need to change the design to
4766         // popup the notification immediately when the network is partial connectivity.
4767         if (nai.partialConnectivity) {
4768             showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
4769         } else {
4770             showNetworkNotification(nai, NotificationType.NO_INTERNET);
4771         }
4772     }
4773 
handleNetworkUnvalidated(NetworkAgentInfo nai)4774     private void handleNetworkUnvalidated(NetworkAgentInfo nai) {
4775         NetworkCapabilities nc = nai.networkCapabilities;
4776         if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc);
4777 
4778         if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
4779             return;
4780         }
4781 
4782         if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
4783             showNetworkNotification(nai, NotificationType.LOST_INTERNET);
4784         }
4785     }
4786 
4787     @Override
getMultipathPreference(Network network)4788     public int getMultipathPreference(Network network) {
4789         enforceAccessPermission();
4790 
4791         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4792         if (nai != null && nai.networkCapabilities
4793                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
4794             return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
4795         }
4796 
4797         final NetworkPolicyManager netPolicyManager =
4798                  mContext.getSystemService(NetworkPolicyManager.class);
4799 
4800         final long token = Binder.clearCallingIdentity();
4801         final int networkPreference;
4802         try {
4803             networkPreference = netPolicyManager.getMultipathPreference(network);
4804         } finally {
4805             Binder.restoreCallingIdentity(token);
4806         }
4807         if (networkPreference != 0) {
4808             return networkPreference;
4809         }
4810         return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
4811     }
4812 
4813     @Override
getDefaultRequest()4814     public NetworkRequest getDefaultRequest() {
4815         return mDefaultRequest.mRequests.get(0);
4816     }
4817 
4818     private class InternalHandler extends Handler {
InternalHandler(Looper looper)4819         public InternalHandler(Looper looper) {
4820             super(looper);
4821         }
4822 
4823         @Override
handleMessage(Message msg)4824         public void handleMessage(Message msg) {
4825             switch (msg.what) {
4826                 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK:
4827                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
4828                     handleReleaseNetworkTransitionWakelock(msg.what);
4829                     break;
4830                 }
4831                 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
4832                     mProxyTracker.loadDeprecatedGlobalHttpProxy();
4833                     break;
4834                 }
4835                 case EVENT_PROXY_HAS_CHANGED: {
4836                     final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj;
4837                     handleApplyDefaultProxy(arg.second);
4838                     break;
4839                 }
4840                 case EVENT_REGISTER_NETWORK_PROVIDER: {
4841                     handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj);
4842                     break;
4843                 }
4844                 case EVENT_UNREGISTER_NETWORK_PROVIDER: {
4845                     handleUnregisterNetworkProvider((Messenger) msg.obj);
4846                     break;
4847                 }
4848                 case EVENT_REGISTER_NETWORK_OFFER: {
4849                     handleRegisterNetworkOffer((NetworkOffer) msg.obj);
4850                     break;
4851                 }
4852                 case EVENT_UNREGISTER_NETWORK_OFFER: {
4853                     final NetworkOfferInfo offer =
4854                             findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj);
4855                     if (null != offer) {
4856                         handleUnregisterNetworkOffer(offer);
4857                     }
4858                     break;
4859                 }
4860                 case EVENT_REGISTER_NETWORK_AGENT: {
4861                     final Pair<NetworkAgentInfo, INetworkMonitor> arg =
4862                             (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj;
4863                     handleRegisterNetworkAgent(arg.first, arg.second);
4864                     break;
4865                 }
4866                 case EVENT_REGISTER_NETWORK_REQUEST:
4867                 case EVENT_REGISTER_NETWORK_LISTENER: {
4868                     handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
4869                     break;
4870                 }
4871                 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
4872                 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
4873                     handleRegisterNetworkRequestWithIntent(msg);
4874                     break;
4875                 }
4876                 case EVENT_TIMEOUT_NETWORK_REQUEST: {
4877                     NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
4878                     handleTimedOutNetworkRequest(nri);
4879                     break;
4880                 }
4881                 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
4882                     handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
4883                     break;
4884                 }
4885                 case EVENT_RELEASE_NETWORK_REQUEST: {
4886                     handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1,
4887                             /* callOnUnavailable */ false);
4888                     break;
4889                 }
4890                 case EVENT_SET_ACCEPT_UNVALIDATED: {
4891                     Network network = (Network) msg.obj;
4892                     handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2));
4893                     break;
4894                 }
4895                 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: {
4896                     Network network = (Network) msg.obj;
4897                     handleSetAcceptPartialConnectivity(network, toBool(msg.arg1),
4898                             toBool(msg.arg2));
4899                     break;
4900                 }
4901                 case EVENT_SET_AVOID_UNVALIDATED: {
4902                     handleSetAvoidUnvalidated((Network) msg.obj);
4903                     break;
4904                 }
4905                 case EVENT_PROMPT_UNVALIDATED: {
4906                     handlePromptUnvalidated((Network) msg.obj);
4907                     break;
4908                 }
4909                 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
4910                     handleConfigureAlwaysOnNetworks();
4911                     break;
4912                 }
4913                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
4914                 case NetworkAgent.CMD_START_SOCKET_KEEPALIVE: {
4915                     mKeepaliveTracker.handleStartKeepalive(msg);
4916                     break;
4917                 }
4918                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
4919                 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: {
4920                     NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
4921                     int slot = msg.arg1;
4922                     int reason = msg.arg2;
4923                     mKeepaliveTracker.handleStopKeepalive(nai, slot, reason);
4924                     break;
4925                 }
4926                 case EVENT_REVALIDATE_NETWORK: {
4927                     handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2));
4928                     break;
4929                 }
4930                 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
4931                     handlePrivateDnsSettingsChanged();
4932                     break;
4933                 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
4934                     handlePrivateDnsValidationUpdate(
4935                             (PrivateDnsValidationUpdate) msg.obj);
4936                     break;
4937                 case EVENT_UID_BLOCKED_REASON_CHANGED:
4938                     handleUidBlockedReasonChanged(msg.arg1, msg.arg2);
4939                     break;
4940                 case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
4941                     handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
4942                     break;
4943                 case EVENT_SET_OEM_NETWORK_PREFERENCE: {
4944                     final Pair<OemNetworkPreferences, IOnCompleteListener> arg =
4945                             (Pair<OemNetworkPreferences, IOnCompleteListener>) msg.obj;
4946                     handleSetOemNetworkPreference(arg.first, arg.second);
4947                     break;
4948                 }
4949                 case EVENT_SET_PROFILE_NETWORK_PREFERENCE: {
4950                     final Pair<ProfileNetworkPreferences.Preference, IOnCompleteListener> arg =
4951                             (Pair<ProfileNetworkPreferences.Preference, IOnCompleteListener>)
4952                                     msg.obj;
4953                     handleSetProfileNetworkPreference(arg.first, arg.second);
4954                     break;
4955                 }
4956                 case EVENT_REPORT_NETWORK_ACTIVITY:
4957                     mNetworkActivityTracker.handleReportNetworkActivity();
4958                     break;
4959                 case EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED:
4960                     handleMobileDataPreferredUidsChanged();
4961                     break;
4962                 case EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL:
4963                     final long timeMs = ((Long) msg.obj).longValue();
4964                     mMultinetworkPolicyTracker.setTestAllowBadWifiUntil(timeMs);
4965                     break;
4966             }
4967         }
4968     }
4969 
4970     @Override
4971     @Deprecated
getLastTetherError(String iface)4972     public int getLastTetherError(String iface) {
4973         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4974                 Context.TETHERING_SERVICE);
4975         return tm.getLastTetherError(iface);
4976     }
4977 
4978     @Override
4979     @Deprecated
getTetherableIfaces()4980     public String[] getTetherableIfaces() {
4981         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4982                 Context.TETHERING_SERVICE);
4983         return tm.getTetherableIfaces();
4984     }
4985 
4986     @Override
4987     @Deprecated
getTetheredIfaces()4988     public String[] getTetheredIfaces() {
4989         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4990                 Context.TETHERING_SERVICE);
4991         return tm.getTetheredIfaces();
4992     }
4993 
4994 
4995     @Override
4996     @Deprecated
getTetheringErroredIfaces()4997     public String[] getTetheringErroredIfaces() {
4998         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4999                 Context.TETHERING_SERVICE);
5000 
5001         return tm.getTetheringErroredIfaces();
5002     }
5003 
5004     @Override
5005     @Deprecated
getTetherableUsbRegexs()5006     public String[] getTetherableUsbRegexs() {
5007         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
5008                 Context.TETHERING_SERVICE);
5009 
5010         return tm.getTetherableUsbRegexs();
5011     }
5012 
5013     @Override
5014     @Deprecated
getTetherableWifiRegexs()5015     public String[] getTetherableWifiRegexs() {
5016         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
5017                 Context.TETHERING_SERVICE);
5018         return tm.getTetherableWifiRegexs();
5019     }
5020 
5021     // Called when we lose the default network and have no replacement yet.
5022     // This will automatically be cleared after X seconds or a new default network
5023     // becomes CONNECTED, whichever happens first.  The timer is started by the
5024     // first caller and not restarted by subsequent callers.
ensureNetworkTransitionWakelock(String forWhom)5025     private void ensureNetworkTransitionWakelock(String forWhom) {
5026         synchronized (this) {
5027             if (mNetTransitionWakeLock.isHeld()) {
5028                 return;
5029             }
5030             mNetTransitionWakeLock.acquire();
5031             mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime();
5032             mTotalWakelockAcquisitions++;
5033         }
5034         mWakelockLogs.log("ACQUIRE for " + forWhom);
5035         Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
5036         final int lockTimeout = mResources.get().getInteger(
5037                 R.integer.config_networkTransitionTimeout);
5038         mHandler.sendMessageDelayed(msg, lockTimeout);
5039     }
5040 
5041     // Called when we gain a new default network to release the network transition wakelock in a
5042     // second, to allow a grace period for apps to reconnect over the new network. Pending expiry
5043     // message is cancelled.
scheduleReleaseNetworkTransitionWakelock()5044     private void scheduleReleaseNetworkTransitionWakelock() {
5045         synchronized (this) {
5046             if (!mNetTransitionWakeLock.isHeld()) {
5047                 return; // expiry message released the lock first.
5048             }
5049         }
5050         // Cancel self timeout on wakelock hold.
5051         mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
5052         Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK);
5053         mHandler.sendMessageDelayed(msg, 1000);
5054     }
5055 
5056     // Called when either message of ensureNetworkTransitionWakelock or
5057     // scheduleReleaseNetworkTransitionWakelock is processed.
handleReleaseNetworkTransitionWakelock(int eventId)5058     private void handleReleaseNetworkTransitionWakelock(int eventId) {
5059         String event = eventName(eventId);
5060         synchronized (this) {
5061             if (!mNetTransitionWakeLock.isHeld()) {
5062                 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event));
5063                 Log.w(TAG, "expected Net Transition WakeLock to be held");
5064                 return;
5065             }
5066             mNetTransitionWakeLock.release();
5067             long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
5068             mTotalWakelockDurationMs += lockDuration;
5069             mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration);
5070             mTotalWakelockReleases++;
5071         }
5072         mWakelockLogs.log(String.format("RELEASE (%s)", event));
5073     }
5074 
5075     // 100 percent is full good, 0 is full bad.
5076     @Override
reportInetCondition(int networkType, int percentage)5077     public void reportInetCondition(int networkType, int percentage) {
5078         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
5079         if (nai == null) return;
5080         reportNetworkConnectivity(nai.network, percentage > 50);
5081     }
5082 
5083     @Override
reportNetworkConnectivity(Network network, boolean hasConnectivity)5084     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
5085         enforceAccessPermission();
5086         enforceInternetPermission();
5087         final int uid = mDeps.getCallingUid();
5088         final int connectivityInfo = encodeBool(hasConnectivity);
5089 
5090         // Handle ConnectivityDiagnostics event before attempting to revalidate the network. This
5091         // forces an ordering of ConnectivityDiagnostics events in the case where hasConnectivity
5092         // does not match the known connectivity of the network - this causes NetworkMonitor to
5093         // revalidate the network and generate a ConnectivityDiagnostics ConnectivityReport event.
5094         final NetworkAgentInfo nai;
5095         if (network == null) {
5096             nai = getDefaultNetwork();
5097         } else {
5098             nai = getNetworkAgentInfoForNetwork(network);
5099         }
5100         if (nai != null) {
5101             mConnectivityDiagnosticsHandler.sendMessage(
5102                     mConnectivityDiagnosticsHandler.obtainMessage(
5103                             ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
5104                             connectivityInfo, 0, nai));
5105         }
5106 
5107         mHandler.sendMessage(
5108                 mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network));
5109     }
5110 
handleReportNetworkConnectivity( Network network, int uid, boolean hasConnectivity)5111     private void handleReportNetworkConnectivity(
5112             Network network, int uid, boolean hasConnectivity) {
5113         final NetworkAgentInfo nai;
5114         if (network == null) {
5115             nai = getDefaultNetwork();
5116         } else {
5117             nai = getNetworkAgentInfoForNetwork(network);
5118         }
5119         if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
5120             nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
5121             return;
5122         }
5123         // Revalidate if the app report does not match our current validated state.
5124         if (hasConnectivity == nai.lastValidated) {
5125             return;
5126         }
5127         if (DBG) {
5128             int netid = nai.network.getNetId();
5129             log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid);
5130         }
5131         // Validating a network that has not yet connected could result in a call to
5132         // rematchNetworkAndRequests() which is not meant to work on such networks.
5133         if (!nai.everConnected) {
5134             return;
5135         }
5136         final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
5137         if (isNetworkWithCapabilitiesBlocked(nc, uid, false)) {
5138             return;
5139         }
5140         nai.networkMonitor().forceReevaluation(uid);
5141     }
5142 
5143     // TODO: call into netd.
queryUserAccess(int uid, Network network)5144     private boolean queryUserAccess(int uid, Network network) {
5145         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5146         if (nai == null) return false;
5147 
5148         // Any UID can use its default network.
5149         if (nai == getDefaultNetworkForUid(uid)) return true;
5150 
5151         // Privileged apps can use any network.
5152         if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) {
5153             return true;
5154         }
5155 
5156         // An unprivileged UID can use a VPN iff the VPN applies to it.
5157         if (nai.isVPN()) {
5158             return nai.networkCapabilities.appliesToUid(uid);
5159         }
5160 
5161         // An unprivileged UID can bypass the VPN that applies to it only if it can protect its
5162         // sockets, i.e., if it is the owner.
5163         final NetworkAgentInfo vpn = getVpnForUid(uid);
5164         if (vpn != null && !vpn.networkAgentConfig.allowBypass
5165                 && uid != vpn.networkCapabilities.getOwnerUid()) {
5166             return false;
5167         }
5168 
5169         // The UID's permission must be at least sufficient for the network. Since the restricted
5170         // permission was already checked above, that just leaves background networks.
5171         if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) {
5172             return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid);
5173         }
5174 
5175         // Unrestricted network. Anyone gets to use it.
5176         return true;
5177     }
5178 
5179     /**
5180      * Returns information about the proxy a certain network is using. If given a null network, it
5181      * it will return the proxy for the bound network for the caller app or the default proxy if
5182      * none.
5183      *
5184      * @param network the network we want to get the proxy information for.
5185      * @return Proxy information if a network has a proxy configured, or otherwise null.
5186      */
5187     @Override
getProxyForNetwork(Network network)5188     public ProxyInfo getProxyForNetwork(Network network) {
5189         final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy();
5190         if (globalProxy != null) return globalProxy;
5191         if (network == null) {
5192             // Get the network associated with the calling UID.
5193             final Network activeNetwork = getActiveNetworkForUidInternal(mDeps.getCallingUid(),
5194                     true);
5195             if (activeNetwork == null) {
5196                 return null;
5197             }
5198             return getLinkPropertiesProxyInfo(activeNetwork);
5199         } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) {
5200             // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
5201             // caller may not have.
5202             return getLinkPropertiesProxyInfo(network);
5203         }
5204         // No proxy info available if the calling UID does not have network access.
5205         return null;
5206     }
5207 
5208 
getLinkPropertiesProxyInfo(Network network)5209     private ProxyInfo getLinkPropertiesProxyInfo(Network network) {
5210         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5211         if (nai == null) return null;
5212         synchronized (nai) {
5213             final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy();
5214             return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy);
5215         }
5216     }
5217 
5218     @Override
setGlobalProxy(@ullable final ProxyInfo proxyProperties)5219     public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) {
5220         PermissionUtils.enforceNetworkStackPermission(mContext);
5221         mProxyTracker.setGlobalProxy(proxyProperties);
5222     }
5223 
5224     @Override
5225     @Nullable
getGlobalProxy()5226     public ProxyInfo getGlobalProxy() {
5227         return mProxyTracker.getGlobalProxy();
5228     }
5229 
handleApplyDefaultProxy(ProxyInfo proxy)5230     private void handleApplyDefaultProxy(ProxyInfo proxy) {
5231         if (proxy != null && TextUtils.isEmpty(proxy.getHost())
5232                 && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
5233             proxy = null;
5234         }
5235         mProxyTracker.setDefaultProxy(proxy);
5236     }
5237 
5238     // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called
5239     // when any network changes proxy.
5240     // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a
5241     // multi-network world where an app might be bound to a non-default network.
updateProxy(LinkProperties newLp, LinkProperties oldLp)5242     private void updateProxy(LinkProperties newLp, LinkProperties oldLp) {
5243         ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
5244         ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
5245 
5246         if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
5247             mProxyTracker.sendProxyBroadcast();
5248         }
5249     }
5250 
5251     private static class SettingsObserver extends ContentObserver {
5252         final private HashMap<Uri, Integer> mUriEventMap;
5253         final private Context mContext;
5254         final private Handler mHandler;
5255 
SettingsObserver(Context context, Handler handler)5256         SettingsObserver(Context context, Handler handler) {
5257             super(null);
5258             mUriEventMap = new HashMap<>();
5259             mContext = context;
5260             mHandler = handler;
5261         }
5262 
observe(Uri uri, int what)5263         void observe(Uri uri, int what) {
5264             mUriEventMap.put(uri, what);
5265             final ContentResolver resolver = mContext.getContentResolver();
5266             resolver.registerContentObserver(uri, false, this);
5267         }
5268 
5269         @Override
onChange(boolean selfChange)5270         public void onChange(boolean selfChange) {
5271             Log.wtf(TAG, "Should never be reached.");
5272         }
5273 
5274         @Override
onChange(boolean selfChange, Uri uri)5275         public void onChange(boolean selfChange, Uri uri) {
5276             final Integer what = mUriEventMap.get(uri);
5277             if (what != null) {
5278                 mHandler.obtainMessage(what).sendToTarget();
5279             } else {
5280                 loge("No matching event to send for URI=" + uri);
5281             }
5282         }
5283     }
5284 
log(String s)5285     private static void log(String s) {
5286         Log.d(TAG, s);
5287     }
5288 
logw(String s)5289     private static void logw(String s) {
5290         Log.w(TAG, s);
5291     }
5292 
logwtf(String s)5293     private static void logwtf(String s) {
5294         Log.wtf(TAG, s);
5295     }
5296 
logwtf(String s, Throwable t)5297     private static void logwtf(String s, Throwable t) {
5298         Log.wtf(TAG, s, t);
5299     }
5300 
loge(String s)5301     private static void loge(String s) {
5302         Log.e(TAG, s);
5303     }
5304 
loge(String s, Throwable t)5305     private static void loge(String s, Throwable t) {
5306         Log.e(TAG, s, t);
5307     }
5308 
5309     /**
5310      * Return the information of all ongoing VPNs.
5311      *
5312      * <p>This method is used to update NetworkStatsService.
5313      *
5314      * <p>Must be called on the handler thread.
5315      */
getAllVpnInfo()5316     private UnderlyingNetworkInfo[] getAllVpnInfo() {
5317         ensureRunningOnConnectivityServiceThread();
5318         if (mLockdownEnabled) {
5319             return new UnderlyingNetworkInfo[0];
5320         }
5321         List<UnderlyingNetworkInfo> infoList = new ArrayList<>();
5322         for (NetworkAgentInfo nai : mNetworkAgentInfos) {
5323             UnderlyingNetworkInfo info = createVpnInfo(nai);
5324             if (info != null) {
5325                 infoList.add(info);
5326             }
5327         }
5328         return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]);
5329     }
5330 
5331     /**
5332      * @return VPN information for accounting, or null if we can't retrieve all required
5333      *         information, e.g underlying ifaces.
5334      */
createVpnInfo(NetworkAgentInfo nai)5335     private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) {
5336         Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
5337         // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
5338         // the underlyingNetworks list.
5339         // TODO: stop using propagateUnderlyingCapabilities here, for example, by always
5340         // initializing NetworkAgentInfo#declaredUnderlyingNetworks to an empty array.
5341         if (underlyingNetworks == null && nai.propagateUnderlyingCapabilities()) {
5342             final NetworkAgentInfo defaultNai = getDefaultNetworkForUid(
5343                     nai.networkCapabilities.getOwnerUid());
5344             if (defaultNai != null) {
5345                 underlyingNetworks = new Network[] { defaultNai.network };
5346             }
5347         }
5348 
5349         if (CollectionUtils.isEmpty(underlyingNetworks)) return null;
5350 
5351         List<String> interfaces = new ArrayList<>();
5352         for (Network network : underlyingNetworks) {
5353             NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network);
5354             if (underlyingNai == null) continue;
5355             LinkProperties lp = underlyingNai.linkProperties;
5356             for (String iface : lp.getAllInterfaceNames()) {
5357                 if (!TextUtils.isEmpty(iface)) {
5358                     interfaces.add(iface);
5359                 }
5360             }
5361         }
5362 
5363         if (interfaces.isEmpty()) return null;
5364 
5365         // Must be non-null or NetworkStatsService will crash.
5366         // Cannot happen in production code because Vpn only registers the NetworkAgent after the
5367         // tun or ipsec interface is created.
5368         // TODO: Remove this check.
5369         if (nai.linkProperties.getInterfaceName() == null) return null;
5370 
5371         return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(),
5372                 nai.linkProperties.getInterfaceName(), interfaces);
5373     }
5374 
5375     // TODO This needs to be the default network that applies to the NAI.
underlyingNetworksOrDefault(final int ownerUid, Network[] underlyingNetworks)5376     private Network[] underlyingNetworksOrDefault(final int ownerUid,
5377             Network[] underlyingNetworks) {
5378         final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid));
5379         if (underlyingNetworks == null && defaultNetwork != null) {
5380             // null underlying networks means to track the default.
5381             underlyingNetworks = new Network[] { defaultNetwork };
5382         }
5383         return underlyingNetworks;
5384     }
5385 
5386     // Returns true iff |network| is an underlying network of |nai|.
hasUnderlyingNetwork(NetworkAgentInfo nai, Network network)5387     private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) {
5388         // TODO: support more than one level of underlying networks, either via a fixed-depth search
5389         // (e.g., 2 levels of underlying networks), or via loop detection, or....
5390         if (!nai.propagateUnderlyingCapabilities()) return false;
5391         final Network[] underlying = underlyingNetworksOrDefault(
5392                 nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks);
5393         return CollectionUtils.contains(underlying, network);
5394     }
5395 
5396     /**
5397      * Recompute the capabilities for any networks that had a specific network as underlying.
5398      *
5399      * When underlying networks change, such networks may have to update capabilities to reflect
5400      * things like the metered bit, their transports, and so on. The capabilities are calculated
5401      * immediately. This method runs on the ConnectivityService thread.
5402      */
propagateUnderlyingNetworkCapabilities(Network updatedNetwork)5403     private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) {
5404         ensureRunningOnConnectivityServiceThread();
5405         for (NetworkAgentInfo nai : mNetworkAgentInfos) {
5406             if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) {
5407                 updateCapabilitiesForNetwork(nai);
5408             }
5409         }
5410     }
5411 
isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges)5412     private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) {
5413         // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies
5414         // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when
5415         // a VPN is not up.
5416         final NetworkAgentInfo vpnNai = getVpnForUid(uid);
5417         if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false;
5418         for (UidRange range : blockedUidRanges) {
5419             if (range.contains(uid)) return true;
5420         }
5421         return false;
5422     }
5423 
5424     @Override
setRequireVpnForUids(boolean requireVpn, UidRange[] ranges)5425     public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
5426         enforceNetworkStackOrSettingsPermission();
5427         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS,
5428                 encodeBool(requireVpn), 0 /* arg2 */, ranges));
5429     }
5430 
handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges)5431     private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
5432         if (DBG) {
5433             Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: "
5434                     + Arrays.toString(ranges));
5435         }
5436         // Cannot use a Set since the list of UID ranges might contain duplicates.
5437         final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges);
5438         for (int i = 0; i < ranges.length; i++) {
5439             if (requireVpn) {
5440                 newVpnBlockedUidRanges.add(ranges[i]);
5441             } else {
5442                 newVpnBlockedUidRanges.remove(ranges[i]);
5443             }
5444         }
5445 
5446         try {
5447             mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges));
5448         } catch (RemoteException | ServiceSpecificException e) {
5449             Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", "
5450                     + Arrays.toString(ranges) + "): netd command failed: " + e);
5451         }
5452 
5453         for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
5454             final boolean curMetered = nai.networkCapabilities.isMetered();
5455             maybeNotifyNetworkBlocked(nai, curMetered, curMetered,
5456                     mVpnBlockedUidRanges, newVpnBlockedUidRanges);
5457         }
5458 
5459         mVpnBlockedUidRanges = newVpnBlockedUidRanges;
5460     }
5461 
5462     @Override
setLegacyLockdownVpnEnabled(boolean enabled)5463     public void setLegacyLockdownVpnEnabled(boolean enabled) {
5464         enforceNetworkStackOrSettingsPermission();
5465         mHandler.post(() -> mLockdownEnabled = enabled);
5466     }
5467 
isLegacyLockdownNai(NetworkAgentInfo nai)5468     private boolean isLegacyLockdownNai(NetworkAgentInfo nai) {
5469         return mLockdownEnabled
5470                 && getVpnType(nai) == VpnManager.TYPE_VPN_LEGACY
5471                 && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID);
5472     }
5473 
getLegacyLockdownNai()5474     private NetworkAgentInfo getLegacyLockdownNai() {
5475         if (!mLockdownEnabled) {
5476             return null;
5477         }
5478         // The legacy lockdown VPN always only applies to userId 0.
5479         final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID);
5480         if (nai == null || !isLegacyLockdownNai(nai)) return null;
5481 
5482         // The legacy lockdown VPN must always have exactly one underlying network.
5483         // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in
5484         // a local variable. There is no need to make a copy because its contents cannot change.
5485         final Network[] underlying = nai.declaredUnderlyingNetworks;
5486         if (underlying == null ||  underlying.length != 1) {
5487             return null;
5488         }
5489 
5490         // The legacy lockdown VPN always uses the default network.
5491         // If the VPN's underlying network is no longer the current default network, it means that
5492         // the default network has just switched, and the VPN is about to disconnect.
5493         // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten
5494         // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED.
5495         final NetworkAgentInfo defaultNetwork = getDefaultNetwork();
5496         if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) {
5497             return null;
5498         }
5499 
5500         return nai;
5501     };
5502 
5503     // TODO: move all callers to filterForLegacyLockdown and delete this method.
5504     // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of
5505     // just a DetailedState object.
getLegacyLockdownState(DetailedState origState)5506     private DetailedState getLegacyLockdownState(DetailedState origState) {
5507         if (origState != DetailedState.CONNECTED) {
5508             return origState;
5509         }
5510         return (mLockdownEnabled && getLegacyLockdownNai() == null)
5511                 ? DetailedState.CONNECTING
5512                 : DetailedState.CONNECTED;
5513     }
5514 
filterForLegacyLockdown(NetworkInfo ni)5515     private void filterForLegacyLockdown(NetworkInfo ni) {
5516         if (!mLockdownEnabled || !ni.isConnected()) return;
5517         // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the
5518         // state of its VPN. This is to ensure that when an underlying network connects, apps will
5519         // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN
5520         // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying
5521         // network, this time with a state of CONNECTED.
5522         //
5523         // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access
5524         // to the internal state of the Vpn object, always replace the state with CONNECTING. This
5525         // is not too far off the truth, since an always-on VPN, when not connected, is always
5526         // trying to reconnect.
5527         if (getLegacyLockdownNai() == null) {
5528             ni.setDetailedState(DetailedState.CONNECTING, "", null);
5529         }
5530     }
5531 
5532     @Override
setProvisioningNotificationVisible(boolean visible, int networkType, String action)5533     public void setProvisioningNotificationVisible(boolean visible, int networkType,
5534             String action) {
5535         enforceSettingsPermission();
5536         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
5537             return;
5538         }
5539         final long ident = Binder.clearCallingIdentity();
5540         try {
5541             // Concatenate the range of types onto the range of NetIDs.
5542             int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
5543             mNotifier.setProvNotificationVisible(visible, id, action);
5544         } finally {
5545             Binder.restoreCallingIdentity(ident);
5546         }
5547     }
5548 
5549     @Override
setAirplaneMode(boolean enable)5550     public void setAirplaneMode(boolean enable) {
5551         enforceAirplaneModePermission();
5552         final long ident = Binder.clearCallingIdentity();
5553         try {
5554             final ContentResolver cr = mContext.getContentResolver();
5555             Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable));
5556             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
5557             intent.putExtra("state", enable);
5558             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
5559         } finally {
5560             Binder.restoreCallingIdentity(ident);
5561         }
5562     }
5563 
onUserAdded(@onNull final UserHandle user)5564     private void onUserAdded(@NonNull final UserHandle user) {
5565         mPermissionMonitor.onUserAdded(user);
5566         if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
5567             handleSetOemNetworkPreference(mOemNetworkPreferences, null);
5568         }
5569     }
5570 
onUserRemoved(@onNull final UserHandle user)5571     private void onUserRemoved(@NonNull final UserHandle user) {
5572         mPermissionMonitor.onUserRemoved(user);
5573         // If there was a network preference for this user, remove it.
5574         handleSetProfileNetworkPreference(new ProfileNetworkPreferences.Preference(user, null),
5575                 null /* listener */);
5576         if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
5577             handleSetOemNetworkPreference(mOemNetworkPreferences, null);
5578         }
5579     }
5580 
onPackageChanged(@onNull final String packageName)5581     private void onPackageChanged(@NonNull final String packageName) {
5582         // This is necessary in case a package is added or removed, but also when it's replaced to
5583         // run as a new UID by its manifest rules. Also, if a separate package shares the same UID
5584         // as one in the preferences, then it should follow the same routing as that other package,
5585         // which means updating the rules is never to be needed in this case (whether it joins or
5586         // leaves a UID with a preference).
5587         if (isMappedInOemNetworkPreference(packageName)) {
5588             handleSetOemNetworkPreference(mOemNetworkPreferences, null);
5589         }
5590     }
5591 
5592     private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
5593         @Override
5594         public void onReceive(Context context, Intent intent) {
5595             ensureRunningOnConnectivityServiceThread();
5596             final String action = intent.getAction();
5597             final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
5598 
5599             // User should be filled for below intents, check the existence.
5600             if (user == null) {
5601                 Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER");
5602                 return;
5603             }
5604 
5605             if (Intent.ACTION_USER_ADDED.equals(action)) {
5606                 onUserAdded(user);
5607             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
5608                 onUserRemoved(user);
5609             }  else {
5610                 Log.wtf(TAG, "received unexpected intent: " + action);
5611             }
5612         }
5613     };
5614 
5615     private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
5616         @Override
5617         public void onReceive(Context context, Intent intent) {
5618             ensureRunningOnConnectivityServiceThread();
5619             switch (intent.getAction()) {
5620                 case Intent.ACTION_PACKAGE_ADDED:
5621                 case Intent.ACTION_PACKAGE_REMOVED:
5622                 case Intent.ACTION_PACKAGE_REPLACED:
5623                     onPackageChanged(intent.getData().getSchemeSpecificPart());
5624                     break;
5625                 default:
5626                     Log.wtf(TAG, "received unexpected intent: " + intent.getAction());
5627             }
5628         }
5629     };
5630 
5631     private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>();
5632     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
5633 
5634     private static class NetworkProviderInfo {
5635         public final String name;
5636         public final Messenger messenger;
5637         private final IBinder.DeathRecipient mDeathRecipient;
5638         public final int providerId;
5639 
NetworkProviderInfo(String name, Messenger messenger, int providerId, @NonNull IBinder.DeathRecipient deathRecipient)5640         NetworkProviderInfo(String name, Messenger messenger, int providerId,
5641                 @NonNull IBinder.DeathRecipient deathRecipient) {
5642             this.name = name;
5643             this.messenger = messenger;
5644             this.providerId = providerId;
5645             mDeathRecipient = deathRecipient;
5646 
5647             if (mDeathRecipient == null) {
5648                 throw new AssertionError("Must pass a deathRecipient");
5649             }
5650         }
5651 
connect(Context context, Handler handler)5652         void connect(Context context, Handler handler) {
5653             try {
5654                 messenger.getBinder().linkToDeath(mDeathRecipient, 0);
5655             } catch (RemoteException e) {
5656                 mDeathRecipient.binderDied();
5657             }
5658         }
5659     }
5660 
ensureAllNetworkRequestsHaveType(List<NetworkRequest> requests)5661     private void ensureAllNetworkRequestsHaveType(List<NetworkRequest> requests) {
5662         for (int i = 0; i < requests.size(); i++) {
5663             ensureNetworkRequestHasType(requests.get(i));
5664         }
5665     }
5666 
ensureNetworkRequestHasType(NetworkRequest request)5667     private void ensureNetworkRequestHasType(NetworkRequest request) {
5668         if (request.type == NetworkRequest.Type.NONE) {
5669             throw new IllegalArgumentException(
5670                     "All NetworkRequests in ConnectivityService must have a type");
5671         }
5672     }
5673 
5674     /**
5675      * Tracks info about the requester.
5676      * Also used to notice when the calling process dies so as to self-expire
5677      */
5678     @VisibleForTesting
5679     protected class NetworkRequestInfo implements IBinder.DeathRecipient {
5680         // The requests to be satisfied in priority order. Non-multilayer requests will only have a
5681         // single NetworkRequest in mRequests.
5682         final List<NetworkRequest> mRequests;
5683 
5684         // mSatisfier and mActiveRequest rely on one another therefore set them together.
setSatisfier( @ullable final NetworkAgentInfo satisfier, @Nullable final NetworkRequest activeRequest)5685         void setSatisfier(
5686                 @Nullable final NetworkAgentInfo satisfier,
5687                 @Nullable final NetworkRequest activeRequest) {
5688             mSatisfier = satisfier;
5689             mActiveRequest = activeRequest;
5690         }
5691 
5692         // The network currently satisfying this NRI. Only one request in an NRI can have a
5693         // satisfier. For non-multilayer requests, only non-listen requests can have a satisfier.
5694         @Nullable
5695         private NetworkAgentInfo mSatisfier;
getSatisfier()5696         NetworkAgentInfo getSatisfier() {
5697             return mSatisfier;
5698         }
5699 
5700         // The request in mRequests assigned to a network agent. This is null if none of the
5701         // requests in mRequests can be satisfied. This member has the constraint of only being
5702         // accessible on the handler thread.
5703         @Nullable
5704         private NetworkRequest mActiveRequest;
getActiveRequest()5705         NetworkRequest getActiveRequest() {
5706             return mActiveRequest;
5707         }
5708 
5709         final PendingIntent mPendingIntent;
5710         boolean mPendingIntentSent;
5711         @Nullable
5712         final Messenger mMessenger;
5713 
5714         // Information about the caller that caused this object to be created.
5715         @Nullable
5716         private final IBinder mBinder;
5717         final int mPid;
5718         final int mUid;
5719         final @NetworkCallback.Flag int mCallbackFlags;
5720         @Nullable
5721         final String mCallingAttributionTag;
5722 
5723         // Counter keeping track of this NRI.
5724         final PerUidCounter mPerUidCounter;
5725 
5726         // Effective UID of this request. This is different from mUid when a privileged process
5727         // files a request on behalf of another UID. This UID is used to determine blocked status,
5728         // UID matching, and so on. mUid above is used for permission checks and to enforce the
5729         // maximum limit of registered callbacks per UID.
5730         final int mAsUid;
5731 
5732         // Default network priority of this request.
5733         final int mPreferencePriority;
5734 
5735         // In order to preserve the mapping of NetworkRequest-to-callback when apps register
5736         // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be
5737         // maintained for keying off of. This is only a concern when the original nri
5738         // mNetworkRequests changes which happens currently for apps that register callbacks to
5739         // track the default network. In those cases, the nri is updated to have mNetworkRequests
5740         // that match the per-app default nri that currently tracks the calling app's uid so that
5741         // callbacks are fired at the appropriate time. When the callbacks fire,
5742         // mNetworkRequestForCallback will be used so as to preserve the caller's mapping. When
5743         // callbacks are updated to key off of an nri vs NetworkRequest, this stops being an issue.
5744         // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects.
5745         @NonNull
5746         private final NetworkRequest mNetworkRequestForCallback;
getNetworkRequestForCallback()5747         NetworkRequest getNetworkRequestForCallback() {
5748             return mNetworkRequestForCallback;
5749         }
5750 
5751         /**
5752          * Get the list of UIDs this nri applies to.
5753          */
5754         @NonNull
getUids()5755         Set<UidRange> getUids() {
5756             // networkCapabilities.getUids() returns a defensive copy.
5757             // multilayer requests will all have the same uids so return the first one.
5758             final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges();
5759             return (null == uids) ? new ArraySet<>() : uids;
5760         }
5761 
NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final PendingIntent pi, @Nullable String callingAttributionTag)5762         NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r,
5763                 @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) {
5764             this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag,
5765                     PREFERENCE_PRIORITY_INVALID);
5766         }
5767 
NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi, @Nullable String callingAttributionTag, final int preferencePriority)5768         NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
5769                 @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi,
5770                 @Nullable String callingAttributionTag, final int preferencePriority) {
5771             ensureAllNetworkRequestsHaveType(r);
5772             mRequests = initializeRequests(r);
5773             mNetworkRequestForCallback = requestForCallback;
5774             mPendingIntent = pi;
5775             mMessenger = null;
5776             mBinder = null;
5777             mPid = getCallingPid();
5778             mUid = mDeps.getCallingUid();
5779             mAsUid = asUid;
5780             mPerUidCounter = getRequestCounter(this);
5781             mPerUidCounter.incrementCountOrThrow(mUid);
5782             /**
5783              * Location sensitive data not included in pending intent. Only included in
5784              * {@link NetworkCallback}.
5785              */
5786             mCallbackFlags = NetworkCallback.FLAG_NONE;
5787             mCallingAttributionTag = callingAttributionTag;
5788             mPreferencePriority = preferencePriority;
5789         }
5790 
NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m, @Nullable final IBinder binder, @NetworkCallback.Flag int callbackFlags, @Nullable String callingAttributionTag)5791         NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m,
5792                 @Nullable final IBinder binder,
5793                 @NetworkCallback.Flag int callbackFlags,
5794                 @Nullable String callingAttributionTag) {
5795             this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags,
5796                     callingAttributionTag);
5797         }
5798 
NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m, @Nullable final IBinder binder, @NetworkCallback.Flag int callbackFlags, @Nullable String callingAttributionTag)5799         NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
5800                 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m,
5801                 @Nullable final IBinder binder,
5802                 @NetworkCallback.Flag int callbackFlags,
5803                 @Nullable String callingAttributionTag) {
5804             super();
5805             ensureAllNetworkRequestsHaveType(r);
5806             mRequests = initializeRequests(r);
5807             mNetworkRequestForCallback = requestForCallback;
5808             mMessenger = m;
5809             mBinder = binder;
5810             mPid = getCallingPid();
5811             mUid = mDeps.getCallingUid();
5812             mAsUid = asUid;
5813             mPendingIntent = null;
5814             mPerUidCounter = getRequestCounter(this);
5815             mPerUidCounter.incrementCountOrThrow(mUid);
5816             mCallbackFlags = callbackFlags;
5817             mCallingAttributionTag = callingAttributionTag;
5818             mPreferencePriority = PREFERENCE_PRIORITY_INVALID;
5819             linkDeathRecipient();
5820         }
5821 
NetworkRequestInfo(@onNull final NetworkRequestInfo nri, @NonNull final List<NetworkRequest> r)5822         NetworkRequestInfo(@NonNull final NetworkRequestInfo nri,
5823                 @NonNull final List<NetworkRequest> r) {
5824             super();
5825             ensureAllNetworkRequestsHaveType(r);
5826             mRequests = initializeRequests(r);
5827             mNetworkRequestForCallback = nri.getNetworkRequestForCallback();
5828             final NetworkAgentInfo satisfier = nri.getSatisfier();
5829             if (null != satisfier) {
5830                 // If the old NRI was satisfied by an NAI, then it may have had an active request.
5831                 // The active request is necessary to figure out what callbacks to send, in
5832                 // particular then a network updates its capabilities.
5833                 // As this code creates a new NRI with a new set of requests, figure out which of
5834                 // the list of requests should be the active request. It is always the first
5835                 // request of the list that can be satisfied by the satisfier since the order of
5836                 // requests is a priority order.
5837                 // Note even in the presence of a satisfier there may not be an active request,
5838                 // when the satisfier is the no-service network.
5839                 NetworkRequest activeRequest = null;
5840                 for (final NetworkRequest candidate : r) {
5841                     if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) {
5842                         activeRequest = candidate;
5843                         break;
5844                     }
5845                 }
5846                 setSatisfier(satisfier, activeRequest);
5847             }
5848             mMessenger = nri.mMessenger;
5849             mBinder = nri.mBinder;
5850             mPid = nri.mPid;
5851             mUid = nri.mUid;
5852             mAsUid = nri.mAsUid;
5853             mPendingIntent = nri.mPendingIntent;
5854             mPerUidCounter = nri.mPerUidCounter;
5855             mPerUidCounter.incrementCountOrThrow(mUid);
5856             mCallbackFlags = nri.mCallbackFlags;
5857             mCallingAttributionTag = nri.mCallingAttributionTag;
5858             mPreferencePriority = PREFERENCE_PRIORITY_INVALID;
5859             linkDeathRecipient();
5860         }
5861 
NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r)5862         NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) {
5863             this(asUid, Collections.singletonList(r), PREFERENCE_PRIORITY_INVALID);
5864         }
5865 
NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, final int preferencePriority)5866         NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
5867                 final int preferencePriority) {
5868             this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */,
5869                     preferencePriority);
5870         }
5871 
5872         // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer
5873         // set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning
5874         // false.
isBeingSatisfied()5875         boolean isBeingSatisfied() {
5876             return (null != mSatisfier && null != mActiveRequest);
5877         }
5878 
isMultilayerRequest()5879         boolean isMultilayerRequest() {
5880             return mRequests.size() > 1;
5881         }
5882 
initializeRequests(List<NetworkRequest> r)5883         private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) {
5884             // Creating a defensive copy to prevent the sender from modifying the list being
5885             // reflected in the return value of this method.
5886             final List<NetworkRequest> tempRequests = new ArrayList<>(r);
5887             return Collections.unmodifiableList(tempRequests);
5888         }
5889 
decrementRequestCount()5890         void decrementRequestCount() {
5891             mPerUidCounter.decrementCount(mUid);
5892         }
5893 
linkDeathRecipient()5894         void linkDeathRecipient() {
5895             if (null != mBinder) {
5896                 try {
5897                     mBinder.linkToDeath(this, 0);
5898                 } catch (RemoteException e) {
5899                     binderDied();
5900                 }
5901             }
5902         }
5903 
unlinkDeathRecipient()5904         void unlinkDeathRecipient() {
5905             if (null != mBinder) {
5906                 mBinder.unlinkToDeath(this, 0);
5907             }
5908         }
5909 
hasHigherPriorityThan(@onNull final NetworkRequestInfo target)5910         boolean hasHigherPriorityThan(@NonNull final NetworkRequestInfo target) {
5911             // Compare two priorities, larger value means lower priority.
5912             return mPreferencePriority < target.mPreferencePriority;
5913         }
5914 
getPriorityForNetd()5915         int getPriorityForNetd() {
5916             if (mPreferencePriority >= PREFERENCE_PRIORITY_NONE
5917                     && mPreferencePriority <= PREFERENCE_PRIORITY_LOWEST) {
5918                 return mPreferencePriority;
5919             }
5920             return PREFERENCE_PRIORITY_NONE;
5921         }
5922 
5923         @Override
binderDied()5924         public void binderDied() {
5925             log("ConnectivityService NetworkRequestInfo binderDied(" +
5926                     "uid/pid:" + mUid + "/" + mPid + ", " + mBinder + ")");
5927             // As an immutable collection, mRequests cannot change by the time the
5928             // lambda is evaluated on the handler thread so calling .get() from a binder thread
5929             // is acceptable. Use handleReleaseNetworkRequest and not directly
5930             // handleRemoveNetworkRequest so as to force a lookup in the requests map, in case
5931             // the app already unregistered the request.
5932             mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0),
5933                     mUid, false /* callOnUnavailable */));
5934         }
5935 
5936         @Override
toString()5937         public String toString() {
5938             final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid;
5939             return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: "
5940                     + (mActiveRequest == null ? null : mActiveRequest.requestId)
5941                     + " callbackRequest: "
5942                     + mNetworkRequestForCallback.requestId
5943                     + " " + mRequests
5944                     + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
5945                     + " callback flags: " + mCallbackFlags
5946                     + " priority: " + mPreferencePriority;
5947         }
5948     }
5949 
ensureRequestableCapabilities(NetworkCapabilities networkCapabilities)5950     private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) {
5951         final String badCapability = networkCapabilities.describeFirstNonRequestableCapability();
5952         if (badCapability != null) {
5953             throw new IllegalArgumentException("Cannot request network with " + badCapability);
5954         }
5955     }
5956 
5957     // This checks that the passed capabilities either do not request a
5958     // specific SSID/SignalStrength, or the calling app has permission to do so.
ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid, String callerPackageName)5959     private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
5960             int callerPid, int callerUid, String callerPackageName) {
5961         if (null != nc.getSsid() && !checkSettingsPermission(callerPid, callerUid)) {
5962             throw new SecurityException("Insufficient permissions to request a specific SSID");
5963         }
5964 
5965         if (nc.hasSignalStrength()
5966                 && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) {
5967             throw new SecurityException(
5968                     "Insufficient permissions to request a specific signal strength");
5969         }
5970         mAppOpsManager.checkPackage(callerUid, callerPackageName);
5971 
5972         if (!nc.getSubscriptionIds().isEmpty()) {
5973             enforceNetworkFactoryPermission();
5974         }
5975     }
5976 
getSignalStrengthThresholds(@onNull final NetworkAgentInfo nai)5977     private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) {
5978         final SortedSet<Integer> thresholds = new TreeSet<>();
5979         synchronized (nai) {
5980             // mNetworkRequests may contain the same value multiple times in case of
5981             // multilayer requests. It won't matter in this case because the thresholds
5982             // will then be the same and be deduplicated as they enter the `thresholds` set.
5983             // TODO : have mNetworkRequests be a Set<NetworkRequestInfo> or the like.
5984             for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
5985                 for (final NetworkRequest req : nri.mRequests) {
5986                     if (req.networkCapabilities.hasSignalStrength()
5987                             && nai.satisfiesImmutableCapabilitiesOf(req)) {
5988                         thresholds.add(req.networkCapabilities.getSignalStrength());
5989                     }
5990                 }
5991             }
5992         }
5993         return CollectionUtils.toIntArray(new ArrayList<>(thresholds));
5994     }
5995 
updateSignalStrengthThresholds( NetworkAgentInfo nai, String reason, NetworkRequest request)5996     private void updateSignalStrengthThresholds(
5997             NetworkAgentInfo nai, String reason, NetworkRequest request) {
5998         final int[] thresholdsArray = getSignalStrengthThresholds(nai);
5999 
6000         if (VDBG || (DBG && !"CONNECT".equals(reason))) {
6001             String detail;
6002             if (request != null && request.networkCapabilities.hasSignalStrength()) {
6003                 detail = reason + " " + request.networkCapabilities.getSignalStrength();
6004             } else {
6005                 detail = reason;
6006             }
6007             log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
6008                     detail, Arrays.toString(thresholdsArray), nai.toShortString()));
6009         }
6010 
6011         nai.onSignalStrengthThresholdsUpdated(thresholdsArray);
6012     }
6013 
ensureValidNetworkSpecifier(NetworkCapabilities nc)6014     private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
6015         if (nc == null) {
6016             return;
6017         }
6018         NetworkSpecifier ns = nc.getNetworkSpecifier();
6019         if (ns == null) {
6020             return;
6021         }
6022         if (ns instanceof MatchAllNetworkSpecifier) {
6023             throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted");
6024         }
6025     }
6026 
ensureValid(NetworkCapabilities nc)6027     private void ensureValid(NetworkCapabilities nc) {
6028         ensureValidNetworkSpecifier(nc);
6029         if (nc.isPrivateDnsBroken()) {
6030             throw new IllegalArgumentException("Can't request broken private DNS");
6031         }
6032     }
6033 
isTargetSdkAtleast(int version, int callingUid, @NonNull String callingPackageName)6034     private boolean isTargetSdkAtleast(int version, int callingUid,
6035             @NonNull String callingPackageName) {
6036         final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
6037         final PackageManager pm =
6038                 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
6039         try {
6040             final int callingVersion = pm.getTargetSdkVersion(callingPackageName);
6041             if (callingVersion < version) return false;
6042         } catch (PackageManager.NameNotFoundException e) { }
6043         return true;
6044     }
6045 
6046     @Override
requestNetwork(int asUid, NetworkCapabilities networkCapabilities, int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder, int legacyType, int callbackFlags, @NonNull String callingPackageName, @Nullable String callingAttributionTag)6047     public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities,
6048             int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder,
6049             int legacyType, int callbackFlags, @NonNull String callingPackageName,
6050             @Nullable String callingAttributionTag) {
6051         if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
6052             if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(),
6053                     callingPackageName)) {
6054                 throw new SecurityException("Insufficient permissions to specify legacy type");
6055             }
6056         }
6057         final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities;
6058         final int callingUid = mDeps.getCallingUid();
6059         // Privileged callers can track the default network of another UID by passing in a UID.
6060         if (asUid != Process.INVALID_UID) {
6061             enforceSettingsPermission();
6062         } else {
6063             asUid = callingUid;
6064         }
6065         final NetworkRequest.Type reqType;
6066         try {
6067             reqType = NetworkRequest.Type.values()[reqTypeInt];
6068         } catch (ArrayIndexOutOfBoundsException e) {
6069             throw new IllegalArgumentException("Unsupported request type " + reqTypeInt);
6070         }
6071         switch (reqType) {
6072             case TRACK_DEFAULT:
6073                 // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
6074                 // is unused and will be replaced by ones appropriate for the UID (usually, the
6075                 // calling app). This allows callers to keep track of the default network.
6076                 networkCapabilities = copyDefaultNetworkCapabilitiesForUid(
6077                         defaultNc, asUid, callingUid, callingPackageName);
6078                 enforceAccessPermission();
6079                 break;
6080             case TRACK_SYSTEM_DEFAULT:
6081                 enforceSettingsPermission();
6082                 networkCapabilities = new NetworkCapabilities(defaultNc);
6083                 break;
6084             case BACKGROUND_REQUEST:
6085                 enforceNetworkStackOrSettingsPermission();
6086                 // Fall-through since other checks are the same with normal requests.
6087             case REQUEST:
6088                 networkCapabilities = new NetworkCapabilities(networkCapabilities);
6089                 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
6090                         callingAttributionTag);
6091                 // TODO: this is incorrect. We mark the request as metered or not depending on
6092                 //  the state of the app when the request is filed, but we never change the
6093                 //  request if the app changes network state. http://b/29964605
6094                 enforceMeteredApnPolicy(networkCapabilities);
6095                 break;
6096             case LISTEN_FOR_BEST:
6097                 enforceAccessPermission();
6098                 networkCapabilities = new NetworkCapabilities(networkCapabilities);
6099                 break;
6100             default:
6101                 throw new IllegalArgumentException("Unsupported request type " + reqType);
6102         }
6103         ensureRequestableCapabilities(networkCapabilities);
6104         ensureSufficientPermissionsForRequest(networkCapabilities,
6105                 Binder.getCallingPid(), callingUid, callingPackageName);
6106 
6107         // Enforce FOREGROUND if the caller does not have permission to use background network.
6108         if (reqType == LISTEN_FOR_BEST) {
6109             restrictBackgroundRequestForCaller(networkCapabilities);
6110         }
6111 
6112         // Set the UID range for this request to the single UID of the requester, unless the
6113         // requester has the permission to specify other UIDs.
6114         // This will overwrite any allowed UIDs in the requested capabilities. Though there
6115         // are no visible methods to set the UIDs, an app could use reflection to try and get
6116         // networks for other apps so it's essential that the UIDs are overwritten.
6117         // Also set the requester UID and package name in the request.
6118         restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
6119                 callingUid, callingPackageName);
6120 
6121         if (timeoutMs < 0) {
6122             throw new IllegalArgumentException("Bad timeout specified");
6123         }
6124         ensureValid(networkCapabilities);
6125 
6126         final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
6127                 nextNetworkRequestId(), reqType);
6128         final NetworkRequestInfo nri = getNriToRegister(
6129                 asUid, networkRequest, messenger, binder, callbackFlags,
6130                 callingAttributionTag);
6131         if (DBG) log("requestNetwork for " + nri);
6132 
6133         // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
6134         // copied from the default request above. (This is necessary to ensure, for example, that
6135         // the callback does not leak sensitive information to unprivileged apps.) Check that the
6136         // changes don't alter request matching.
6137         if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT &&
6138                 (!networkCapabilities.equalRequestableCapabilities(defaultNc))) {
6139             throw new IllegalStateException(
6140                     "TRACK_SYSTEM_DEFAULT capabilities don't match default request: "
6141                     + networkCapabilities + " vs. " + defaultNc);
6142         }
6143 
6144         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
6145         if (timeoutMs > 0) {
6146             mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
6147                     nri), timeoutMs);
6148         }
6149         return networkRequest;
6150     }
6151 
6152     /**
6153      * Return the nri to be used when registering a network request. Specifically, this is used with
6154      * requests registered to track the default request. If there is currently a per-app default
6155      * tracking the app requestor, then we need to create a version of this nri that mirrors that of
6156      * the tracking per-app default so that callbacks are sent to the app requestor appropriately.
6157      * @param asUid the uid on behalf of which to file the request. Different from requestorUid
6158      *              when a privileged caller is tracking the default network for another uid.
6159      * @param nr the network request for the nri.
6160      * @param msgr the messenger for the nri.
6161      * @param binder the binder for the nri.
6162      * @param callingAttributionTag the calling attribution tag for the nri.
6163      * @return the nri to register.
6164      */
getNriToRegister(final int asUid, @NonNull final NetworkRequest nr, @Nullable final Messenger msgr, @Nullable final IBinder binder, @NetworkCallback.Flag int callbackFlags, @Nullable String callingAttributionTag)6165     private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr,
6166             @Nullable final Messenger msgr, @Nullable final IBinder binder,
6167             @NetworkCallback.Flag int callbackFlags,
6168             @Nullable String callingAttributionTag) {
6169         final List<NetworkRequest> requests;
6170         if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) {
6171             requests = copyDefaultNetworkRequestsForUid(
6172                     asUid, nr.getRequestorUid(), nr.getRequestorPackageName());
6173         } else {
6174             requests = Collections.singletonList(nr);
6175         }
6176         return new NetworkRequestInfo(
6177                 asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
6178     }
6179 
enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities, String callingPackageName, String callingAttributionTag)6180     private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
6181             String callingPackageName, String callingAttributionTag) {
6182         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
6183             enforceConnectivityRestrictedNetworksPermission();
6184         } else {
6185             enforceChangePermission(callingPackageName, callingAttributionTag);
6186         }
6187     }
6188 
6189     @Override
requestBandwidthUpdate(Network network)6190     public boolean requestBandwidthUpdate(Network network) {
6191         enforceAccessPermission();
6192         NetworkAgentInfo nai = null;
6193         if (network == null) {
6194             return false;
6195         }
6196         synchronized (mNetworkForNetId) {
6197             nai = mNetworkForNetId.get(network.getNetId());
6198         }
6199         if (nai != null) {
6200             nai.onBandwidthUpdateRequested();
6201             synchronized (mBandwidthRequests) {
6202                 final int uid = mDeps.getCallingUid();
6203                 Integer uidReqs = mBandwidthRequests.get(uid);
6204                 if (uidReqs == null) {
6205                     uidReqs = 0;
6206                 }
6207                 mBandwidthRequests.put(uid, ++uidReqs);
6208             }
6209             return true;
6210         }
6211         return false;
6212     }
6213 
isSystem(int uid)6214     private boolean isSystem(int uid) {
6215         return uid < Process.FIRST_APPLICATION_UID;
6216     }
6217 
enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities)6218     private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
6219         final int uid = mDeps.getCallingUid();
6220         if (isSystem(uid)) {
6221             // Exemption for system uid.
6222             return;
6223         }
6224         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
6225             // Policy already enforced.
6226             return;
6227         }
6228         final long ident = Binder.clearCallingIdentity();
6229         try {
6230             if (mPolicyManager.isUidRestrictedOnMeteredNetworks(uid)) {
6231                 // If UID is restricted, don't allow them to bring up metered APNs.
6232                 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
6233             }
6234         } finally {
6235             Binder.restoreCallingIdentity(ident);
6236         }
6237     }
6238 
6239     @Override
pendingRequestForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation, @NonNull String callingPackageName, @Nullable String callingAttributionTag)6240     public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
6241             PendingIntent operation, @NonNull String callingPackageName,
6242             @Nullable String callingAttributionTag) {
6243         Objects.requireNonNull(operation, "PendingIntent cannot be null.");
6244         final int callingUid = mDeps.getCallingUid();
6245         networkCapabilities = new NetworkCapabilities(networkCapabilities);
6246         enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
6247                 callingAttributionTag);
6248         enforceMeteredApnPolicy(networkCapabilities);
6249         ensureRequestableCapabilities(networkCapabilities);
6250         ensureSufficientPermissionsForRequest(networkCapabilities,
6251                 Binder.getCallingPid(), callingUid, callingPackageName);
6252         ensureValidNetworkSpecifier(networkCapabilities);
6253         restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
6254                 callingUid, callingPackageName);
6255 
6256         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
6257                 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
6258         NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
6259                 callingAttributionTag);
6260         if (DBG) log("pendingRequest for " + nri);
6261         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
6262                 nri));
6263         return networkRequest;
6264     }
6265 
releasePendingNetworkRequestWithDelay(PendingIntent operation)6266     private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
6267         mHandler.sendMessageDelayed(
6268                 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
6269                 mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
6270     }
6271 
6272     @Override
releasePendingNetworkRequest(PendingIntent operation)6273     public void releasePendingNetworkRequest(PendingIntent operation) {
6274         Objects.requireNonNull(operation, "PendingIntent cannot be null.");
6275         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
6276                 mDeps.getCallingUid(), 0, operation));
6277     }
6278 
6279     // In order to implement the compatibility measure for pre-M apps that call
6280     // WifiManager.enableNetwork(..., true) without also binding to that network explicitly,
6281     // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork.
6282     // This ensures it has permission to do so.
hasWifiNetworkListenPermission(NetworkCapabilities nc)6283     private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) {
6284         if (nc == null) {
6285             return false;
6286         }
6287         int[] transportTypes = nc.getTransportTypes();
6288         if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) {
6289             return false;
6290         }
6291         try {
6292             mContext.enforceCallingOrSelfPermission(
6293                     android.Manifest.permission.ACCESS_WIFI_STATE,
6294                     "ConnectivityService");
6295         } catch (SecurityException e) {
6296             return false;
6297         }
6298         return true;
6299     }
6300 
6301     @Override
listenForNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, IBinder binder, @NetworkCallback.Flag int callbackFlags, @NonNull String callingPackageName, @NonNull String callingAttributionTag)6302     public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
6303             Messenger messenger, IBinder binder,
6304             @NetworkCallback.Flag int callbackFlags,
6305             @NonNull String callingPackageName, @NonNull String callingAttributionTag) {
6306         final int callingUid = mDeps.getCallingUid();
6307         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
6308             enforceAccessPermission();
6309         }
6310 
6311         NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
6312         ensureSufficientPermissionsForRequest(networkCapabilities,
6313                 Binder.getCallingPid(), callingUid, callingPackageName);
6314         restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
6315         // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
6316         // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
6317         // onLost and onAvailable callbacks when networks move in and out of the background.
6318         // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
6319         // can't request networks.
6320         restrictBackgroundRequestForCaller(nc);
6321         ensureValid(nc);
6322 
6323         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
6324                 NetworkRequest.Type.LISTEN);
6325         NetworkRequestInfo nri =
6326                 new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags,
6327                         callingAttributionTag);
6328         if (VDBG) log("listenForNetwork for " + nri);
6329 
6330         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
6331         return networkRequest;
6332     }
6333 
6334     @Override
pendingListenForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation, @NonNull String callingPackageName, @Nullable String callingAttributionTag)6335     public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
6336             PendingIntent operation, @NonNull String callingPackageName,
6337             @Nullable String callingAttributionTag) {
6338         Objects.requireNonNull(operation, "PendingIntent cannot be null.");
6339         final int callingUid = mDeps.getCallingUid();
6340         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
6341             enforceAccessPermission();
6342         }
6343         ensureValid(networkCapabilities);
6344         ensureSufficientPermissionsForRequest(networkCapabilities,
6345                 Binder.getCallingPid(), callingUid, callingPackageName);
6346         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
6347         restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
6348 
6349         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
6350                 NetworkRequest.Type.LISTEN);
6351         NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
6352                 callingAttributionTag);
6353         if (VDBG) log("pendingListenForNetwork for " + nri);
6354 
6355         mHandler.sendMessage(mHandler.obtainMessage(
6356                     EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT, nri));
6357     }
6358 
6359     /** Returns the next Network provider ID. */
nextNetworkProviderId()6360     public final int nextNetworkProviderId() {
6361         return mNextNetworkProviderId.getAndIncrement();
6362     }
6363 
6364     @Override
releaseNetworkRequest(NetworkRequest networkRequest)6365     public void releaseNetworkRequest(NetworkRequest networkRequest) {
6366         ensureNetworkRequestHasType(networkRequest);
6367         mHandler.sendMessage(mHandler.obtainMessage(
6368                 EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest));
6369     }
6370 
handleRegisterNetworkProvider(NetworkProviderInfo npi)6371     private void handleRegisterNetworkProvider(NetworkProviderInfo npi) {
6372         if (mNetworkProviderInfos.containsKey(npi.messenger)) {
6373             // Avoid creating duplicates. even if an app makes a direct AIDL call.
6374             // This will never happen if an app calls ConnectivityManager#registerNetworkProvider,
6375             // as that will throw if a duplicate provider is registered.
6376             loge("Attempt to register existing NetworkProviderInfo "
6377                     + mNetworkProviderInfos.get(npi.messenger).name);
6378             return;
6379         }
6380 
6381         if (DBG) log("Got NetworkProvider Messenger for " + npi.name);
6382         mNetworkProviderInfos.put(npi.messenger, npi);
6383         npi.connect(mContext, mTrackerHandler);
6384     }
6385 
6386     @Override
registerNetworkProvider(Messenger messenger, String name)6387     public int registerNetworkProvider(Messenger messenger, String name) {
6388         enforceNetworkFactoryOrSettingsPermission();
6389         Objects.requireNonNull(messenger, "messenger must be non-null");
6390         NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
6391                 nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
6392         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
6393         return npi.providerId;
6394     }
6395 
6396     @Override
unregisterNetworkProvider(Messenger messenger)6397     public void unregisterNetworkProvider(Messenger messenger) {
6398         enforceNetworkFactoryOrSettingsPermission();
6399         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger));
6400     }
6401 
6402     @Override
offerNetwork(final int providerId, @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps, @NonNull final INetworkOfferCallback callback)6403     public void offerNetwork(final int providerId,
6404             @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps,
6405             @NonNull final INetworkOfferCallback callback) {
6406         Objects.requireNonNull(score);
6407         Objects.requireNonNull(caps);
6408         Objects.requireNonNull(callback);
6409         final NetworkOffer offer = new NetworkOffer(
6410                 FullScore.makeProspectiveScore(score, caps), caps, callback, providerId);
6411         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer));
6412     }
6413 
6414     @Override
unofferNetwork(@onNull final INetworkOfferCallback callback)6415     public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
6416         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback));
6417     }
6418 
handleUnregisterNetworkProvider(Messenger messenger)6419     private void handleUnregisterNetworkProvider(Messenger messenger) {
6420         NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger);
6421         if (npi == null) {
6422             loge("Failed to find Messenger in unregisterNetworkProvider");
6423             return;
6424         }
6425         // Unregister all the offers from this provider
6426         final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>();
6427         for (final NetworkOfferInfo noi : mNetworkOffers) {
6428             if (noi.offer.providerId == npi.providerId) {
6429                 // Can't call handleUnregisterNetworkOffer here because iteration is in progress
6430                 toRemove.add(noi);
6431             }
6432         }
6433         for (final NetworkOfferInfo noi : toRemove) {
6434             handleUnregisterNetworkOffer(noi);
6435         }
6436         if (DBG) log("unregisterNetworkProvider for " + npi.name);
6437     }
6438 
6439     @Override
declareNetworkRequestUnfulfillable(@onNull final NetworkRequest request)6440     public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) {
6441         if (request.hasTransport(TRANSPORT_TEST)) {
6442             enforceNetworkFactoryOrTestNetworksPermission();
6443         } else {
6444             enforceNetworkFactoryPermission();
6445         }
6446         final NetworkRequestInfo nri = mNetworkRequests.get(request);
6447         if (nri != null) {
6448             // declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests.
6449             ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable");
6450             mHandler.post(() -> handleReleaseNetworkRequest(
6451                     nri.mRequests.get(0), mDeps.getCallingUid(), true));
6452         }
6453     }
6454 
6455     // NOTE: Accessed on multiple threads, must be synchronized on itself.
6456     @GuardedBy("mNetworkForNetId")
6457     private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
6458     // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId.
6459     // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so
6460     // there may not be a strict 1:1 correlation between the two.
6461     private final NetIdManager mNetIdManager;
6462 
6463     // Tracks all NetworkAgents that are currently registered.
6464     // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
6465     private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>();
6466 
6467     // UID ranges for users that are currently blocked by VPNs.
6468     // This array is accessed and iterated on multiple threads without holding locks, so its
6469     // contents must never be mutated. When the ranges change, the array is replaced with a new one
6470     // (on the handler thread).
6471     private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>();
6472 
6473     // Must only be accessed on the handler thread
6474     @NonNull
6475     private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>();
6476 
6477     @GuardedBy("mBlockedAppUids")
6478     private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
6479 
6480     // Current OEM network preferences. This object must only be written to on the handler thread.
6481     // Since it is immutable and always non-null, other threads may read it if they only care
6482     // about seeing a consistent object but not that it is current.
6483     @NonNull
6484     private OemNetworkPreferences mOemNetworkPreferences =
6485             new OemNetworkPreferences.Builder().build();
6486     // Current per-profile network preferences. This object follows the same threading rules as
6487     // the OEM network preferences above.
6488     @NonNull
6489     private ProfileNetworkPreferences mProfileNetworkPreferences = new ProfileNetworkPreferences();
6490 
6491     // A set of UIDs that should use mobile data preferentially if available. This object follows
6492     // the same threading rules as the OEM network preferences above.
6493     @NonNull
6494     private Set<Integer> mMobileDataPreferredUids = new ArraySet<>();
6495 
6496     // OemNetworkPreferences activity String log entries.
6497     private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20;
6498     @NonNull
6499     private final LocalLog mOemNetworkPreferencesLogs =
6500             new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS);
6501 
6502     /**
6503      * Determine whether a given package has a mapping in the current OemNetworkPreferences.
6504      * @param packageName the package name to check existence of a mapping for.
6505      * @return true if a mapping exists, false otherwise
6506      */
isMappedInOemNetworkPreference(@onNull final String packageName)6507     private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) {
6508         return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName);
6509     }
6510 
6511     // The always-on request for an Internet-capable network that apps without a specific default
6512     // fall back to.
6513     @VisibleForTesting
6514     @NonNull
6515     final NetworkRequestInfo mDefaultRequest;
6516     // Collection of NetworkRequestInfo's used for default networks.
6517     @VisibleForTesting
6518     @NonNull
6519     final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>();
6520 
isPerAppDefaultRequest(@onNull final NetworkRequestInfo nri)6521     private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) {
6522         return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri);
6523     }
6524 
6525     /**
6526      * Return the default network request currently tracking the given uid.
6527      * @param uid the uid to check.
6528      * @return the NetworkRequestInfo tracking the given uid.
6529      */
6530     @NonNull
getDefaultRequestTrackingUid(final int uid)6531     private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) {
6532         NetworkRequestInfo highestPriorityNri = mDefaultRequest;
6533         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
6534             // Checking the first request is sufficient as only multilayer requests will have more
6535             // than one request and for multilayer, all requests will track the same uids.
6536             if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) {
6537                 // Find out the highest priority request.
6538                 if (nri.hasHigherPriorityThan(highestPriorityNri)) {
6539                     highestPriorityNri = nri;
6540                 }
6541             }
6542         }
6543         return highestPriorityNri;
6544     }
6545 
6546     /**
6547      * Get a copy of the network requests of the default request that is currently tracking the
6548      * given uid.
6549      * @param asUid the uid on behalf of which to file the request. Different from requestorUid
6550      *              when a privileged caller is tracking the default network for another uid.
6551      * @param requestorUid the uid to check the default for.
6552      * @param requestorPackageName the requestor's package name.
6553      * @return a copy of the default's NetworkRequest that is tracking the given uid.
6554      */
6555     @NonNull
copyDefaultNetworkRequestsForUid( final int asUid, final int requestorUid, @NonNull final String requestorPackageName)6556     private List<NetworkRequest> copyDefaultNetworkRequestsForUid(
6557             final int asUid, final int requestorUid, @NonNull final String requestorPackageName) {
6558         return copyNetworkRequestsForUid(
6559                 getDefaultRequestTrackingUid(asUid).mRequests,
6560                 asUid, requestorUid, requestorPackageName);
6561     }
6562 
6563     /**
6564      * Copy the given nri's NetworkRequest collection.
6565      * @param requestsToCopy the NetworkRequest collection to be copied.
6566      * @param asUid the uid on behalf of which to file the request. Different from requestorUid
6567      *              when a privileged caller is tracking the default network for another uid.
6568      * @param requestorUid the uid to set on the copied collection.
6569      * @param requestorPackageName the package name to set on the copied collection.
6570      * @return the copied NetworkRequest collection.
6571      */
6572     @NonNull
copyNetworkRequestsForUid( @onNull final List<NetworkRequest> requestsToCopy, final int asUid, final int requestorUid, @NonNull final String requestorPackageName)6573     private List<NetworkRequest> copyNetworkRequestsForUid(
6574             @NonNull final List<NetworkRequest> requestsToCopy, final int asUid,
6575             final int requestorUid, @NonNull final String requestorPackageName) {
6576         final List<NetworkRequest> requests = new ArrayList<>();
6577         for (final NetworkRequest nr : requestsToCopy) {
6578             requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid(
6579                             nr.networkCapabilities, asUid, requestorUid, requestorPackageName),
6580                     nr.legacyType, nextNetworkRequestId(), nr.type));
6581         }
6582         return requests;
6583     }
6584 
6585     @NonNull
copyDefaultNetworkCapabilitiesForUid( @onNull final NetworkCapabilities netCapToCopy, final int asUid, final int requestorUid, @NonNull final String requestorPackageName)6586     private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid(
6587             @NonNull final NetworkCapabilities netCapToCopy, final int asUid,
6588             final int requestorUid, @NonNull final String requestorPackageName) {
6589         // These capabilities are for a TRACK_DEFAULT callback, so:
6590         // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between
6591         //    mDefaultRequest and a per-UID default request.
6592         //    TODO: stop depending on the fact that these two unrelated things happen to be the same
6593         // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will
6594         //    not do this in the case of a privileged application.
6595         final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy);
6596         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
6597         netCap.setSingleUid(asUid);
6598         restrictRequestUidsForCallerAndSetRequestorInfo(
6599                 netCap, requestorUid, requestorPackageName);
6600         return netCap;
6601     }
6602 
6603     /**
6604      * Get the nri that is currently being tracked for callbacks by per-app defaults.
6605      * @param nr the network request to check for equality against.
6606      * @return the nri if one exists, null otherwise.
6607      */
6608     @Nullable
getNriForAppRequest(@onNull final NetworkRequest nr)6609     private NetworkRequestInfo getNriForAppRequest(@NonNull final NetworkRequest nr) {
6610         for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
6611             if (nri.getNetworkRequestForCallback().equals(nr)) {
6612                 return nri;
6613             }
6614         }
6615         return null;
6616     }
6617 
6618     /**
6619      * Check if an nri is currently being managed by per-app default networking.
6620      * @param nri the nri to check.
6621      * @return true if this nri is currently being managed by per-app default networking.
6622      */
isPerAppTrackedNri(@onNull final NetworkRequestInfo nri)6623     private boolean isPerAppTrackedNri(@NonNull final NetworkRequestInfo nri) {
6624         // nri.mRequests.get(0) is only different from the original request filed in
6625         // nri.getNetworkRequestForCallback() if nri.mRequests was changed by per-app default
6626         // functionality therefore if these two don't match, it means this particular nri is
6627         // currently being managed by a per-app default.
6628         return nri.getNetworkRequestForCallback() != nri.mRequests.get(0);
6629     }
6630 
6631     /**
6632      * Determine if an nri is a managed default request that disallows default networking.
6633      * @param nri the request to evaluate
6634      * @return true if device-default networking is disallowed
6635      */
isDefaultBlocked(@onNull final NetworkRequestInfo nri)6636     private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) {
6637         // Check if this nri is a managed default that supports the default network at its
6638         // lowest priority request.
6639         final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0);
6640         final NetworkCapabilities lowestPriorityNetCap =
6641                 nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities;
6642         return isPerAppDefaultRequest(nri)
6643                 && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities(
6644                         lowestPriorityNetCap));
6645     }
6646 
6647     // Request used to optionally keep mobile data active even when higher
6648     // priority networks like Wi-Fi are active.
6649     private final NetworkRequest mDefaultMobileDataRequest;
6650 
6651     // Request used to optionally keep wifi data active even when higher
6652     // priority networks like ethernet are active.
6653     private final NetworkRequest mDefaultWifiRequest;
6654 
6655     // Request used to optionally keep vehicle internal network always active
6656     private final NetworkRequest mDefaultVehicleRequest;
6657 
6658     // Sentinel NAI used to direct apps with default networks that should have no connectivity to a
6659     // network with no service. This NAI should never be matched against, nor should any public API
6660     // ever return the associated network. For this reason, this NAI is not in the list of available
6661     // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device
6662     // default requests that don't support using the device default network which will ultimately
6663     // allow ConnectivityService to use this no-service network when calling makeDefaultForApps().
6664     @VisibleForTesting
6665     final NetworkAgentInfo mNoServiceNetwork;
6666 
6667     // The NetworkAgentInfo currently satisfying the default request, if any.
getDefaultNetwork()6668     private NetworkAgentInfo getDefaultNetwork() {
6669         return mDefaultRequest.mSatisfier;
6670     }
6671 
getDefaultNetworkForUid(final int uid)6672     private NetworkAgentInfo getDefaultNetworkForUid(final int uid) {
6673         NetworkRequestInfo highestPriorityNri = mDefaultRequest;
6674         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
6675             // Currently, all network requests will have the same uids therefore checking the first
6676             // one is sufficient. If/when uids are tracked at the nri level, this can change.
6677             final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges();
6678             if (null == uids) {
6679                 continue;
6680             }
6681             for (final UidRange range : uids) {
6682                 if (range.contains(uid)) {
6683                     if (nri.hasHigherPriorityThan(highestPriorityNri)) {
6684                         highestPriorityNri = nri;
6685                     }
6686                 }
6687             }
6688         }
6689         return highestPriorityNri.getSatisfier();
6690     }
6691 
6692     @Nullable
getNetwork(@ullable NetworkAgentInfo nai)6693     private Network getNetwork(@Nullable NetworkAgentInfo nai) {
6694         return nai != null ? nai.network : null;
6695     }
6696 
ensureRunningOnConnectivityServiceThread()6697     private void ensureRunningOnConnectivityServiceThread() {
6698         if (mHandler.getLooper().getThread() != Thread.currentThread()) {
6699             throw new IllegalStateException(
6700                     "Not running on ConnectivityService thread: "
6701                             + Thread.currentThread().getName());
6702         }
6703     }
6704 
6705     @VisibleForTesting
isDefaultNetwork(NetworkAgentInfo nai)6706     protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
6707         return nai == getDefaultNetwork();
6708     }
6709 
6710     /**
6711      * Register a new agent with ConnectivityService to handle a network.
6712      *
6713      * @param na a reference for ConnectivityService to contact the agent asynchronously.
6714      * @param networkInfo the initial info associated with this network. It can be updated later :
6715      *         see {@link #updateNetworkInfo}.
6716      * @param linkProperties the initial link properties of this network. They can be updated
6717      *         later : see {@link #updateLinkProperties}.
6718      * @param networkCapabilities the initial capabilites of this network. They can be updated
6719      *         later : see {@link #updateCapabilities}.
6720      * @param initialScore the initial score of the network. See
6721      *         {@link NetworkAgentInfo#getCurrentScore}.
6722      * @param networkAgentConfig metadata about the network. This is never updated.
6723      * @param providerId the ID of the provider owning this NetworkAgent.
6724      * @return the network created for this agent.
6725      */
registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig, int providerId)6726     public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo,
6727             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
6728             @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig,
6729             int providerId) {
6730         Objects.requireNonNull(networkInfo, "networkInfo must not be null");
6731         Objects.requireNonNull(linkProperties, "linkProperties must not be null");
6732         Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null");
6733         Objects.requireNonNull(initialScore, "initialScore must not be null");
6734         Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null");
6735         if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
6736             enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS);
6737         } else {
6738             enforceNetworkFactoryPermission();
6739         }
6740 
6741         final int uid = mDeps.getCallingUid();
6742         final long token = Binder.clearCallingIdentity();
6743         try {
6744             return registerNetworkAgentInternal(na, networkInfo, linkProperties,
6745                     networkCapabilities, initialScore, networkAgentConfig, providerId, uid);
6746         } finally {
6747             Binder.restoreCallingIdentity(token);
6748         }
6749     }
6750 
registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid)6751     private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo,
6752             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
6753             NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId,
6754             int uid) {
6755         if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
6756             // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
6757             // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
6758             // sees capabilities that may be malicious, which might prevent mistakes in the future.
6759             networkCapabilities = new NetworkCapabilities(networkCapabilities);
6760             networkCapabilities.restrictCapabilitesForTestNetwork(uid);
6761         }
6762 
6763         LinkProperties lp = new LinkProperties(linkProperties);
6764 
6765         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
6766         final NetworkAgentInfo nai = new NetworkAgentInfo(na,
6767                 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
6768                 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
6769                 this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs,
6770                 mQosCallbackTracker, mDeps);
6771 
6772         // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
6773         processCapabilitiesFromAgent(nai, nc);
6774         nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
6775         processLinkPropertiesFromAgent(nai, nai.linkProperties);
6776 
6777         final String extraInfo = networkInfo.getExtraInfo();
6778         final String name = TextUtils.isEmpty(extraInfo)
6779                 ? nai.networkCapabilities.getSsid() : extraInfo;
6780         if (DBG) log("registerNetworkAgent " + nai);
6781         mDeps.getNetworkStack().makeNetworkMonitor(
6782                 nai.network, name, new NetworkMonitorCallbacks(nai));
6783         // NetworkAgentInfo registration will finish when the NetworkMonitor is created.
6784         // If the network disconnects or sends any other event before that, messages are deferred by
6785         // NetworkAgent until nai.connect(), which will be called when finalizing the
6786         // registration.
6787         return nai.network;
6788     }
6789 
handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor)6790     private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
6791         nai.onNetworkMonitorCreated(networkMonitor);
6792         if (VDBG) log("Got NetworkAgent Messenger");
6793         mNetworkAgentInfos.add(nai);
6794         synchronized (mNetworkForNetId) {
6795             mNetworkForNetId.put(nai.network.getNetId(), nai);
6796         }
6797 
6798         try {
6799             networkMonitor.start();
6800         } catch (RemoteException e) {
6801             e.rethrowAsRuntimeException();
6802         }
6803         nai.notifyRegistered();
6804         NetworkInfo networkInfo = nai.networkInfo;
6805         updateNetworkInfo(nai, networkInfo);
6806         updateUids(nai, null, nai.networkCapabilities);
6807     }
6808 
6809     private class NetworkOfferInfo implements IBinder.DeathRecipient {
6810         @NonNull public final NetworkOffer offer;
6811 
NetworkOfferInfo(@onNull final NetworkOffer offer)6812         NetworkOfferInfo(@NonNull final NetworkOffer offer) {
6813             this.offer = offer;
6814         }
6815 
6816         @Override
binderDied()6817         public void binderDied() {
6818             mHandler.post(() -> handleUnregisterNetworkOffer(this));
6819         }
6820     }
6821 
isNetworkProviderWithIdRegistered(final int providerId)6822     private boolean isNetworkProviderWithIdRegistered(final int providerId) {
6823         for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
6824             if (npi.providerId == providerId) return true;
6825         }
6826         return false;
6827     }
6828 
6829     /**
6830      * Register or update a network offer.
6831      * @param newOffer The new offer. If the callback member is the same as an existing
6832      *                 offer, it is an update of that offer.
6833      */
handleRegisterNetworkOffer(@onNull final NetworkOffer newOffer)6834     private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) {
6835         ensureRunningOnConnectivityServiceThread();
6836         if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) {
6837             // This may actually happen if a provider updates its score or registers and then
6838             // immediately unregisters. The offer would still be in the handler queue, but the
6839             // provider would have been removed.
6840             if (DBG) log("Received offer from an unregistered provider");
6841             return;
6842         }
6843         final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback);
6844         if (null != existingOffer) {
6845             handleUnregisterNetworkOffer(existingOffer);
6846             newOffer.migrateFrom(existingOffer.offer);
6847         }
6848         final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer);
6849         try {
6850             noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */);
6851         } catch (RemoteException e) {
6852             noi.binderDied();
6853             return;
6854         }
6855         mNetworkOffers.add(noi);
6856         issueNetworkNeeds(noi);
6857     }
6858 
handleUnregisterNetworkOffer(@onNull final NetworkOfferInfo noi)6859     private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) {
6860         ensureRunningOnConnectivityServiceThread();
6861         mNetworkOffers.remove(noi);
6862         noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */);
6863     }
6864 
findNetworkOfferInfoByCallback( @onNull final INetworkOfferCallback callback)6865     @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback(
6866             @NonNull final INetworkOfferCallback callback) {
6867         ensureRunningOnConnectivityServiceThread();
6868         for (final NetworkOfferInfo noi : mNetworkOffers) {
6869             if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi;
6870         }
6871         return null;
6872     }
6873 
6874     /**
6875      * Called when receiving LinkProperties directly from a NetworkAgent.
6876      * Stores into |nai| any data coming from the agent that might also be written to the network's
6877      * LinkProperties by ConnectivityService itself. This ensures that the data provided by the
6878      * agent is not lost when updateLinkProperties is called.
6879      * This method should never alter the agent's LinkProperties, only store data in |nai|.
6880      */
processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp)6881     private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
6882         lp.ensureDirectlyConnectedRoutes();
6883         nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
6884         nai.networkAgentPortalData = lp.getCaptivePortalData();
6885     }
6886 
updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp, @NonNull LinkProperties oldLp)6887     private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp,
6888             @NonNull LinkProperties oldLp) {
6889         int netId = networkAgent.network.getNetId();
6890 
6891         // The NetworkAgent does not know whether clatd is running on its network or not, or whether
6892         // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure
6893         // the LinkProperties for the network are accurate.
6894         networkAgent.clatd.fixupLinkProperties(oldLp, newLp);
6895 
6896         updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities);
6897 
6898         // update filtering rules, need to happen after the interface update so netd knows about the
6899         // new interface (the interface name -> index map becomes initialized)
6900         updateVpnFiltering(newLp, oldLp, networkAgent);
6901 
6902         updateMtu(newLp, oldLp);
6903         // TODO - figure out what to do for clat
6904 //        for (LinkProperties lp : newLp.getStackedLinks()) {
6905 //            updateMtu(lp, null);
6906 //        }
6907         if (isDefaultNetwork(networkAgent)) {
6908             updateTcpBufferSizes(newLp.getTcpBufferSizes());
6909         }
6910 
6911         updateRoutes(newLp, oldLp, netId);
6912         updateDnses(newLp, oldLp, netId);
6913         // Make sure LinkProperties represents the latest private DNS status.
6914         // This does not need to be done before updateDnses because the
6915         // LinkProperties are not the source of the private DNS configuration.
6916         // updateDnses will fetch the private DNS configuration from DnsManager.
6917         mDnsManager.updatePrivateDnsStatus(netId, newLp);
6918 
6919         if (isDefaultNetwork(networkAgent)) {
6920             handleApplyDefaultProxy(newLp.getHttpProxy());
6921         } else {
6922             updateProxy(newLp, oldLp);
6923         }
6924 
6925         updateWakeOnLan(newLp);
6926 
6927         // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo.
6928         // It is not always contained in the LinkProperties sent from NetworkAgents, and if it
6929         // does, it needs to be merged here.
6930         newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData,
6931                 networkAgent.capportApiData));
6932 
6933         // TODO - move this check to cover the whole function
6934         if (!Objects.equals(newLp, oldLp)) {
6935             synchronized (networkAgent) {
6936                 networkAgent.linkProperties = newLp;
6937             }
6938             // Start or stop DNS64 detection and 464xlat according to network state.
6939             networkAgent.clatd.update();
6940             notifyIfacesChangedForNetworkStats();
6941             networkAgent.networkMonitor().notifyLinkPropertiesChanged(
6942                     new LinkProperties(newLp, true /* parcelSensitiveFields */));
6943             if (networkAgent.everConnected) {
6944                 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
6945             }
6946         }
6947 
6948         mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
6949     }
6950 
6951     /**
6952      * @param naData captive portal data from NetworkAgent
6953      * @param apiData captive portal data from capport API
6954      */
6955     @Nullable
mergeCaptivePortalData(CaptivePortalData naData, CaptivePortalData apiData)6956     private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData,
6957             CaptivePortalData apiData) {
6958         if (naData == null || apiData == null) {
6959             return naData == null ? apiData : naData;
6960         }
6961         final CaptivePortalData.Builder captivePortalBuilder =
6962                 new CaptivePortalData.Builder(naData);
6963 
6964         if (apiData.isCaptive()) {
6965             captivePortalBuilder.setCaptive(true);
6966         }
6967         if (apiData.isSessionExtendable()) {
6968             captivePortalBuilder.setSessionExtendable(true);
6969         }
6970         if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) {
6971             // Expiry time, bytes remaining, refresh time all need to come from the same source,
6972             // otherwise data would be inconsistent. Prefer the capport API info if present,
6973             // as it can generally be refreshed more often.
6974             captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis());
6975             captivePortalBuilder.setBytesRemaining(apiData.getByteLimit());
6976             captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis());
6977         } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) {
6978             // No source has time / bytes remaining information: surface the newest refresh time
6979             // for other fields
6980             captivePortalBuilder.setRefreshTime(
6981                     Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis()));
6982         }
6983 
6984         // Prioritize the user portal URL from the network agent if the source is authenticated.
6985         if (apiData.getUserPortalUrl() != null && naData.getUserPortalUrlSource()
6986                 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) {
6987             captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl(),
6988                     apiData.getUserPortalUrlSource());
6989         }
6990         // Prioritize the venue information URL from the network agent if the source is
6991         // authenticated.
6992         if (apiData.getVenueInfoUrl() != null && naData.getVenueInfoUrlSource()
6993                 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) {
6994             captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl(),
6995                     apiData.getVenueInfoUrlSource());
6996         }
6997         return captivePortalBuilder.build();
6998     }
6999 
wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add)7000     private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) {
7001         // Marks are only available on WiFi interfaces. Checking for
7002         // marks on unsupported interfaces is harmless.
7003         if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
7004             return;
7005         }
7006 
7007         int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark);
7008         int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask);
7009 
7010         // Mask/mark of zero will not detect anything interesting.
7011         // Don't install rules unless both values are nonzero.
7012         if (mark == 0 || mask == 0) {
7013             return;
7014         }
7015 
7016         final String prefix = "iface:" + iface;
7017         try {
7018             if (add) {
7019                 mNetd.wakeupAddInterface(iface, prefix, mark, mask);
7020             } else {
7021                 mNetd.wakeupDelInterface(iface, prefix, mark, mask);
7022             }
7023         } catch (Exception e) {
7024             loge("Exception modifying wakeup packet monitoring: " + e);
7025         }
7026 
7027     }
7028 
updateInterfaces(final @Nullable LinkProperties newLp, final @Nullable LinkProperties oldLp, final int netId, final @NonNull NetworkCapabilities caps)7029     private void updateInterfaces(final @Nullable LinkProperties newLp,
7030             final @Nullable LinkProperties oldLp, final int netId,
7031             final @NonNull NetworkCapabilities caps) {
7032         final CompareResult<String> interfaceDiff = new CompareResult<>(
7033                 oldLp != null ? oldLp.getAllInterfaceNames() : null,
7034                 newLp != null ? newLp.getAllInterfaceNames() : null);
7035         if (!interfaceDiff.added.isEmpty()) {
7036             for (final String iface : interfaceDiff.added) {
7037                 try {
7038                     if (DBG) log("Adding iface " + iface + " to network " + netId);
7039                     mNetd.networkAddInterface(netId, iface);
7040                     wakeupModifyInterface(iface, caps, true);
7041                     mDeps.reportNetworkInterfaceForTransports(mContext, iface,
7042                             caps.getTransportTypes());
7043                 } catch (Exception e) {
7044                     logw("Exception adding interface: " + e);
7045                 }
7046             }
7047         }
7048         for (final String iface : interfaceDiff.removed) {
7049             try {
7050                 if (DBG) log("Removing iface " + iface + " from network " + netId);
7051                 wakeupModifyInterface(iface, caps, false);
7052                 mNetd.networkRemoveInterface(netId, iface);
7053             } catch (Exception e) {
7054                 loge("Exception removing interface: " + e);
7055             }
7056         }
7057     }
7058 
7059     // TODO: move to frameworks/libs/net.
convertRouteInfo(RouteInfo route)7060     private RouteInfoParcel convertRouteInfo(RouteInfo route) {
7061         final String nextHop;
7062 
7063         switch (route.getType()) {
7064             case RouteInfo.RTN_UNICAST:
7065                 if (route.hasGateway()) {
7066                     nextHop = route.getGateway().getHostAddress();
7067                 } else {
7068                     nextHop = INetd.NEXTHOP_NONE;
7069                 }
7070                 break;
7071             case RouteInfo.RTN_UNREACHABLE:
7072                 nextHop = INetd.NEXTHOP_UNREACHABLE;
7073                 break;
7074             case RouteInfo.RTN_THROW:
7075                 nextHop = INetd.NEXTHOP_THROW;
7076                 break;
7077             default:
7078                 nextHop = INetd.NEXTHOP_NONE;
7079                 break;
7080         }
7081 
7082         final RouteInfoParcel rip = new RouteInfoParcel();
7083         rip.ifName = route.getInterface();
7084         rip.destination = route.getDestination().toString();
7085         rip.nextHop = nextHop;
7086         rip.mtu = route.getMtu();
7087 
7088         return rip;
7089     }
7090 
7091     /**
7092      * Have netd update routes from oldLp to newLp.
7093      * @return true if routes changed between oldLp and newLp
7094      */
updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId)7095     private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
7096         // compare the route diff to determine which routes have been updated
7097         final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff =
7098                 new CompareOrUpdateResult<>(
7099                         oldLp != null ? oldLp.getAllRoutes() : null,
7100                         newLp != null ? newLp.getAllRoutes() : null,
7101                         (r) -> r.getRouteKey());
7102 
7103         // add routes before removing old in case it helps with continuous connectivity
7104 
7105         // do this twice, adding non-next-hop routes first, then routes they are dependent on
7106         for (RouteInfo route : routeDiff.added) {
7107             if (route.hasGateway()) continue;
7108             if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
7109             try {
7110                 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
7111             } catch (Exception e) {
7112                 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
7113                     loge("Exception in networkAddRouteParcel for non-gateway: " + e);
7114                 }
7115             }
7116         }
7117         for (RouteInfo route : routeDiff.added) {
7118             if (!route.hasGateway()) continue;
7119             if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
7120             try {
7121                 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
7122             } catch (Exception e) {
7123                 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
7124                     loge("Exception in networkAddRouteParcel for gateway: " + e);
7125                 }
7126             }
7127         }
7128 
7129         for (RouteInfo route : routeDiff.removed) {
7130             if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId);
7131             try {
7132                 mNetd.networkRemoveRouteParcel(netId, convertRouteInfo(route));
7133             } catch (Exception e) {
7134                 loge("Exception in networkRemoveRouteParcel: " + e);
7135             }
7136         }
7137 
7138         for (RouteInfo route : routeDiff.updated) {
7139             if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId);
7140             try {
7141                 mNetd.networkUpdateRouteParcel(netId, convertRouteInfo(route));
7142             } catch (Exception e) {
7143                 loge("Exception in networkUpdateRouteParcel: " + e);
7144             }
7145         }
7146         return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty()
7147                 || !routeDiff.updated.isEmpty();
7148     }
7149 
updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId)7150     private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
7151         if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
7152             return;  // no updating necessary
7153         }
7154 
7155         if (DBG) {
7156             final Collection<InetAddress> dnses = newLp.getDnsServers();
7157             log("Setting DNS servers for network " + netId + " to " + dnses);
7158         }
7159         try {
7160             mDnsManager.noteDnsServersForNetwork(netId, newLp);
7161             mDnsManager.flushVmDnsCache();
7162         } catch (Exception e) {
7163             loge("Exception in setDnsConfigurationForNetwork: " + e);
7164         }
7165     }
7166 
updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai)7167     private void updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp,
7168             NetworkAgentInfo nai) {
7169         final String oldIface = oldLp != null ? oldLp.getInterfaceName() : null;
7170         final String newIface = newLp != null ? newLp.getInterfaceName() : null;
7171         final boolean wasFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, oldLp);
7172         final boolean needsFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, newLp);
7173 
7174         if (!wasFiltering && !needsFiltering) {
7175             // Nothing to do.
7176             return;
7177         }
7178 
7179         if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) {
7180             // Nothing changed.
7181             return;
7182         }
7183 
7184         final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges();
7185         final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
7186         // TODO: this create a window of opportunity for apps to receive traffic between the time
7187         // when the old rules are removed and the time when new rules are added. To fix this,
7188         // make eBPF support two allowlisted interfaces so here new rules can be added before the
7189         // old rules are being removed.
7190         if (wasFiltering) {
7191             mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid);
7192         }
7193         if (needsFiltering) {
7194             mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid);
7195         }
7196     }
7197 
updateWakeOnLan(@onNull LinkProperties lp)7198     private void updateWakeOnLan(@NonNull LinkProperties lp) {
7199         if (mWolSupportedInterfaces == null) {
7200             mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray(
7201                     R.array.config_wakeonlan_supported_interfaces));
7202         }
7203         lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
7204     }
7205 
getNetworkPermission(NetworkCapabilities nc)7206     private int getNetworkPermission(NetworkCapabilities nc) {
7207         if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
7208             return INetd.PERMISSION_SYSTEM;
7209         }
7210         if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
7211             return INetd.PERMISSION_NETWORK;
7212         }
7213         return INetd.PERMISSION_NONE;
7214     }
7215 
updateNetworkPermissions(@onNull final NetworkAgentInfo nai, @NonNull final NetworkCapabilities newNc)7216     private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai,
7217             @NonNull final NetworkCapabilities newNc) {
7218         final int oldPermission = getNetworkPermission(nai.networkCapabilities);
7219         final int newPermission = getNetworkPermission(newNc);
7220         if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
7221             try {
7222                 mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission);
7223             } catch (RemoteException | ServiceSpecificException e) {
7224                 loge("Exception in networkSetPermissionForNetwork: " + e);
7225             }
7226         }
7227     }
7228 
7229     /**
7230      * Called when receiving NetworkCapabilities directly from a NetworkAgent.
7231      * Stores into |nai| any data coming from the agent that might also be written to the network's
7232      * NetworkCapabilities by ConnectivityService itself. This ensures that the data provided by the
7233      * agent is not lost when updateCapabilities is called.
7234      * This method should never alter the agent's NetworkCapabilities, only store data in |nai|.
7235      */
processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc)7236     private void processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc) {
7237         // Note: resetting the owner UID before storing the agent capabilities in NAI means that if
7238         // the agent attempts to change the owner UID, then nai.declaredCapabilities will not
7239         // actually be the same as the capabilities sent by the agent. Still, it is safer to reset
7240         // the owner UID here and behave as if the agent had never tried to change it.
7241         if (nai.networkCapabilities.getOwnerUid() != nc.getOwnerUid()) {
7242             Log.e(TAG, nai.toShortString() + ": ignoring attempt to change owner from "
7243                     + nai.networkCapabilities.getOwnerUid() + " to " + nc.getOwnerUid());
7244             nc.setOwnerUid(nai.networkCapabilities.getOwnerUid());
7245         }
7246         nai.declaredCapabilities = new NetworkCapabilities(nc);
7247     }
7248 
7249     /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */
7250     @VisibleForTesting
applyUnderlyingCapabilities(@ullable Network[] underlyingNetworks, @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc)7251     void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks,
7252             @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) {
7253         underlyingNetworks = underlyingNetworksOrDefault(
7254                 agentCaps.getOwnerUid(), underlyingNetworks);
7255         long transportTypes = NetworkCapabilitiesUtils.packBits(agentCaps.getTransportTypes());
7256         int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
7257         int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
7258         // metered if any underlying is metered, or originally declared metered by the agent.
7259         boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
7260         boolean roaming = false; // roaming if any underlying is roaming
7261         boolean congested = false; // congested if any underlying is congested
7262         boolean suspended = true; // suspended if all underlying are suspended
7263 
7264         boolean hadUnderlyingNetworks = false;
7265         if (null != underlyingNetworks) {
7266             for (Network underlyingNetwork : underlyingNetworks) {
7267                 final NetworkAgentInfo underlying =
7268                         getNetworkAgentInfoForNetwork(underlyingNetwork);
7269                 if (underlying == null) continue;
7270 
7271                 final NetworkCapabilities underlyingCaps = underlying.networkCapabilities;
7272                 hadUnderlyingNetworks = true;
7273                 for (int underlyingType : underlyingCaps.getTransportTypes()) {
7274                     transportTypes |= 1L << underlyingType;
7275                 }
7276 
7277                 // Merge capabilities of this underlying network. For bandwidth, assume the
7278                 // worst case.
7279                 downKbps = NetworkCapabilities.minBandwidth(downKbps,
7280                         underlyingCaps.getLinkDownstreamBandwidthKbps());
7281                 upKbps = NetworkCapabilities.minBandwidth(upKbps,
7282                         underlyingCaps.getLinkUpstreamBandwidthKbps());
7283                 // If this underlying network is metered, the VPN is metered (it may cost money
7284                 // to send packets on this network).
7285                 metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
7286                 // If this underlying network is roaming, the VPN is roaming (the billing structure
7287                 // is different than the usual, local one).
7288                 roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING);
7289                 // If this underlying network is congested, the VPN is congested (the current
7290                 // condition of the network affects the performance of this network).
7291                 congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED);
7292                 // If this network is not suspended, the VPN is not suspended (the VPN
7293                 // is able to transfer some data).
7294                 suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
7295             }
7296         }
7297         if (!hadUnderlyingNetworks) {
7298             // No idea what the underlying networks are; assume reasonable defaults
7299             metered = true;
7300             roaming = false;
7301             congested = false;
7302             suspended = false;
7303         }
7304 
7305         newNc.setTransportTypes(NetworkCapabilitiesUtils.unpackBits(transportTypes));
7306         newNc.setLinkDownstreamBandwidthKbps(downKbps);
7307         newNc.setLinkUpstreamBandwidthKbps(upKbps);
7308         newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
7309         newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming);
7310         newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested);
7311         newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended);
7312     }
7313 
7314     /**
7315      * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
7316      * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
7317      * and foreground status).
7318      */
7319     @NonNull
mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc)7320     private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
7321         // Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
7322          // Don't complain for VPNs since they're not driven by requests and there is no risk of
7323          // causing a connect/teardown loop.
7324          // TODO: remove this altogether and make it the responsibility of the NetworkProviders to
7325          // avoid connect/teardown loops.
7326         if (nai.everConnected &&
7327                 !nai.isVPN() &&
7328                 !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
7329             // TODO: consider not complaining when a network agent degrades its capabilities if this
7330             // does not cause any request (that is not a listen) currently matching that agent to
7331             // stop being matched by the updated agent.
7332             String diff = nai.networkCapabilities.describeImmutableDifferences(nc);
7333             if (!TextUtils.isEmpty(diff)) {
7334                 Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
7335             }
7336         }
7337 
7338         // Don't modify caller's NetworkCapabilities.
7339         final NetworkCapabilities newNc = new NetworkCapabilities(nc);
7340         if (nai.lastValidated) {
7341             newNc.addCapability(NET_CAPABILITY_VALIDATED);
7342         } else {
7343             newNc.removeCapability(NET_CAPABILITY_VALIDATED);
7344         }
7345         if (nai.lastCaptivePortalDetected) {
7346             newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
7347         } else {
7348             newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
7349         }
7350         if (nai.isBackgroundNetwork()) {
7351             newNc.removeCapability(NET_CAPABILITY_FOREGROUND);
7352         } else {
7353             newNc.addCapability(NET_CAPABILITY_FOREGROUND);
7354         }
7355         if (nai.partialConnectivity) {
7356             newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
7357         } else {
7358             newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
7359         }
7360         newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken());
7361 
7362         // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING
7363         if (!newNc.hasTransport(TRANSPORT_CELLULAR)) {
7364             newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
7365             newNc.addCapability(NET_CAPABILITY_NOT_ROAMING);
7366         }
7367 
7368         if (nai.propagateUnderlyingCapabilities()) {
7369             applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, nai.declaredCapabilities,
7370                     newNc);
7371         }
7372 
7373         return newNc;
7374     }
7375 
updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)7376     private void updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai,
7377             NetworkCapabilities prevNc, NetworkCapabilities newNc) {
7378         final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
7379         final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
7380         final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
7381         final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
7382         if (prevSuspended != suspended) {
7383             // TODO (b/73132094) : remove this call once the few users of onSuspended and
7384             // onResumed have been removed.
7385             notifyNetworkCallbacks(nai, suspended ? ConnectivityManager.CALLBACK_SUSPENDED
7386                     : ConnectivityManager.CALLBACK_RESUMED);
7387         }
7388         if (prevSuspended != suspended || prevRoaming != roaming) {
7389             // updateNetworkInfo will mix in the suspended info from the capabilities and
7390             // take appropriate action for the network having possibly changed state.
7391             updateNetworkInfo(nai, nai.networkInfo);
7392         }
7393     }
7394 
7395     /**
7396      * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically:
7397      *
7398      * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the
7399      *    capabilities we manage and store in {@code nai}, such as validated status and captive
7400      *    portal status)
7401      * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and
7402      *    potentially triggers rematches.
7403      * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the
7404      *    change.)
7405      *
7406      * @param oldScore score of the network before any of the changes that prompted us
7407      *                 to call this function.
7408      * @param nai the network having its capabilities updated.
7409      * @param nc the new network capabilities.
7410      */
updateCapabilities(final int oldScore, @NonNull final NetworkAgentInfo nai, @NonNull final NetworkCapabilities nc)7411     private void updateCapabilities(final int oldScore, @NonNull final NetworkAgentInfo nai,
7412             @NonNull final NetworkCapabilities nc) {
7413         NetworkCapabilities newNc = mixInCapabilities(nai, nc);
7414         if (Objects.equals(nai.networkCapabilities, newNc)) return;
7415         updateNetworkPermissions(nai, newNc);
7416         final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
7417 
7418         updateUids(nai, prevNc, newNc);
7419         nai.updateScoreForNetworkAgentUpdate();
7420 
7421         if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) {
7422             // If the requestable capabilities haven't changed, and the score hasn't changed, then
7423             // the change we're processing can't affect any requests, it can only affect the listens
7424             // on this network. We might have been called by rematchNetworkAndRequests when a
7425             // network changed foreground state.
7426             processListenRequests(nai);
7427         } else {
7428             // If the requestable capabilities have changed or the score changed, we can't have been
7429             // called by rematchNetworkAndRequests, so it's safe to start a rematch.
7430             rematchAllNetworksAndRequests();
7431             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
7432         }
7433         updateNetworkInfoForRoamingAndSuspended(nai, prevNc, newNc);
7434 
7435         final boolean oldMetered = prevNc.isMetered();
7436         final boolean newMetered = newNc.isMetered();
7437         final boolean meteredChanged = oldMetered != newMetered;
7438 
7439         if (meteredChanged) {
7440             maybeNotifyNetworkBlocked(nai, oldMetered, newMetered,
7441                     mVpnBlockedUidRanges, mVpnBlockedUidRanges);
7442         }
7443 
7444         final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING)
7445                 != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
7446 
7447         // Report changes that are interesting for network statistics tracking.
7448         if (meteredChanged || roamingChanged) {
7449             notifyIfacesChangedForNetworkStats();
7450         }
7451 
7452         // This network might have been underlying another network. Propagate its capabilities.
7453         propagateUnderlyingNetworkCapabilities(nai.network);
7454 
7455         if (!newNc.equalsTransportTypes(prevNc)) {
7456             mDnsManager.updateTransportsForNetwork(
7457                     nai.network.getNetId(), newNc.getTransportTypes());
7458         }
7459 
7460         maybeSendProxyBroadcast(nai, prevNc, newNc);
7461     }
7462 
7463     /** Convenience method to update the capabilities for a given network. */
updateCapabilitiesForNetwork(NetworkAgentInfo nai)7464     private void updateCapabilitiesForNetwork(NetworkAgentInfo nai) {
7465         updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
7466     }
7467 
7468     /**
7469      * Returns whether VPN isolation (ingress interface filtering) should be applied on the given
7470      * network.
7471      *
7472      * Ingress interface filtering enforces that all apps under the given network can only receive
7473      * packets from the network's interface (and loopback). This is important for VPNs because
7474      * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any
7475      * non-VPN interfaces.
7476      *
7477      * As a result, this method should return true iff
7478      *  1. the network is an app VPN (not legacy VPN)
7479      *  2. the VPN does not allow bypass
7480      *  3. the VPN is fully-routed
7481      *  4. the VPN interface is non-null
7482      *
7483      * @see INetd#firewallAddUidInterfaceRules
7484      * @see INetd#firewallRemoveUidInterfaceRules
7485      */
requiresVpnIsolation(@onNull NetworkAgentInfo nai, NetworkCapabilities nc, LinkProperties lp)7486     private boolean requiresVpnIsolation(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc,
7487             LinkProperties lp) {
7488         if (nc == null || lp == null) return false;
7489         return nai.isVPN()
7490                 && !nai.networkAgentConfig.allowBypass
7491                 && nc.getOwnerUid() != Process.SYSTEM_UID
7492                 && lp.getInterfaceName() != null
7493                 && (lp.hasIpv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute())
7494                 && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute());
7495     }
7496 
toUidRangeStableParcels(final @NonNull Set<UidRange> ranges)7497     private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) {
7498         final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()];
7499         int index = 0;
7500         for (UidRange range : ranges) {
7501             stableRanges[index] = new UidRangeParcel(range.start, range.stop);
7502             index++;
7503         }
7504         return stableRanges;
7505     }
7506 
toUidRangeStableParcels(UidRange[] ranges)7507     private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) {
7508         final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
7509         for (int i = 0; i < ranges.length; i++) {
7510             stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop);
7511         }
7512         return stableRanges;
7513     }
7514 
maybeCloseSockets(NetworkAgentInfo nai, UidRangeParcel[] ranges, int[] exemptUids)7515     private void maybeCloseSockets(NetworkAgentInfo nai, UidRangeParcel[] ranges,
7516             int[] exemptUids) {
7517         if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) {
7518             try {
7519                 mNetd.socketDestroy(ranges, exemptUids);
7520             } catch (Exception e) {
7521                 loge("Exception in socket destroy: ", e);
7522             }
7523         }
7524     }
7525 
updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges)7526     private void updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) {
7527         int[] exemptUids = new int[2];
7528         // TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used
7529         // by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when
7530         // starting a legacy VPN, and remove VPN_UID here. (b/176542831)
7531         exemptUids[0] = VPN_UID;
7532         exemptUids[1] = nai.networkCapabilities.getOwnerUid();
7533         UidRangeParcel[] ranges = toUidRangeStableParcels(uidRanges);
7534 
7535         maybeCloseSockets(nai, ranges, exemptUids);
7536         try {
7537             if (add) {
7538                 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
7539                         nai.network.netId, ranges, PREFERENCE_PRIORITY_VPN));
7540             } else {
7541                 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
7542                         nai.network.netId, ranges, PREFERENCE_PRIORITY_VPN));
7543             }
7544         } catch (Exception e) {
7545             loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges +
7546                     " on netId " + nai.network.netId + ". " + e);
7547         }
7548         maybeCloseSockets(nai, ranges, exemptUids);
7549     }
7550 
isProxySetOnAnyDefaultNetwork()7551     private boolean isProxySetOnAnyDefaultNetwork() {
7552         ensureRunningOnConnectivityServiceThread();
7553         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
7554             final NetworkAgentInfo nai = nri.getSatisfier();
7555             if (nai != null && nai.linkProperties.getHttpProxy() != null) {
7556                 return true;
7557             }
7558         }
7559         return false;
7560     }
7561 
maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)7562     private void maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc,
7563             NetworkCapabilities newNc) {
7564         // When the apps moved from/to a VPN, a proxy broadcast is needed to inform the apps that
7565         // the proxy might be changed since the default network satisfied by the apps might also
7566         // changed.
7567         // TODO: Try to track the default network that apps use and only send a proxy broadcast when
7568         //  that happens to prevent false alarms.
7569         if (nai.isVPN() && nai.everConnected && !NetworkCapabilities.hasSameUids(prevNc, newNc)
7570                 && (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) {
7571             mProxyTracker.sendProxyBroadcast();
7572         }
7573     }
7574 
updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)7575     private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
7576             NetworkCapabilities newNc) {
7577         Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges();
7578         Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges();
7579         if (null == prevRanges) prevRanges = new ArraySet<>();
7580         if (null == newRanges) newRanges = new ArraySet<>();
7581         final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
7582 
7583         prevRanges.removeAll(newRanges);
7584         newRanges.removeAll(prevRangesCopy);
7585 
7586         try {
7587             // When updating the VPN uid routing rules, add the new range first then remove the old
7588             // range. If old range were removed first, there would be a window between the old
7589             // range being removed and the new range being added, during which UIDs contained
7590             // in both ranges are not subject to any VPN routing rules. Adding new range before
7591             // removing old range works because, unlike the filtering rules below, it's possible to
7592             // add duplicate UID routing rules.
7593             // TODO: calculate the intersection of add & remove. Imagining that we are trying to
7594             // remove uid 3 from a set containing 1-5. Intersection of the prev and new sets is:
7595             //   [1-5] & [1-2],[4-5] == [3]
7596             // Then we can do:
7597             //   maybeCloseSockets([3])
7598             //   mNetd.networkAddUidRanges([1-2],[4-5])
7599             //   mNetd.networkRemoveUidRanges([1-5])
7600             //   maybeCloseSockets([3])
7601             // This can prevent the sockets of uid 1-2, 4-5 from being closed. It also reduce the
7602             // number of binder calls from 6 to 4.
7603             if (!newRanges.isEmpty()) {
7604                 updateVpnUidRanges(true, nai, newRanges);
7605             }
7606             if (!prevRanges.isEmpty()) {
7607                 updateVpnUidRanges(false, nai, prevRanges);
7608             }
7609             final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties);
7610             final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties);
7611             final String iface = nai.linkProperties.getInterfaceName();
7612             // For VPN uid interface filtering, old ranges need to be removed before new ranges can
7613             // be added, due to the range being expanded and stored as individual UIDs. For example
7614             // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means
7615             // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges
7616             // were added first and then newRanges got removed later, there would be only one uid
7617             // 10013 left. A consequence of removing old ranges before adding new ranges is that
7618             // there is now a window of opportunity when the UIDs are not subject to any filtering.
7619             // Note that this is in contrast with the (more robust) update of VPN routing rules
7620             // above, where the addition of new ranges happens before the removal of old ranges.
7621             // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
7622             // to be removed will never overlap with the new range to be added.
7623             if (wasFiltering && !prevRanges.isEmpty()) {
7624                 mPermissionMonitor.onVpnUidRangesRemoved(iface, prevRanges, prevNc.getOwnerUid());
7625             }
7626             if (shouldFilter && !newRanges.isEmpty()) {
7627                 mPermissionMonitor.onVpnUidRangesAdded(iface, newRanges, newNc.getOwnerUid());
7628             }
7629         } catch (Exception e) {
7630             // Never crash!
7631             loge("Exception in updateUids: ", e);
7632         }
7633     }
7634 
handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp)7635     public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
7636         ensureRunningOnConnectivityServiceThread();
7637 
7638         if (!mNetworkAgentInfos.contains(nai)) {
7639             // Ignore updates for disconnected networks
7640             return;
7641         }
7642         if (VDBG || DDBG) {
7643             log("Update of LinkProperties for " + nai.toShortString()
7644                     + "; created=" + nai.created
7645                     + "; everConnected=" + nai.everConnected);
7646         }
7647         // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
7648         // modify its oldLp parameter.
7649         updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties));
7650     }
7651 
sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType)7652     private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
7653             int notificationType) {
7654         if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
7655             Intent intent = new Intent();
7656             intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network);
7657             // If apps could file multi-layer requests with PendingIntents, they'd need to know
7658             // which of the layer is satisfied alongside with some ID for the request. Hence, if
7659             // such an API is ever implemented, there is no doubt the right request to send in
7660             // EXTRA_NETWORK_REQUEST is the active request, and whatever ID would be added would
7661             // need to be sent as a separate extra.
7662             final NetworkRequest req = nri.isMultilayerRequest()
7663                     ? nri.getActiveRequest()
7664                     // Non-multilayer listen requests do not have an active request
7665                     : nri.mRequests.get(0);
7666             if (req == null) {
7667                 Log.wtf(TAG, "No request in NRI " + nri);
7668             }
7669             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, req);
7670             nri.mPendingIntentSent = true;
7671             sendIntent(nri.mPendingIntent, intent);
7672         }
7673         // else not handled
7674     }
7675 
sendIntent(PendingIntent pendingIntent, Intent intent)7676     private void sendIntent(PendingIntent pendingIntent, Intent intent) {
7677         mPendingIntentWakeLock.acquire();
7678         try {
7679             if (DBG) log("Sending " + pendingIntent);
7680             pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */);
7681         } catch (PendingIntent.CanceledException e) {
7682             if (DBG) log(pendingIntent + " was not sent, it had been canceled.");
7683             mPendingIntentWakeLock.release();
7684             releasePendingNetworkRequest(pendingIntent);
7685         }
7686         // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished()
7687     }
7688 
7689     @Override
onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)7690     public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
7691             String resultData, Bundle resultExtras) {
7692         if (DBG) log("Finished sending " + pendingIntent);
7693         mPendingIntentWakeLock.release();
7694         // Release with a delay so the receiving client has an opportunity to put in its
7695         // own request.
7696         releasePendingNetworkRequestWithDelay(pendingIntent);
7697     }
7698 
callCallbackForRequest(@onNull final NetworkRequestInfo nri, @NonNull final NetworkAgentInfo networkAgent, final int notificationType, final int arg1)7699     private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri,
7700             @NonNull final NetworkAgentInfo networkAgent, final int notificationType,
7701             final int arg1) {
7702         if (nri.mMessenger == null) {
7703             // Default request has no msgr. Also prevents callbacks from being invoked for
7704             // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks
7705             // are Type.LISTEN, but should not have NetworkCallbacks invoked.
7706             return;
7707         }
7708         Bundle bundle = new Bundle();
7709         // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects.
7710         // TODO: check if defensive copies of data is needed.
7711         final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback();
7712         putParcelable(bundle, nrForCallback);
7713         Message msg = Message.obtain();
7714         if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
7715             putParcelable(bundle, networkAgent.network);
7716         }
7717         final boolean includeLocationSensitiveInfo =
7718                 (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0;
7719         switch (notificationType) {
7720             case ConnectivityManager.CALLBACK_AVAILABLE: {
7721                 final NetworkCapabilities nc =
7722                         networkCapabilitiesRestrictedForCallerPermissions(
7723                                 networkAgent.networkCapabilities, nri.mPid, nri.mUid);
7724                 putParcelable(
7725                         bundle,
7726                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
7727                                 nc, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
7728                                 nrForCallback.getRequestorPackageName(),
7729                                 nri.mCallingAttributionTag));
7730                 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
7731                         networkAgent.linkProperties, nri.mPid, nri.mUid));
7732                 // For this notification, arg1 contains the blocked status.
7733                 msg.arg1 = arg1;
7734                 break;
7735             }
7736             case ConnectivityManager.CALLBACK_LOSING: {
7737                 msg.arg1 = arg1;
7738                 break;
7739             }
7740             case ConnectivityManager.CALLBACK_CAP_CHANGED: {
7741                 // networkAgent can't be null as it has been accessed a few lines above.
7742                 final NetworkCapabilities netCap =
7743                         networkCapabilitiesRestrictedForCallerPermissions(
7744                                 networkAgent.networkCapabilities, nri.mPid, nri.mUid);
7745                 putParcelable(
7746                         bundle,
7747                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
7748                                 netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
7749                                 nrForCallback.getRequestorPackageName(),
7750                                 nri.mCallingAttributionTag));
7751                 break;
7752             }
7753             case ConnectivityManager.CALLBACK_IP_CHANGED: {
7754                 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
7755                         networkAgent.linkProperties, nri.mPid, nri.mUid));
7756                 break;
7757             }
7758             case ConnectivityManager.CALLBACK_BLK_CHANGED: {
7759                 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1);
7760                 msg.arg1 = arg1;
7761                 break;
7762             }
7763         }
7764         msg.what = notificationType;
7765         msg.setData(bundle);
7766         try {
7767             if (VDBG) {
7768                 String notification = ConnectivityManager.getCallbackName(notificationType);
7769                 log("sending notification " + notification + " for " + nrForCallback);
7770             }
7771             nri.mMessenger.send(msg);
7772         } catch (RemoteException e) {
7773             // may occur naturally in the race of binder death.
7774             loge("RemoteException caught trying to send a callback msg for " + nrForCallback);
7775         }
7776     }
7777 
putParcelable(Bundle bundle, T t)7778     private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) {
7779         bundle.putParcelable(t.getClass().getSimpleName(), t);
7780     }
7781 
teardownUnneededNetwork(NetworkAgentInfo nai)7782     private void teardownUnneededNetwork(NetworkAgentInfo nai) {
7783         if (nai.numRequestNetworkRequests() != 0) {
7784             for (int i = 0; i < nai.numNetworkRequests(); i++) {
7785                 NetworkRequest nr = nai.requestAt(i);
7786                 // Ignore listening and track default requests.
7787                 if (!nr.isRequest()) continue;
7788                 loge("Dead network still had at least " + nr);
7789                 break;
7790             }
7791         }
7792         nai.disconnect();
7793     }
7794 
handleLingerComplete(NetworkAgentInfo oldNetwork)7795     private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
7796         if (oldNetwork == null) {
7797             loge("Unknown NetworkAgentInfo in handleLingerComplete");
7798             return;
7799         }
7800         if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString());
7801 
7802         // If we get here it means that the last linger timeout for this network expired. So there
7803         // must be no other active linger timers, and we must stop lingering.
7804         oldNetwork.clearInactivityState();
7805 
7806         if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
7807             // Tear the network down.
7808             teardownUnneededNetwork(oldNetwork);
7809         } else {
7810             // Put the network in the background if it doesn't satisfy any foreground request.
7811             updateCapabilitiesForNetwork(oldNetwork);
7812         }
7813     }
7814 
processDefaultNetworkChanges(@onNull final NetworkReassignment changes)7815     private void processDefaultNetworkChanges(@NonNull final NetworkReassignment changes) {
7816         boolean isDefaultChanged = false;
7817         for (final NetworkRequestInfo defaultRequestInfo : mDefaultNetworkRequests) {
7818             final NetworkReassignment.RequestReassignment reassignment =
7819                     changes.getReassignment(defaultRequestInfo);
7820             if (null == reassignment) {
7821                 continue;
7822             }
7823             // reassignment only contains those instances where the satisfying network changed.
7824             isDefaultChanged = true;
7825             // Notify system services of the new default.
7826             makeDefault(defaultRequestInfo, reassignment.mOldNetwork, reassignment.mNewNetwork);
7827         }
7828 
7829         if (isDefaultChanged) {
7830             // Hold a wakelock for a short time to help apps in migrating to a new default.
7831             scheduleReleaseNetworkTransitionWakelock();
7832         }
7833     }
7834 
makeDefault(@onNull final NetworkRequestInfo nri, @Nullable final NetworkAgentInfo oldDefaultNetwork, @Nullable final NetworkAgentInfo newDefaultNetwork)7835     private void makeDefault(@NonNull final NetworkRequestInfo nri,
7836             @Nullable final NetworkAgentInfo oldDefaultNetwork,
7837             @Nullable final NetworkAgentInfo newDefaultNetwork) {
7838         if (DBG) {
7839             log("Switching to new default network for: " + nri + " using " + newDefaultNetwork);
7840         }
7841 
7842         // Fix up the NetworkCapabilities of any networks that have this network as underlying.
7843         if (newDefaultNetwork != null) {
7844             propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network);
7845         }
7846 
7847         // Set an app level managed default and return since further processing only applies to the
7848         // default network.
7849         if (mDefaultRequest != nri) {
7850             makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork);
7851             return;
7852         }
7853 
7854         makeDefaultNetwork(newDefaultNetwork);
7855 
7856         if (oldDefaultNetwork != null) {
7857             mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork);
7858         }
7859         mNetworkActivityTracker.updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork);
7860         handleApplyDefaultProxy(null != newDefaultNetwork
7861                 ? newDefaultNetwork.linkProperties.getHttpProxy() : null);
7862         updateTcpBufferSizes(null != newDefaultNetwork
7863                 ? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null);
7864         notifyIfacesChangedForNetworkStats();
7865     }
7866 
makeDefaultForApps(@onNull final NetworkRequestInfo nri, @Nullable final NetworkAgentInfo oldDefaultNetwork, @Nullable final NetworkAgentInfo newDefaultNetwork)7867     private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri,
7868             @Nullable final NetworkAgentInfo oldDefaultNetwork,
7869             @Nullable final NetworkAgentInfo newDefaultNetwork) {
7870         try {
7871             if (VDBG) {
7872                 log("Setting default network for " + nri
7873                         + " using UIDs " + nri.getUids()
7874                         + " with old network " + (oldDefaultNetwork != null
7875                         ? oldDefaultNetwork.network().getNetId() : "null")
7876                         + " and new network " + (newDefaultNetwork != null
7877                         ? newDefaultNetwork.network().getNetId() : "null"));
7878             }
7879             if (nri.getUids().isEmpty()) {
7880                 throw new IllegalStateException("makeDefaultForApps called without specifying"
7881                         + " any applications to set as the default." + nri);
7882             }
7883             if (null != newDefaultNetwork) {
7884                 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
7885                         newDefaultNetwork.network.getNetId(),
7886                         toUidRangeStableParcels(nri.getUids()),
7887                         nri.getPriorityForNetd()));
7888             }
7889             if (null != oldDefaultNetwork) {
7890                 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
7891                         oldDefaultNetwork.network.getNetId(),
7892                         toUidRangeStableParcels(nri.getUids()),
7893                         nri.getPriorityForNetd()));
7894             }
7895         } catch (RemoteException | ServiceSpecificException e) {
7896             loge("Exception setting app default network", e);
7897         }
7898     }
7899 
makeDefaultNetwork(@ullable final NetworkAgentInfo newDefaultNetwork)7900     private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) {
7901         try {
7902             if (null != newDefaultNetwork) {
7903                 mNetd.networkSetDefault(newDefaultNetwork.network.getNetId());
7904             } else {
7905                 mNetd.networkClearDefault();
7906             }
7907         } catch (RemoteException | ServiceSpecificException e) {
7908             loge("Exception setting default network :" + e);
7909         }
7910     }
7911 
processListenRequests(@onNull final NetworkAgentInfo nai)7912     private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
7913         // For consistency with previous behaviour, send onLost callbacks before onAvailable.
7914         processNewlyLostListenRequests(nai);
7915         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
7916         processNewlySatisfiedListenRequests(nai);
7917     }
7918 
processNewlyLostListenRequests(@onNull final NetworkAgentInfo nai)7919     private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) {
7920         for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
7921             if (nri.isMultilayerRequest()) {
7922                 continue;
7923             }
7924             final NetworkRequest nr = nri.mRequests.get(0);
7925             if (!nr.isListen()) continue;
7926             if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) {
7927                 nai.removeRequest(nr.requestId);
7928                 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0);
7929             }
7930         }
7931     }
7932 
processNewlySatisfiedListenRequests(@onNull final NetworkAgentInfo nai)7933     private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) {
7934         for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
7935             if (nri.isMultilayerRequest()) {
7936                 continue;
7937             }
7938             final NetworkRequest nr = nri.mRequests.get(0);
7939             if (!nr.isListen()) continue;
7940             if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) {
7941                 nai.addRequest(nr);
7942                 notifyNetworkAvailable(nai, nri);
7943             }
7944         }
7945     }
7946 
7947     // An accumulator class to gather the list of changes that result from a rematch.
7948     private static class NetworkReassignment {
7949         static class RequestReassignment {
7950             @NonNull public final NetworkRequestInfo mNetworkRequestInfo;
7951             @Nullable public final NetworkRequest mOldNetworkRequest;
7952             @Nullable public final NetworkRequest mNewNetworkRequest;
7953             @Nullable public final NetworkAgentInfo mOldNetwork;
7954             @Nullable public final NetworkAgentInfo mNewNetwork;
RequestReassignment(@onNull final NetworkRequestInfo networkRequestInfo, @Nullable final NetworkRequest oldNetworkRequest, @Nullable final NetworkRequest newNetworkRequest, @Nullable final NetworkAgentInfo oldNetwork, @Nullable final NetworkAgentInfo newNetwork)7955             RequestReassignment(@NonNull final NetworkRequestInfo networkRequestInfo,
7956                     @Nullable final NetworkRequest oldNetworkRequest,
7957                     @Nullable final NetworkRequest newNetworkRequest,
7958                     @Nullable final NetworkAgentInfo oldNetwork,
7959                     @Nullable final NetworkAgentInfo newNetwork) {
7960                 mNetworkRequestInfo = networkRequestInfo;
7961                 mOldNetworkRequest = oldNetworkRequest;
7962                 mNewNetworkRequest = newNetworkRequest;
7963                 mOldNetwork = oldNetwork;
7964                 mNewNetwork = newNetwork;
7965             }
7966 
toString()7967             public String toString() {
7968                 final NetworkRequest requestToShow = null != mNewNetworkRequest
7969                         ? mNewNetworkRequest : mNetworkRequestInfo.mRequests.get(0);
7970                 return requestToShow.requestId + " : "
7971                         + (null != mOldNetwork ? mOldNetwork.network.getNetId() : "null")
7972                         + " → " + (null != mNewNetwork ? mNewNetwork.network.getNetId() : "null");
7973             }
7974         }
7975 
7976         @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>();
7977 
getRequestReassignments()7978         @NonNull Iterable<RequestReassignment> getRequestReassignments() {
7979             return mReassignments;
7980         }
7981 
addRequestReassignment(@onNull final RequestReassignment reassignment)7982         void addRequestReassignment(@NonNull final RequestReassignment reassignment) {
7983             if (Build.isDebuggable()) {
7984                 // The code is never supposed to add two reassignments of the same request. Make
7985                 // sure this stays true, but without imposing this expensive check on all
7986                 // reassignments on all user devices.
7987                 for (final RequestReassignment existing : mReassignments) {
7988                     if (existing.mNetworkRequestInfo.equals(reassignment.mNetworkRequestInfo)) {
7989                         throw new IllegalStateException("Trying to reassign ["
7990                                 + reassignment + "] but already have ["
7991                                 + existing + "]");
7992                     }
7993                 }
7994             }
7995             mReassignments.add(reassignment);
7996         }
7997 
7998         // Will return null if this reassignment does not change the network assigned to
7999         // the passed request.
8000         @Nullable
getReassignment(@onNull final NetworkRequestInfo nri)8001         private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) {
8002             for (final RequestReassignment event : getRequestReassignments()) {
8003                 if (nri == event.mNetworkRequestInfo) return event;
8004             }
8005             return null;
8006         }
8007 
toString()8008         public String toString() {
8009             final StringJoiner sj = new StringJoiner(", " /* delimiter */,
8010                     "NetReassign [" /* prefix */, "]" /* suffix */);
8011             if (mReassignments.isEmpty()) return sj.add("no changes").toString();
8012             for (final RequestReassignment rr : getRequestReassignments()) {
8013                 sj.add(rr.toString());
8014             }
8015             return sj.toString();
8016         }
8017 
debugString()8018         public String debugString() {
8019             final StringBuilder sb = new StringBuilder();
8020             sb.append("NetworkReassignment :");
8021             if (mReassignments.isEmpty()) return sb.append(" no changes").toString();
8022             for (final RequestReassignment rr : getRequestReassignments()) {
8023                 sb.append("\n  ").append(rr);
8024             }
8025             return sb.append("\n").toString();
8026         }
8027     }
8028 
updateSatisfiersForRematchRequest(@onNull final NetworkRequestInfo nri, @Nullable final NetworkRequest previousRequest, @Nullable final NetworkRequest newRequest, @Nullable final NetworkAgentInfo previousSatisfier, @Nullable final NetworkAgentInfo newSatisfier, final long now)8029     private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri,
8030             @Nullable final NetworkRequest previousRequest,
8031             @Nullable final NetworkRequest newRequest,
8032             @Nullable final NetworkAgentInfo previousSatisfier,
8033             @Nullable final NetworkAgentInfo newSatisfier,
8034             final long now) {
8035         if (null != newSatisfier && mNoServiceNetwork != newSatisfier) {
8036             if (VDBG) log("rematch for " + newSatisfier.toShortString());
8037             if (null != previousRequest && null != previousSatisfier) {
8038                 if (VDBG || DDBG) {
8039                     log("   accepting network in place of " + previousSatisfier.toShortString());
8040                 }
8041                 previousSatisfier.removeRequest(previousRequest.requestId);
8042                 previousSatisfier.lingerRequest(previousRequest.requestId, now);
8043             } else {
8044                 if (VDBG || DDBG) log("   accepting network in place of null");
8045             }
8046 
8047             // To prevent constantly CPU wake up for nascent timer, if a network comes up
8048             // and immediately satisfies a request then remove the timer. This will happen for
8049             // all networks except in the case of an underlying network for a VCN.
8050             if (newSatisfier.isNascent()) {
8051                 newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE);
8052                 newSatisfier.unsetInactive();
8053             }
8054 
8055             // if newSatisfier is not null, then newRequest may not be null.
8056             newSatisfier.unlingerRequest(newRequest.requestId);
8057             if (!newSatisfier.addRequest(newRequest)) {
8058                 Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has "
8059                         + newRequest);
8060             }
8061         } else if (null != previousRequest && null != previousSatisfier) {
8062             if (DBG) {
8063                 log("Network " + previousSatisfier.toShortString() + " stopped satisfying"
8064                         + " request " + previousRequest.requestId);
8065             }
8066             previousSatisfier.removeRequest(previousRequest.requestId);
8067         }
8068         nri.setSatisfier(newSatisfier, newRequest);
8069     }
8070 
8071     /**
8072      * This function is triggered when something can affect what network should satisfy what
8073      * request, and it computes the network reassignment from the passed collection of requests to
8074      * network match to the one that the system should now have. That data is encoded in an
8075      * object that is a list of changes, each of them having an NRI, and old satisfier, and a new
8076      * satisfier.
8077      *
8078      * After the reassignment is computed, it is applied to the state objects.
8079      *
8080      * @param networkRequests the nri objects to evaluate for possible network reassignment
8081      * @return NetworkReassignment listing of proposed network assignment changes
8082      */
8083     @NonNull
computeNetworkReassignment( @onNull final Collection<NetworkRequestInfo> networkRequests)8084     private NetworkReassignment computeNetworkReassignment(
8085             @NonNull final Collection<NetworkRequestInfo> networkRequests) {
8086         final NetworkReassignment changes = new NetworkReassignment();
8087 
8088         // Gather the list of all relevant agents.
8089         final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
8090         for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
8091             if (!nai.everConnected) {
8092                 continue;
8093             }
8094             nais.add(nai);
8095         }
8096 
8097         for (final NetworkRequestInfo nri : networkRequests) {
8098             // Non-multilayer listen requests can be ignored.
8099             if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) {
8100                 continue;
8101             }
8102             NetworkAgentInfo bestNetwork = null;
8103             NetworkRequest bestRequest = null;
8104             for (final NetworkRequest req : nri.mRequests) {
8105                 bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier());
8106                 // Stop evaluating as the highest possible priority request is satisfied.
8107                 if (null != bestNetwork) {
8108                     bestRequest = req;
8109                     break;
8110                 }
8111             }
8112             if (null == bestNetwork && isDefaultBlocked(nri)) {
8113                 // Remove default networking if disallowed for managed default requests.
8114                 bestNetwork = mNoServiceNetwork;
8115             }
8116             if (nri.getSatisfier() != bestNetwork) {
8117                 // bestNetwork may be null if no network can satisfy this request.
8118                 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
8119                         nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork));
8120             }
8121         }
8122         return changes;
8123     }
8124 
getNrisFromGlobalRequests()8125     private Set<NetworkRequestInfo> getNrisFromGlobalRequests() {
8126         return new HashSet<>(mNetworkRequests.values());
8127     }
8128 
8129     /**
8130      * Attempt to rematch all Networks with all NetworkRequests.  This may result in Networks
8131      * being disconnected.
8132      */
rematchAllNetworksAndRequests()8133     private void rematchAllNetworksAndRequests() {
8134         rematchNetworksAndRequests(getNrisFromGlobalRequests());
8135     }
8136 
8137     /**
8138      * Attempt to rematch all Networks with given NetworkRequests.  This may result in Networks
8139      * being disconnected.
8140      */
rematchNetworksAndRequests( @onNull final Set<NetworkRequestInfo> networkRequests)8141     private void rematchNetworksAndRequests(
8142             @NonNull final Set<NetworkRequestInfo> networkRequests) {
8143         ensureRunningOnConnectivityServiceThread();
8144         // TODO: This may be slow, and should be optimized.
8145         final long now = SystemClock.elapsedRealtime();
8146         final NetworkReassignment changes = computeNetworkReassignment(networkRequests);
8147         if (VDBG || DDBG) {
8148             log(changes.debugString());
8149         } else if (DBG) {
8150             log(changes.toString()); // Shorter form, only one line of log
8151         }
8152         applyNetworkReassignment(changes, now);
8153         issueNetworkNeeds();
8154     }
8155 
applyNetworkReassignment(@onNull final NetworkReassignment changes, final long now)8156     private void applyNetworkReassignment(@NonNull final NetworkReassignment changes,
8157             final long now) {
8158         final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos;
8159 
8160         // Since most of the time there are only 0 or 1 background networks, it would probably
8161         // be more efficient to just use an ArrayList here. TODO : measure performance
8162         final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>();
8163         for (final NetworkAgentInfo nai : nais) {
8164             if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai);
8165         }
8166 
8167         // First, update the lists of satisfied requests in the network agents. This is necessary
8168         // because some code later depends on this state to be correct, most prominently computing
8169         // the linger status.
8170         for (final NetworkReassignment.RequestReassignment event :
8171                 changes.getRequestReassignments()) {
8172             updateSatisfiersForRematchRequest(event.mNetworkRequestInfo,
8173                     event.mOldNetworkRequest, event.mNewNetworkRequest,
8174                     event.mOldNetwork, event.mNewNetwork,
8175                     now);
8176         }
8177 
8178         // Process default network changes if applicable.
8179         processDefaultNetworkChanges(changes);
8180 
8181         // Notify requested networks are available after the default net is switched, but
8182         // before LegacyTypeTracker sends legacy broadcasts
8183         for (final NetworkReassignment.RequestReassignment event :
8184                 changes.getRequestReassignments()) {
8185             if (null != event.mNewNetwork) {
8186                 notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo);
8187             } else {
8188                 callCallbackForRequest(event.mNetworkRequestInfo, event.mOldNetwork,
8189                         ConnectivityManager.CALLBACK_LOST, 0);
8190             }
8191         }
8192 
8193         // Update the inactivity state before processing listen callbacks, because the background
8194         // computation depends on whether the network is inactive. Don't send the LOSING callbacks
8195         // just yet though, because they have to be sent after the listens are processed to keep
8196         // backward compatibility.
8197         final ArrayList<NetworkAgentInfo> inactiveNetworks = new ArrayList<>();
8198         for (final NetworkAgentInfo nai : nais) {
8199             // Rematching may have altered the inactivity state of some networks, so update all
8200             // inactivity timers. updateInactivityState reads the state from the network agent
8201             // and does nothing if the state has not changed : the source of truth is controlled
8202             // with NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which
8203             // have been called while rematching the individual networks above.
8204             if (updateInactivityState(nai, now)) {
8205                 inactiveNetworks.add(nai);
8206             }
8207         }
8208 
8209         for (final NetworkAgentInfo nai : nais) {
8210             if (!nai.everConnected) continue;
8211             final boolean oldBackground = oldBgNetworks.contains(nai);
8212             // Process listen requests and update capabilities if the background state has
8213             // changed for this network. For consistency with previous behavior, send onLost
8214             // callbacks before onAvailable.
8215             processNewlyLostListenRequests(nai);
8216             if (oldBackground != nai.isBackgroundNetwork()) {
8217                 applyBackgroundChangeForRematch(nai);
8218             }
8219             processNewlySatisfiedListenRequests(nai);
8220         }
8221 
8222         for (final NetworkAgentInfo nai : inactiveNetworks) {
8223             // For nascent networks, if connecting with no foreground request, skip broadcasting
8224             // LOSING for backward compatibility. This is typical when mobile data connected while
8225             // wifi connected with mobile data always-on enabled.
8226             if (nai.isNascent()) continue;
8227             notifyNetworkLosing(nai, now);
8228         }
8229 
8230         updateLegacyTypeTrackerAndVpnLockdownForRematch(changes, nais);
8231 
8232         // Tear down all unneeded networks.
8233         for (NetworkAgentInfo nai : mNetworkAgentInfos) {
8234             if (unneeded(nai, UnneededFor.TEARDOWN)) {
8235                 if (nai.getInactivityExpiry() > 0) {
8236                     // This network has active linger timers and no requests, but is not
8237                     // lingering. Linger it.
8238                     //
8239                     // One way (the only way?) this can happen if this network is unvalidated
8240                     // and became unneeded due to another network improving its score to the
8241                     // point where this network will no longer be able to satisfy any requests
8242                     // even if it validates.
8243                     if (updateInactivityState(nai, now)) {
8244                         notifyNetworkLosing(nai, now);
8245                     }
8246                 } else {
8247                     if (DBG) log("Reaping " + nai.toShortString());
8248                     teardownUnneededNetwork(nai);
8249                 }
8250             }
8251         }
8252     }
8253 
8254     /**
8255      * Apply a change in background state resulting from rematching networks with requests.
8256      *
8257      * During rematch, a network may change background states by starting to satisfy or stopping
8258      * to satisfy a foreground request. Listens don't count for this. When a network changes
8259      * background states, its capabilities need to be updated and callbacks fired for the
8260      * capability change.
8261      *
8262      * @param nai The network that changed background states
8263      */
applyBackgroundChangeForRematch(@onNull final NetworkAgentInfo nai)8264     private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) {
8265         final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities);
8266         if (Objects.equals(nai.networkCapabilities, newNc)) return;
8267         updateNetworkPermissions(nai, newNc);
8268         nai.getAndSetNetworkCapabilities(newNc);
8269         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
8270     }
8271 
updateLegacyTypeTrackerAndVpnLockdownForRematch( @onNull final NetworkReassignment changes, @NonNull final Collection<NetworkAgentInfo> nais)8272     private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
8273             @NonNull final NetworkReassignment changes,
8274             @NonNull final Collection<NetworkAgentInfo> nais) {
8275         final NetworkReassignment.RequestReassignment reassignmentOfDefault =
8276                 changes.getReassignment(mDefaultRequest);
8277         final NetworkAgentInfo oldDefaultNetwork =
8278                 null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null;
8279         final NetworkAgentInfo newDefaultNetwork =
8280                 null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null;
8281 
8282         if (oldDefaultNetwork != newDefaultNetwork) {
8283             // Maintain the illusion : since the legacy API only understands one network at a time,
8284             // if the default network changed, apps should see a disconnected broadcast for the
8285             // old default network before they see a connected broadcast for the new one.
8286             if (oldDefaultNetwork != null) {
8287                 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
8288                         oldDefaultNetwork, true);
8289             }
8290             if (newDefaultNetwork != null) {
8291                 // The new default network can be newly null if and only if the old default
8292                 // network doesn't satisfy the default request any more because it lost a
8293                 // capability.
8294                 mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0;
8295                 mLegacyTypeTracker.add(
8296                         newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
8297             }
8298         }
8299 
8300         // Now that all the callbacks have been sent, send the legacy network broadcasts
8301         // as needed. This is necessary so that legacy requests correctly bind dns
8302         // requests to this network. The legacy users are listening for this broadcast
8303         // and will generally do a dns request so they can ensureRouteToHost and if
8304         // they do that before the callbacks happen they'll use the default network.
8305         //
8306         // TODO: Is there still a race here? The legacy broadcast will be sent after sending
8307         // callbacks, but if apps can receive the broadcast before the callback, they still might
8308         // have an inconsistent view of networking.
8309         //
8310         // This *does* introduce a race where if the user uses the new api
8311         // (notification callbacks) and then uses the old api (getNetworkInfo(type))
8312         // they may get old info. Reverse this after the old startUsing api is removed.
8313         // This is on top of the multiple intent sequencing referenced in the todo above.
8314         for (NetworkAgentInfo nai : nais) {
8315             if (nai.everConnected) {
8316                 addNetworkToLegacyTypeTracker(nai);
8317             }
8318         }
8319     }
8320 
issueNetworkNeeds()8321     private void issueNetworkNeeds() {
8322         ensureRunningOnConnectivityServiceThread();
8323         for (final NetworkOfferInfo noi : mNetworkOffers) {
8324             issueNetworkNeeds(noi);
8325         }
8326     }
8327 
issueNetworkNeeds(@onNull final NetworkOfferInfo noi)8328     private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) {
8329         ensureRunningOnConnectivityServiceThread();
8330         for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
8331             informOffer(nri, noi.offer, mNetworkRanker);
8332         }
8333     }
8334 
8335     /**
8336      * Inform a NetworkOffer about any new situation of a request.
8337      *
8338      * This function handles updates to offers. A number of events may happen that require
8339      * updating the registrant for this offer about the situation :
8340      * • The offer itself was updated. This may lead the offer to no longer being able
8341      *     to satisfy a request or beat a satisfier (and therefore be no longer needed),
8342      *     or conversely being strengthened enough to beat the satisfier (and therefore
8343      *     start being needed)
8344      * • The network satisfying a request changed (including cases where the request
8345      *     starts or stops being satisfied). The new network may be a stronger or weaker
8346      *     match than the old one, possibly affecting whether the offer is needed.
8347      * • The network satisfying a request updated their score. This may lead the offer
8348      *     to no longer be able to beat it if the current satisfier got better, or
8349      *     conversely start being a good choice if the current satisfier got weaker.
8350      *
8351      * @param nri The request
8352      * @param offer The offer. This may be an updated offer.
8353      */
informOffer(@onNull NetworkRequestInfo nri, @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker)8354     private static void informOffer(@NonNull NetworkRequestInfo nri,
8355             @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) {
8356         final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null;
8357         final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null;
8358 
8359         // Multi-layer requests have a currently active request, the one being satisfied.
8360         // Since the system will try to bring up a better network than is currently satisfying
8361         // the request, NetworkProviders need to be told the offers matching the requests *above*
8362         // the currently satisfied one are needed, that the ones *below* the satisfied one are
8363         // not needed, and the offer is needed for the active request iff the offer can beat
8364         // the satisfier.
8365         // For non-multilayer requests, the logic above gracefully degenerates to only the
8366         // last case.
8367         // To achieve this, the loop below will proceed in three steps. In a first phase, inform
8368         // providers that the offer is needed for this request, until the active request is found.
8369         // In a second phase, deal with the currently active request. In a third phase, inform
8370         // the providers that offer is unneeded for the remaining requests.
8371 
8372         // First phase : inform providers of all requests above the active request.
8373         int i;
8374         for (i = 0; nri.mRequests.size() > i; ++i) {
8375             final NetworkRequest request = nri.mRequests.get(i);
8376             if (activeRequest == request) break; // Found the active request : go to phase 2
8377             if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
8378             // Since this request is higher-priority than the one currently satisfied, if the
8379             // offer can satisfy it, the provider should try and bring up the network for sure ;
8380             // no need to even ask the ranker – an offer that can satisfy is always better than
8381             // no network. Hence tell the provider so unless it already knew.
8382             if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) {
8383                 offer.onNetworkNeeded(request);
8384             }
8385         }
8386 
8387         // Second phase : deal with the active request (if any)
8388         if (null != activeRequest && activeRequest.isRequest()) {
8389             final boolean oldNeeded = offer.neededFor(activeRequest);
8390             // If an offer can satisfy the request, it is considered needed if it is currently
8391             // served by this provider or if this offer can beat the current satisfier.
8392             final boolean currentlyServing = satisfier != null
8393                     && satisfier.factorySerialNumber == offer.providerId
8394                     && activeRequest.canBeSatisfiedBy(offer.caps);
8395             final boolean newNeeded = currentlyServing
8396                     || networkRanker.mightBeat(activeRequest, satisfier, offer);
8397             if (newNeeded != oldNeeded) {
8398                 if (newNeeded) {
8399                     offer.onNetworkNeeded(activeRequest);
8400                 } else {
8401                     // The offer used to be able to beat the satisfier. Now it can't.
8402                     offer.onNetworkUnneeded(activeRequest);
8403                 }
8404             }
8405         }
8406 
8407         // Third phase : inform the providers that the offer isn't needed for any request
8408         // below the active one.
8409         for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) {
8410             final NetworkRequest request = nri.mRequests.get(i);
8411             if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
8412             // Since this request is lower-priority than the one currently satisfied, if the
8413             // offer can satisfy it, the provider should not try and bring up the network.
8414             // Hence tell the provider so unless it already knew.
8415             if (offer.neededFor(request)) {
8416                 offer.onNetworkUnneeded(request);
8417             }
8418         }
8419     }
8420 
addNetworkToLegacyTypeTracker(@onNull final NetworkAgentInfo nai)8421     private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) {
8422         for (int i = 0; i < nai.numNetworkRequests(); i++) {
8423             NetworkRequest nr = nai.requestAt(i);
8424             if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
8425                 // legacy type tracker filters out repeat adds
8426                 mLegacyTypeTracker.add(nr.legacyType, nai);
8427             }
8428         }
8429 
8430         // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
8431         // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
8432         // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
8433         // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
8434         if (nai.isVPN()) {
8435             mLegacyTypeTracker.add(TYPE_VPN, nai);
8436         }
8437     }
8438 
updateInetCondition(NetworkAgentInfo nai)8439     private void updateInetCondition(NetworkAgentInfo nai) {
8440         // Don't bother updating until we've graduated to validated at least once.
8441         if (!nai.everValidated) return;
8442         // For now only update icons for the default connection.
8443         // TODO: Update WiFi and cellular icons separately. b/17237507
8444         if (!isDefaultNetwork(nai)) return;
8445 
8446         int newInetCondition = nai.lastValidated ? 100 : 0;
8447         // Don't repeat publish.
8448         if (newInetCondition == mDefaultInetConditionPublished) return;
8449 
8450         mDefaultInetConditionPublished = newInetCondition;
8451         sendInetConditionBroadcast(nai.networkInfo);
8452     }
8453 
8454     @NonNull
mixInInfo(@onNull final NetworkAgentInfo nai, @NonNull NetworkInfo info)8455     private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) {
8456         final NetworkInfo newInfo = new NetworkInfo(info);
8457         // The suspended and roaming bits are managed in NetworkCapabilities.
8458         final boolean suspended =
8459                 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
8460         if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
8461             // Only override the state with SUSPENDED if the network is currently in CONNECTED
8462             // state. This is because the network could have been suspended before connecting,
8463             // or it could be disconnecting while being suspended, and in both these cases
8464             // the state should not be overridden. Note that the only detailed state that
8465             // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to
8466             // worry about multiple different substates of CONNECTED.
8467             newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(),
8468                     info.getExtraInfo());
8469         } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) {
8470             // SUSPENDED state is currently only overridden from CONNECTED state. In the case the
8471             // network agent is created, then goes to suspended, then goes out of suspended without
8472             // ever setting connected. Check if network agent is ever connected to update the state.
8473             newInfo.setDetailedState(nai.everConnected
8474                     ? NetworkInfo.DetailedState.CONNECTED
8475                     : NetworkInfo.DetailedState.CONNECTING,
8476                     info.getReason(),
8477                     info.getExtraInfo());
8478         }
8479         newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING));
8480         return newInfo;
8481     }
8482 
updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info)8483     private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) {
8484         final NetworkInfo newInfo = mixInInfo(networkAgent, info);
8485 
8486         final NetworkInfo.State state = newInfo.getState();
8487         NetworkInfo oldInfo = null;
8488         synchronized (networkAgent) {
8489             oldInfo = networkAgent.networkInfo;
8490             networkAgent.networkInfo = newInfo;
8491         }
8492 
8493         if (DBG) {
8494             log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from "
8495                     + oldInfo.getState() + " to " + state);
8496         }
8497 
8498         if (!networkAgent.created
8499                 && (state == NetworkInfo.State.CONNECTED
8500                 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
8501 
8502             // A network that has just connected has zero requests and is thus a foreground network.
8503             networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
8504 
8505             if (!createNativeNetwork(networkAgent)) return;
8506             if (networkAgent.propagateUnderlyingCapabilities()) {
8507                 // Initialize the network's capabilities to their starting values according to the
8508                 // underlying networks. This ensures that the capabilities are correct before
8509                 // anything happens to the network.
8510                 updateCapabilitiesForNetwork(networkAgent);
8511             }
8512             networkAgent.created = true;
8513             networkAgent.onNetworkCreated();
8514         }
8515 
8516         if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
8517             networkAgent.everConnected = true;
8518 
8519             // NetworkCapabilities need to be set before sending the private DNS config to
8520             // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
8521             networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities);
8522 
8523             handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
8524             updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties),
8525                     null);
8526 
8527             // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect
8528             // command must be sent after updating LinkProperties to maximize chances of
8529             // NetworkMonitor seeing the correct LinkProperties when starting.
8530             // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
8531             if (networkAgent.networkAgentConfig.acceptPartialConnectivity) {
8532                 networkAgent.networkMonitor().setAcceptPartialConnectivity();
8533             }
8534             networkAgent.networkMonitor().notifyNetworkConnected(
8535                     new LinkProperties(networkAgent.linkProperties,
8536                             true /* parcelSensitiveFields */),
8537                     networkAgent.networkCapabilities);
8538             scheduleUnvalidatedPrompt(networkAgent);
8539 
8540             // Whether a particular NetworkRequest listen should cause signal strength thresholds to
8541             // be communicated to a particular NetworkAgent depends only on the network's immutable,
8542             // capabilities, so it only needs to be done once on initial connect, not every time the
8543             // network's capabilities change. Note that we do this before rematching the network,
8544             // so we could decide to tear it down immediately afterwards. That's fine though - on
8545             // disconnection NetworkAgents should stop any signal strength monitoring they have been
8546             // doing.
8547             updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
8548 
8549             // Before first rematching networks, put an inactivity timer without any request, this
8550             // allows {@code updateInactivityState} to update the state accordingly and prevent
8551             // tearing down for any {@code unneeded} evaluation in this period.
8552             // Note that the timer will not be rescheduled since the expiry time is
8553             // fixed after connection regardless of the network satisfying other requests or not.
8554             // But it will be removed as soon as the network satisfies a request for the first time.
8555             networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE,
8556                     SystemClock.elapsedRealtime(), mNascentDelayMs);
8557             networkAgent.setInactive();
8558 
8559             // Consider network even though it is not yet validated.
8560             rematchAllNetworksAndRequests();
8561 
8562             // This has to happen after matching the requests, because callbacks are just requests.
8563             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
8564         } else if (state == NetworkInfo.State.DISCONNECTED) {
8565             networkAgent.disconnect();
8566             if (networkAgent.isVPN()) {
8567                 updateUids(networkAgent, networkAgent.networkCapabilities, null);
8568             }
8569             disconnectAndDestroyNetwork(networkAgent);
8570             if (networkAgent.isVPN()) {
8571                 // As the active or bound network changes for apps, broadcast the default proxy, as
8572                 // apps may need to update their proxy data. This is called after disconnecting from
8573                 // VPN to make sure we do not broadcast the old proxy data.
8574                 // TODO(b/122649188): send the broadcast only to VPN users.
8575                 mProxyTracker.sendProxyBroadcast();
8576             }
8577         } else if (networkAgent.created && (oldInfo.getState() == NetworkInfo.State.SUSPENDED ||
8578                 state == NetworkInfo.State.SUSPENDED)) {
8579             mLegacyTypeTracker.update(networkAgent);
8580         }
8581     }
8582 
updateNetworkScore(@onNull final NetworkAgentInfo nai, final NetworkScore score)8583     private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) {
8584         if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score);
8585         nai.setScore(score);
8586         rematchAllNetworksAndRequests();
8587     }
8588 
8589     // Notify only this one new request of the current state. Transfer all the
8590     // current state by calling NetworkCapabilities and LinkProperties callbacks
8591     // so that callers can be guaranteed to have as close to atomicity in state
8592     // transfer as can be supported by this current API.
notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri)8593     protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) {
8594         mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
8595         if (nri.mPendingIntent != null) {
8596             sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE);
8597             // Attempt no subsequent state pushes where intents are involved.
8598             return;
8599         }
8600 
8601         final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
8602         final boolean metered = nai.networkCapabilities.isMetered();
8603         final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges);
8604         callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE,
8605                 getBlockedState(blockedReasons, metered, vpnBlocked));
8606     }
8607 
8608     // Notify the requests on this NAI that the network is now lingered.
notifyNetworkLosing(@onNull final NetworkAgentInfo nai, final long now)8609     private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) {
8610         final int lingerTime = (int) (nai.getInactivityExpiry() - now);
8611         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
8612     }
8613 
getBlockedState(int reasons, boolean metered, boolean vpnBlocked)8614     private static int getBlockedState(int reasons, boolean metered, boolean vpnBlocked) {
8615         if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK;
8616         return vpnBlocked
8617                 ? reasons | BLOCKED_REASON_LOCKDOWN_VPN
8618                 : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN;
8619     }
8620 
setUidBlockedReasons(int uid, @BlockedReason int blockedReasons)8621     private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) {
8622         if (blockedReasons == BLOCKED_REASON_NONE) {
8623             mUidBlockedReasons.delete(uid);
8624         } else {
8625             mUidBlockedReasons.put(uid, blockedReasons);
8626         }
8627     }
8628 
8629     /**
8630      * Notify of the blocked state apps with a registered callback matching a given NAI.
8631      *
8632      * Unlike other callbacks, blocked status is different between each individual uid. So for
8633      * any given nai, all requests need to be considered according to the uid who filed it.
8634      *
8635      * @param nai The target NetworkAgentInfo.
8636      * @param oldMetered True if the previous network capabilities were metered.
8637      * @param newMetered True if the current network capabilities are metered.
8638      * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN.
8639      * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN.
8640      */
maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, boolean newMetered, List<UidRange> oldBlockedUidRanges, List<UidRange> newBlockedUidRanges)8641     private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
8642             boolean newMetered, List<UidRange> oldBlockedUidRanges,
8643             List<UidRange> newBlockedUidRanges) {
8644 
8645         for (int i = 0; i < nai.numNetworkRequests(); i++) {
8646             NetworkRequest nr = nai.requestAt(i);
8647             NetworkRequestInfo nri = mNetworkRequests.get(nr);
8648 
8649             final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
8650             final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
8651             final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
8652                     ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges)
8653                     : oldVpnBlocked;
8654 
8655             final int oldBlockedState = getBlockedState(blockedReasons, oldMetered, oldVpnBlocked);
8656             final int newBlockedState = getBlockedState(blockedReasons, newMetered, newVpnBlocked);
8657             if (oldBlockedState != newBlockedState) {
8658                 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
8659                         newBlockedState);
8660             }
8661         }
8662     }
8663 
8664     /**
8665      * Notify apps with a given UID of the new blocked state according to new uid state.
8666      * @param uid The uid for which the rules changed.
8667      * @param blockedReasons The reasons for why an uid is blocked.
8668      */
maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons)8669     private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) {
8670         for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
8671             final boolean metered = nai.networkCapabilities.isMetered();
8672             final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
8673 
8674             final int oldBlockedState = getBlockedState(
8675                     mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked);
8676             final int newBlockedState = getBlockedState(blockedReasons, metered, vpnBlocked);
8677             if (oldBlockedState == newBlockedState) {
8678                 continue;
8679             }
8680             for (int i = 0; i < nai.numNetworkRequests(); i++) {
8681                 NetworkRequest nr = nai.requestAt(i);
8682                 NetworkRequestInfo nri = mNetworkRequests.get(nr);
8683                 if (nri != null && nri.mAsUid == uid) {
8684                     callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
8685                             newBlockedState);
8686                 }
8687             }
8688         }
8689     }
8690 
8691     @VisibleForTesting
sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type)8692     protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
8693         // The NetworkInfo we actually send out has no bearing on the real
8694         // state of affairs. For example, if the default connection is mobile,
8695         // and a request for HIPRI has just gone away, we need to pretend that
8696         // HIPRI has just disconnected. So we need to set the type to HIPRI and
8697         // the state to DISCONNECTED, even though the network is of type MOBILE
8698         // and is still connected.
8699         NetworkInfo info = new NetworkInfo(nai.networkInfo);
8700         info.setType(type);
8701         filterForLegacyLockdown(info);
8702         if (state != DetailedState.DISCONNECTED) {
8703             info.setDetailedState(state, null, info.getExtraInfo());
8704             sendConnectedBroadcast(info);
8705         } else {
8706             info.setDetailedState(state, info.getReason(), info.getExtraInfo());
8707             Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
8708             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
8709             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
8710             if (info.isFailover()) {
8711                 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
8712                 nai.networkInfo.setFailover(false);
8713             }
8714             if (info.getReason() != null) {
8715                 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
8716             }
8717             if (info.getExtraInfo() != null) {
8718                 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
8719             }
8720             NetworkAgentInfo newDefaultAgent = null;
8721             if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) {
8722                 newDefaultAgent = mDefaultRequest.getSatisfier();
8723                 if (newDefaultAgent != null) {
8724                     intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
8725                             newDefaultAgent.networkInfo);
8726                 } else {
8727                     intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
8728                 }
8729             }
8730             intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
8731                     mDefaultInetConditionPublished);
8732             sendStickyBroadcast(intent);
8733             if (newDefaultAgent != null) {
8734                 sendConnectedBroadcast(newDefaultAgent.networkInfo);
8735             }
8736         }
8737     }
8738 
notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1)8739     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) {
8740         if (VDBG || DDBG) {
8741             String notification = ConnectivityManager.getCallbackName(notifyType);
8742             log("notifyType " + notification + " for " + networkAgent.toShortString());
8743         }
8744         for (int i = 0; i < networkAgent.numNetworkRequests(); i++) {
8745             NetworkRequest nr = networkAgent.requestAt(i);
8746             NetworkRequestInfo nri = mNetworkRequests.get(nr);
8747             if (VDBG) log(" sending notification for " + nr);
8748             if (nri.mPendingIntent == null) {
8749                 callCallbackForRequest(nri, networkAgent, notifyType, arg1);
8750             } else {
8751                 sendPendingIntentForRequest(nri, networkAgent, notifyType);
8752             }
8753         }
8754     }
8755 
notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType)8756     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
8757         notifyNetworkCallbacks(networkAgent, notifyType, 0);
8758     }
8759 
8760     /**
8761      * Returns the list of all interfaces that could be used by network traffic that does not
8762      * explicitly specify a network. This includes the default network, but also all VPNs that are
8763      * currently connected.
8764      *
8765      * Must be called on the handler thread.
8766      */
8767     @NonNull
getDefaultNetworks()8768     private ArrayList<Network> getDefaultNetworks() {
8769         ensureRunningOnConnectivityServiceThread();
8770         final ArrayList<Network> defaultNetworks = new ArrayList<>();
8771         final Set<Integer> activeNetIds = new ArraySet<>();
8772         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
8773             if (nri.isBeingSatisfied()) {
8774                 activeNetIds.add(nri.getSatisfier().network().netId);
8775             }
8776         }
8777         for (NetworkAgentInfo nai : mNetworkAgentInfos) {
8778             if (nai.everConnected && (activeNetIds.contains(nai.network().netId) || nai.isVPN())) {
8779                 defaultNetworks.add(nai.network);
8780             }
8781         }
8782         return defaultNetworks;
8783     }
8784 
8785     /**
8786      * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
8787      * active iface's tracked properties has changed.
8788      */
notifyIfacesChangedForNetworkStats()8789     private void notifyIfacesChangedForNetworkStats() {
8790         ensureRunningOnConnectivityServiceThread();
8791         String activeIface = null;
8792         LinkProperties activeLinkProperties = getActiveLinkProperties();
8793         if (activeLinkProperties != null) {
8794             activeIface = activeLinkProperties.getInterfaceName();
8795         }
8796 
8797         final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo();
8798         try {
8799             final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>();
8800             for (final NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) {
8801                 snapshots.add(snapshot);
8802             }
8803             mStatsManager.notifyNetworkStatus(getDefaultNetworks(),
8804                     snapshots, activeIface, Arrays.asList(underlyingNetworkInfos));
8805         } catch (Exception ignored) {
8806         }
8807     }
8808 
8809     @Override
getCaptivePortalServerUrl()8810     public String getCaptivePortalServerUrl() {
8811         enforceNetworkStackOrSettingsPermission();
8812         String settingUrl = mResources.get().getString(
8813                 R.string.config_networkCaptivePortalServerUrl);
8814 
8815         if (!TextUtils.isEmpty(settingUrl)) {
8816             return settingUrl;
8817         }
8818 
8819         settingUrl = Settings.Global.getString(mContext.getContentResolver(),
8820                 ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL);
8821         if (!TextUtils.isEmpty(settingUrl)) {
8822             return settingUrl;
8823         }
8824 
8825         return DEFAULT_CAPTIVE_PORTAL_HTTP_URL;
8826     }
8827 
8828     @Override
startNattKeepalive(Network network, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr)8829     public void startNattKeepalive(Network network, int intervalSeconds,
8830             ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) {
8831         enforceKeepalivePermission();
8832         mKeepaliveTracker.startNattKeepalive(
8833                 getNetworkAgentInfoForNetwork(network), null /* fd */,
8834                 intervalSeconds, cb,
8835                 srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT);
8836     }
8837 
8838     @Override
startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, String dstAddr)8839     public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId,
8840             int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
8841             String dstAddr) {
8842         try {
8843             final FileDescriptor fd = pfd.getFileDescriptor();
8844             mKeepaliveTracker.startNattKeepalive(
8845                     getNetworkAgentInfoForNetwork(network), fd, resourceId,
8846                     intervalSeconds, cb,
8847                     srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT);
8848         } finally {
8849             // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
8850             // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately.
8851             if (pfd != null && Binder.getCallingPid() != Process.myPid()) {
8852                 IoUtils.closeQuietly(pfd);
8853             }
8854         }
8855     }
8856 
8857     @Override
startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds, ISocketKeepaliveCallback cb)8858     public void startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds,
8859             ISocketKeepaliveCallback cb) {
8860         try {
8861             enforceKeepalivePermission();
8862             final FileDescriptor fd = pfd.getFileDescriptor();
8863             mKeepaliveTracker.startTcpKeepalive(
8864                     getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
8865         } finally {
8866             // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
8867             // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately.
8868             if (pfd != null && Binder.getCallingPid() != Process.myPid()) {
8869                 IoUtils.closeQuietly(pfd);
8870             }
8871         }
8872     }
8873 
8874     @Override
stopKeepalive(Network network, int slot)8875     public void stopKeepalive(Network network, int slot) {
8876         mHandler.sendMessage(mHandler.obtainMessage(
8877                 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, slot, SocketKeepalive.SUCCESS, network));
8878     }
8879 
8880     @Override
factoryReset()8881     public void factoryReset() {
8882         enforceSettingsPermission();
8883 
8884         final int uid = mDeps.getCallingUid();
8885         final long token = Binder.clearCallingIdentity();
8886         try {
8887             if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_NETWORK_RESET,
8888                     UserHandle.getUserHandleForUid(uid))) {
8889                 return;
8890             }
8891 
8892             final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
8893             ipMemoryStore.factoryReset();
8894 
8895             // Turn airplane mode off
8896             setAirplaneMode(false);
8897 
8898             // restore private DNS settings to default mode (opportunistic)
8899             if (!mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
8900                     UserHandle.getUserHandleForUid(uid))) {
8901                 ConnectivitySettingsManager.setPrivateDnsMode(mContext,
8902                         PRIVATE_DNS_MODE_OPPORTUNISTIC);
8903             }
8904 
8905             Settings.Global.putString(mContext.getContentResolver(),
8906                     ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null);
8907         } finally {
8908             Binder.restoreCallingIdentity(token);
8909         }
8910     }
8911 
8912     @Override
getNetworkWatchlistConfigHash()8913     public byte[] getNetworkWatchlistConfigHash() {
8914         NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class);
8915         if (nwm == null) {
8916             loge("Unable to get NetworkWatchlistManager");
8917             return null;
8918         }
8919         // Redirect it to network watchlist service to access watchlist file and calculate hash.
8920         return nwm.getWatchlistConfigHash();
8921     }
8922 
logNetworkEvent(NetworkAgentInfo nai, int evtype)8923     private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {
8924         int[] transports = nai.networkCapabilities.getTransportTypes();
8925         mMetricsLog.log(nai.network.getNetId(), transports, new NetworkEvent(evtype));
8926     }
8927 
toBool(int encodedBoolean)8928     private static boolean toBool(int encodedBoolean) {
8929         return encodedBoolean != 0; // Only 0 means false.
8930     }
8931 
encodeBool(boolean b)8932     private static int encodeBool(boolean b) {
8933         return b ? 1 : 0;
8934     }
8935 
8936     @Override
handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)8937     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
8938             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
8939             @NonNull String[] args) {
8940         return new ShellCmd().exec(this, in.getFileDescriptor(), out.getFileDescriptor(),
8941                 err.getFileDescriptor(), args);
8942     }
8943 
8944     private class ShellCmd extends BasicShellCommandHandler {
8945         @Override
onCommand(String cmd)8946         public int onCommand(String cmd) {
8947             if (cmd == null) {
8948                 return handleDefaultCommands(cmd);
8949             }
8950             final PrintWriter pw = getOutPrintWriter();
8951             try {
8952                 switch (cmd) {
8953                     case "airplane-mode":
8954                         final String action = getNextArg();
8955                         if ("enable".equals(action)) {
8956                             setAirplaneMode(true);
8957                             return 0;
8958                         } else if ("disable".equals(action)) {
8959                             setAirplaneMode(false);
8960                             return 0;
8961                         } else if (action == null) {
8962                             final ContentResolver cr = mContext.getContentResolver();
8963                             final int enabled = Settings.Global.getInt(cr,
8964                                     Settings.Global.AIRPLANE_MODE_ON);
8965                             pw.println(enabled == 0 ? "disabled" : "enabled");
8966                             return 0;
8967                         } else {
8968                             onHelp();
8969                             return -1;
8970                         }
8971                     default:
8972                         return handleDefaultCommands(cmd);
8973                 }
8974             } catch (Exception e) {
8975                 pw.println(e);
8976             }
8977             return -1;
8978         }
8979 
8980         @Override
onHelp()8981         public void onHelp() {
8982             PrintWriter pw = getOutPrintWriter();
8983             pw.println("Connectivity service commands:");
8984             pw.println("  help");
8985             pw.println("    Print this help text.");
8986             pw.println("  airplane-mode [enable|disable]");
8987             pw.println("    Turn airplane mode on or off.");
8988             pw.println("  airplane-mode");
8989             pw.println("    Get airplane mode.");
8990         }
8991     }
8992 
getVpnType(@ullable NetworkAgentInfo vpn)8993     private int getVpnType(@Nullable NetworkAgentInfo vpn) {
8994         if (vpn == null) return VpnManager.TYPE_VPN_NONE;
8995         final TransportInfo ti = vpn.networkCapabilities.getTransportInfo();
8996         if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE;
8997         return ((VpnTransportInfo) ti).getType();
8998     }
8999 
9000     /**
9001      * @param connectionInfo the connection to resolve.
9002      * @return {@code uid} if the connection is found and the app has permission to observe it
9003      * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the
9004      * connection is not found.
9005      */
getConnectionOwnerUid(ConnectionInfo connectionInfo)9006     public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
9007         if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
9008             throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
9009         }
9010 
9011         final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol,
9012                 connectionInfo.local, connectionInfo.remote);
9013 
9014         if (uid == INVALID_UID) return uid;  // Not found.
9015 
9016         // Connection owner UIDs are visible only to the network stack and to the VpnService-based
9017         // VPN, if any, that applies to the UID that owns the connection.
9018         if (checkNetworkStackPermission()) return uid;
9019 
9020         final NetworkAgentInfo vpn = getVpnForUid(uid);
9021         if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE
9022                 || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) {
9023             return INVALID_UID;
9024         }
9025 
9026         return uid;
9027     }
9028 
9029     /**
9030      * Returns a IBinder to a TestNetworkService. Will be lazily created as needed.
9031      *
9032      * <p>The TestNetworkService must be run in the system server due to TUN creation.
9033      */
9034     @Override
startOrGetTestNetworkService()9035     public IBinder startOrGetTestNetworkService() {
9036         synchronized (mTNSLock) {
9037             TestNetworkService.enforceTestNetworkPermissions(mContext);
9038 
9039             if (mTNS == null) {
9040                 mTNS = new TestNetworkService(mContext);
9041             }
9042 
9043             return mTNS;
9044         }
9045     }
9046 
9047     /**
9048      * Handler used for managing all Connectivity Diagnostics related functions.
9049      *
9050      * @see android.net.ConnectivityDiagnosticsManager
9051      *
9052      * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file
9053      */
9054     @VisibleForTesting
9055     class ConnectivityDiagnosticsHandler extends Handler {
9056         private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName();
9057 
9058         /**
9059          * Used to handle ConnectivityDiagnosticsCallback registration events from {@link
9060          * android.net.ConnectivityDiagnosticsManager}.
9061          * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and
9062          * NetworkRequestInfo to be registered
9063          */
9064         private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1;
9065 
9066         /**
9067          * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link
9068          * android.net.ConnectivityDiagnosticsManager}.
9069          * obj = the IConnectivityDiagnosticsCallback to be unregistered
9070          * arg1 = the uid of the caller
9071          */
9072         private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2;
9073 
9074         /**
9075          * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks
9076          * after processing {@link #EVENT_NETWORK_TESTED} events.
9077          * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from
9078          * NetworkMonitor.
9079          * data = PersistableBundle of extras passed from NetworkMonitor.
9080          *
9081          * <p>See {@link ConnectivityService#EVENT_NETWORK_TESTED}.
9082          */
9083         private static final int EVENT_NETWORK_TESTED = ConnectivityService.EVENT_NETWORK_TESTED;
9084 
9085         /**
9086          * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has
9087          * been detected on the network.
9088          * obj = Long the timestamp (in millis) for when the suspected data stall was detected.
9089          * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method.
9090          * arg2 = NetID.
9091          * data = PersistableBundle of extras passed from NetworkMonitor.
9092          */
9093         private static final int EVENT_DATA_STALL_SUSPECTED = 4;
9094 
9095         /**
9096          * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to
9097          * the platform. This event will invoke {@link
9098          * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned
9099          * callbacks.
9100          * obj = Network that was reported on
9101          * arg1 = boolint for the quality reported
9102          */
9103         private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5;
9104 
ConnectivityDiagnosticsHandler(Looper looper)9105         private ConnectivityDiagnosticsHandler(Looper looper) {
9106             super(looper);
9107         }
9108 
9109         @Override
handleMessage(Message msg)9110         public void handleMessage(Message msg) {
9111             switch (msg.what) {
9112                 case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
9113                     handleRegisterConnectivityDiagnosticsCallback(
9114                             (ConnectivityDiagnosticsCallbackInfo) msg.obj);
9115                     break;
9116                 }
9117                 case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
9118                     handleUnregisterConnectivityDiagnosticsCallback(
9119                             (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1);
9120                     break;
9121                 }
9122                 case EVENT_NETWORK_TESTED: {
9123                     final ConnectivityReportEvent reportEvent =
9124                             (ConnectivityReportEvent) msg.obj;
9125 
9126                     handleNetworkTestedWithExtras(reportEvent, reportEvent.mExtras);
9127                     break;
9128                 }
9129                 case EVENT_DATA_STALL_SUSPECTED: {
9130                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
9131                     final Pair<Long, PersistableBundle> arg =
9132                             (Pair<Long, PersistableBundle>) msg.obj;
9133                     if (nai == null) break;
9134 
9135                     handleDataStallSuspected(nai, arg.first, msg.arg1, arg.second);
9136                     break;
9137                 }
9138                 case EVENT_NETWORK_CONNECTIVITY_REPORTED: {
9139                     handleNetworkConnectivityReported((NetworkAgentInfo) msg.obj, toBool(msg.arg1));
9140                     break;
9141                 }
9142                 default: {
9143                     Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what);
9144                 }
9145             }
9146         }
9147     }
9148 
9149     /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */
9150     @VisibleForTesting
9151     class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient {
9152         @NonNull private final IConnectivityDiagnosticsCallback mCb;
9153         @NonNull private final NetworkRequestInfo mRequestInfo;
9154         @NonNull private final String mCallingPackageName;
9155 
9156         @VisibleForTesting
ConnectivityDiagnosticsCallbackInfo( @onNull IConnectivityDiagnosticsCallback cb, @NonNull NetworkRequestInfo nri, @NonNull String callingPackageName)9157         ConnectivityDiagnosticsCallbackInfo(
9158                 @NonNull IConnectivityDiagnosticsCallback cb,
9159                 @NonNull NetworkRequestInfo nri,
9160                 @NonNull String callingPackageName) {
9161             mCb = cb;
9162             mRequestInfo = nri;
9163             mCallingPackageName = callingPackageName;
9164         }
9165 
9166         @Override
binderDied()9167         public void binderDied() {
9168             log("ConnectivityDiagnosticsCallback IBinder died.");
9169             unregisterConnectivityDiagnosticsCallback(mCb);
9170         }
9171     }
9172 
9173     /**
9174      * Class used for sending information from {@link
9175      * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it.
9176      */
9177     private static class NetworkTestedResults {
9178         private final int mNetId;
9179         private final int mTestResult;
9180         private final long mTimestampMillis;
9181         @Nullable private final String mRedirectUrl;
9182 
NetworkTestedResults( int netId, int testResult, long timestampMillis, @Nullable String redirectUrl)9183         private NetworkTestedResults(
9184                 int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) {
9185             mNetId = netId;
9186             mTestResult = testResult;
9187             mTimestampMillis = timestampMillis;
9188             mRedirectUrl = redirectUrl;
9189         }
9190     }
9191 
9192     /**
9193      * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link
9194      * ConnectivityDiagnosticsHandler}.
9195      */
9196     private static class ConnectivityReportEvent {
9197         private final long mTimestampMillis;
9198         @NonNull private final NetworkAgentInfo mNai;
9199         private final PersistableBundle mExtras;
9200 
ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai, PersistableBundle p)9201         private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai,
9202                 PersistableBundle p) {
9203             mTimestampMillis = timestampMillis;
9204             mNai = nai;
9205             mExtras = p;
9206         }
9207     }
9208 
handleRegisterConnectivityDiagnosticsCallback( @onNull ConnectivityDiagnosticsCallbackInfo cbInfo)9209     private void handleRegisterConnectivityDiagnosticsCallback(
9210             @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) {
9211         ensureRunningOnConnectivityServiceThread();
9212 
9213         final IConnectivityDiagnosticsCallback cb = cbInfo.mCb;
9214         final IBinder iCb = cb.asBinder();
9215         final NetworkRequestInfo nri = cbInfo.mRequestInfo;
9216 
9217         // Connectivity Diagnostics are meant to be used with a single network request. It would be
9218         // confusing for these networks to change when an NRI is satisfied in another layer.
9219         if (nri.isMultilayerRequest()) {
9220             throw new IllegalArgumentException("Connectivity Diagnostics do not support multilayer "
9221                 + "network requests.");
9222         }
9223 
9224         // This means that the client registered the same callback multiple times. Do
9225         // not override the previous entry, and exit silently.
9226         if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) {
9227             if (VDBG) log("Diagnostics callback is already registered");
9228 
9229             // Decrement the reference count for this NetworkRequestInfo. The reference count is
9230             // incremented when the NetworkRequestInfo is created as part of
9231             // enforceRequestCountLimit().
9232             nri.decrementRequestCount();
9233             return;
9234         }
9235 
9236         mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo);
9237 
9238         try {
9239             iCb.linkToDeath(cbInfo, 0);
9240         } catch (RemoteException e) {
9241             cbInfo.binderDied();
9242             return;
9243         }
9244 
9245         // Once registered, provide ConnectivityReports for matching Networks
9246         final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>();
9247         synchronized (mNetworkForNetId) {
9248             for (int i = 0; i < mNetworkForNetId.size(); i++) {
9249                 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
9250                 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0)
9251                 if (nai.satisfies(nri.mRequests.get(0))) {
9252                     matchingNetworks.add(nai);
9253                 }
9254             }
9255         }
9256         for (final NetworkAgentInfo nai : matchingNetworks) {
9257             final ConnectivityReport report = nai.getConnectivityReport();
9258             if (report == null) {
9259                 continue;
9260             }
9261             if (!checkConnectivityDiagnosticsPermissions(
9262                     nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
9263                 continue;
9264             }
9265 
9266             try {
9267                 cb.onConnectivityReportAvailable(report);
9268             } catch (RemoteException e) {
9269                 // Exception while sending the ConnectivityReport. Move on to the next network.
9270             }
9271         }
9272     }
9273 
handleUnregisterConnectivityDiagnosticsCallback( @onNull IConnectivityDiagnosticsCallback cb, int uid)9274     private void handleUnregisterConnectivityDiagnosticsCallback(
9275             @NonNull IConnectivityDiagnosticsCallback cb, int uid) {
9276         ensureRunningOnConnectivityServiceThread();
9277         final IBinder iCb = cb.asBinder();
9278 
9279         final ConnectivityDiagnosticsCallbackInfo cbInfo =
9280                 mConnectivityDiagnosticsCallbacks.remove(iCb);
9281         if (cbInfo == null) {
9282             if (VDBG) log("Removing diagnostics callback that is not currently registered");
9283             return;
9284         }
9285 
9286         final NetworkRequestInfo nri = cbInfo.mRequestInfo;
9287 
9288         // Caller's UID must either be the registrants (if they are unregistering) or the System's
9289         // (if the Binder died)
9290         if (uid != nri.mUid && uid != Process.SYSTEM_UID) {
9291             if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's");
9292             return;
9293         }
9294 
9295         // Decrement the reference count for this NetworkRequestInfo. The reference count is
9296         // incremented when the NetworkRequestInfo is created as part of
9297         // enforceRequestCountLimit().
9298         nri.decrementRequestCount();
9299 
9300         iCb.unlinkToDeath(cbInfo, 0);
9301     }
9302 
handleNetworkTestedWithExtras( @onNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras)9303     private void handleNetworkTestedWithExtras(
9304             @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) {
9305         final NetworkAgentInfo nai = reportEvent.mNai;
9306         final NetworkCapabilities networkCapabilities =
9307                 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
9308         final ConnectivityReport report =
9309                 new ConnectivityReport(
9310                         reportEvent.mNai.network,
9311                         reportEvent.mTimestampMillis,
9312                         nai.linkProperties,
9313                         networkCapabilities,
9314                         extras);
9315         nai.setConnectivityReport(report);
9316         final List<IConnectivityDiagnosticsCallback> results =
9317                 getMatchingPermissionedCallbacks(nai);
9318         for (final IConnectivityDiagnosticsCallback cb : results) {
9319             try {
9320                 cb.onConnectivityReportAvailable(report);
9321             } catch (RemoteException ex) {
9322                 loge("Error invoking onConnectivityReport", ex);
9323             }
9324         }
9325     }
9326 
handleDataStallSuspected( @onNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod, @NonNull PersistableBundle extras)9327     private void handleDataStallSuspected(
9328             @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod,
9329             @NonNull PersistableBundle extras) {
9330         final NetworkCapabilities networkCapabilities =
9331                 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
9332         final DataStallReport report =
9333                 new DataStallReport(
9334                         nai.network,
9335                         timestampMillis,
9336                         detectionMethod,
9337                         nai.linkProperties,
9338                         networkCapabilities,
9339                         extras);
9340         final List<IConnectivityDiagnosticsCallback> results =
9341                 getMatchingPermissionedCallbacks(nai);
9342         for (final IConnectivityDiagnosticsCallback cb : results) {
9343             try {
9344                 cb.onDataStallSuspected(report);
9345             } catch (RemoteException ex) {
9346                 loge("Error invoking onDataStallSuspected", ex);
9347             }
9348         }
9349     }
9350 
handleNetworkConnectivityReported( @onNull NetworkAgentInfo nai, boolean connectivity)9351     private void handleNetworkConnectivityReported(
9352             @NonNull NetworkAgentInfo nai, boolean connectivity) {
9353         final List<IConnectivityDiagnosticsCallback> results =
9354                 getMatchingPermissionedCallbacks(nai);
9355         for (final IConnectivityDiagnosticsCallback cb : results) {
9356             try {
9357                 cb.onNetworkConnectivityReported(nai.network, connectivity);
9358             } catch (RemoteException ex) {
9359                 loge("Error invoking onNetworkConnectivityReported", ex);
9360             }
9361         }
9362     }
9363 
getNetworkCapabilitiesWithoutUids(@onNull NetworkCapabilities nc)9364     private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) {
9365         final NetworkCapabilities sanitized = new NetworkCapabilities(nc,
9366                 NetworkCapabilities.REDACT_ALL);
9367         sanitized.setUids(null);
9368         sanitized.setAdministratorUids(new int[0]);
9369         sanitized.setOwnerUid(Process.INVALID_UID);
9370         return sanitized;
9371     }
9372 
getMatchingPermissionedCallbacks( @onNull NetworkAgentInfo nai)9373     private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks(
9374             @NonNull NetworkAgentInfo nai) {
9375         final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>();
9376         for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry :
9377                 mConnectivityDiagnosticsCallbacks.entrySet()) {
9378             final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue();
9379             final NetworkRequestInfo nri = cbInfo.mRequestInfo;
9380             // Connectivity Diagnostics rejects multilayer requests at registration hence get(0).
9381             if (nai.satisfies(nri.mRequests.get(0))) {
9382                 if (checkConnectivityDiagnosticsPermissions(
9383                         nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
9384                     results.add(entry.getValue().mCb);
9385                 }
9386             }
9387         }
9388         return results;
9389     }
9390 
isLocationPermissionRequiredForConnectivityDiagnostics( @onNull NetworkAgentInfo nai)9391     private boolean isLocationPermissionRequiredForConnectivityDiagnostics(
9392             @NonNull NetworkAgentInfo nai) {
9393         // TODO(b/188483916): replace with a transport-agnostic location-aware check
9394         return nai.networkCapabilities.hasTransport(TRANSPORT_WIFI);
9395     }
9396 
hasLocationPermission(String packageName, int uid)9397     private boolean hasLocationPermission(String packageName, int uid) {
9398         // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
9399         // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
9400         // call in a try-catch.
9401         try {
9402             if (!mLocationPermissionChecker.checkLocationPermission(
9403                         packageName, null /* featureId */, uid, null /* message */)) {
9404                 return false;
9405             }
9406         } catch (SecurityException e) {
9407             return false;
9408         }
9409 
9410         return true;
9411     }
9412 
ownsVpnRunningOverNetwork(int uid, Network network)9413     private boolean ownsVpnRunningOverNetwork(int uid, Network network) {
9414         for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
9415             if (virtual.propagateUnderlyingCapabilities()
9416                     && virtual.networkCapabilities.getOwnerUid() == uid
9417                     && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)) {
9418                 return true;
9419             }
9420         }
9421 
9422         return false;
9423     }
9424 
9425     @VisibleForTesting
checkConnectivityDiagnosticsPermissions( int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName)9426     boolean checkConnectivityDiagnosticsPermissions(
9427             int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) {
9428         if (checkNetworkStackPermission(callbackPid, callbackUid)) {
9429             return true;
9430         }
9431 
9432         // Administrator UIDs also contains the Owner UID
9433         final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
9434         if (!CollectionUtils.contains(administratorUids, callbackUid)
9435                 && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) {
9436             return false;
9437         }
9438 
9439         return !isLocationPermissionRequiredForConnectivityDiagnostics(nai)
9440                 || hasLocationPermission(callbackPackageName, callbackUid);
9441     }
9442 
9443     @Override
registerConnectivityDiagnosticsCallback( @onNull IConnectivityDiagnosticsCallback callback, @NonNull NetworkRequest request, @NonNull String callingPackageName)9444     public void registerConnectivityDiagnosticsCallback(
9445             @NonNull IConnectivityDiagnosticsCallback callback,
9446             @NonNull NetworkRequest request,
9447             @NonNull String callingPackageName) {
9448         if (request.legacyType != TYPE_NONE) {
9449             throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated."
9450                     + " Please use NetworkCapabilities instead.");
9451         }
9452         final int callingUid = mDeps.getCallingUid();
9453         mAppOpsManager.checkPackage(callingUid, callingPackageName);
9454 
9455         // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid
9456         // and administrator uids to be safe.
9457         final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities);
9458         restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
9459 
9460         final NetworkRequest requestWithId =
9461                 new NetworkRequest(
9462                         nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN);
9463 
9464         // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit.
9465         //
9466         // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in
9467         // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the
9468         // callback's binder death.
9469         final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId);
9470         final ConnectivityDiagnosticsCallbackInfo cbInfo =
9471                 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName);
9472 
9473         mConnectivityDiagnosticsHandler.sendMessage(
9474                 mConnectivityDiagnosticsHandler.obtainMessage(
9475                         ConnectivityDiagnosticsHandler
9476                                 .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
9477                         cbInfo));
9478     }
9479 
9480     @Override
unregisterConnectivityDiagnosticsCallback( @onNull IConnectivityDiagnosticsCallback callback)9481     public void unregisterConnectivityDiagnosticsCallback(
9482             @NonNull IConnectivityDiagnosticsCallback callback) {
9483         Objects.requireNonNull(callback, "callback must be non-null");
9484         mConnectivityDiagnosticsHandler.sendMessage(
9485                 mConnectivityDiagnosticsHandler.obtainMessage(
9486                         ConnectivityDiagnosticsHandler
9487                                 .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
9488                         mDeps.getCallingUid(),
9489                         0,
9490                         callback));
9491     }
9492 
9493     @Override
simulateDataStall(int detectionMethod, long timestampMillis, @NonNull Network network, @NonNull PersistableBundle extras)9494     public void simulateDataStall(int detectionMethod, long timestampMillis,
9495             @NonNull Network network, @NonNull PersistableBundle extras) {
9496         enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS,
9497                 android.Manifest.permission.NETWORK_STACK);
9498         final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
9499         if (!nc.hasTransport(TRANSPORT_TEST)) {
9500             throw new SecurityException("Data Stall simluation is only possible for test networks");
9501         }
9502 
9503         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
9504         if (nai == null || nai.creatorUid != mDeps.getCallingUid()) {
9505             throw new SecurityException("Data Stall simulation is only possible for network "
9506                 + "creators");
9507         }
9508 
9509         // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat
9510         // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the
9511         // Data Stall information as a DataStallReportParcelable and passing to
9512         // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are
9513         // still passed to ConnectivityDiagnostics (with new detection methods masked).
9514         final DataStallReportParcelable p = new DataStallReportParcelable();
9515         p.timestampMillis = timestampMillis;
9516         p.detectionMethod = detectionMethod;
9517 
9518         if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
9519             p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS);
9520         }
9521         if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
9522             p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE);
9523             p.tcpMetricsCollectionPeriodMillis = extras.getInt(
9524                     KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS);
9525         }
9526 
9527         notifyDataStallSuspected(p, network.getNetId());
9528     }
9529 
9530     private class NetdCallback extends BaseNetdUnsolicitedEventListener {
9531         @Override
onInterfaceClassActivityChanged(boolean isActive, int transportType, long timestampNs, int uid)9532         public void onInterfaceClassActivityChanged(boolean isActive, int transportType,
9533                 long timestampNs, int uid) {
9534             mNetworkActivityTracker.setAndReportNetworkActive(isActive, transportType, timestampNs);
9535         }
9536 
9537         @Override
onInterfaceLinkStateChanged(String iface, boolean up)9538         public void onInterfaceLinkStateChanged(String iface, boolean up) {
9539             for (NetworkAgentInfo nai : mNetworkAgentInfos) {
9540                 nai.clatd.interfaceLinkStateChanged(iface, up);
9541             }
9542         }
9543 
9544         @Override
onInterfaceRemoved(String iface)9545         public void onInterfaceRemoved(String iface) {
9546             for (NetworkAgentInfo nai : mNetworkAgentInfos) {
9547                 nai.clatd.interfaceRemoved(iface);
9548             }
9549         }
9550     }
9551 
9552     private final LegacyNetworkActivityTracker mNetworkActivityTracker;
9553 
9554     /**
9555      * Class used for updating network activity tracking with netd and notify network activity
9556      * changes.
9557      */
9558     private static final class LegacyNetworkActivityTracker {
9559         private static final int NO_UID = -1;
9560         private final Context mContext;
9561         private final INetd mNetd;
9562         private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
9563                 new RemoteCallbackList<>();
9564         // Indicate the current system default network activity is active or not.
9565         @GuardedBy("mActiveIdleTimers")
9566         private boolean mNetworkActive;
9567         @GuardedBy("mActiveIdleTimers")
9568         private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap();
9569         private final Handler mHandler;
9570 
9571         private class IdleTimerParams {
9572             public final int timeout;
9573             public final int transportType;
9574 
IdleTimerParams(int timeout, int transport)9575             IdleTimerParams(int timeout, int transport) {
9576                 this.timeout = timeout;
9577                 this.transportType = transport;
9578             }
9579         }
9580 
LegacyNetworkActivityTracker(@onNull Context context, @NonNull Handler handler, @NonNull INetd netd)9581         LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler,
9582                 @NonNull INetd netd) {
9583             mContext = context;
9584             mNetd = netd;
9585             mHandler = handler;
9586         }
9587 
setAndReportNetworkActive(boolean active, int transportType, long tsNanos)9588         public void setAndReportNetworkActive(boolean active, int transportType, long tsNanos) {
9589             sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, tsNanos);
9590             synchronized (mActiveIdleTimers) {
9591                 mNetworkActive = active;
9592                 // If there are no idle timers, it means that system is not monitoring
9593                 // activity, so the system default network for those default network
9594                 // unspecified apps is always considered active.
9595                 //
9596                 // TODO: If the mActiveIdleTimers is empty, netd will actually not send
9597                 // any network activity change event. Whenever this event is received,
9598                 // the mActiveIdleTimers should be always not empty. The legacy behavior
9599                 // is no-op. Remove to refer to mNetworkActive only.
9600                 if (mNetworkActive || mActiveIdleTimers.isEmpty()) {
9601                     mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY));
9602                 }
9603             }
9604         }
9605 
9606         // The network activity should only be updated from ConnectivityService handler thread
9607         // when mActiveIdleTimers lock is held.
9608         @GuardedBy("mActiveIdleTimers")
reportNetworkActive()9609         private void reportNetworkActive() {
9610             final int length = mNetworkActivityListeners.beginBroadcast();
9611             if (DDBG) log("reportNetworkActive, notify " + length + " listeners");
9612             try {
9613                 for (int i = 0; i < length; i++) {
9614                     try {
9615                         mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
9616                     } catch (RemoteException | RuntimeException e) {
9617                         loge("Fail to send network activie to listener " + e);
9618                     }
9619                 }
9620             } finally {
9621                 mNetworkActivityListeners.finishBroadcast();
9622             }
9623         }
9624 
9625         @GuardedBy("mActiveIdleTimers")
handleReportNetworkActivity()9626         public void handleReportNetworkActivity() {
9627             synchronized (mActiveIdleTimers) {
9628                 reportNetworkActive();
9629             }
9630         }
9631 
9632         // This is deprecated and only to support legacy use cases.
transportTypeToLegacyType(int type)9633         private int transportTypeToLegacyType(int type) {
9634             switch (type) {
9635                 case NetworkCapabilities.TRANSPORT_CELLULAR:
9636                     return TYPE_MOBILE;
9637                 case NetworkCapabilities.TRANSPORT_WIFI:
9638                     return TYPE_WIFI;
9639                 case NetworkCapabilities.TRANSPORT_BLUETOOTH:
9640                     return TYPE_BLUETOOTH;
9641                 case NetworkCapabilities.TRANSPORT_ETHERNET:
9642                     return TYPE_ETHERNET;
9643                 default:
9644                     loge("Unexpected transport in transportTypeToLegacyType: " + type);
9645             }
9646             return ConnectivityManager.TYPE_NONE;
9647         }
9648 
sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos)9649         public void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
9650             final Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
9651             intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
9652             intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
9653             intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
9654             final long ident = Binder.clearCallingIdentity();
9655             try {
9656                 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
9657                         RECEIVE_DATA_ACTIVITY_CHANGE,
9658                         null /* resultReceiver */,
9659                         null /* scheduler */,
9660                         0 /* initialCode */,
9661                         null /* initialData */,
9662                         null /* initialExtra */);
9663             } finally {
9664                 Binder.restoreCallingIdentity(ident);
9665             }
9666         }
9667 
9668         /**
9669          * Setup data activity tracking for the given network.
9670          *
9671          * Every {@code setupDataActivityTracking} should be paired with a
9672          * {@link #removeDataActivityTracking} for cleanup.
9673          */
setupDataActivityTracking(NetworkAgentInfo networkAgent)9674         private void setupDataActivityTracking(NetworkAgentInfo networkAgent) {
9675             final String iface = networkAgent.linkProperties.getInterfaceName();
9676 
9677             final int timeout;
9678             final int type;
9679 
9680             if (networkAgent.networkCapabilities.hasTransport(
9681                     NetworkCapabilities.TRANSPORT_CELLULAR)) {
9682                 timeout = Settings.Global.getInt(mContext.getContentResolver(),
9683                         ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE,
9684                         10);
9685                 type = NetworkCapabilities.TRANSPORT_CELLULAR;
9686             } else if (networkAgent.networkCapabilities.hasTransport(
9687                     NetworkCapabilities.TRANSPORT_WIFI)) {
9688                 timeout = Settings.Global.getInt(mContext.getContentResolver(),
9689                         ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI,
9690                         15);
9691                 type = NetworkCapabilities.TRANSPORT_WIFI;
9692             } else {
9693                 return; // do not track any other networks
9694             }
9695 
9696             updateRadioPowerState(true /* isActive */, type);
9697 
9698             if (timeout > 0 && iface != null) {
9699                 try {
9700                     synchronized (mActiveIdleTimers) {
9701                         // Networks start up.
9702                         mNetworkActive = true;
9703                         mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
9704                         mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type));
9705                         reportNetworkActive();
9706                     }
9707                 } catch (Exception e) {
9708                     // You shall not crash!
9709                     loge("Exception in setupDataActivityTracking " + e);
9710                 }
9711             }
9712         }
9713 
9714         /**
9715          * Remove data activity tracking when network disconnects.
9716          */
removeDataActivityTracking(NetworkAgentInfo networkAgent)9717         private void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
9718             final String iface = networkAgent.linkProperties.getInterfaceName();
9719             final NetworkCapabilities caps = networkAgent.networkCapabilities;
9720 
9721             if (iface == null) return;
9722 
9723             final int type;
9724             if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
9725                 type = NetworkCapabilities.TRANSPORT_CELLULAR;
9726             } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
9727                 type = NetworkCapabilities.TRANSPORT_WIFI;
9728             } else {
9729                 return; // do not track any other networks
9730             }
9731 
9732             try {
9733                 updateRadioPowerState(false /* isActive */, type);
9734                 synchronized (mActiveIdleTimers) {
9735                     final IdleTimerParams params = mActiveIdleTimers.remove(iface);
9736                     // The call fails silently if no idle timer setup for this interface
9737                     mNetd.idletimerRemoveInterface(iface, params.timeout,
9738                             Integer.toString(params.transportType));
9739                 }
9740             } catch (Exception e) {
9741                 // You shall not crash!
9742                 loge("Exception in removeDataActivityTracking " + e);
9743             }
9744         }
9745 
9746         /**
9747          * Update data activity tracking when network state is updated.
9748          */
updateDataActivityTracking(NetworkAgentInfo newNetwork, NetworkAgentInfo oldNetwork)9749         public void updateDataActivityTracking(NetworkAgentInfo newNetwork,
9750                 NetworkAgentInfo oldNetwork) {
9751             if (newNetwork != null) {
9752                 setupDataActivityTracking(newNetwork);
9753             }
9754             if (oldNetwork != null) {
9755                 removeDataActivityTracking(oldNetwork);
9756             }
9757         }
9758 
updateRadioPowerState(boolean isActive, int transportType)9759         private void updateRadioPowerState(boolean isActive, int transportType) {
9760             final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class);
9761             switch (transportType) {
9762                 case NetworkCapabilities.TRANSPORT_CELLULAR:
9763                     bs.reportMobileRadioPowerState(isActive, NO_UID);
9764                     break;
9765                 case NetworkCapabilities.TRANSPORT_WIFI:
9766                     bs.reportWifiRadioPowerState(isActive, NO_UID);
9767                     break;
9768                 default:
9769                     logw("Untracked transport type:" + transportType);
9770             }
9771         }
9772 
isDefaultNetworkActive()9773         public boolean isDefaultNetworkActive() {
9774             synchronized (mActiveIdleTimers) {
9775                 // If there are no idle timers, it means that system is not monitoring activity,
9776                 // so the default network is always considered active.
9777                 //
9778                 // TODO : Distinguish between the cases where mActiveIdleTimers is empty because
9779                 // tracking is disabled (negative idle timer value configured), or no active default
9780                 // network. In the latter case, this reports active but it should report inactive.
9781                 return mNetworkActive || mActiveIdleTimers.isEmpty();
9782             }
9783         }
9784 
registerNetworkActivityListener(@onNull INetworkActivityListener l)9785         public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
9786             mNetworkActivityListeners.register(l);
9787         }
9788 
unregisterNetworkActivityListener(@onNull INetworkActivityListener l)9789         public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
9790             mNetworkActivityListeners.unregister(l);
9791         }
9792 
dump(IndentingPrintWriter pw)9793         public void dump(IndentingPrintWriter pw) {
9794             synchronized (mActiveIdleTimers) {
9795                 pw.print("mNetworkActive="); pw.println(mNetworkActive);
9796                 pw.println("Idle timers:");
9797                 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
9798                     pw.print("  "); pw.print(ent.getKey()); pw.println(":");
9799                     final IdleTimerParams params = ent.getValue();
9800                     pw.print("    timeout="); pw.print(params.timeout);
9801                     pw.print(" type="); pw.println(params.transportType);
9802                 }
9803             }
9804         }
9805     }
9806 
9807     /**
9808      * Registers {@link QosSocketFilter} with {@link IQosCallback}.
9809      *
9810      * @param socketInfo the socket information
9811      * @param callback the callback to register
9812      */
9813     @Override
registerQosSocketCallback(@onNull final QosSocketInfo socketInfo, @NonNull final IQosCallback callback)9814     public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo,
9815             @NonNull final IQosCallback callback) {
9816         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork());
9817         if (nai == null || nai.networkCapabilities == null) {
9818             try {
9819                 callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED);
9820             } catch (final RemoteException ex) {
9821                 loge("registerQosCallbackInternal: RemoteException", ex);
9822             }
9823             return;
9824         }
9825         registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai);
9826     }
9827 
9828     /**
9829      * Register a {@link IQosCallback} with base {@link QosFilter}.
9830      *
9831      * @param filter the filter to register
9832      * @param callback the callback to register
9833      * @param nai the agent information related to the filter's network
9834      */
9835     @VisibleForTesting
registerQosCallbackInternal(@onNull final QosFilter filter, @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai)9836     public void registerQosCallbackInternal(@NonNull final QosFilter filter,
9837             @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) {
9838         if (filter == null) throw new IllegalArgumentException("filter must be non-null");
9839         if (callback == null) throw new IllegalArgumentException("callback must be non-null");
9840 
9841         if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
9842             enforceConnectivityRestrictedNetworksPermission();
9843         }
9844         mQosCallbackTracker.registerCallback(callback, filter, nai);
9845     }
9846 
9847     /**
9848      * Unregisters the given callback.
9849      *
9850      * @param callback the callback to unregister
9851      */
9852     @Override
unregisterQosCallback(@onNull final IQosCallback callback)9853     public void unregisterQosCallback(@NonNull final IQosCallback callback) {
9854         Objects.requireNonNull(callback, "callback must be non-null");
9855         mQosCallbackTracker.unregisterCallback(callback);
9856     }
9857 
9858     /**
9859      * Request that a user profile is put by default on a network matching a given preference.
9860      *
9861      * See the documentation for the individual preferences for a description of the supported
9862      * behaviors.
9863      *
9864      * @param profile the profile concerned.
9865      * @param preference the preference for this profile, as one of the PROFILE_NETWORK_PREFERENCE_*
9866      *                   constants.
9867      * @param listener an optional listener to listen for completion of the operation.
9868      */
9869     @Override
setProfileNetworkPreference(@onNull final UserHandle profile, @ConnectivityManager.ProfileNetworkPreference final int preference, @Nullable final IOnCompleteListener listener)9870     public void setProfileNetworkPreference(@NonNull final UserHandle profile,
9871             @ConnectivityManager.ProfileNetworkPreference final int preference,
9872             @Nullable final IOnCompleteListener listener) {
9873         Objects.requireNonNull(profile);
9874         PermissionUtils.enforceNetworkStackPermission(mContext);
9875         if (DBG) {
9876             log("setProfileNetworkPreference " + profile + " to " + preference);
9877         }
9878         if (profile.getIdentifier() < 0) {
9879             throw new IllegalArgumentException("Must explicitly specify a user handle ("
9880                     + "UserHandle.CURRENT not supported)");
9881         }
9882         final UserManager um = mContext.getSystemService(UserManager.class);
9883         if (!um.isManagedProfile(profile.getIdentifier())) {
9884             throw new IllegalArgumentException("Profile must be a managed profile");
9885         }
9886 
9887         final NetworkCapabilities nc;
9888         switch (preference) {
9889             case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT:
9890                 nc = null;
9891                 break;
9892             case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE:
9893                 final UidRange uids = UidRange.createForUser(profile);
9894                 nc = createDefaultNetworkCapabilitiesForUidRange(uids);
9895                 nc.addCapability(NET_CAPABILITY_ENTERPRISE);
9896                 nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
9897                 break;
9898             default:
9899                 throw new IllegalArgumentException(
9900                         "Invalid preference in setProfileNetworkPreference");
9901         }
9902         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_PROFILE_NETWORK_PREFERENCE,
9903                 new Pair<>(new ProfileNetworkPreferences.Preference(profile, nc), listener)));
9904     }
9905 
validateNetworkCapabilitiesOfProfileNetworkPreference( @ullable final NetworkCapabilities nc)9906     private void validateNetworkCapabilitiesOfProfileNetworkPreference(
9907             @Nullable final NetworkCapabilities nc) {
9908         if (null == nc) return; // Null caps are always allowed. It means to remove the setting.
9909         ensureRequestableCapabilities(nc);
9910     }
9911 
createNrisFromProfileNetworkPreferences( @onNull final ProfileNetworkPreferences prefs)9912     private ArraySet<NetworkRequestInfo> createNrisFromProfileNetworkPreferences(
9913             @NonNull final ProfileNetworkPreferences prefs) {
9914         final ArraySet<NetworkRequestInfo> result = new ArraySet<>();
9915         for (final ProfileNetworkPreferences.Preference pref : prefs.preferences) {
9916             // The NRI for a user should be comprised of two layers:
9917             // - The request for the capabilities
9918             // - The request for the default network, for fallback. Create an image of it to
9919             //   have the correct UIDs in it (also a request can only be part of one NRI, because
9920             //   of lookups in 1:1 associations like mNetworkRequests).
9921             // Note that denying a fallback can be implemented simply by not adding the second
9922             // request.
9923             final ArrayList<NetworkRequest> nrs = new ArrayList<>();
9924             nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
9925             nrs.add(createDefaultInternetRequestForTransport(
9926                     TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
9927             setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
9928             final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs,
9929                     PREFERENCE_PRIORITY_PROFILE);
9930             result.add(nri);
9931         }
9932         return result;
9933     }
9934 
handleSetProfileNetworkPreference( @onNull final ProfileNetworkPreferences.Preference preference, @Nullable final IOnCompleteListener listener)9935     private void handleSetProfileNetworkPreference(
9936             @NonNull final ProfileNetworkPreferences.Preference preference,
9937             @Nullable final IOnCompleteListener listener) {
9938         validateNetworkCapabilitiesOfProfileNetworkPreference(preference.capabilities);
9939 
9940         mProfileNetworkPreferences = mProfileNetworkPreferences.plus(preference);
9941         mSystemNetworkRequestCounter.transact(
9942                 mDeps.getCallingUid(), mProfileNetworkPreferences.preferences.size(),
9943                 () -> {
9944                     final ArraySet<NetworkRequestInfo> nris =
9945                             createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences);
9946                     replaceDefaultNetworkRequestsForPreference(nris, PREFERENCE_PRIORITY_PROFILE);
9947                 });
9948         // Finally, rematch.
9949         rematchAllNetworksAndRequests();
9950 
9951         if (null != listener) {
9952             try {
9953                 listener.onComplete();
9954             } catch (RemoteException e) {
9955                 loge("Listener for setProfileNetworkPreference has died");
9956             }
9957         }
9958     }
9959 
9960     @VisibleForTesting
9961     @NonNull
createNrisFromMobileDataPreferredUids( @onNull final Set<Integer> uids)9962     ArraySet<NetworkRequestInfo> createNrisFromMobileDataPreferredUids(
9963             @NonNull final Set<Integer> uids) {
9964         final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
9965         if (uids.size() == 0) {
9966             // Should not create NetworkRequestInfo if no preferences. Without uid range in
9967             // NetworkRequestInfo, makeDefaultForApps() would treat it as a illegal NRI.
9968             if (DBG) log("Don't create NetworkRequestInfo because no preferences");
9969             return nris;
9970         }
9971 
9972         final List<NetworkRequest> requests = new ArrayList<>();
9973         // The NRI should be comprised of two layers:
9974         // - The request for the mobile network preferred.
9975         // - The request for the default network, for fallback.
9976         requests.add(createDefaultInternetRequestForTransport(
9977                 TRANSPORT_CELLULAR, NetworkRequest.Type.REQUEST));
9978         requests.add(createDefaultInternetRequestForTransport(
9979                 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
9980         final Set<UidRange> ranges = new ArraySet<>();
9981         for (final int uid : uids) {
9982             ranges.add(new UidRange(uid, uid));
9983         }
9984         setNetworkRequestUids(requests, ranges);
9985         nris.add(new NetworkRequestInfo(Process.myUid(), requests,
9986                 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED));
9987         return nris;
9988     }
9989 
handleMobileDataPreferredUidsChanged()9990     private void handleMobileDataPreferredUidsChanged() {
9991         mMobileDataPreferredUids = ConnectivitySettingsManager.getMobileDataPreferredUids(mContext);
9992         mSystemNetworkRequestCounter.transact(
9993                 mDeps.getCallingUid(), 1 /* numOfNewRequests */,
9994                 () -> {
9995                     final ArraySet<NetworkRequestInfo> nris =
9996                             createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids);
9997                     replaceDefaultNetworkRequestsForPreference(nris,
9998                             PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
9999                 });
10000         // Finally, rematch.
10001         rematchAllNetworksAndRequests();
10002     }
10003 
enforceAutomotiveDevice()10004     private void enforceAutomotiveDevice() {
10005         final boolean isAutomotiveDevice =
10006                 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
10007         if (!isAutomotiveDevice) {
10008             throw new UnsupportedOperationException(
10009                     "setOemNetworkPreference() is only available on automotive devices.");
10010         }
10011     }
10012 
10013     /**
10014      * Used by automotive devices to set the network preferences used to direct traffic at an
10015      * application level as per the given OemNetworkPreferences. An example use-case would be an
10016      * automotive OEM wanting to provide connectivity for applications critical to the usage of a
10017      * vehicle via a particular network.
10018      *
10019      * Calling this will overwrite the existing preference.
10020      *
10021      * @param preference {@link OemNetworkPreferences} The application network preference to be set.
10022      * @param listener {@link ConnectivityManager.OnCompleteListener} Listener used
10023      * to communicate completion of setOemNetworkPreference();
10024      */
10025     @Override
setOemNetworkPreference( @onNull final OemNetworkPreferences preference, @Nullable final IOnCompleteListener listener)10026     public void setOemNetworkPreference(
10027             @NonNull final OemNetworkPreferences preference,
10028             @Nullable final IOnCompleteListener listener) {
10029 
10030         Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
10031         // Only bypass the permission/device checks if this is a valid test request.
10032         if (isValidTestOemNetworkPreference(preference)) {
10033             enforceManageTestNetworksPermission();
10034         } else {
10035             enforceAutomotiveDevice();
10036             enforceOemNetworkPreferencesPermission();
10037             validateOemNetworkPreferences(preference);
10038         }
10039 
10040         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE,
10041                 new Pair<>(preference, listener)));
10042     }
10043 
10044     /**
10045      * Check the validity of an OEM network preference to be used for testing purposes.
10046      * @param preference the preference to validate
10047      * @return true if this is a valid OEM network preference test request.
10048      */
isValidTestOemNetworkPreference( @onNull final OemNetworkPreferences preference)10049     private boolean isValidTestOemNetworkPreference(
10050             @NonNull final OemNetworkPreferences preference) {
10051         // Allow for clearing of an existing OemNetworkPreference used for testing.
10052         // This isn't called on the handler thread so it is possible that mOemNetworkPreferences
10053         // changes after this check is complete. This is an unlikely scenario as calling of this API
10054         // is controlled by the OEM therefore the added complexity is not worth adding given those
10055         // circumstances. That said, it is an edge case to be aware of hence this comment.
10056         final boolean isValidTestClearPref = preference.getNetworkPreferences().size() == 0
10057                 && isTestOemNetworkPreference(mOemNetworkPreferences);
10058         return isTestOemNetworkPreference(preference) || isValidTestClearPref;
10059     }
10060 
isTestOemNetworkPreference(@onNull final OemNetworkPreferences preference)10061     private boolean isTestOemNetworkPreference(@NonNull final OemNetworkPreferences preference) {
10062         final Map<String, Integer> prefMap = preference.getNetworkPreferences();
10063         return prefMap.size() == 1
10064                 && (prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST)
10065                 || prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST_ONLY));
10066     }
10067 
validateOemNetworkPreferences(@onNull OemNetworkPreferences preference)10068     private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) {
10069         for (@OemNetworkPreferences.OemNetworkPreference final int pref
10070                 : preference.getNetworkPreferences().values()) {
10071             if (pref <= 0 || OemNetworkPreferences.OEM_NETWORK_PREFERENCE_MAX < pref) {
10072                 throw new IllegalArgumentException(
10073                         OemNetworkPreferences.oemNetworkPreferenceToString(pref)
10074                                 + " is an invalid value.");
10075             }
10076         }
10077     }
10078 
handleSetOemNetworkPreference( @onNull final OemNetworkPreferences preference, @Nullable final IOnCompleteListener listener)10079     private void handleSetOemNetworkPreference(
10080             @NonNull final OemNetworkPreferences preference,
10081             @Nullable final IOnCompleteListener listener) {
10082         Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
10083         if (DBG) {
10084             log("set OEM network preferences :" + preference.toString());
10085         }
10086 
10087         mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference);
10088         final int uniquePreferenceCount = new ArraySet<>(
10089                 preference.getNetworkPreferences().values()).size();
10090         mSystemNetworkRequestCounter.transact(
10091                 mDeps.getCallingUid(), uniquePreferenceCount,
10092                 () -> {
10093                     final ArraySet<NetworkRequestInfo> nris =
10094                             new OemNetworkRequestFactory()
10095                                     .createNrisFromOemNetworkPreferences(preference);
10096                     replaceDefaultNetworkRequestsForPreference(nris, PREFERENCE_PRIORITY_OEM);
10097                 });
10098         mOemNetworkPreferences = preference;
10099 
10100         if (null != listener) {
10101             try {
10102                 listener.onComplete();
10103             } catch (RemoteException e) {
10104                 loge("Can't send onComplete in handleSetOemNetworkPreference", e);
10105             }
10106         }
10107     }
10108 
replaceDefaultNetworkRequestsForPreference( @onNull final Set<NetworkRequestInfo> nris, final int preferencePriority)10109     private void replaceDefaultNetworkRequestsForPreference(
10110             @NonNull final Set<NetworkRequestInfo> nris, final int preferencePriority) {
10111         // Skip the requests which are set by other network preference. Because the uid range rules
10112         // should stay in netd.
10113         final Set<NetworkRequestInfo> requests = new ArraySet<>(mDefaultNetworkRequests);
10114         requests.removeIf(request -> request.mPreferencePriority != preferencePriority);
10115         handleRemoveNetworkRequests(requests);
10116         addPerAppDefaultNetworkRequests(nris);
10117     }
10118 
addPerAppDefaultNetworkRequests(@onNull final Set<NetworkRequestInfo> nris)10119     private void addPerAppDefaultNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
10120         ensureRunningOnConnectivityServiceThread();
10121         mDefaultNetworkRequests.addAll(nris);
10122         final ArraySet<NetworkRequestInfo> perAppCallbackRequestsToUpdate =
10123                 getPerAppCallbackRequestsToUpdate();
10124         final ArraySet<NetworkRequestInfo> nrisToRegister = new ArraySet<>(nris);
10125         mSystemNetworkRequestCounter.transact(
10126                 mDeps.getCallingUid(), perAppCallbackRequestsToUpdate.size(),
10127                 () -> {
10128                     nrisToRegister.addAll(
10129                             createPerAppCallbackRequestsToRegister(perAppCallbackRequestsToUpdate));
10130                     handleRemoveNetworkRequests(perAppCallbackRequestsToUpdate);
10131                     handleRegisterNetworkRequests(nrisToRegister);
10132                 });
10133     }
10134 
10135     /**
10136      * All current requests that are tracking the default network need to be assessed as to whether
10137      * or not the current set of per-application default requests will be changing their default
10138      * network. If so, those requests will need to be updated so that they will send callbacks for
10139      * default network changes at the appropriate time. Additionally, those requests tracking the
10140      * default that were previously updated by this flow will need to be reassessed.
10141      * @return the nris which will need to be updated.
10142      */
getPerAppCallbackRequestsToUpdate()10143     private ArraySet<NetworkRequestInfo> getPerAppCallbackRequestsToUpdate() {
10144         final ArraySet<NetworkRequestInfo> defaultCallbackRequests = new ArraySet<>();
10145         // Get the distinct nris to check since for multilayer requests, it is possible to have the
10146         // same nri in the map's values for each of its NetworkRequest objects.
10147         final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(mNetworkRequests.values());
10148         for (final NetworkRequestInfo nri : nris) {
10149             // Include this nri if it is currently being tracked.
10150             if (isPerAppTrackedNri(nri)) {
10151                 defaultCallbackRequests.add(nri);
10152                 continue;
10153             }
10154             // We only track callbacks for requests tracking the default.
10155             if (NetworkRequest.Type.TRACK_DEFAULT != nri.mRequests.get(0).type) {
10156                 continue;
10157             }
10158             // Include this nri if it will be tracked by the new per-app default requests.
10159             final boolean isNriGoingToBeTracked =
10160                     getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest;
10161             if (isNriGoingToBeTracked) {
10162                 defaultCallbackRequests.add(nri);
10163             }
10164         }
10165         return defaultCallbackRequests;
10166     }
10167 
10168     /**
10169      * Create nris for those network requests that are currently tracking the default network that
10170      * are being controlled by a per-application default.
10171      * @param perAppCallbackRequestsForUpdate the baseline network requests to be used as the
10172      * foundation when creating the nri. Important items include the calling uid's original
10173      * NetworkRequest to be used when mapping callbacks as well as the caller's uid and name. These
10174      * requests are assumed to have already been validated as needing to be updated.
10175      * @return the Set of nris to use when registering network requests.
10176      */
createPerAppCallbackRequestsToRegister( @onNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate)10177     private ArraySet<NetworkRequestInfo> createPerAppCallbackRequestsToRegister(
10178             @NonNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate) {
10179         final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>();
10180         for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) {
10181             final NetworkRequestInfo trackingNri =
10182                     getDefaultRequestTrackingUid(callbackRequest.mAsUid);
10183 
10184             // If this nri is not being tracked, then change it back to an untracked nri.
10185             if (trackingNri == mDefaultRequest) {
10186                 callbackRequestsToRegister.add(new NetworkRequestInfo(
10187                         callbackRequest,
10188                         Collections.singletonList(callbackRequest.getNetworkRequestForCallback())));
10189                 continue;
10190             }
10191 
10192             final NetworkRequest request = callbackRequest.mRequests.get(0);
10193             callbackRequestsToRegister.add(new NetworkRequestInfo(
10194                     callbackRequest,
10195                     copyNetworkRequestsForUid(
10196                             trackingNri.mRequests, callbackRequest.mAsUid,
10197                             callbackRequest.mUid, request.getRequestorPackageName())));
10198         }
10199         return callbackRequestsToRegister;
10200     }
10201 
setNetworkRequestUids(@onNull final List<NetworkRequest> requests, @NonNull final Set<UidRange> uids)10202     private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests,
10203             @NonNull final Set<UidRange> uids) {
10204         for (final NetworkRequest req : requests) {
10205             req.networkCapabilities.setUids(UidRange.toIntRanges(uids));
10206         }
10207     }
10208 
10209     /**
10210      * Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}.
10211      */
10212     @VisibleForTesting
10213     final class OemNetworkRequestFactory {
createNrisFromOemNetworkPreferences( @onNull final OemNetworkPreferences preference)10214         ArraySet<NetworkRequestInfo> createNrisFromOemNetworkPreferences(
10215                 @NonNull final OemNetworkPreferences preference) {
10216             final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
10217             final SparseArray<Set<Integer>> uids =
10218                     createUidsFromOemNetworkPreferences(preference);
10219             for (int i = 0; i < uids.size(); i++) {
10220                 final int key = uids.keyAt(i);
10221                 final Set<Integer> value = uids.valueAt(i);
10222                 final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value);
10223                 // No need to add an nri without any requests.
10224                 if (0 == nri.mRequests.size()) {
10225                     continue;
10226                 }
10227                 nris.add(nri);
10228             }
10229 
10230             return nris;
10231         }
10232 
createUidsFromOemNetworkPreferences( @onNull final OemNetworkPreferences preference)10233         private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences(
10234                 @NonNull final OemNetworkPreferences preference) {
10235             final SparseArray<Set<Integer>> prefToUids = new SparseArray<>();
10236             final PackageManager pm = mContext.getPackageManager();
10237             final List<UserHandle> users =
10238                     mContext.getSystemService(UserManager.class).getUserHandles(true);
10239             if (null == users || users.size() == 0) {
10240                 if (VDBG || DDBG) {
10241                     log("No users currently available for setting the OEM network preference.");
10242                 }
10243                 return prefToUids;
10244             }
10245             for (final Map.Entry<String, Integer> entry :
10246                     preference.getNetworkPreferences().entrySet()) {
10247                 @OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue();
10248                 // Add the rules for all users as this policy is device wide.
10249                 for (final UserHandle user : users) {
10250                     try {
10251                         final int uid = pm.getApplicationInfoAsUser(entry.getKey(), 0, user).uid;
10252                         if (!prefToUids.contains(pref)) {
10253                             prefToUids.put(pref, new ArraySet<>());
10254                         }
10255                         prefToUids.get(pref).add(uid);
10256                     } catch (PackageManager.NameNotFoundException e) {
10257                         // Although this may seem like an error scenario, it is ok that uninstalled
10258                         // packages are sent on a network preference as the system will watch for
10259                         // package installations associated with this network preference and update
10260                         // accordingly. This is done to minimize race conditions on app install.
10261                         continue;
10262                     }
10263                 }
10264             }
10265             return prefToUids;
10266         }
10267 
createNriFromOemNetworkPreferences( @emNetworkPreferences.OemNetworkPreference final int preference, @NonNull final Set<Integer> uids)10268         private NetworkRequestInfo createNriFromOemNetworkPreferences(
10269                 @OemNetworkPreferences.OemNetworkPreference final int preference,
10270                 @NonNull final Set<Integer> uids) {
10271             final List<NetworkRequest> requests = new ArrayList<>();
10272             // Requests will ultimately be evaluated by order of insertion therefore it matters.
10273             switch (preference) {
10274                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID:
10275                     requests.add(createUnmeteredNetworkRequest());
10276                     requests.add(createOemPaidNetworkRequest());
10277                     requests.add(createDefaultInternetRequestForTransport(
10278                             TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
10279                     break;
10280                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
10281                     requests.add(createUnmeteredNetworkRequest());
10282                     requests.add(createOemPaidNetworkRequest());
10283                     break;
10284                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY:
10285                     requests.add(createOemPaidNetworkRequest());
10286                     break;
10287                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
10288                     requests.add(createOemPrivateNetworkRequest());
10289                     break;
10290                 case OEM_NETWORK_PREFERENCE_TEST:
10291                     requests.add(createUnmeteredNetworkRequest());
10292                     requests.add(createTestNetworkRequest());
10293                     requests.add(createDefaultRequest());
10294                     break;
10295                 case OEM_NETWORK_PREFERENCE_TEST_ONLY:
10296                     requests.add(createTestNetworkRequest());
10297                     break;
10298                 default:
10299                     // This should never happen.
10300                     throw new IllegalArgumentException("createNriFromOemNetworkPreferences()"
10301                             + " called with invalid preference of " + preference);
10302             }
10303 
10304             final ArraySet<UidRange> ranges = new ArraySet<>();
10305             for (final int uid : uids) {
10306                 ranges.add(new UidRange(uid, uid));
10307             }
10308             setNetworkRequestUids(requests, ranges);
10309             return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_PRIORITY_OEM);
10310         }
10311 
createUnmeteredNetworkRequest()10312         private NetworkRequest createUnmeteredNetworkRequest() {
10313             final NetworkCapabilities netcap = createDefaultPerAppNetCap()
10314                     .addCapability(NET_CAPABILITY_NOT_METERED)
10315                     .addCapability(NET_CAPABILITY_VALIDATED);
10316             return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap);
10317         }
10318 
createOemPaidNetworkRequest()10319         private NetworkRequest createOemPaidNetworkRequest() {
10320             // NET_CAPABILITY_OEM_PAID is a restricted capability.
10321             final NetworkCapabilities netcap = createDefaultPerAppNetCap()
10322                     .addCapability(NET_CAPABILITY_OEM_PAID)
10323                     .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
10324             return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
10325         }
10326 
createOemPrivateNetworkRequest()10327         private NetworkRequest createOemPrivateNetworkRequest() {
10328             // NET_CAPABILITY_OEM_PRIVATE is a restricted capability.
10329             final NetworkCapabilities netcap = createDefaultPerAppNetCap()
10330                     .addCapability(NET_CAPABILITY_OEM_PRIVATE)
10331                     .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
10332             return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
10333         }
10334 
createDefaultPerAppNetCap()10335         private NetworkCapabilities createDefaultPerAppNetCap() {
10336             final NetworkCapabilities netcap = new NetworkCapabilities();
10337             netcap.addCapability(NET_CAPABILITY_INTERNET);
10338             netcap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
10339             return netcap;
10340         }
10341 
createTestNetworkRequest()10342         private NetworkRequest createTestNetworkRequest() {
10343             final NetworkCapabilities netcap = new NetworkCapabilities();
10344             netcap.clearAll();
10345             netcap.addTransportType(TRANSPORT_TEST);
10346             return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
10347         }
10348     }
10349 }
10350