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